2026 年 3 月,我们一个用 OpenAI Assistants API + function calling 做的"企业内部 AI 助手"(财务报销、HR 查询、技术工单、知识检索四合一),在工具数从最初的 11 个扩展到 47 个 后,出现了一个非常隐蔽的退化——"function calling 准确率从 91% 跌到 58%"。用户反馈"AI 总是调错工具",我们花了 3 周深度治理,把准确率回到 93%,并沉淀出一套"大型工具集 Agent 架构"。
这次复盘是 LLM Agent 工程化中最常见也最容易被忽视的问题——"工具数量增长带来的认知过载"。从最初怀疑模型能力下降、调 prompt、换 GPT-4o 都没用,到最终发现真凶是"工具描述质量 + 命名空间冲突 + tool selection prompt 上下文爆炸"三重叠加。这篇文章给你一份"Agent 工具集治理 SOP"。
项目背景:这个 AI 助手的规模
| 维度 | 规模/参数 |
|---|---|
| 日均对话量 | 1.8 万次 / 7200 活跃用户 |
| 模型 | OpenAI GPT-4o(via Assistants API) |
| 工具数 | 初版 11 个 → 6 个月后 47 个 |
| function calling 准确率 | 初版 91% → 退化到 58% |
| 每次对话平均工具调用 | 2.3 次 |
| 每次工具调用平均上下文 | 初版 1200 token → 退化时 8400 token |
| 用户投诉率 | 从 0.8% 飙到 11.4% |
| API 月度成本 | $3200 → $9800(工具描述膨胀) |
项目从 2025 年中上线,初期只有 11 个工具(报销 3 个、HR 4 个、技术工单 2 个、知识检索 2 个),准确率非常高。但随着业务部门不断申请"我也要接入 AI",6 个月内工具数翻了 4 倍,出现了一个临界点——"工具数过 30 之后,准确率断崖式下降"。
事故时间线
| 时间 | 事件 |
|---|---|
| D1 | 客服转来一批投诉:"AI 帮我查工资,结果调了报销工具",团队开始排查 |
| D2 | 怀疑 GPT-4o 退化,换 GPT-4-turbo 测试,准确率没变(都 58%) |
| D3 | 对比初版 vs 当前的 tool schema,发现工具数从 11 涨到 47,描述质量参差不齐 |
| D4-D7 | 采样 200 个错误调用,分类归因——67% 是工具选择错误,而非参数错误 |
| D8-D14 | 第一轮治理:统一工具描述格式,准确率回升到 71% |
| D15-D17 | 引入"工具分组路由"机制,先选组再选工具,准确率到 86% |
| D18-D21 | 引入"语义检索 + 工具子集"动态选工具,准确率到 93% |
第一轮:误以为模型退化了
最先想到的可能性是"GPT-4o 又被 OpenAI 默默降级了"。我们做了对照实验:
# 对照实验:用初版 11 个工具的 schema,测试当前 GPT-4o
from openai import OpenAI
client = OpenAI()
# 11 个工具的 schema(从 6 个月前 git 历史里取出)
tools_v1 = [
{"type": "function", "function": {"name": "create_expense", ...}},
# ... 11 个
]
# 47 个工具的 schema(当前)
tools_v2 = [
{"type": "function", "function": {"name": "create_expense_general", ...}},
{"type": "function", "function": {"name": "create_expense_travel", ...}},
{"type": "function", "function": {"name": "create_expense_marketing", ...}},
# ... 47 个
]
# 用同一批 200 个测试 case 跑两组
def run_test(tools, cases):
correct = 0
for case in cases:
resp = client.chat.completions.create(
model="gpt-4o", tools=tools,
messages=[{"role": "user", "content": case["query"]}]
)
called = resp.choices[0].message.tool_calls[0].function.name
if called == case["expected_tool"]:
correct += 1
return correct / len(cases)
# 结果:
# tools_v1 + GPT-4o: 准确率 89%(接近初版 91%)
# tools_v2 + GPT-4o: 准确率 58%
# 模型没退化,是工具集本身有问题
这个对照实验让我们排除了"模型能力下降"的假设。瓶颈在工具集设计,不在模型。这之后的所有调优方向都聚焦在工具集本身。
第二轮:200 个错误案例的归因分析
我们采样了 200 个错误调用,逐个分析失败原因,分类如下:
| 错误类型 | 占比 | 典型案例 |
|---|---|---|
| 工具选择错(选了相似名称的工具) | 43% | 用户问"差旅费报销",AI 调了 create_expense_general(应该 create_expense_travel) |
| 工具未选(本该调工具但回答了空话) | 24% | 用户问"我的剩余年假",AI 答"建议联系 HR",没调 query_leave_balance |
| 错误的语义路由 | 18% | 用户问"团建预算",AI 调了 query_budget(应该 query_team_building_budget) |
| 参数错误 | 9% | 调对了工具,参数格式不对 |
| 多步推理错 | 6% | 需要先查 user_id 再查记录,跳过了第一步 |
67% 的错误都是"选错工具"类型,这就把问题彻底定位到了"tool selection"环节。我们进一步分析这 43% 的"相似名称选错"案例,发现根因是工具命名的命名空间冲突 + 工具描述质量差异。比如下面这两个工具,在 LLM 看来几乎一样:
{
"name": "create_expense_general",
"description": "Create a general expense report"
}
{
"name": "create_expense_travel",
"description": "Create a travel expense report"
}
描述短到几乎没信息量,GPT-4o 只能靠"general"和"travel"这两个词来区分,而用户的查询如"我上周出差打车花了 500 块要报销",里面既没有"general"也没有"travel"字面词,模型只能猜。工具描述质量是 function calling 准确率的第一杀手,这个发现是整个治理的起点。
问题本质:工具数增长带来的三重压力
修法 1:统一工具描述格式规范
第一步是制定"工具描述 SOP",所有工具必须按统一模板写描述:
# 工具描述模板 - 强制结构化
TOOL_DESCRIPTION_TEMPLATE = """
[用途] {一句话说明这个工具解决什么问题}
[何时使用] {用户的什么意图触发,给 2-3 个例子}
[何时不使用] {容易混淆的场景,与哪些相似工具区分}
[输入说明] {关键参数的语义说明}
[输出说明] {返回什么数据}
"""
# 改造前(8 行,12 个 token 的描述):
{
"name": "create_expense_travel",
"description": "Create a travel expense report"
}
# 改造后(80 行,200 个 token 的描述):
{
"name": "create_expense_travel",
"description": """
[用途] 创建一笔差旅费用报销单(出差期间的交通、住宿、餐饮)
[何时使用] 用户提到"出差"、"差旅"、"外地办公"、"打车去客户公司"、"机票/高铁"等场景
示例 1: "我上周出差去深圳,打车花了 500 要报销"
示例 2: "帮我提一笔差旅报销,3000 块的高铁票"
示例 3: "上海出差住酒店的发票怎么报"
[何时不使用]
- 如果是市内日常打车(非出差),用 create_expense_general
- 如果是团建活动,用 create_expense_team_building
- 如果是市场推广活动,用 create_expense_marketing
[输入说明]
- destination: 出差目的地(城市级)
- amount: 金额(单位:元)
- category: travel/hotel/meal 之一
- receipt_url: 发票图片 URL(可选)
[输出说明] 返回报销单 ID 和审批流程预计耗时
"""
}
这一步显著提升了相似工具的区分度,但代价是tool schema 总 token 从 4500 涨到 18000,每次请求成本翻倍。准确率从 58% 提到 71%,但成本暴涨,不可持续。这就需要第二步治理。
修法 2:工具分组 + 二级路由
47 个工具按业务领域分成 6 个组:
TOOL_GROUPS = {
"finance": {
"description": "财务相关:报销、发票、付款、对账",
"tools": ["create_expense_general", "create_expense_travel",
"create_expense_marketing", "query_invoice", ...]
},
"hr": {
"description": "人力资源:请假、年假、薪资、绩效、培训",
"tools": ["query_leave_balance", "apply_leave", "query_salary", ...]
},
"tech_ticket": {
"description": "技术工单:报障、IT 设备申请、密码重置",
"tools": ["create_it_ticket", "reset_password", ...]
},
"knowledge": {
"description": "知识检索:公司政策、流程指南、产品手册",
"tools": ["search_policy", "search_handbook", ...]
},
"approval": {
"description": "审批相关:发起审批、查询审批状态、撤回审批",
"tools": ["create_approval", "query_approval_status", ...]
},
"meeting": {
"description": "会议相关:预订会议室、安排会议、查询日程",
"tools": ["book_meeting_room", "schedule_meeting", ...]
}
}
# 二级路由:先选组,再选工具
def two_stage_tool_selection(user_query: str):
# Stage 1: 用一个轻量 prompt 选组
group_selector_tools = [
{"type": "function", "function": {
"name": "select_group",
"description": "Select the most relevant tool group",
"parameters": {
"type": "object",
"properties": {
"group": {"enum": list(TOOL_GROUPS.keys())}
}
}
}}
]
stage1_resp = client.chat.completions.create(
model="gpt-4o-mini", # 用便宜的模型选组
tools=group_selector_tools,
messages=[
{"role": "system", "content": "根据用户问题选择最相关的工具组:" +
json.dumps({k: v["description"] for k, v in TOOL_GROUPS.items()})},
{"role": "user", "content": user_query}
]
)
selected_group = json.loads(
stage1_resp.choices[0].message.tool_calls[0].function.arguments
)["group"]
# Stage 2: 只把该组的工具传给 GPT-4o
group_tools = TOOL_GROUPS[selected_group]["tools"]
stage2_resp = client.chat.completions.create(
model="gpt-4o",
tools=[get_tool_schema(t) for t in group_tools],
messages=[{"role": "user", "content": user_query}]
)
return stage2_resp
这一步把每次请求的工具数从 47 个降到平均 6-8 个,准确率从 71% 提升到 86%,同时 token 成本回到原来的 60%。代价是多了一次 LLM 调用(stage 1),增加了 300ms 延迟。
修法 3:语义检索动态工具子集
分组路由还有边界问题——比如"我出差的发票丢了能补开吗"既涉及 finance(发票)又涉及 hr(出差),固定分组难以覆盖。我们引入"语义检索 + 动态工具子集":
from openai import OpenAI
import numpy as np
# 预计算所有工具描述的 embedding
TOOL_EMBEDDINGS = {}
for tool_name, tool in ALL_TOOLS.items():
# 用工具描述生成 embedding
embed = client.embeddings.create(
model="text-embedding-3-large",
input=tool["description"]
).data[0].embedding
TOOL_EMBEDDINGS[tool_name] = np.array(embed)
def select_tools_by_semantic(user_query: str, top_k=8):
# 1. 把 query embed
query_embed = np.array(client.embeddings.create(
model="text-embedding-3-large",
input=user_query
).data[0].embedding)
# 2. 计算所有工具的相似度
sims = {
name: np.dot(query_embed, emb) / (
np.linalg.norm(query_embed) * np.linalg.norm(emb)
)
for name, emb in TOOL_EMBEDDINGS.items()
}
# 3. 取 top_k 工具
top_tools = sorted(sims.items(), key=lambda x: -x[1])[:top_k]
return [name for name, _ in top_tools]
def smart_tool_calling(user_query: str):
# 用语义检索选 top 8 工具
relevant_tools = select_tools_by_semantic(user_query, top_k=8)
# 只把相关工具传给 GPT-4o
resp = client.chat.completions.create(
model="gpt-4o",
tools=[get_tool_schema(t) for t in relevant_tools],
messages=[{"role": "user", "content": user_query}]
)
return resp
这一步用"语义相似度"动态选 top 8 工具,准确率最终到 93%,而且没有固定分组的边界问题。代价是要预先生成所有工具的 embedding(一次性成本),以及每次请求多一次 embedding 调用(增加 50ms,但比修法 2 的 stage 1 LLM 调用快 6 倍)。
修复前后基准
| 指标 | 初版 | 退化后 | 修法 1 | 修法 2 | 修法 3 |
|---|---|---|---|---|---|
| 工具数 | 11 | 47 | 47 | 47 | 47 |
| 每次传给 LLM 的工具数 | 11 | 47 | 47 | 6-8 | 8 |
| function calling 准确率 | 91% | 58% | 71% | 86% | 93% |
| 每次请求 tool schema token | 1200 | 4500 | 18000 | 4800 | 3200 |
| 每次请求 LLM 调用次数 | 1 | 1 | 1 | 2 | 1 |
| 每次请求平均延迟 | 1.2s | 1.8s | 2.4s | 1.9s | 1.4s |
| 每次请求成本 | $0.012 | $0.038 | $0.094 | $0.028 | $0.019 |
| 月度 API 成本 | $3200 | $9800 | $25000 | $7500 | $5100 |
决策树:大型工具集 Agent 架构
我们立的 12 条 Agent 工具集治理纪律
- 工具描述必须用模板:用途 / 何时用 / 何时不用 / 输入 / 输出,五段式;
- "何时不用"段必须列出易混淆工具:这是区分度的关键;
- 工具数过 25 必须分组:不要怀疑模型能力,直接做架构层治理;
- 工具数过 50 必须用语义检索:静态方法失效,改用动态子集;
- 工具命名必须避免前缀冲突:create_xxx 类工具不能超过 5 个,超过要重新设计命名;
- 每个工具必须有 5+ 个正负样本测试:用回归测试集监控准确率;
- 每月跑一次工具准确率 benchmark:发现退化立刻治理;
- 新工具上线必须做"是否新增组"评估:不要无脑加到现有组;
- 工具下线机制:6 个月调用量低于 10 次的工具自动下线;
- 工具调用日志全量留存:用于后续分析错误模式;
- 动态子集 top_k 要 tune:6-12 之间,过小漏召、过大稀释注意力;
- 语义检索 embedding 模型必须固定版本:换模型要重新生成所有 embedding,不可在线热切。
引申一:为什么 LLM 在工具数多时表现下降
这背后有几个根本原因:
- 上下文稀释效应:工具 schema 在 prompt 里占的比例越大,user query 的"信号"越弱;
- 命名相似性误导:LLM 用 attention 机制处理工具名,相似名字会互相干扰;
- 训练数据偏好:OpenAI 的 RLHF 训练里,function calling 案例的工具数通常 < 20 个,数量大时分布偏离训练集;
- 幻觉放大:工具多了,LLM 找不到完美匹配时倾向"硬选一个",而不是返回"没有合适工具"。
这些都不是 prompt engineering 能彻底解决的,必须从架构层下手。提示工程是战术,工具集架构是战略,战术解决不了战略问题。
引申二:Anthropic Claude 的 tool use 是否有同样问题
我们做了对照测试,用 Claude 4.7 跑同样 47 个工具:
| 模型 | 11 工具准确率 | 47 工具准确率 | 下降幅度 |
|---|---|---|---|
| GPT-4o | 91% | 58% | -33% |
| GPT-4-turbo | 89% | 56% | -33% |
| Claude 4.7 | 93% | 76% | -17% |
| Claude 4.6 Sonnet | 90% | 72% | -18% |
| Gemini 2.0 Pro | 87% | 61% | -26% |
Claude 在多工具场景下表现更好,下降幅度只有 GPT 的一半。原因是 Claude 的 tool use 训练数据集里包含了更多大工具集的案例,模型对工具数不那么敏感。但即使 Claude,47 工具下也只有 76%,远低于 11 工具的 93%。没有任何模型能完全免疫"工具数增长导致准确率下降",架构层治理是普适的。
引申三:工具集 vs MCP server 的对比
2024-2025 年 MCP(Model Context Protocol)流行后,有人会说"用 MCP 不就好了吗"。我们评估了 MCP 在我们场景下的适用性:
- MCP 解决的是工具发布和复用:把工具做成 server,多 agent 共享,这部分是真的好;
- MCP 不解决"工具数过多导致选择困难":agent 仍然要从 47 个 MCP 工具里选,问题本质一样;
- MCP 增加了一层网络延迟:每次工具调用要走 IPC 或网络;
- MCP 适合"多 agent 共享工具池":不适合"单 agent 优化"。
我们最终的架构是"内部用函数级 function calling + 跨团队共享用 MCP"——核心高频工具仍然是函数级注册(快、可控),低频或跨团队工具走 MCP 接入(标准化、可发现)。这种混合架构在工程实践里很常见。
引申四:工具描述写作的具体技巧
我们沉淀了一套"工具描述写作技巧",分享几个实操性强的:
- "何时使用"段必须有 3 个真实用户原话:不要写"用于查询薪资",要写"我这个月工资到账了吗"、"帮我看看上月工资条"、"我的年终奖发了没";
- "何时不使用"段对比相似工具:明确写出"如果是 X 场景,改用 tool_Y";
- 避免技术术语:不要写"调用 ERP 系统的 R3 模块",要写"查询公司报销系统";
- 参数描述用"语义",不用"格式":不要写"date: ISO 8601 格式",要写"date: 用户提到的日期,如'明天'、'下周三'";
- 用 negative example 防误用:在描述里写"⚠️ 注意:此工具仅查询余额,不能用于扣款"。
这些技巧看似细节,但累积起来对准确率影响巨大。我们的实践是"工具描述要给 LLM 看,不是给程序员看"——LLM 看的是自然语言,程序员看的是技术规格,两套描述要分开维护。
引申五:Agent 准确率监控体系
治理完之后,我们建了一套 Agent 准确率监控体系,核心是 4 类指标:
# 监控指标采集
class AgentMetrics:
def log_tool_call(self, session_id, user_query, selected_tool,
expected_tool, latency_ms, token_used):
# 1. 选择准确率(对比 expected_tool,需要 ground truth)
# 2. 工具调用次数分布
# 3. 每次会话平均工具数
# 4. token 成本
self.metrics.put({
"timestamp": now(),
"session_id": session_id,
"query": user_query,
"selected_tool": selected_tool,
"expected_tool": expected_tool,
"is_correct": selected_tool == expected_tool,
"latency_ms": latency_ms,
"token_used": token_used,
})
def daily_report(self):
# 每天生成报告:
# - 总准确率
# - 按工具分组的准确率
# - 错误案例 top 20(供 review)
# - token 成本趋势
pass
ground truth 的获取有两种方式:一是人工标注(贵但准),二是用户反馈(便宜但稀疏)。我们用混合方式——每天采样 100 条人工标注 + 收集用户的👍👎反馈。没有监控的 Agent 系统就是黑盒,出问题永远是用户先发现,自己永远不知道在退化。
引申六:Agent 系统的"复杂度预算"
这次事故让我们认识到 Agent 系统的"复杂度预算"概念——工具数、prompt 长度、工具调用链深度,都是有限的"复杂度资源",超过预算系统就崩。我们公司的预算是:
| 资源 | 初版预算 | 当前预算 | 触线告警 |
|---|---|---|---|
| 单次请求工具数 | ≤ 15 | ≤ 10(动态子集后) | > 12 告警 |
| 工具调用链深度 | ≤ 3 步 | ≤ 5 步 | > 6 步告警 |
| 单次会话 token | ≤ 8000 | ≤ 12000 | > 15000 告警 |
| 单次会话 LLM 调用 | ≤ 3 次 | ≤ 5 次 | > 6 次告警 |
预算的好处是给"加功能"的冲动设置物理上限。业务方总是希望"再接一个工具",但每加一个都要评估是否撑爆预算。预算用完,要么砍掉低优先级工具,要么做架构升级。没有预算就没有约束,没有约束就一定会退化。
引申七:为什么"小工具集 + 多 Agent"是另一种选择
除了"单 agent + 大工具集 + 动态子集"路线,还有一种"小工具集 + 多 agent 协作"路线。比如不要做一个"全能助手",而是做"财务助手"、"HR 助手"、"IT 助手",每个 agent 只有 8-15 个工具,用一个"路由 agent"分发请求:
| 架构 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 单 agent 大工具集 | 用户体验好(单一入口) | 架构复杂,工具数受限 | 工具 < 50 |
| 多 agent 小工具集 | 每个 agent 简单,易扩展 | 跨域问题需要协作 | 工具 > 50,业务领域清晰 |
| 混合(我们的选择) | 核心场景单 agent,边缘场景路由 | 架构复杂度最高 | 大型企业级 Agent |
我们最终的架构是混合的——"4 个核心域 agent + 1 个路由 agent + 1 个回退 agent",每个核心 agent 工具数控制在 12 个以内,路由 agent 负责分发,回退 agent 处理路由不确定的边缘情况。这种架构准确率达到 95%(比单 agent 的 93% 更高),但开发成本增加 40%。架构选择没有银弹,要看你的业务规模、团队规模、用户体验诉求的优先级。
引申八:Agent 工具集的"演进式设计"
这次治理给我们一个普适的认识:Agent 系统不能"一次设计成型",必须演进式。具体的实践原则:
- MVP 阶段:5-10 个工具,直接 function calling,验证用户接受度;
- 增长阶段(10-25 工具):开始规范工具描述,建监控;
- 成熟阶段(25-50 工具):做分组路由,引入静态子集;
- 规模化阶段(> 50 工具):语义检索动态子集,或拆多 agent;
- 每个阶段都要重新审视架构:不能因为"以前能跑"就不调整。
很多团队的错误是用 MVP 的架构去支撑规模化阶段,结果就是我们遇到的"准确率断崖"。Agent 工程化是"架构跟着业务规模动态升级",不是"一次设计永远用"。这个认识值得所有做 LLM Agent 的团队反复内化。
引申八·五:tool_choice 参数的妙用
OpenAI Assistants API 有个 tool_choice 参数,很多人不知道它的高级用法。我们用它做了几件事:
# 用法 1: 强制必须调某个工具(用户明确指令场景)
# 用户说"创建报销单",直接强制调用 create_expense_*
resp = client.chat.completions.create(
model="gpt-4o", tools=tools,
tool_choice={"type": "function", "function": {"name": "create_expense_travel"}},
messages=[...]
)
# 用法 2: 强制必须调工具(不能用文字回答)
# 适合"AI 助手只通过工具响应,不闲聊"的场景
resp = client.chat.completions.create(
model="gpt-4o", tools=tools,
tool_choice="required", # 必须调工具
messages=[...]
)
# 用法 3: 禁用工具调用(纯对话场景)
resp = client.chat.completions.create(
model="gpt-4o", tools=tools,
tool_choice="none", # 即使有工具也不调
messages=[...]
)
这些参数在治理时非常有用。比如"用法 2 required" 在我们的 stage 2 调用里强制 LLM 必须调工具,杜绝了"调而不答"的情况;"用法 1 强制工具" 用在用户意图明确的场景(比如带"创建"、"查询"等关键词的指令),跳过模型选择直接调用。不要把模型选择当成万能,在确定的场景下强制指定工具是更可靠的方案。
引申九:语义检索 embedding 模型的选择
修法 3 用 text-embedding-3-large 做工具语义检索,我们对比了几个 embedding 模型:
| 模型 | 维度 | 检索准确率 | 每次成本 | 延迟 |
|---|---|---|---|---|
| text-embedding-3-large | 3072 | 93% | $0.00013 | 40ms |
| text-embedding-3-small | 1536 | 89% | $0.00002 | 35ms |
| BGE-M3 (本地) | 1024 | 91% | $0(GPU 摊销) | 15ms |
| Cohere embed-v3 | 1024 | 92% | $0.0001 | 55ms |
我们最终选了 text-embedding-3-large——准确率最高,虽然贵但跟 GPT-4o 调用成本比微不足道。如果对延迟敏感或要省钱,BGE-M3 本地部署是性价比之王。embedding 模型的选择,要从准确率、成本、延迟、自主可控四个维度综合权衡,不要无脑用最贵的。
引申九·五:工具调用的可观测性建设
治理之后我们建了一个 Agent 调用链路 dashboard,核心 5 个面板:
- 面板 1:工具调用 funnel:请求 → 工具选择 → 参数生成 → 执行 → 返回,每一步的转化率;
- 面板 2:工具调用 latency 分布:P50/P95/P99 latency 按工具拆分;
- 面板 3:错误归因实时图:选择错 / 参数错 / 执行错 三类错误的实时占比;
- 面板 4:token 成本:按工具、按用户、按部门维度拆分;
- 面板 5:用户反馈热度:👍👎 反馈率,差评工具排行。
这套 dashboard 让我们在事故发生前就能发现退化趋势,比之前"靠用户投诉发现"早了 2-3 周。可观测性建设是 Agent 工程化的必修课,不是奢侈品。
引申十:工具集治理的 ROI 计算
这次 3 周治理的投入产出比值得算清楚:
- 投入:3 周 × 2 人(我 + 一个 backend 工程师)= 30 人日,按 ¥1500/天 = ¥4.5 万;
- 直接收益:月度 API 成本从 $9800 降到 $5100 = 节省 $4700/月 ≈ ¥3.4 万/月;
- 间接收益:用户投诉率从 11.4% 降到 0.6%,客服处理工时月省 80 小时 ≈ ¥1.6 万/月;
- 回本周期:¥4.5 万 ÷ (¥3.4 万 + ¥1.6 万) ≈ 0.9 个月。
不到 1 个月回本的项目在企业里极其稀有。但这种"治理类项目"经常被低估——管理层只看到"修 bug 的成本",看不到"不修的成本"。把 ROI 算清楚再去要资源,比"我觉得很重要"有效 100 倍。这是给所有想推动技术治理的工程师的一条朴素经验。
总结
这次工具数增长导致准确率下降的事故,核心是"低估了 LLM 在大工具集下的认知压力"。修复路径是"规范工具描述 → 业务分组路由 → 语义检索动态子集"三层架构,把单次请求的工具数控制在 8 个以内,LLM 的注意力才能聚焦。这条路径已被验证适用于 GPT、Claude、Gemini 各种主流模型。
更重要的认知是:LLM Agent 不是"接更多工具就更强大",而是"工具集的设计质量决定上限"。10 个高质量描述、清晰边界的工具,远比 50 个堆砌的工具有用。我们 6 个月前疯狂接入工具,以为是在"赋能业务",其实是在"破坏体验"。这次事故让我们彻底反思了"AI 助手"的设计哲学——少而精,大于多而杂。这是给所有正在做 LLM Agent 工程化团队的真诚建议:克制扩张冲动,珍惜工具集的简洁性。每一个工具的加入,都要经过严格的"必要性 + 描述质量 + 边界清晰度"三道审查,这才是高质量 Agent 系统真正的护城河,无可替代,无法绕过。
—— 别看了 · 2026