为什么「全能Agent」必死——场景路由把一个Agent拆成6个专家
现状之痛:你的Agent配了20+工具,理论上什么都能做。实际上频繁用错工具——用户问运费,它去搜联系人。
读完你将:学会场景路由——用一个路由层把「全能Agent」拆成6个场景专家,每个场景只看到自己的工具。
〇、写在前面:为什么这一系列先放一放OPC
上一篇文章「我给Agent装了『三明治』架构」发出后,后台涌进来很多留言。
粉丝问得最多的三类问题:
- 「三明治我知道好,但具体每一步怎么落地?」
- 「我的Agent还是会在复杂任务里乱套,怎么治?」
- 「你说的『确定性代码包抄概率LLM』,能不能给一套完整的、能直接抄的体系?」
说实话,这些问题我也都踩过。做OPC的过程中,我花了大量时间在「可商业化的工程化体系」上——不是模型不够聪明,是让模型在真实业务里稳定、可控、可审计地输出正确结果,太难了。
所以,原计划的OPC系列先放一放。我要先把「Agent工程化的脚手架与控制体系」这块内容讲深、讲全、讲细——因为它才是OPC(以及任何一个商业Agent系统)真正能跑起来的底座。
这一系列,我打算用6篇,把一套完整的商业化Agent工程体系从头到尾拆给你看:
01 · 场景路由——为什么「全能Agent」必死 ← 这篇
02 · 双层分类——正则+语义,没有漏网之鱼
03 · 复合流程容器——报告不是场景,是管道
04 · 可观测性三件套——门禁+审计+纠正沉淀
05 · 纠正沉淀——让系统永不犯同样的错
06 · 工具隔离与最小权限——Agent的安全边界
为什么值得你读完?
因为这不仅是技术教程,更是一套能商业化的体系。每一篇讲的,都是从真实系统里跑出来的方案,不是纸上谈兵。你把这6篇读透、照做,搭出来的Agent系统,就是能扛住真实业务的那种——稳定、可靠、可交付。
好,开讲。
一、问题:你走进厨房找锤子
想象一下:你走进厨房找锤子,走进车库找菜刀。每个房间有它该有的工具——但如果你把所有工具都堆在客厅,找锤子时你会看到菜刀、扳手、螺丝刀、电钻……然后选错。
早期的Agent架构正是如此。我配了20+工具:邮件搜索、SQLite查询、PDF生成、联系人搜索、报价计算、运费查询……理论上它什么都能做。实际上,它频繁地在错误场景调用错误工具。
典型的翻车现场:
- 用户问「XX航班运费多少钱」,Agent却去搜联系人
- 用户问「帮我查下这票货的进展」,Agent却在生成报价单
原因很简单:工具太多了。LLM的推理链路在多个工具域之间反复跳跃,上下文碎片化,最后选错。
核心洞察:LLM的工具调用准确率与可见工具数量成反比。工具越多,选错的概率呈指数级上升。

*▲ 场景路由:全能Agent → Router分发 → 6个专有Worker*
二、核心思路:场景隔离
场景路由的核心思想:不要让一个Agent处理所有场景。
先由路由层判断当前任务的场景类型,然后为该场景注入专属的SOP、工具集和知识库。
这类似微服务架构——你不需要一个单体服务处理所有请求,而是通过API网关路由到对应的后端服务。场景路由就是Agent的「API网关」。
一个物流AI助理需要处理:邮件、报价、报告、联系人、财务、知识查询。如果所有工具都开放给LLM,每次调用都要从30多个工具中挑选,误选率极高。
解决方案:task_dispatcher.classify() 将请求分类到6个场景,每个场景有自己的工具白名单、Schema强制和SOP注入。
效果立竿见影:上下文长度减少60%,工具调用准确率提升40%。 因为LLM不需要在一堆无关工具中做选择,只需要看自己场景里的那5-6个工具。
三、技术实现
3.1 第一道关卡:task_dispatcher.classify()
所有用户请求进入系统后,第一站是分类器:
def classify(request_text: str) -> SceneContext:
# 第一步:正则精确匹配(覆盖90%)
scene_id = regex_match(request_text)
if scene_id:
return SceneContext(scene_id=scene_id)
# 第二步:语义模糊匹配(覆盖剩余10%)
scene_id = semantic_match(request_text)
if scene_id:
return SceneContext(scene_id=scene_id)
# 兜底:通用对话场景
return SceneContext(scene_id="general")
分类结果是一个结构化的 SceneContext 对象,包含:scene_id、sop_path 和工具白名单。
3.2 SCENE_CONFIG:场景的配置文件
每个场景有自己的配置:
SCENE_CONFIG = {
"email": {
"tools": ["imap_fetch", "smtp_send", "contact_lookup"], # 工具白名单
"sop": "sops/email_sop.md", # SOP注入路径
"schema": "schemas/email_schema.json", # 输出格式
"gates": ["check_email_format", "check_signature"],
},
"quoting": {
"tools": ["rate_query", "quote_template", "history_lookup"],
"sop": "sops/quoting_sop.md",
"schema": "schemas/quote_schema.json",
"gates": ["check_profit_margin", "check_currency"],
},
# ... 6个场景
}
关键:不在白名单里的工具根本不会被加载。 邮件场景无法调用数据库写入,财务场景无法发送邮件。互相隔离,各自独立。
✅ 验证:引入场景隔离后,工具误选率从15%降到2%以下(实际运行日志统计)。
踩坑:最初以为「工具越多越好」,给LLM所有工具自由发挥。结果误选率15%,每5次就错1次。隔离后降到2%。
3.3 inject-sop:执行前加载专属SOP
SOP注入是场景路由的关键。当场景确定后,inject-sop 机制把对应场景的SOP注入到LLM上下文:
# inject-sop.sh —— 每次LLM调用前注入场景SOP
scene_id=$(cat /tmp/task_context.json | jq -r '.scene_id')
sop_path="sops/${scene_id}_sop.md"
cat "$sop_path" >> /tmp/llm_context.txt
不同场景注入不同的SOP:邮件场景注入「邮件编写SOP」,报价场景注入「报价SOP」,报告场景注入「报告SOP」。
SOP不是一次性注入的。 inject-sop会检查上下文窗口,在关键节点重新注入,防止被长对话稀释。
价值:每个场景只看到自己的SOP和工具,上下文干净,误调用大幅减少。
▸ 认知跃迁:场景路由的本质不是技术革新,是架构思维的转变——让Agent专业化而不是全栈化。
四、六个场景详解
| 场景 | 工具 | 说明 |
|---|---|---|
| 邮件处理 email | IMAP/SMTP | 读取、分类、回复、转发 |
| 询价报价 quoting | 运费库/报价模板 | 运费查询、报价生成 |
| 报告生成 report | 不限制 | 在途报告、日报、月报 |
| 联系人 contact | 联系人库 | 客户/代理信息检索 |
| 财务 finance | 财务库/报表模板 | 应收应付、计件统计 |
| 知识查询 knowledge | 知识库检索 | 行业知识问答 |
五、优缺点
✅ 优点
- 上下文干净——LLM只看到当前场景相关的工具和知识
- 工具调用准确率提升90%以上
- 输出格式一致——每场景固定Schema
- 调试友好——问题定位在场景级别
- 扩展简单——新增场景只需配置SCENE_CONFIG
⚠️ 缺点
- 多场景任务无法自动拆解
- 场景边界难以精确界定
- 路由失败成本高——分类错了全错
- 配置复杂——6个场景要维护6套配置+SOP
六、此刻的你
此刻的你,已经不再是那个「给Agent配一堆工具期待它全能发挥」的乐观主义者。你正在成为一个能用场景隔离约束Agent行为边界的系统设计者。
就像一家公司需要销售部、技术部、财务部一样,一个Agent系统也需要「部门」划分。场景路由让每个Agent场景做一件事、做好一件事。它牺牲了「万能」的幻觉,换来了「可靠」的现实。
下一篇:路由层怎么做到没有漏网之鱼?正则+语义双层分类,把分类准确率从80%提到100%。
️ 实体:场景路由, Agent, 工具白名单, SCENE_CONFIG 价值:Agent商业化, 工具隔离, 最小权限 认知:从万能幻想到场景专家——专业化比全能更可靠

浙公网安备 33010602011771号