1. 先搞清楚多 AI 智能体到底在解决什么问题你可能已经用过不少对话式 AI问一句答一句你不问它就停在那里。这种模式在写文案、查资料时够用但一旦任务变成“帮我把下周的客户拜访安排明白”它就开始露怯——因为它不会自己拆步骤不会主动去查你的日历更不会在关键节点停下来问你一句“这个时间行不行”。多 AI 智能体要解决的正是这种“喂一句动一下”的被动感。它把一个大目标拆成若干子任务分给不同的“角色”去执行中间还能调用外部工具查天气、读文件、发请求并且在需要人拍板的时候主动中断等你确认后再继续。打个生活化的比方传统对话 AI 像计算器你按一个键它出一个结果多 AI 智能体更像你请了一个小团队——有人负责列计划有人负责跑腿办事有人负责在花钱之前先问你一句。自主规划、工具调用、交互中断就是这个小团队的三个核心机制。这篇面向零基础读者不讲论文里的抽象定义直接给你一份可复制的多智能体配置骨架并带你跑通一次“规划→调用→中断→恢复”的最小闭环。全程只需要一个能发 HTTP 请求的环境加上一个模型 API Key。2. 前置准备用 TaoToken 拿到模型调用能力多智能体系统里规划器需要模型来“想”工具调用需要模型来“决定调哪个”中断恢复需要模型来“接着往下走”。所以第一步是让本地环境能稳定调用模型。TaoToken 在这里扮演的是统一接入层你不需要分别去对接多家模型服务用一个 Key 就能在规划器、执行器、总结器之间切换不同模型。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。操作顺序很简单先注册账号然后进控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建后把 Key 复制到本地环境变量里别写死在代码中。export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你后面想长期跑编码类或 Agent 类任务可以了解下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。只是想先验证模型通不通用模型对话页最快https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。注意Key 只存在服务端或本地环境变量不要提交到 Git也不要在前端代码里明文出现。3. 可复制配置多智能体骨架文件下面这份配置是整个闭环的核心。它用 YAML 描述三个角色planner规划器、executor执行器、reviewer审核器并注册两个工具get_weather 和 read_file。中断点设在“执行器准备调用工具之前”这样你可以在真正动手前接管。# agents.yaml version: 1.0 model: base_url: https://taotoken.net/api api_key_env: TAOTOKEN_API_KEY default_model: gpt-4o-mini agents: - name: planner role: 任务规划器 system_prompt: | 你是一个任务规划器。收到用户目标后把它拆成 2-4 个可执行步骤。 每一步必须说明要做什么、用哪个工具、预期产出。 只输出 JSON格式为 {steps:[{id:1,action:...,tool:...,expect:...}]} tools: [] - name: executor role: 工具执行器 system_prompt: | 你根据规划器给出的步骤决定调用哪个工具并给出调用参数。 只输出 JSON格式为 {tool:工具名,args:{...}} tools: [get_weather, read_file] - name: reviewer role: 结果审核器 system_prompt: | 你检查执行结果是否符合预期输出 {pass:true/false,reason:...} tools: [] tools: - name: get_weather description: 查询指定城市的天气 endpoint: https://taotoken.net/api/tools/weather method: POST params: city: string - name: read_file description: 读取本地文本文件内容 endpoint: local://read_file method: FUNCTION params: path: string interrupt: enabled: true before_tool_call: true resume_token_env: TAOTOKEN_RESUME_TOKEN这份骨架的关键点有三个。第一planner 只负责拆步骤不碰工具避免“既当裁判又当运动员”。第二executor 的工具列表是白名单没注册的工具它调不到。第三interrupt 节点设在工具调用之前这样任何外部动作发生前你都有机会喊停。把文件保存到本地后用一段 Python 脚本加载它并模拟一次完整流程。下面这段代码不依赖复杂框架只用标准库加 requests方便你直接跑。import os, json, yaml, requests with open(agents.yaml, r, encodingutf-8) as f: cfg yaml.safe_load(f) BASE cfg[model][base_url] KEY os.environ[cfg[model][api_key_env]] HEADERS {Authorization: fBearer {KEY}, Content-Type: application/json} def call_model(system_prompt, user_input): payload { model: cfg[model][default_model], messages: [ {role: system, content: system_prompt}, {role: user, content: user_input} ] } r requests.post(f{BASE}/v1/chat/completions, headersHEADERS, jsonpayload, timeout60) r.raise_for_status() return r.json()[choices][0][message][content] def run_planner(goal): agent next(a for a in cfg[agents] if a[name] planner) return call_model(agent[system_prompt], goal) def run_executor(step): agent next(a for a in cfg[agents] if a[name] executor) return call_model(agent[system_prompt], json.dumps(step, ensure_asciiFalse)) def run_reviewer(result): agent next(a for a in cfg[agents] if a[name] reviewer) return call_model(agent[system_prompt], result)到这里配置和加载逻辑就齐了。接下来是真正跑一次闭环。4. 验证请求跑通“规划→调用→中断→恢复”先发一个目标给 planner看它能不能拆出合理步骤。请求体如下curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [ {role: system, content: 你是一个任务规划器。把目标拆成2-4步只输出JSON。}, {role: user, content: 帮我确认明天杭州是否适合户外拍摄} ] }预期返回类似{ steps: [ {id: 1, action: 查询杭州明天天气, tool: get_weather, expect: 温度与降水概率}, {id: 2, action: 判断是否适合户外, tool: none, expect: 结论与建议} ] }拿到步骤后executor 会决定调用 get_weather。此时因为配置里before_tool_call: true系统不会直接发请求而是返回一个中断信号类似{ status: interrupted, interrupt_id: int_20250101_001, pending_tool: get_weather, args: {city: 杭州}, message: 工具调用前需人工确认 }这就是交互中断的价值模型可以自己规划、自己决定调什么但真正触碰外部世界之前控制权回到你手里。你确认后用 resume 接口继续curl -X POST https://taotoken.net/api/v1/agents/resume \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { interrupt_id: int_20250101_001, decision: approve, edited_args: {city: 杭州} }恢复后工具真正执行返回天气数据reviewer 再判断结果是否满足预期。整个链路跑通时你会看到类似输出{ status: completed, plan: [查询杭州天气, 判断户外适宜性], tool_result: {city: 杭州, temp: 22, rain_prob: 0.1}, review: {pass: true, reason: 降水概率低温度适宜} }如果中途你选择decision: reject系统会回到 planner 重新规划而不是硬着头皮往下走。这就是“中断-恢复”比“直接报错”更实用的地方。5. 本篇常见错排查报错一401 Unauthorized。九成是 Key 没读到。先确认echo $TAOTOKEN_API_KEY有值再检查请求头是不是Bearer加空格。如果用的是配置文件里的api_key_env注意环境变量名大小写要一致。报错二工具调用返回 404。检查agents.yaml里工具的endpoint是否写全。本地函数类工具如 read_file不会走 HTTP如果你的执行器把它当远程接口请求就会 404。区分method: FUNCTION和method: POST。报错三中断后 resume 提示 interrupt_id 不存在。中断状态需要持久化。如果你用的是内存存储进程重启后 ID 就丢了。生产环境建议把中断状态落到 Redis 或 SQLite恢复时先查状态再续接。报错四planner 输出不是合法 JSON。模型偶尔会加解释文字。在 system prompt 里强调“只输出 JSON”并在代码里加一层容错截取第一个{到最后一个}之间的内容再解析。报错五executor 调用了未注册工具。这是白名单没生效。检查加载配置时是否真的把tools列表传给了执行器而不是只写在 YAML 里没读取。6. 接下来怎么用这套骨架这套最小闭环跑通后你可以按需扩展。想加“记忆”就在 planner 前面挂一个检索步骤把历史任务摘要塞进上下文。想加“多智能体协作”就再注册一个 researcher 角色让 planner 把调研类步骤分给它。想验证不同模型在规划上的差异直接去模型对话页切换对比https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。如果你打算把这套东西接到日常编码或长期 Agent 任务里Coding Plan 的额度模型会更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入过程中遇到鉴权或参数问题先翻接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 大部分报错在里面都有对照说明。最后留一个我踩过的坑中断点不要设得太密。每个工具调用前都中断人会烦设得太疏又失去接管意义。我的做法是只对“写操作”和“花钱操作”开中断读操作直接放行。你可以从before_tool_call改成按工具名匹配只对write_file、send_email这类动作生效。
