AI 编码 Agent 工具太多导致 Token 暴涨还变傻了?Ratel 用渐进式上下文工程精准匹配每次调用
场景:你的 Agent 被自己的工具淹没了
想象一下这个场景:你给 Claude Code 或 Codex 注册了 50 个 MCP 工具——文件操作、搜索、网络请求、数据库查询、代码分析、Git 操作……每个工具都带着自己的 Schema 描述。然后你的 Agent 每发一次推理请求,LLM 都得在这堆工具描述中”大海捞针”,找出当前任务需要的那个。
结果就是两件事同时发生:
- Token 暴涨:每次调用都在给模型塞 50 个工具 Schema,90% 是当前轮次用不到的
- 准确率下降:模型被海量工具选择压垮——文档越多,模型选错工具的概率越高
这不是理论问题。Ratel 的作者在 benchmark.ratel.sh 上发布了实测数据:在本地模型和前沿模型上,过多的工具 Schema 会导致工具选择准确率显著下降,同时 Token 消耗线性增长。
Ratel 就是为了解决这个问题而生的——一个上下文工程(Context Engineering)层,用渐进式披露(Progressive Disclosure)的方式,只在 Agent 需要的轮次注入匹配的工具和技能,而非把所有东西一次性塞进系统提示词。
Ratel 的核心理念:召回代替全注入
传统做法是把所有工具 Schema 全部放在 system prompt 里:
tools = [
{"name": "read_file", "description": "..."},
{"name": "write_file", "description": "..."},
{"name": "search_files", "description": "..."},
{"name": "run_bash", "description": "..."},
# ... 50 个工具
]
response = llm.complete(prompt, tools=tools) # 10KB 上下文浪费
Ratel 的做法完全相反——它先把所有工具和技能索引到一个目录(Catalog)中,每次 Agent 需要操作时,调用 search_capabilities 从目录中检索出当前轮次需要的工具和技能,只把匹配的那些注入到上下文中:
// ✅ Ratel 方式:按需检索注入
const catalog = new ToolCatalog();
// 注册所有工具到目录
catalog.register({
id: "read_file",
name: "read_file",
description: "Read a file from local disk.",
inputSchema: { type: "object", properties: { path: { type: "string" } } },
outputSchema: { type: "object", properties: { contents: { type: "string" } } },
execute: async ({ path }) => ({ contents: await readFile(path, "utf8") }),
});
// 在 Agent 循环中,每次需要操作时只检索匹配的工具
const search = searchCapabilitiesTool(catalog, skills);
const invoke = invokeToolTool(catalog);
当 Agent 需要读取文件时,它调用 search_capabilities 检索工具目录,只返回 read_file 等匹配的工具定义——而不是 50 个无关工具的 Schema 一起上。
BM25 检索引擎:不需要向量数据库
Ratel 默认使用 BM25 算法(与大多数搜索引擎相同的检索算法)来索引和匹配工具。这带来三个实用好处:
- 零基础设施:不需要部署向量数据库,不需要配置 Embedding 模型
- 快速确定:BM25 是确定性检索,不会因为语义漂移导致不一致的结果
- 进程内运行:Rust 核心引擎直接在 Agent 进程中运行,毫秒级响应
如果想提升召回质量,Ratel 也支持语义检索和混合排序模式——在每个目录或每次调用时选择开启,使用本地 Embedding 模型在同一进程中运行。
渐进式披露的三个层次
Ratel 的上下文工程不只做工具召回,还分三个层次管理上下文:
1. 工具目录(Tool Catalog)
管理所有可调用工具的定义和 Schema。Agent 每次调用 search_capabilities 时,只有当前轮次匹配的工具 Schema 被注入上下文。
2. 技能目录(Skill Catalog)
管理更高层次的操作技能——每个技能是一个”操作剧本”(playbook),包含需要哪些工具和完整的操作说明。技能的内容不预先加载,只有 Agent 调用 get_skill_content 时才从目录中取出:
const skills = new SkillCatalog();
skills.register({
id: "inspect-local-file",
name: "inspect-local-file",
description: "Inspect a local file before answering questions about it.",
tools: ["read_file"],
body: "Read the requested file, then ground your answer in its contents.",
});
// 技能指令直到 Agent 需要时才加载
const loadSkill = getSkillContentTool(skills);
3. 渐进式注入
工具和技能的注入策略是渐进式的——不是一次性全检索,而是随轮次推进逐步暴露。第一调用可能只注入 1-2 个相关工具,随着任务加深再检索后续需要的工具。
Ratel-MCP:给 Claude Code 和 Codex 装上上下文引擎
对于大多数开发者来说,最快使用 Ratel 的方式是安装 Ratel-MCP——一个针对编码 Agent 的本地方案,作为 MCP 服务端运行:
安装后,Claude Code 或 Codex 会自动通过 Ratel 的 MCP 服务端来管理工具调用和技能加载。Ratel 会接管 Agent 的工具选择逻辑,在每次推理前先检索再注入,而不是把所有工具描述一次性发给 LLM。
实际效果
Ratel 的基准测试数据显示了几个关键效果:
- Token 节省:通过只在需要时注入匹配的工具和技能,大幅减少每次 LLM 调用的输入 Token 数
- 准确率恢复:减少工具选择的”信号噪声比”,模型在更少的候选工具中更容易选出正确的那个
- 零基础设施:不需要向量数据库、不需要 API Key、不需要外部服务——
npm install @ratel-ai/sdk或pip install ratel-ai即可
适用场景
Ratel 最适合以下场景:
- 工具丰富的 Agent 设置:注册了 10+ 个 MCP 工具或自定义工具的 Agent
- 多技能 Agent:同时管理多个操作技能和工具组合的 Agent 系统
- Token 敏感场景:使用本地模型或 Token 计费 API 时,每轮调用的输入 Token 直接决定成本
- 工具选择不稳定的 Agent:Agent 频繁选错工具、或者在不同轮次对同一任务的工具选择不一致
结语
给 AI Agent 注册大量工具就像给一个开发者一个塞满万本书的图书馆——如果不做索引和检索,TA 翻找的时间比阅读的时间还长。Ratel 的渐进式上下文工程将工具和技能的选择从 “全部展示” 变为 “按需检索”,既省 Token 又保准确率。
如果你正在使用 Claude Code、Codex 或 Cursor 且感觉工具选择越来越不稳定,或者本地模型的 Token 预算总被工具 Schema 占据,Ratel 是一个值得试的方向。
相关链接