AI概念速览:Agent、Model、Scaffolding、Harness 一次讲清,配 TaoToken 统一 Key 跑通最小示例
1. 先把四个词摆到一张桌上Agent、Model、Scaffolding、Harness 到底谁管谁刚接触 AI 工程化的朋友最容易在这四个词上打转Agent、Model、Scaffolding、Harness。它们经常被混着用甚至有人把「接了个大模型 API」直接叫成「做了个 Agent」。我试过在同一个项目里把这几个概念拆开标注代码立刻清爽很多排障也知道该看哪一层。先用一句话给它们分工Model 是只会「文本进、文本出」的大脑Scaffolding 是喂给这个大脑的剧本和道具清单也就是系统提示词、工具描述、输出格式约束Harness 是真正让模型跑起来的执行引擎负责循环调用、解析工具调用、判断停止条件Agent 则是 Model Scaffolding Harness Tools 组装出来的完整系统能围绕目标拆任务、调工具、看结果、再修正。适合谁看如果你正在写第一个带工具调用的脚本或者准备把「聊天机器人」升级成「能自己干活的智能体」这篇就是给你的一张概念地图。下面我会先给对照表再给一份可复制的 settings.json 骨架最后用一个最小 Agent 循环把四层怎么协作跑通给你看。全程用 TaoToken 的统一 Key省去在多个模型供应商之间来回切 Key 的麻烦。1.1 四层概念对照表概念职责不负责什么类比Model文本进、文本出生成意图与内容没有记忆、不循环、不主动行动光动嘴不动手的大脑Scaffolding系统提示词、工具描述、输出格式约束不负责运行逻辑与循环给模型看的剧本和道具清单Harness循环调用模型、处理工具调用、判断停止不决定「你是谁」只决定「怎么跑」喊 Action 的导演Agent目标驱动拆任务、调工具、观察、修正不是单个模型也不是单次对话完整作战单元注意Chatbot 和 Agent 的分界线在「是否围绕目标执行任务」。Chatbot 围绕对话生成回复Agent 围绕目标推进任务这个区别决定了你要不要写 Harness。2. 前置准备用 TaoToken 统一 Key 管住模型入口在写 Harness 之前先把模型入口统一掉。否则你的 settings.json 里会散落一堆不同厂商的 base_url 和 key换模型时改到崩溃。TaoToken 的思路是给你一个统一的 API 入口和一把 Key模型名在请求里指定即可。你需要准备两样东西一把 API Key以及一个兼容 OpenAI 风格的 base_url。Key 在控制台的 API Keys 页面创建地址是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。创建后复制保存页面只完整显示一次。base_url 用 https://taotoken.net/api 注意这个地址后面不加任何 UTM 参数直接作为 OpenAI SDK 的 base_url 使用。模型名按你实际要用的填比如 claude 系列或 gpt 系列具体可用列表在接入文档里查https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。提示把 Key 放进环境变量不要硬编码进 settings.json 提交到仓库。settings.json 里用占位符引用环境变量即可。2.1 环境变量与依赖安装先装依赖Python 侧用 openai 官方 SDK 就能对接因为 TaoToken 兼容 OpenAI 风格接口。pip install openai export TAOTOKEN_API_KEY你的Key如果你用 Node装 openai 包同理npm install openai export TAOTOKEN_API_KEY你的Key3. 可复制配置settings.json 骨架与四层映射下面这份 settings.json 是我常用的骨架把四层概念直接映射成配置字段。model 段对应 Model 层scaffolding 段对应剧本harness 段对应执行引擎参数agent 段把前三者组装起来。{ model: { provider: taotoken, base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, name: claude-sonnet-4-5, temperature: 0.2, max_tokens: 2048 }, scaffolding: { system_prompt: 你是一个会使用工具的助手。每次只输出一个动作要么调用工具要么给出最终答案。, tools: [ { name: read_file, description: 读取指定路径的文件内容, parameters: { type: object, properties: { path: { type: string, description: 文件路径 } }, required: [path] } }, { name: write_file, description: 把内容写入指定路径的文件, parameters: { type: object, properties: { path: { type: string }, content: { type: string } }, required: [path, content] } } ], output_format: json }, harness: { max_turns: 8, stop_on_final_answer: true, tool_timeout_seconds: 15, on_tool_error: return_to_model }, agent: { name: minimal-file-agent, goal: 读取 input.txt 并把内容转成大写写入 output.txt, scaffolding_ref: scaffolding, harness_ref: harness, model_ref: model } }几个字段值得单独说。harness.max_turns 是循环上限防止模型陷入死循环on_tool_error 设为 return_to_model意思是工具报错时把错误信息回传给模型让它自己决定下一步而不是直接崩掉。scaffolding.output_format 设为 json是为了让 Harness 好解析模型返回的动作。注意Scaffolding 里的 tools 描述要写清楚参数含义模型靠这段描述决定怎么填参数。描述含糊工具调用就容易出错这是最常见的坑。4. 跑通最小 Agent 循环验证四层如何协作配置就绪后写一个最小 Harness。它的逻辑很朴素把 scaffolding 拼成 messages调用 Model解析返回如果是工具调用就执行工具、把结果塞回 messages再进入下一轮如果是最终答案就停止。import os import json from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlhttps://taotoken.net/api, ) SYSTEM_PROMPT 你是一个会使用工具的助手。每次只输出一个 JSON{\action\:\tool\,\name\:\...\,\args\:{...}} 或 {\action\:\final\,\answer\:\...\}。 def call_model(messages): resp client.chat.completions.create( modelclaude-sonnet-4-5, messagesmessages, temperature0.2, ) return resp.choices[0].message.content def run_tool(name, args): if name read_file: with open(args[path], r, encodingutf-8) as f: return f.read() if name write_file: with open(args[path], w, encodingutf-8) as f: f.write(args[content]) return written return funknown tool: {name} def agent_loop(goal, max_turns8): messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: goal}, ] for turn in range(max_turns): raw call_model(messages) print(f[turn {turn}] model - {raw}) try: action json.loads(raw) except json.JSONDecodeError: messages.append({role: assistant, content: raw}) messages.append({role: user, content: 请只输出合法 JSON。}) continue if action[action] final: return action[answer] if action[action] tool: result run_tool(action[name], action.get(args, {})) messages.append({role: assistant, content: raw}) messages.append({role: user, content: f工具结果{result}}) return 达到最大轮数未完成 if __name__ __main__: print(agent_loop(读取 input.txt 并把内容转成大写写入 output.txt))跑之前先造一个输入文件echo hello taotoken input.txt python agent.py预期你会看到类似这样的过程第一轮模型返回 read_file 动作Harness 执行读取把内容回传第二轮模型返回 write_file 动作Harness 写入第三轮模型返回 final循环结束。此时 output.txt 里应该是 HELLO TAOTOKEN。4.1 四层协作的观察点跑通后回头看四层的边界非常清楚。Model 只负责生成那段 JSON它不知道文件系统长什么样Scaffolding 决定了它「知道有哪些工具、要按什么格式回答」Harness 负责解析 JSON、执行工具、把结果拼回上下文、控制轮数Agent 是这三者加上工具后表现出的整体行为。任何一环出问题现象都不一样模型答非所问多半是 Scaffolding 的提示词或工具描述没写清循环停不下来多半是 Harness 的停止条件或 max_turns 没设好工具执行报错则是 Tools 层的事。5. 本篇常见错排查第一个高频错误是 401。现象是调用直接返回鉴权失败原因通常是环境变量没导出或者 Key 复制时带了空格。检查echo $TAOTOKEN_API_KEY是否有值再确认 base_url 写的是 https://taotoken.net/api 而不是别的路径。第二个是模型返回不是合法 JSON导致 json.loads 抛异常。这属于 Scaffolding 问题解决办法是在系统提示词里强调「只输出 JSON」并在 Harness 里加一层容错解析失败就把原文和纠正指令回传让它重试。上面代码里已经这么处理了。第三个是工具调用参数缺失。模型可能只给了 path 没给 content或者字段名拼错。排查方法是打印 action 对象对照 scaffolding.tools 里的 parameters 定义看描述是否足够明确。参数描述越具体模型填错概率越低。第四个是循环不停止。如果模型一直返回工具调用而不给 finalmax_turns 会兜底。但更好的做法是在 Scaffolding 里明确「任务完成后必须返回 final」并在 Harness 里检测重复动作同一工具同一参数连续出现两次就强制终止。第五个是超时。工具执行慢会拖垮整个循环harness.tool_timeout_seconds 就是干这个的。给每个工具执行加超时超时后把错误信息回传模型让它换策略。提示排障时按 Model → Scaffolding → Harness → Tools 的顺序逐层看比漫无目的地改代码快得多。接入细节和参数说明可以对照接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。6. 把 Key 和循环都收进统一入口到这里你已经有了概念对照表、可复制的 settings.json 骨架以及一个能跑通的最小 Agent 循环。接下来最省事的做法是把模型入口固定成 TaoToken 的统一 Key这样换模型只改 settings.json 里的 name 字段Harness 和 Scaffolding 都不用动。如果你只是想先验证模型返回格式和工具调用长什么样可以直接在模型对话页里试https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。如果你准备长期写编码类 Agent或者要跑多轮的工具循环建议用 Coding Plan 把额度管起来https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。Key 的创建和管理都在控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite API Keys 页面单独在这里https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。最后留一个我踩过的坑别急着给 Agent 加一堆工具。先把 read_file 和 write_file 两个跑顺确认 Harness 的循环、停止条件、错误回传都正常再逐个加工具。工具越多Scaffolding 的描述越长模型选错工具的概率越高。四层里最容易被低估的是 Scaffolding它决定了模型的行为边界值得你多花时间打磨提示词和工具描述。