数据截至 (上游 commit ae57a2357745)
第 1 章 · 路由层:一句话怎么变成「派给谁」
本章讲:AgenticSeek 怎么不动用 LLM,只靠两个小分类器就把你的请求分发给合适的 agent。
1.1 它要解决的小问题
用户敲一句话进来,系统必须先答两个问题:
- 谁接这活? 闲聊、写代码、翻文件、上网,还是要先做规划?
- 这活多难? 一步能完的交单个 agent;要跨多个能力的,得先拆计划。
为什么不直接问 LLM
这本来是最省事的做法——把 agent 列表塞进 prompt,让模型自己选。但 AgenticSeek 的目标模型是本地跑的 14B~32B,README 的硬件表里明写 7B 「planner agents will likely fail」。让这个量级的模型做元决策,两个毛病躲不掉:
- 选错人(把「找文件」派给 web agent);
- 输出格式飘(多一句解释、少一个引号,解析就崩)。
所以项目把路由整个搬出 LLM,交给判别式小模型。
1.2 思路:两个模型投票,取长补短
不是一个分类器,是两个,各有各的短板:
| 分类器 | 是什么 | 强在哪 | 弱在哪 |
|---|---|---|---|
| BART zero-shot | facebook/bart-large-mnli,给一组候选标签就打分 | 泛化好,没见过的说法也能猜 | 不懂本项目的黑话 |
| AdaptiveClassifier | 从 llm_router/ 载入的 distilbert 权重,现场喂 few-shot | 贴合本项目真实请求措辞 | 分布外就懵 |
两者各出「标签 + 置信度」,归一化后比大小, 高者胜。
复杂度判断是第三个模型——另一个独立的 AdaptiveClassifier 实例,标签只有 LOW / HIGH。
加载在 AgentRouter.__init__ 里一次做完(sources/router.py:23-32):
self.pipelines = self.load_pipelines() # BART
self.talk_classifier = self.load_llm_router() # 任务分类器
self.complexity_classifier = self.load_llm_router() # 复杂度分类器(另一份实例)
self.learn_few_shots_tasks()
self.learn_few_shots_complexity()
注意
load_llm_router()被调了两次,得到两个互不干扰的实例,然后各喂各的 few-shot(sources/router.py:45-59)。