Agent Skill 结构 推导

张开发
2026/4/4 11:25:34 15 分钟阅读
Agent Skill 结构 推导
Agent Skill 结构 推导在 Eino 框架中我们看到了各种预置的 Agent 模式ReAct, Flow, Supervisor, PlanExecute。它们解决的是“控制流”的问题。但当我们面对真实的垂直业务比如“帮我分析这个 PDF”、“帮我写一个 Taro 小程序”时单靠通用的控制流是不够的。大模型需要“专业知识Domain Knowledge”和“领域工具Domain Tools”。这就是 adk/middlewares/skill 诞生的背景。它本质上是 Agent 的动态外挂大脑插件系统。1. 寻找“第一性原理”最朴素的知识注入如果不使用任何框架当用户要求我们做一件专业的事情比如解析 PDF时我们最朴素的做法就是把所有关于 PDF 的知识、解析规则、工具使用方法全部硬编码写进 Agent 的 System Prompt 里// 第一性原理把所有专业知识塞进脑子里funcRunAgent(userInputstring){systemPrompt: You are an AI assistant. [PDF 解析规则] 如果你要解析 PDF请使用 pdf_parser 工具。 注意处理带图片的 PDF 时必须先调用 OCR 工具。 [Excel 处理规则] 如果你要处理 Excel请使用 xlsx_reader 工具。 ... llm.Generate(systemPrompt,userInput)}致命痛点Context 爆炸如果你有 100 种专业技能Skill把它们全塞进 System Prompt上下文窗口会瞬间爆满且严重稀释大模型的注意力导致它“什么都做不好”。知识与工具的耦合不同的技能需要不同的提示词、甚至需要调用不同的外部工具。静态的 Prompt 无法动态加载这些工具。2. 第一次演进渐进式展示Progressive Disclosure与工具化推导解决我们需要把庞大的知识库拆分成一个个独立的“技能包Skill”。在初始状态下大模型只能看到所有技能的名字和简短描述类似于目录。当它发现用户的需求匹配某个技能时它必须通过调用一个特定的工具Tool来把这个技能的**详细内容Full Content**加载到当前上下文中。这就引出了skill中间件最核心的设计把“加载知识”本身变成一个工具。// 第一次演进渐进式加载的 Skill TooltypeSkillstruct{NamestringDescriptionstringContentstring// 真正的详细规则和提示词}// 框架初始化时只给大模型看目录funcinitAgent(){agent.SystemPrompt你有以下可用技能[PDF解析, Excel处理]。如果你需要使用请调用 load_skill 工具。agent.Toolsappend(agent.Tools,load_skill)}// load_skill 工具的实现funcLoadSkill(skillNamestring)string{skill:db.Get(skillName)returnskill.Content// 将详细内容作为工具结果返回给大模型}2.1 疑问澄清渐进式加载是“平铺目录”还是“多层索引”在 Eino 当前的实现中见 prompt.go 的toolDescriptionTemplate它采用的是平铺目录一阶展开。也就是说它会在skill工具的描述里把所有技能的Name和Description全部通过available_skills标签硬塞进去。局限性如果系统里只有 10-50 个技能这种做法非常完美既省 Token 又保证了可见性。但如果系统里有 10,000 个技能光是平铺的Name和Description就会撑爆 Context。Eino 是否支持多层索引如向量检索目前skill中间件原生并不支持。如果要支持海量技能的多层索引即大模型先调用一个搜索工具查出 5 个相关技能再决定 load 哪一个需要借用另外一个组件adk/middlewares/dynamictool动态工具层支持基于向量检索的工具下发而不是依赖当前的skill包。3. 第二次演进上下文污染与环境隔离Context Mode新痛点上面的“渐进式加载”解决了 Context 爆炸的问题但引出了一个极其凶险的**上下文污染Context Pollution**问题。假设大模型加载了一个极其复杂的“代码审查Code Review”Skill这个 Skill 的Content里包含了成百上千行的审查规范和示例代码。当它把这些内容拉取到当前的Messages历史中后当前会话被带偏大模型会被这几千行“外来物种”严重干扰可能忘了用户最初的简单指令。无法切换模型有些专业技能必须用专门微调过的模型比如写代码用 工具调用微调过的 Claude但当前的 Agent 可能绑定的是普通的 GPT-4o在单体 Agent 内部是无法动态切换底层模型的推导解决当技能过于复杂时不能把它拉取到“当前线程”来执行。我们必须**“拉起一个子进程Fork Sub-Agent”把这个复杂的技能交给一个全新的、甚至挂载了不同底座模型的独立 Agent 去执行执行完后只把最终结果**返回给主 Agent。3.1 疑问澄清谁来判断 Skill 是否“复杂”Eino 并不在代码里做任何智能判断。它完全依赖“人类开发者的声明式配置”。是否拉起独立 Agent完全取决于这个技能对应的SKILL.md文件顶部的 YAMLFrontMatter是怎么写的。# 简单的技能直接拉进当前会话默认 inlinename:获取时间description:获取当前系统时间---直接调用 get_time 工具。# 复杂的技能开发者主动声明必须用 fork 模式甚至指定底座模型name:代码审查description:执行深度的代码质量审查context:fork# 核心人类告诉框架这个必须隔离执行model:claude-opus# 核心人类告诉框架这个必须切模型---这里是 5000 字的审查规范...映射到源码skill.go 的switch skill.Context实现了纯粹的查表路由。如果是ContextModeFork框架就会去AgentHub里拉起一个新的独立 Agent见runAgentMode。如果是默认情况就直接把文本作为工具结果返回。// 第二次演进隔离执行的 Fork 模式typeSkillstruct{NamestringContentstringContextstring// 运行模式inline 或 forkModelstring// 指定这个技能必须用什么模型跑}funcLoadSkill(skillNamestring)string{skill:db.Get(skillName)ifskill.Contextfork{// 拉起一个全新的独立 Agent它的系统提示词就是这个 Skill 的 ContentsubAgent:NewAgent(systemPrompt:skill.Content,model:skill.Model)result:subAgent.Run(userInput)return子任务执行结果: result}// 否则直接返回内容 (inline)returnskill.Content}映射到源码skill.go 定义了极其关键的ContextModefork和fork_with_context。skill.go 的switch skill.Context实现了基于模式的路由。skill.go 的runAgentMode实现了真正的“拉起子 Agent”。它不仅会从AgentHub借用一个 Agent还会根据 FrontMatter 中的skill.Model从ModelHub中动态替换底座模型4. 批判性总结优势极其优雅的“反熵增”设计完美化解大一统 Agent 的臃肿通过渐进式展示Progressive Disclosure主 Agent 永远保持清爽。它只做路由把脏活累活都通过工具下放。Fork 模式的降维打击允许通过 FrontMatterYAML声明式地配置context: fork和model: claude-3.5。这使得业务开发人员完全不需要写 Go 代码只需写一份SKILL.md就能在运行时动态拉起一个异构的专家 Agent 网络。这极大地降低了多 Agent 协作的门槛。代价与局限协议脆弱与黑盒调试强依赖大模型的“顺从度”这种设计极其依赖主模型能乖乖听话。如果主模型比较笨它可能会无视Skill目录或者在加载了 Skill Content 后根本看不懂里面的工作流。嵌套 Fork 的幽灵如果Agent Afork 出了Agent B来执行 Skill而Agent B在执行过程中又调用了另一个需要 fork 的 Skill 触发了Agent C… 这种无限制的递归 Fork 会导致极难排查的超时Timeout和费用爆炸。框架目前并没有限制 Fork 深度。文件后端的局限目前的 filesystem_backend.go 强制要求按目录组织SKILL.md并在头部写 YAML。这对于本地开发很爽但在云端动态分发比如在 SaaS 平台上让用户动态配置技能时解析 Markdown FrontMatter 显得过于极客和笨重后续必然需要向真正的关系型/文档型数据库 Backend 演进。总结adk/middlewares/skill不是一个简单的“读文件工具”而是一个披着工具外衣的**“动态子 Agent 孵化器”**。它将“知识管理”与“运行时调度”完美结合是 Eino 能够支撑复杂业务落地的最核心基建之一。

更多文章