分诊台的护士看都没看你一眼,指着右边说:「骨折去骨科,发烧去内科,失恋去精神科。」
你说你只是想问一下WiFi密码。
她说:「那你得去找IT科。」
这就是语义路由。它不看你的挂号单,只看你嘴里说出的那句话。
语义路由到底是个啥?
🍕 比喻时间:火锅店的点菜系统
想象你走进一家火锅店,店里没有服务员,只有一个智能语音系统:
你说「我要毛肚」→ 系统自动派单给荤菜区
你说「来份鹅肠」→ 系统自动派单给冷鲜区
你说「有素菜吗」→ 系统自动派单给蔬菜区
你说「你家WiFi密码多少」→ 系统沉默了3秒,然后把你踢出店铺
这个语音系统,就是语义路由。它不理解火锅的味道,但它理解你这句话该交给谁处理。
在AI Agent的世界里,语义路由(Semantic Routing)就是根据用户输入的语义内容,把请求精准派发给最合适的Agent或工具。
注意关键词:语义。不是关键词匹配,不是正则表达式,不是"你说'天气'我就调天气API"。它理解的是意思。
语义路由:这哥们在问天气,✅ 派给天气Agent。
这就是语义路由的精髓——它听得懂人话。或者说,它假装听得懂人话。实际上它只是用一个 embedding 模型把你的话变成一串数字,然后和各个 Agent 的"能力描述"做相似度计算。但效果上,确实像听懂了人话。
没有语义路由会怎样?
那画面太美,我不敢看。
场景1:轮流坐庄法
你有5个Agent,用户每个请求都按顺序给每个Agent试一遍:
# 没有 路由的灾难现场
用户: "帮我查一下明天北京的天气"
Agent-HR: "我只会招人,天气这事你问我?"
Agent-PR: "要不我给你写个'下雨天适合看的10部文艺片'推文?"
Agent-知识管家: "北京年均降水585mm,你问的是这个吗?"
Agent-妙趣AI: "我正在帮你查……哦等等,这不是我的活。"
Agent-特别助理: "我把你的需求转发给了天气API……不对,那个API我没权限。"
5个Agent排队试了一遍,最后没人处理。用户等了15秒,收到了5句废话。Token烧了5000个,事情一件没办。
场景2:关键词匹配法
你说"代码",路由到编程Agent。但你其实是想说"二维码怎么扫不开"。
你说"设计",路由到设计Agent。但你其实是想说"他的设计方案一团糟"(是在吐槽,不是要设计)。
关键词匹配就像用菜刀切牛排——能切,但你会怀疑人生。
语义路由怎么工作?
📥 用户说了一句话
「帮我把这个PDF翻译成日语」
🔢 路由器把话变成数字
用一个 Embedding 模型把用户的话变成一个向量(比如1536维的数字数组)。这句话的"味道"被数字化了。
🔍 和所有Agent的"能力描述"做对比
HR Agent:[招聘, 面试, 简历...] → 相似度 0.12
翻译Agent:[翻译, 多语言, 本地化...] → 相似度 0.89
妙趣AI:[内容, 营销, 搞笑...] → 相似度 0.23
设计Agent:[UI, 配色, 原型...] → 相似度 0.08
🎯 相似度最高的Agent中选
翻译Agent 0.89 胜出!请求被路由到翻译Agent。整个过程不到50毫秒。
⚡ 技术实现:三行代码的语义路由
# 最简语义路由(伪代码)
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
query_vec = model.encode("帮我把这个PDF翻译成日语")
agents = {
"HR": model.encode("负责招聘面试简历管理"),
"翻译": model.encode("负责多语言翻译本地化"),
"妙趣AI": model.encode("负责内容创作营销运营"),
}
best_agent = max(agents, key=lambda k: cosine_sim(query_vec, agents[k]))
# 输出: "翻译" ✅
当然,生产环境的语义路由比这复杂100倍。它要处理:
- 意图模糊的情况——「你帮我看看这个」到底看什么?
- 多意图的情况——「翻译这个PDF然后发邮件」涉及翻译+邮件两个Agent
- 兜底策略——没有任何Agent匹配时怎么办
- 上下文继承——用户已经说了三句话,路由器需要结合完整对话历史
三种主流路由策略
| 策略 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 语义相似度 | Embedding向量余弦相似度 | 简单快速,无需训练 | 区分度有限,容易"张冠李戴" | Agent职责明确的场景 |
| LLM分类器 | 用LLM直接判断该派给谁 | 理解力强,能处理复杂意图 | 速度慢,成本高,每次路由消耗Token | 复杂的多Agent系统 |
| 意图分类器 | 训练专用的意图分类模型 | 速度快,准确率高 | 需要训练数据和标注 | 高频场景、大规模部署 |
OpenClaw实战:Skills自动路由
说了这么多理论,来点实际的。在 OpenClaw 中,语义路由是Skills系统的核心能力。
场景:妙趣AI团队的Skills路由
老板的妙趣AI团队有5个Agent,每个Agent有一堆Skills。当一个用户请求进来时,OpenClaw怎么决定该激活哪个Skill?
# OpenClaw SOUL.md 中的 Skills 描述示例(妙趣AI)
## Skills
- content-glossary-funny: "为妙趣AI网站创作妙趣风格的术语解释页面"
- daily-news-report: "生成AI行业新闻日报"
- discord-community: "Discord社区日常运营和消息发送"
- seo-batch-generation: "批量生成SEO工具详情页"
## 路由规则
当用户说"写个术语解释" → content-glossary-funny
当用户说"今日AI新闻" → daily-news-report
当用户说"发个Discord消息" → discord-community
当用户说"批量生成工具页" → seo-batch-generation
OpenClaw的路由机制是这样的:
Skill 注册时带描述
每个Skill在 SKILL.md 中都有一个 <description> 标签。这个描述就是这个Skill的"简历"。
用户请求进来时,扫描所有可用Skills
OpenClaw会对比用户请求和每个Skill的描述,找出最匹配的那个。
匹配成功 → 自动加载Skill
被选中的Skill的 SKILL.md 会被读入Agent的上下文,指导Agent执行任务。
实战代码:模拟OpenClaw路由逻辑
# 模拟 OpenClaw 的 Skill 路由逻辑
class SemanticRouter:
def __init__(self):
self.skills = {
"content-glossary-funny":
"Feishu document read/write operations. Activate when user mentions Feishu docs.",
"daily-news-report":
"Generate AI news daily report webpage for the website.",
"discord-community":
"Discord community operations, send messages, daily sharing.",
"seo-batch-generation":
"Batch generate SEO tool detail pages for the website.",
}
def route(self, user_request: str) -> str:
# Step 1: 编码用户请求
query_vec = self.encode(user_request)
# Step 2: 和每个Skill的描述计算相似度
scores = {}
for skill_name, description in self.skills.items():
desc_vec = self.encode(description)
scores[skill_name] = cosine_similarity(query_vec, desc_vec)
# Step 3: 选最高分
best = max(scores, key=scores.get)
if scores[best] < 0.3: # 兜底阈值
return "no-match" # 没有匹配的Skill
return best
# 实际效果
router = SemanticRouter()
router.route("帮我写一个RAG术语解释页面")
# → "content-glossary-funny" ✅
router.route("今天有什么AI新闻")
# → "daily-news-report" ✅
router.route("我想要一个红烧肉的食谱")
# → "no-match" ✅ (妙趣AI不做饭)
当 cron 定时任务触发
content-glossary-funny 时,OpenClaw 会自动匹配到妙趣AI Agent 的 content-glossary-funny Skill。Agent 加载对应的 SKILL.md(指导如何写妙趣风格的术语页面),然后开始创作——全程零人工干预。你现在看到的这篇页面,就是这么被路由、被创作出来的。元了不是?
踩坑实录
💀 坑1:描述写得太宽泛,谁都匹配
某个Agent的描述写的是"处理各种任务"。结果所有请求都被路由到它。这不叫路由,这叫黑洞。
解法:Skill描述要具体到场景。不要写"处理文档",要写"当用户提到飞书文档、docx链接、文档读写时激活"。
💀 坑2:两个Agent描述太像,互相抢活
「翻译Agent」描述:"翻译各种语言"
「本地化Agent」描述:"处理多语言内容"
相似度0.95和0.93,路由器自己都懵了。最后出现的情况是:同一个请求有时给翻译Agent,有时给本地化Agent,用户疯掉。
解法:给Skills描述加上排他性关键词。"翻译Agent:处理文本翻译,不涉及UI/界面"。明确边界,别让两个Agent"撞衫"。
💀 坑3:用户一句话包含多个意图
「帮我查一下明天天气,然后写一个下雨天的营销文案」
语义路由:这到底是天气Agent的活还是营销Agent的活?还是两个都要?
解法:对于多意图场景,需要链式路由或并行路由。OpenClaw中可以通过主Agent先拆解意图,再分别调用不同的SubAgent处理。参考 Subagent 是什么?
💀 坑4:中文的语义陷阱
# 中文语义路由的翻车现场
用户: "这个Agent太智障了"
路由器: 匹配到 AI-Debugging Agent(因为提到了"Agent")
用户: "帮我看看git log"
路由器: 匹配到 Woodworking Agent(因为"log"也有"木头"的意思??)
解法:选一个好的中文Embedding模型。text-embedding-3-large 在中文上表现不错。不要用只训练了英文数据的模型处理中文请求——它会用英文思维理解中文,效果就像用谷歌翻译翻译火锅食谱。
一句话总结
它不看你穿什么衣服,只听你说了什么话,
然后在50毫秒内,把你的请求交给最合适的那个人。
没有语义路由的多Agent系统,就像一个没有前台的医院——
所有人都在大厅里喊,没人知道自己该去哪。
有了语义路由,每个人都知道自己的归属。
哪怕归属是"无解,请回家"。
🧭 延伸阅读
🤖 多Agent系统是什么? — 语义路由是它的血管系统
🎭 Agent Skills 是什么? — 语义路由激活的对象
🥷 Subagent 是什么? — 路由后的执行单元
📡 MCP 协议 — 标准化工具接入的协议
🔄 Agent Workflow — 串联多个Agent的编排框架