☰
AI概念速览:Agent、Model、Scaffolding、Harness 一次讲清,配 TaoToken 统一 Key 跑通最小示例
2026/9/25 13:36:10 网站建设 项目流程

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_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。创建后复制保存,页面只完整显示一次。

base_url 用 https://taotoken.net/api ,注意这个地址后面不加任何 UTM 参数,直接作为 OpenAI SDK 的 base_url 使用。模型名按你实际要用的填,比如 claude 系列或 gpt 系列,具体可用列表在接入文档里查:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。

提示:把 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="你的Key"

3. 可复制配置: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_key=os.environ["TAOTOKEN_API_KEY"], base_url="https://taotoken.net/api", ) SYSTEM_PROMPT = "你是一个会使用工具的助手。每次只输出一个 JSON:{\"action\":\"tool\",\"name\":\"...\",\"args\":{...}} 或 {\"action\":\"final\",\"answer\":\"...\"}。" def call_model(messages): resp = client.chat.completions.create( model="claude-sonnet-4-5", messages=messages, temperature=0.2, ) return resp.choices[0].message.content def run_tool(name, args): if name == "read_file": with open(args["path"], "r", encoding="utf-8") as f: return f.read() if name == "write_file": with open(args["path"], "w", encoding="utf-8") as f: f.write(args["content"]) return "written" return f"unknown tool: {name}" def agent_loop(goal, max_turns=8): 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 定义,看描述是否足够明确。参数描述越具体,模型填错概率越低。

第四个是循环不停止。如果模型一直返回工具调用而不给 final,max_turns 会兜底。但更好的做法是在 Scaffolding 里明确「任务完成后必须返回 final」,并在 Harness 里检测重复动作,同一工具同一参数连续出现两次就强制终止。

第五个是超时。工具执行慢会拖垮整个循环,harness.tool_timeout_seconds 就是干这个的。给每个工具执行加超时,超时后把错误信息回传模型,让它换策略。

提示:排障时按 Model → Scaffolding → Harness → Tools 的顺序逐层看,比漫无目的地改代码快得多。接入细节和参数说明可以对照接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。

6. 把 Key 和循环都收进统一入口

到这里,你已经有了概念对照表、可复制的 settings.json 骨架,以及一个能跑通的最小 Agent 循环。接下来最省事的做法,是把模型入口固定成 TaoToken 的统一 Key,这样换模型只改 settings.json 里的 name 字段,Harness 和 Scaffolding 都不用动。

如果你只是想先验证模型返回格式和工具调用长什么样,可以直接在模型对话页里试:https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。如果你准备长期写编码类 Agent,或者要跑多轮的工具循环,建议用 Coding Plan 把额度管起来:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。Key 的创建和管理都在控制台:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite ,API Keys 页面单独在这里:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。

最后留一个我踩过的坑:别急着给 Agent 加一堆工具。先把 read_file 和 write_file 两个跑顺,确认 Harness 的循环、停止条件、错误回传都正常,再逐个加工具。工具越多,Scaffolding 的描述越长,模型选错工具的概率越高。四层里最容易被低估的是 Scaffolding,它决定了模型的行为边界,值得你多花时间打磨提示词和工具描述。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询