关于 tinysearch
TinySearch 是面向 AI Agent 的快速发现搜索与可自托管网络研究 MCP 服务。它搜索、抓取并在本地重排序网页,只向 Agent 返回带来源 URL 的相关证据,适合需要控制 Token 成本的开发者。
主要功能
- 01search 批量快速发现结果,不爬取不重排
- 02scrape_urls 读取 1 至 5 个已知页面
- 03本地 BM25 与嵌入重排序选取段落
- 04返回原始页面文本及来源 URL
- 05DDGS 默认搜索后端,无需付费搜索密钥
- 06浏览器工具处理需要交互的页面
适用场景
- 01为编码 Agent 检索技术文档并引用原文
- 02对多个独立子问题并行进行网页搜索
- 03读取需要 JavaScript 渲染的页面内容
MCP 相关
TinySearch 作为 MCP 服务运行,向客户端暴露 search、scrape_urls、browser_navigate、browser_act 和 get_current_datetime 等工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx tinysuite-searchMCP_TRANSPORTMCP transport to serve: stdio (default), sse, or streamable-http.TINYSEARCH_CONFIG_PATHPath to a tinysearch_config.json inside the container, for overriding search/embedding defaults.SEARXNG_URLSearXNG search endpoint URL. Only needed if not using the bundled Compose SearXNG service.TINYSEARCH_EMBEDDING_BACKENDEmbedding implementation: onnx (default) or openai_compatible.TINYSEARCH_EMBEDDING_MODELLocal ONNX preset (fast, balanced, quality) or a Hugging Face ONNX repository id.OTEL_SERVICE_NAMEOpenTelemetry service.name resource attribute; defaults to tinysearch.OTEL_EXPORTER_OTLP_ENDPOINTCommon OTLP endpoint for optional TinySearch traces and metrics.OTEL_EXPORTER_OTLP_PROTOCOLOTLP transport: http/protobuf (default) or grpc.OTEL_EXPORTER_OTLP_HEADERS密钥Optional authentication or routing headers for the OTLP exporter.OTEL_RESOURCE_ATTRIBUTESAdditional standard OpenTelemetry resource attributes.OTEL_TRACES_EXPORTERSet to otlp to enable traces explicitly or none to disable them.OTEL_METRICS_EXPORTERSet to otlp to enable metrics explicitly or none to disable them.OTEL_SDK_DISABLEDSet true to disable all OpenTelemetry signals.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
TinySearch
把 Token 用在答案上,而不是网页上。
TinySearch 在本地搜索、抓取并重新排序网页,然后只向你的 Agent 提供值得纳入上下文的证据。
TinySearch 是一款面向 AI Agent 的可自托管网页研究工具。它会搜索网页、阅读优质页面、移除低价值内容,并返回附有来源 URL 的精简证据。
模型接收的是有用段落,无需付费处理整篇网页。
TinySearch 是 TinySuite 的一部分。TinySuite 是一套专注型工具,旨在通过智能检索、筛选和上下文管理技术,最大限度减少 Token 使用量,从而降低 Agent 式操作的成本。
选择一个层级
| 层级 | 适用场景 | 入口点 | 搜索后端 |
|---|---|---|---|
| 1. Python 库 | 使用 TinySuite 或 Python 构建项目 | pip install tinysuite-search | DDGS |
| 2. 一条命令启动 MCP | 希望 MCP 客户端为你启动 TinySearch | uvx --from "tinysuite-search[server]" tinysearch | DDGS |
| 3. Docker + SearXNG | 需要完整的可自托管技术栈和 HTTP MCP | docker compose ... up -d | 捆绑的 SearXNG |
层级 1 和 2 无需搜索服务。层级 3 会额外提供专用的 SearXNG 服务、持久化模型存储和网络 MCP 端点。Docker 设置请参阅安装指南。
Agent 研究的高昂成本在于上下文
搜索结果还不能算有用的证据。Agent 往往需要打开多个页面、读取导航和模板内容,还要消耗付费输入令牌来判断哪些段落有价值。
TinySearch 将这部分工作放到模型运行之前:
flowchart LR
A[Question] --> B[Search and crawl]
B --> C[Local hybrid reranking]
C --> D[Compact evidence<br/>with source URLs]
D --> E[Your agent]
这从三个方面降低成本:
- 缩小模型上下文。 只返回排名最高的证据片段,并将证据量控制在预算范围内。
- 默认无需按量计费的搜索 API。 TinySearch 可以通过 DDGS 搜索,无需付费搜索服务商。
- 默认在本地检索。 ONNX 嵌入和混合重排在你的机器上运行,不会产生嵌入 API 费用。
广泛搜索。在本地读取。只为重要证据支付模型费用。
这是检索,而非摘要:TinySearch 使用本地 BM25 和嵌入重排来筛选值得保留的段落,不会调用模型改写或压缩页面。返回的每个片段都是未经修改的原始页面文本,因此你引用的内容就是页面实际写下的内容。这样可以让整个流程快速运行,并且能在本地免费使用;代价是压缩程度不如专门的内容缩减模型。我们日后可能会探索引入经过训练的缩减步骤,但目前 TinySearch 尚未包含此功能。
实际节省的费用取决于页面、证据限制、客户端模型和服务商定价。TinySearch 会减少发送给模型的网页内容,但不会控制客户端之后如何使用这些证据。
成本面板采用每百万输入令牌 $3.00 的示例费率,未计入搜索、抓取、模型输出和下游 Agent 使用成本。
朴素基准并非虚构的对照产品,而是针对每个查询抓取同样页面、未经筛选便发送给模型的方案,也就是通用的“先搜索,再抓取页面”工具(纯粹的网页搜索加抓取循环,大多数编码 Agent 都内置了这类功能)。基准以当前推荐流程(search 后接 scrape_urls)为参照,并根据实际 MCP 工具结果文本进行计数;这也是 TinySearch 的主要接口。你可以自行复现或重新运行:
python scripts/benchmark_token_savings.py --json-out report.json
快速开始
安装 uv 后,将 TinySearch 添加到任意 MCP 客户端:
{
"mcpServers": {
"tinysearch": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"tinysuite-search[server]",
"tinysearch"
]
}
}
}
客户端需要时会通过 stdio 启动 TinySearch。无需克隆仓库、托管账户或付费搜索密钥。
快速的 search 无需启动 Chromium 或嵌入模型。首次抓取时会初始化 Chromium;定向抓取也会初始化已配置的嵌入模型。如果要使用这些工作流,请提前预热两者:
uvx --from "tinysuite-search[server]" tinysearch setup
MCP 和 FastAPI 服务会在相邻请求之间让抓取浏览器保持运行,并在 browser_idle_shutdown_seconds 之后将其关闭。直接调用 Python 时,则保留其短生命周期,并由调用方负责管理。
更倾向于使用 Docker、远程 MCP 端点或从源代码检出?请参阅安装指南。
MCP 工具
| 工具 | 使用场景 |
|---|---|
search(items) | 需要快速发现内容,按后端排序,无需抓取或重新排序;如有需要,可批量处理相互独立的子问题 |
scrape_urls(items) | 已知 1 到 5 个页面;每个条目都可以使用 *,表示使用已配置的页面顺序清理后令牌预算 |
browser_navigate / browser_act | 页面需要交互才能读取;请参阅浏览器自动化 |
get_current_datetime() | 问题取决于当前日期或时间 |
TinySearch 有意专注于特定用途。它是一个检索层,而非另一个 Agent、聊天界面、托管搜索产品或永久网络索引。
完整参数和响应约定请参阅 MCP 工具参考。
Agent 能获得什么
TinySearch 不会再调用一次大模型来编写最终答案。推荐的流程是先用 search 进行轻量发现,再用 scrape_urls 获取值得阅读的页面。
搜索会返回结构化 JSON。简单查询使用一个条目;只有在处理相互独立的子问题或来源策略时,才添加多个条目。domains 是严格的正向来源限制,接受域名及其子域名:
{"items":[{"query":"Form 8-K Tesla","domains":["sec.gov"]}]}
每个搜索条目都会报告自己的结果和简明的后端尝试信息。零结果响应与后端受阻、不可用或无效的情况不同。
scrape_urls 会返回选取的 Markdown 证据以及单独的相关链接导航候选项,两者各自有独立配置的令牌上限。
MCP 仍使用标准的 JSON-RPC 传输封装,包括协议级错误和可选的 structuredContent。对于需要存储、检查或转换证据的应用,Python 和 FastAPI 会保留其结构化 JSON 约定。
工作原理
search会返回按后端排序的标题、URL、预览、上游日期和后端结果,不会启动 Chromium 或嵌入模型。scrape_urls会并发读取 1 到 5 个已知页面。省略条目的查询,或使用"*",即可在配置的令牌预算内按页面顺序保留清理后的 Markdown。- 当 TinySearch 应先对页面分块并进行混合排序,再返回证据时,请提供聚焦的条目查询。
- 仅当
scrape_urls因内容需要交互而无法获取时,browser_*工具才会介入。请参阅 浏览器自动化。
Python 库
TinySearch 也可以作为常规 Python 包使用:
pip install tinysuite-search
可选的 OpenTelemetry 导出
只有在明确配置 OpenTelemetry 时,TinySearch 才会生成与供应商无关的跟踪和指标。未安装或未配置遥测时,库、MCP 和 FastAPI 的常规行为不变。
为独立 MCP 服务安装可选的导出器支持:
uvx --from "tinysuite-search[server,telemetry]" tinysearch
官方 Docker 镜像也包含相同的可选支持。在任一部署中设置标准的 OTel 变量,即可通过通用端点启用跟踪和指标:
OTEL_SERVICE_NAME=tinysearch \
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318 \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
tinysearch serve
默认使用 http/protobuf,也支持 grpc。使用 OTEL_TRACES_EXPORTER=none、OTEL_METRICS_EXPORTER=none 或 OTEL_SDK_DISABLED=true 可禁用遥测。标准的资源、标头、超时、采样器和信号专用端点设置都会传递给 OpenTelemetry SDK;请将 OTEL_EXPORTER_OTLP_HEADERS 视为密钥。
TinySearch 会导出操作/阶段耗时、结果、计数、后端状态、浏览器使用情况、令牌计数和嵌入模型元数据。它绝不会导出查询、URL、域名、提示词、文档、摘要片段、请求标头、凭据、配置路径、原始错误、异常堆栈、MCP 参数或 MCP 结果。直接使用 Python 库的用户需自行配置 OTel 提供程序;TinySearch 仅会为独立 MCP 和 FastAPI 服务入口点自动配置。
import asyncio
from tinysearch import scrape_urls, search
async def main():
results = await search([{"query": "Python async tasks"}])
print(results["items"][0]["results"])
page_url = results["items"][0]["results"][0]["url"]
evidence = await scrape_urls([{
"url": page_url,
"query": "How does asyncio cancellation work?",
}])
print(evidence["results"])
asyncio.run(main())
Python API 会返回稳定且可序列化为 JSON 的结果。search 接受 1 到 5 个项目,并使用配置的单项结果上限。scrape_urls 接受每次调用的 max_tokens 预算(默认为 4,000);省略项目的抓取查询,或使用 "*",即可按页面顺序处理。将结构化证据呈现为大模型提示词是显式操作,因此应用可以先存储、检查、转换结果或为其设置预算。
可选的 FastAPI 应用提供对应的接口。POST /search 接受相同的批量 JSON 契约。
POST /scrape 接受 1 到 5 个 { "url", "query" } 项目,并始终返回结构化的逐项结果。
POST /browser/navigate 和 POST /browser/act 对应两个 MCP 浏览器工具,并以 { "result": "..." } 的形式返回其无障碍视图。
该应用还提供 /health、/current_datetime 和只读的 /config;写入配置需要显式启用环境变量。
搜索后端
TinySearch 会根据配置选择网页搜索后端,因此你可以先不使用搜索服务,之后再添加,无需更改代码。
"ddgs"(原生默认):在进程内查询ddgs包的自动后端选择。无需部署 SearXNG。"searxng"(Docker 默认):查询可自托管的 SearXNG 实例。如果后端失败,则回退到ddgs,除非将search_backend_fallback设为false。"duckduckgo":跳过 SearXNG,并以仅 DuckDuckGo 模式查询ddgs。"auto":尝试 SearXNG;任何后端失败时都会回退到ddgs。
设置 BRAVE_SEARCH_API_KEY 环境变量,可将 Brave 官方 Web Search API 添加为 ddgs 和 duckduckgo 后端的密钥回退选项。只有当主要调用出错或未返回结果时,才会查询 Brave。
完整的密钥参考、SearXNG JSON 输出设置和 Compose 详情,请参阅配置参考。
浏览器自动化
scrape_urls 是静态抓取,无法看到页面加载后由 JavaScript 渲染的内容、Cookie 提示页后的内容、“加载更多”控件后的内容,或客户端搜索界面中的内容。对于这类页面,TinySearch 会驱动真实浏览器。
安装无需额外花费。TinySearch 已通过 Crawl4AI 依赖 Playwright,并已安装用于抓取的 Chromium,因此浏览器工具会复用同一个驱动和同一个浏览器:无需第二个运行时、第二个浏览器或子进程。
两个工具:browser_navigate 和 browser_act。后者通过一个 action 参数整合了 look、click、type、wait_for、tabs 和 close。
这种拆分是有意为之。MCP 无法对工具进行分组或嵌套——tools/list 是扁平的,而且每次请求都会重新向模型发送每个架构——因此,七个独立的浏览器工具会让服务端的架构占据主导。将入口单独发布为一个工具,并通过一个分发器整合单个页面会话的生命周期,可以让整个服务的架构在五个工具间保持精简。
没有单独的查找工具,因为查找不是点击的同类操作,而是对结果进行筛选。这两个工具都接受一个 find 参数:先尝试将其作为正则表达式(因此 "a|b" 可直接使用);如果不是有效的正则表达式,则回退为不区分大小写的字面子字符串匹配。这样会将返回值限定为匹配的节点及其上下文,而不是整个树。这使得一次调用既能执行操作又能报告结果:点击后显示的表格会作为表格返回,因此 Agent 无需再调用一次来缩小第一次调用的结果范围。早期版本将其拆分为 find 和 find_regex;当模型在普通子字符串参数中使用交替语法,却只得到“没有匹配项”而非提示时,就会白白多一次往返,因此我们将两者合并了。
模型会读取一棵精简的无障碍树,其中每个节点都带有稳定的 ref 和名称,而 TinySearch 会通过真实的浏览器输入事件对其进行操作:
browser_navigate -> url: "...", find: "Accept" -> "- button \"Accept all\" [ref=e79]"
browser_act -> action: "click", target: "e79", find: "Results"
不会合成 DOM 事件或编造 CSS 选择器,click/type 只接受模型实际观察到的 ref,绝不接受原始选择器。
三个有意的设计选择:
- 没有工具可以执行代码。 没有
evaluate工具,也没有用于填写表单、上传或拖动的工具。页面即使在自身渲染的文本中注入指令,也没有危险的操作可供执行,因为这项能力根本不存在,而非仅仅受到劝阻。 find用于控制令牌数,depth是后备方案。 任何返回视图的调用都会接受find,将视图缩小到匹配节点及其上下文。当无法通过筛选器指定目标时,depth会返回一个更浅但仍有效的树,而不是截断的字符串——对于大型页面,约为 700 个字符,而不是约 33,000 个。- Cookie 会持久保存,会话不会。 设置
browser_storage_state_path后,接受一次的同意横幅就无需在之后的每次导航中重复处理。会话保持隔离,因此不会占用浏览器配置文件锁,且并发客户端不会相互冲突。该文件是服务端路径,绝不会暴露给模型或通过 HTTP 暴露。
若要完全关闭这些工具,请设置 "browser_backend": "off";之后它们会从工具列表中移除,而不只是拒绝运行。
通过 CDP 连接外部浏览器
若要驱动单独运行的浏览器,请设置其 Chrome DevTools Protocol 端点。抓取流程和浏览器工具都会使用该端点:
{
"browser_cdp_url": "http://browser:9222"
}
服务进程也接受 TINYSEARCH_BROWSER_CDP_URL。外部浏览器负责管理自己的可执行文件、配置文件、代理和指纹配置;TinySearch 不会选择或安装特定的浏览器后端。
CDP 端点相当于对浏览器的特权远程控制。请将其保留在专用网络或环回接口上;跨主机边界时要求身份验证,并且不要将端口 9222 直接暴露到公共互联网。当 TinySearch 本身运行在 Docker 中时,localhost 指向 TinySearch 容器,因此请使用该容器可访问的端点。
browser_backend、browser_cdp_url 和 browser_storage_state_path 由运维人员管理,即使启用了配置写入,也无法通过 HTTP PUT /config 端点修改。请在启动环境(TINYSEARCH_BROWSER_BACKEND 等变量)或 TINYSEARCH_CONFIG_PATH 指定的文件中设置这些项,然后重启 TinySearch。HTTP 客户端可以继续更新其他设置,只需在部分更新中省略这些字段。
代理
若要通过代理进行抓取,请设置 browser_proxy_server:
{
"browser_proxy_server": "http://gateway.proxyprovider.com:8000",
"browser_proxy_username": "your-username",
"browser_proxy_password": "your-password"
}
支持 http、https 和 socks5 代理 URL,与 Playwright 支持的格式一致。如果服务提供商提供多个固定网关端点,请用逗号分隔,TinySearch 会为每个新浏览器上下文轮流选用一个端点:
{
"browser_proxy_server": "http://gw1.proxyprovider.com:8000, http://gw2.proxyprovider.com:8000"
}
使用 browser_proxy_bypass 指定以逗号分隔的主机列表,这些主机应绕过代理。与上面的 CDP 设置一样,这四个字段由运维人员管理——可通过 TINYSEARCH_BROWSER_PROXY_SERVER、TINYSEARCH_BROWSER_PROXY_USERNAME、TINYSEARCH_BROWSER_PROXY_PASSWORD 和 TINYSEARCH_BROWSER_PROXY_BYPASS 设置,也可在配置文件中设置,但绝不能通过 HTTP 设置。
为什么选择 TinySearch
- 无需供应商参与。 无需 TinySearch 账户,无需 API 密钥,不按请求计费,也无需分析服务或托管的抓取数据缓存。原本需要付费使用搜索 API 的基础设施,现在就在你的机器上运行。
- 基于来源构建。 每个证据片段都是原始页面文本,并始终关联其来源 URL,因此 Agent 答案中的主张可以追溯到某个具体段落,而不会止步于“供应商的模型是这么说的”。
- 围绕 Token 效率构建。 页面筛选和段落筛选在本地完成,之后内容才会进入模型上下文。
- 无需付费基础设施也能实用。 默认使用 DDGS 搜索和本地 ONNX 嵌入。
- 按需接入自己的技术栈。 SearXNG 和 OpenAI 兼容的嵌入服务提供商均为可选项。
- 适用于 Agent 的常用工作环境。 可通过 stdio、Streamable HTTP、Python、FastAPI 或 Docker 使用 MCP。
TinySuite 旗下产品
TinySuite 是围绕一个理念构建的产品套件:Agent 应将 Token 用于有价值的工作,而不是运维开销。
每款工具都专注于 Agent 工作流中的不同环节,并采用针对性技术,在内容进入模型前减少不必要的上下文。TinySearch 负责网页研究层,将页面转换为精简、经过排序且有来源依据的证据包。
文档
README 介绍产品概况。详细的设置和运维资料请参阅 TinySuite 文档:
仓库还包含一份带注释的示例配置文件:configs/tinysearch_config.json。
何时不应使用 TinySearch
TinySearch 有意保持轻量。需要以下功能时,请使用商业搜索 API、 持久化爬虫或完整搜索索引:
- 保证搜索覆盖范围或 SLA
- 大规模或定时索引
- 长期页面存储和变更历史
- 企业级可观测性和访问控制
开发
git clone https://github.com/TinySuiteHQ/TinySearch
cd TinySearch
python -m venv .venv
source .venv/bin/activate
pip install -e ".[server]"
python -m unittest discover tests
TinySearch 支持 Python 3.12 及更高版本。CI 会在 Linux、macOS 和 Windows 上测试 Python 3.12、3.13 和 3.14。
入口点
tinysearch.search和tinysearch.scrape_urls:结构化 Python APItinysearch.get_current_datetime:结构化 UTC 日期和时间tinysearch.to_prompt:纯结构化证据提示词渲染器tinysearch mcp:stdio MCP 服务(也是不带参数时的默认入口)tinysearch serve:Streamable HTTP MCP 服务tinysearch.servers.fastapi_server:app:可选的 FastAPI 应用
社区
欢迎提出问题、分享想法和报告错误:
隐私和许可证
TinySearch 会读取公开页面,并向调用它的客户端返回选定的摘录。搜索、爬取、本地嵌入和重排序都可以在不向嵌入服务提供商发送页面内容的情况下运行。如果选择兼容 OpenAI 的嵌入后端,该提供商会收到用于向量化的文本。
TinySearch 依据 MIT License 提供。下载的模型权重仍受各自模型卡许可证约束。第三方分发详情请参阅 NOTICE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。