ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用 Microsoft Agent Framework 构建 SubAgent(Multi-Agent):config.toml 骨架与验证清单

用 Microsoft Agent Framework 构建 SubAgent(Multi-Agent):config.toml 骨架与验证清单 1. 从单 Agent 到 SubAgent为什么需要 config.toml 骨架如果你已经用 Microsoft Agent Framework 跑通过一个单 Agent大概率会经历这样一个阶段一个 Agent 什么都能干写代码、查资料、跑命令全塞在一个循环里。任务一复杂上下文就开始互相污染调试时根本分不清是哪一步出的问题。SubAgentMulti-Agent要解决的就是这件事——把一个大目标拆给多个职责单一的 Agent每个 Agent 只关心自己那一小段逻辑。Microsoft Agent Framework 里SubAgent 的编排不是靠代码里硬编码 if-else而是靠一份声明式的config.toml。这份文件定义了有哪些 Agent、每个 Agent 用什么模型、能调用哪些工具、以及主 Agent 可以把任务委派给谁。你可以把它理解成一张“组织架构图”主 Agent 是项目经理SubAgent 是各个专项工程师config.toml就是他们的岗位说明书和汇报关系。这篇内容面向已经了解 Agent 基本概念、准备在本地跑通一个最小 Multi-Agent 协作示例的开发者。我会从config.toml骨架出发给出可复制的配置片段然后一步步验证 Agent 注册、SubAgent 编排和调用链是否真的生效。过程中涉及模型调用的部分我会用统一的 Key/API 通道接入避免在多个供应商之间来回切换配置。2. 前置准备统一 Key/API 通道与运行环境在写config.toml之前先把两件事定下来模型调用的通道以及本地运行环境。模型通道这块我建议用一个统一的入口来管理 Key而不是每个 Agent 单独配一套。TaoToken 提供的就是这种统一通道官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。你可以在控制台创建一个 Key后面所有 Agent 的模型调用都走这个 Key 和 API 地址。这样做的好处是SubAgent 数量增加时不用为每个 Agent 单独申请和轮换凭证。具体操作上先到控制台生成 API Key# 控制台地址创建和管理 Key https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite生成后把 Key 存到环境变量里不要写进config.toml明文export TAOTOKEN_API_KEYsk-你的key运行环境方面你需要Python 3.10 以上Microsoft Agent Framework 的 Python 包对版本有要求安装框架本体pip install microsoft-agent-framework一个空的本地项目目录用来放config.toml和测试脚本如果你还没装框架可以先确认版本python -c import agent_framework; print(agent_framework.__version__)能打印出版本号说明环境就绪。接下来所有配置都围绕这个环境展开。3. config.toml 骨架Agent 注册与 SubAgent 编排config.toml的结构可以分成三块全局模型通道、Agent 注册表、SubAgent 委派关系。下面这份骨架可以直接复制到项目根目录改掉模型名和工具路径就能用。# 全局模型通道 [provider] api_base https://taotoken.net/api api_key_env TAOTOKEN_API_KEY default_model gpt-4o-mini # Agent 注册表 [agents.planner] name planner role 主控 Agent负责拆解任务并委派给 SubAgent model gpt-4o-mini tools [delegate, finish] subagents [coder, reviewer] [agents.coder] name coder role 代码生成 SubAgent只负责根据指令写代码 model gpt-4o-mini tools [write_file, read_file] [agents.reviewer] name reviewer role 代码审查 SubAgent检查代码问题并给出修改建议 model gpt-4o-mini tools [read_file] # SubAgent 委派关系 [delegation] max_depth 2 allow_parallel false timeout_seconds 120几个关键点解释一下。[provider]里的api_base指向统一通道api_key_env告诉框架从哪个环境变量读 Key。这样config.toml本身可以提交到版本库不会泄露凭证。[agents.planner]里的subagents [coder, reviewer]是 SubAgent 编排的核心。它声明了 planner 有权把任务委派给 coder 和 reviewer。没有出现在这个列表里的 Agentplanner 调不到。[delegation]控制调用链的边界。max_depth 2表示委派最多嵌套两层防止 Agent 之间无限互相调用。allow_parallel false表示 SubAgent 串行执行调试阶段建议关掉并行方便看日志。工具部分先声明名字具体实现后面在代码里注册。delegate和finish是框架内置的委派与结束工具write_file、read_file需要你自己实现。4. 可复制配置把 SubAgent 接进调用链有了骨架接下来把配置加载进代码并注册工具。下面这段脚本可以直接运行它会读取config.toml构建 Agent 图然后跑一个最小任务。import os import tomllib from agent_framework import AgentRuntime, tool # 读取配置 with open(config.toml, rb) as f: config tomllib.load(f) # 注册工具 tool def write_file(path: str, content: str) - str: with open(path, w, encodingutf-8) as f: f.write(content) return f已写入 {path} tool def read_file(path: str) - str: with open(path, r, encodingutf-8) as f: return f.read() # 构建运行时 runtime AgentRuntime( api_baseconfig[provider][api_base], api_keyos.environ[config[provider][api_key_env]], default_modelconfig[provider][default_model], ) # 注册所有 Agent for agent_id, spec in config[agents].items(): runtime.register_agent( namespec[name], rolespec[role], modelspec[model], toolsspec[tools], subagentsspec.get(subagents, []), ) # 绑定工具实现 runtime.bind_tool(write_file, write_file) runtime.bind_tool(read_file, read_file) # 设置委派边界 runtime.set_delegation( max_depthconfig[delegation][max_depth], allow_parallelconfig[delegation][allow_parallel], timeoutconfig[delegation][timeout_seconds], ) print(Agent 注册完成, runtime.list_agents())运行后如果打印出[planner, coder, reviewer]说明 Agent 注册和 SubAgent 关系都加载成功了。这里有个容易踩的坑tools列表里的名字必须和bind_tool注册的名字完全一致大小写敏感。如果config.toml写的是write_file代码里绑成writeFile运行时会报工具找不到。5. 验证请求跑通一个最小 Multi-Agent 协作配置加载只是第一步真正要验证的是调用链有没有按预期走。下面这段代码发起一个任务让 planner 拆解后委派给 coder 和 reviewer。task 写一个 Python 函数计算斐波那契数列第 n 项并让 reviewer 检查边界条件 result runtime.run( agentplanner, inputtask, traceTrue, # 打开调用链追踪 ) print(最终输出, result.output) print(调用链) for step in result.trace: print(f [{step.agent}] {step.action} - {step.detail})预期看到的调用链大致是这样[planner] delegate - coder [coder] write_file - fib.py [planner] delegate - reviewer [reviewer] read_file - fib.py [reviewer] finish - 边界条件建议n0 时应返回 0 或抛异常 [planner] finish - 任务完成如果你看到delegate后面跟着具体的 SubAgent 名字说明 SubAgent 编排生效了。如果 planner 直接finish而没有委派通常是两个原因一是任务描述太简单planner 判断自己能搞定二是subagents列表没配对。想单独验证某个 SubAgent 是否可用可以绕过 planner 直接调用direct runtime.run(agentcoder, input写一个冒泡排序函数) print(direct.output)这一步能跑通说明 SubAgent 本身注册没问题问题就出在委派关系或 planner 的决策上。6. 本篇常见错排查报错一KeyError: TAOTOKEN_API_KEY环境变量没导出或者导出后没重新加载 shell。检查方式echo $TAOTOKEN_API_KEY如果为空重新执行export或者把它写进.bashrc/.zshrc。报错二Agent coder not found in delegation scopeplanner 的subagents列表里没有 coder或者名字拼写不一致。检查config.toml里[agents.planner]的subagents字段确保和[agents.coder]的name完全一致。报错三Tool write_file is not boundconfig.toml里声明了工具但代码里没有bind_tool。每个在tools列表里出现的名字都必须有对应的绑定。报错四调用链深度超限如果 SubAgent 又去委派别的 Agent可能触发max_depth。调试阶段先把max_depth设成 2确认链路正常后再按需调整。不要一上来就设很大否则出问题时日志会非常长。报错五请求超时timeout_seconds默认 120 秒复杂任务可能不够。但先别急着调大优先看是不是某个 SubAgent 陷入了循环。打开traceTrue看调用链里有没有重复的delegate动作。7. 继续深入从最小示例到可用系统跑通最小示例后下一步通常是两件事一是把 SubAgent 的职责拆得更细比如加一个专门查文档的 Agent二是把模型调用统一到稳定通道上避免多 Key 管理带来的混乱。如果你准备长期做编码类 Agent可以了解 Coding Plan 的接入方式它更适合需要持续调用和额度管理的场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite需要管理多个 Key 或查看调用量时控制台在这里https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Key 的创建和轮换入口https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite接入文档里有完整的参数说明和示例https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite想先直观感受模型对话效果可以直接在模型对话页测试https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite我自己的习惯是每次改完config.toml先跑一遍runtime.list_agents()确认注册表再跑一个最小任务看调用链最后才上真实任务。这样出问题时能快速定位是配置层、注册层还是委派层的问题。
返回列表