大家在做 AI Agent 相关项目时,可能都有过类似的困惑:明明网上到处都在讲 Agent,说自己要“做一个 Agent”,结果一上手,发现还要面对工具调用、上下文维护、错误恢复、权限控制一堆问题。更麻烦的是,很多人把Agent和Harness混为一谈,导致看官方文档时经常绕晕。
最近 OpenAI Codex 被反复提及的一句话是 “Codex as a Platform: Build on the Open Agent Harness”,把Agent Harness这个概念推到了台前。本文就围绕这个主题,从底层原理、核心能力到代码实战,完整拆解一遍 Harness Agent 是什么、怎么用、以及如何从零手写一个极简 Harness。内容偏保姆级,零基础也能跟着做,有后端经验的开发者可以直接跳到第 5 节看代码。
1. 背景与核心概念
1.1 什么是 Agent
先来说 Agent。按最朴素的解释,Agent 是一个能感知环境、做出决策、并调用工具执行任务的程序。
一个普通脚本和 Agent 的根本区别在于:脚本的执行路径是提前写死的,而 Agent 的执行路径是根据当前状态动态决策的。
举例来说:
- 普通脚本:读文件 → 统计行数 → 打印结果,逻辑固定。
- Agent:收到用户指令“帮我统计一下这个文件有多少行,顺便看看有没有重复数据” → 模型决定先读文件、再分析、再调用统计工具 → 根据结果决定下一步。
到了大模型时代,Agent 的典型构成可以概括为:
- 推理内核:通常是一个 LLM,负责理解指令、拆解任务、决定调用哪个工具。
- 工具集合:对外部能力的封装,如搜索、计算、读写文件、调用 API 等。
- 记忆与上下文:保存历史对话、中间结果、任务目标。
- 执行循环:让“决策-行动-观察-再决策”闭环跑起来。
所以,Agent 解决的核心问题是:让程序具备基于目标的自主行动能力。
1.2 什么是 Harness
Harness 在英文里的原意是“马具、挽具”,作用是把动力源和车身连接起来。在 AI Agent 语境下,Harness 可以理解为 Agent 的“驾驶舱”或“运行框架”。
更准确一点:Harness 是包裹在 Agent 内核之外的一层执行框架,负责把模型输出的决策变成真实可执行的行动。
一个典型的 Agent Harness 要做的事情包括:
- 管理输入输出流;
- 维护消息历史和上下文窗口;
- 调度工具调用;
- 处理循环中的错误与异常;
- 执行安全策略与权限限制;
- 记录运行日志和可观测指标。
为什么最近 Harness 这个概念被频繁提到?因为 Codex 已经不只是一个代码补全工具,而是慢慢演变成了一个平台。官方把这层支撑“智能体运行”的骨架抽象出来,开放给开发者,让大家可以基于同一套 Agent Harness 构建自己的编码智能体。这正是 “Codex as a Platform: Build on the Open Agent Harness” 背后的含义:LLM 负责智能,Harness 负责把智能安全的落地成动作。
1.3 为什么开发者需要掌握 Harness
很多人在做 Agent 项目时,会遇到下面这些典型问题:
- 用某个 Agent 框架时,模型经常不调用工具,而是自己“编答案”;
- 上下文稍微一长,Token 就爆了;
- 工具调用偶发报错,整个流程直接中断;
- 想限制 Agent 只能访问某几个接口,不知道在哪一层做控制。
这些问题,几乎都出在 Harness 层,而不是模型本身。
如果能理解 Harness 的原理,你就知道:工具调用需要注册表、上下文需要预算管理、错误需要回传给模型做自纠、权限需要在策略层统一控制。掌握了这些,不管以后用 Codex Agent SDK、LangChain,还是自研框架,思路都是通用的。
2. Harness 与 Agent 的区别
这一节解决一个高频疑问:Harness 和 Agent 到底有什么区别?很多人搜到“harness agent”时,会以为这是两个可以互替的名词,实际上它们描述的是不同层次的东西。
| 对比维度 | Agent | Harness |
|---|---|---|
| 角色定位 | 决策者 | 执行环境与调度者 |
| 核心问题 | 下一步做什么 | 如何安全、高效、可控地执行 |
| 关注点 | 推理、规划、工具选择 | 工具注册、上下文、循环、权限、日志 |
| 类比 | 驾驶员 | 汽车底盘、仪表盘、刹车系统 |
| 生产问题 | 模型答错、规划不合理 | 工具超时、上下文溢出、权限绕过 |
简单来说:Agent 是大脑,Harness 是身体和双手运行的整套机制。
再举一个通俗的例子。你让一个助手“帮我查询天气,如果下雨就提醒我带伞”。助手脑子里想的是“我需要调用天气查询工具,看看要不要提醒”。但真正让这句话落地的,是背后那一套流程:解析出工具调用、传入城市参数、拿到天气结果、决定是否触发提醒、最后反馈给你。这套流程本身,就是 Harness 在做的事。
除了跟 Agent 区分,还有两个容易混淆的“Harness”:
- Test Harness:软件测试领域的“测试脚手架”,用于隔离被测代码并驱动测试用例。它和 Agent Harness 都叫 Harness,但解决的是完全不同的问题。
- Harness 公司:有一家做 CI/CD 的公司叫 Harness。它跟本文讨论的 Agent Harness 没有直接关系,搜索资料时注意区分。
理解这个区别之后,你再去看官方文档里 “Agent” 和 “Harness” 两个词,就不会再晕了。
3. Agent Harness 的底层原理拆解
3.1 核心组件
一个可用的 Agent Harness,内部至少包含下面几个组件:
推理内核(Agent Core) 负责与 LLM 交互。它把用户输入、系统提示词、历史消息、工具描述拼装成请求,发送给模型,再解析模型的输出。
工具注册表(Tool Registry) 统一维护“这个 Agent 能调用哪些工具”。每个工具通常包含名称、描述、参数 JSON Schema、执行函数。注册表的作用有两个:一是给模型提供工具说明,二是限制模型只能调用白名单内的工具。
上下文管理器(Context Manager) 负责维护对话记录。包括 System Prompt、用户消息、助手消息、工具返回结果。它需要处理一个问题:大模型上下文窗口有限,历史消息不能无限增长。
策略引擎(Policy Engine) 负责权限控制、频率限制、安全检查。比如“计算工具只允许处理数值,不允许执行系统命令”“某个工具最多调用 5 次”等约束都放在这里。
可观测模块(Observer) 记录每次决策、工具调用、错误信息、耗时指标。生产环境排障基本靠它。
3.2 一次完整执行循环
理解 Harness 最好的方式,是看一次完整调用链:
- 接收用户输入。用户发来一句自然语言指令,作为本次任务的起点。
- 组装上下文。Harness 把系统提示词、历史消息、工具描述拼装成一个请求。
- 推理。LLM 接收请求,输出结果。结果可能是一个最终回答,也可能是一个工具调用意图。
- 解析决策。Harness 从模型输出中解析出结构化指令,例如“调用工具 get_current_time,参数为空”。
- 执行工具。Harness 根据工具注册表找到对应函数,传入参数并执行。
- 回传结果。工具执行完成后,结果会作为一条新消息追加到上下文中。
- 再决策。Harness 把带工具结果的上下文再次发送给模型,让模型判断任务是否完成。
- 输出或继续。如果模型认为任务完成,就输出最终回答;否则继续进入工具调用循环。
整个过程很像人的工作方式:看一眼任务 → 动一下手 → 看结果 → 再决定下一步。
3.3 上下文窗口与 Token 预算
Harness 里最容易出问题的环节是上下文管理。
LLM 的输入长度是有限制的。当历史消息不断累积,工具结果不断追加时,很快会触达上限。Harness 的上下文管理器一般会做几件事:
- 计算当前消息序列的 Token 占用;
- 移除最早的非关键历史消息;
- 将过长的历史消息摘要压缩;
- 限制单次工具结果的大小,超长内容只截取一部分回传。
所以,不要以为 Agent 能“记住”所有历史,实际上 Harness 是在有限的上下文窗口里做各种取舍。
3.4 错误恢复与回退策略
工具调用不可能永远成功。可能的原因包括:
- 参数格式不对;
- 网络超时;
- 权限不足;
- 工具内部逻辑抛异常。
一个好的 Harness 不会直接崩溃,而是把错误信息作为观察结果回传给模型,让模型修改参数或换一种策略重新尝试。同时,Harness 还要设置最大重试次数和单轮超时时间,避免无限循环或长时间卡死。
这部分工程细节,正是自研 Agent 和直接使用成熟框架时差距最大的地方。
4. 环境准备与工程结构
在进入代码实战之前,先准备好本地环境。
4.1 环境要求
本文的实战部分,会从零实现一个极简 Agent Harness。为了照顾零基础读者,设计上做了两个选择:
- 不依赖任何外部 LLM API,电脑上直接运行;
- 优先展示 Harness 的核心机制,模型决策部分用可替换的模拟函数代替。
环境要求如下:
- Python 3.9 及以上版本;
- 无需安装任何第三方依赖;
- 如果后续要接入真实大模型,再根据所选服务安装对应 SDK。
说明一下:当前 AI 工具链迭代很快,不同版本的 SDK API 差异比较大。本文示例重点在于展示 Harness 的通用设计思路,不绑定某个固定版本号。接入真实模型时,请以所用服务的官方文档为准。
4.2 项目结构
为了便于理解,我按模块拆分项目:
mini_harness/ ├── main.py # 入口,负责组装各模块并启动交互 ├── harness/ │ ├── __init__.py # 包初始化 │ ├── core.py # Harness 核心循环 │ ├── tools.py # 工具注册表与工具实现 │ └── policy.py # 策略引擎,权限与轮数控制 └── requirements.txt # 依赖说明,本文示例为空这个结构参考了生产级 Harness 的分层思路:工具层、策略层、核心调度层彼此独立。这样后续替换真实模型时,只需要修改入口,不需要改动核心循环。
5. 从零实现一个极简 Agent Harness
接下来进入代码实战。我们先定义两个工具,再写策略层,最后实现核心循环。
5.1 工具层实现
文件路径:harness/tools.py
""" 工具注册表与工具实现。 每个工具由三部分组成: 1. 名称 2. 描述信息(供模型理解) 3. 实际执行的函数 """ import datetime def get_current_time() -> str: """返回当前时间字符串。""" now = datetime.datetime.now() return now.strftime("%Y-%m-%d %H:%M:%S") def calculate(expression: str) -> str: """ 计算简单的四则运算表达式。 注意:这里仅供教学演示,实际项目中不要用 eval 处理任意表达式。 """ # 只允许数字、空格和 + - * / ( ) 这些字符 allowed_chars = set("0123456789+-*/() .") for ch in expression: if ch not in allowed_chars: raise ValueError(f"表达式包含非法字符: {ch}") try: result = eval(expression, {"__builtins__": {}}, {}) return str(result) except Exception as e: raise ValueError(f"表达式计算失败: {e}") # 工具注册表:一个字典,key 是工具名,value 是工具元信息 TOOL_REGISTRY = { "get_current_time": { "description": "获取当前日期和时间", "function": get_current_time, "parameters": {}, }, "calculate": { "description": "计算数学表达式,例如 '1 + 2' 或 '(3 + 5) * 2'", "function": calculate, "parameters": {"expression": "string"}, }, }这里有几个设计点需要解释:
- 每个工具的描述很重要。真实场景中,模型就是靠这些描述决定要不要调用、传什么参数。
calculate里的字符白名单是教学用简化方案。实际项目中,应该用更安全的表达式解析库,不要直接用eval。- 工具注册表集中管理,后续增加新工具只需要往字典里加一项,核心循环不用改。
5.2 策略层实现
文件路径:harness/policy.py
""" 策略引擎:负责权限控制和执行约束。 """ class Policy: def __init__(self, allowed_tools=None, max_turns=5): # 允许调用的工具白名单,None 表示全部允许 self.allowed_tools = allowed_tools # 最大执行轮数,防止无限循环 self.max_turns = max_turns # 每个工具的调用计数 self.tool_call_count = {} def check_tool_allowed(self, tool_name: str) -> bool: """检查工具是否被允许调用。""" if self.allowed_tools is None: return True return tool_name in self.allowed_tools def before_tool_call(self, tool_name: str) -> bool: """工具调用前检查:是否允许、是否超次数。""" if not self.check_tool_allowed(tool_name): return False current_count = self.tool_call_count.get(tool_name, 0) # 每个工具最多调用 3 次 if current_count >= 3: return False self.tool_call_count[tool_name] = current_count + 1 return True策略层在 Harness 里的位置很关键。它可以在工具调用前拦截非法操作,防止 Agent 失控。真实生产环境里,这里还会加上身份校验、敏感操作二次确认、频率限制等逻辑。
5.3 核心循环实现
文件路径:harness/core.py
""" Harness 核心循环: 接收用户输入 -> 组装上下文 -> 调用决策函数 -> 执行工具 -> 回传结果 -> 再次决策 """ from .tools import TOOL_REGISTRY from .policy import Policy class MiniHarness: def __init__(self, llm_parse_fn, policy: Policy): """ llm_parse_fn: 决策函数。 输入是消息列表,输出是一个字典,格式为: { "type": "tool_call" 或 "final", "tool": "工具名称"(可选), "args": {...}(可选), "content": "最终回答内容"(当 type 为 final 时) } """ self.llm_parse_fn = llm_parse_fn self.policy = policy self.messages = [] # 记录整个执行过程,方便观察和日志 self.steps = [] def run(self, user_input: str) -> str: self.messages.append({"role": "user", "content": user_input}) for turn in range(self.policy.max_turns): # 1. 调用决策函数(真实场景中是调用大模型) decision = self.llm_parse_fn(self.messages) # 2. 如果模型认为任务完成,直接输出最终结果 if decision.get("type") == "final": final_answer = decision.get("content", "") self.messages.append({"role": "assistant", "content": final_answer}) return final_answer # 3. 否则解析工具调用意图 tool_name = decision.get("tool") tool_args = decision.get("args") or {} # 4. 策略检查:是否允许调用 if not self.policy.before_tool_call(tool_name): error_msg = f"工具 {tool_name} 被策略拦截,请换一种方式回答。" self.messages.append({"role": "tool", "content": error_msg}) continue # 5. 执行工具 try: if tool_name not in TOOL_REGISTRY: raise ValueError(f"未知工具: {tool_name}") tool_function = TOOL_REGISTRY[tool_name]["function"] result = tool_function(**tool_args) result_text = str(result) except Exception as e: # 6. 工具执行失败,把错误信息回传给决策函数,让它自纠 result_text = f"工具执行失败: {str(e)}" self.messages.append({ "role": "tool", "name": tool_name, "content": result_text, }) self.steps.append({ "turn": turn + 1, "tool": tool_name, "args": tool_args, "result": result_text, }) # 超过最大轮数还没有输出最终结果,强制结束 return "已达到最大执行轮数,任务未能完成。" def load_tool_descriptions() -> str: """把注册表信息转成可读的工具说明,真实场景中会拼接到 System Prompt。""" lines = [] for name, meta in TOOL_REGISTRY.items(): params_desc = ", ".join( f"{k}: {v}" for k, v in meta.get("parameters", {}).items() ) lines.append(f"- {name}({params_desc}): {meta['description']}") return "\n".join(lines)核心循环的代码量不大,但已经把 Harness 的关键机制都覆盖了:
- 上下文用
messages列表维护; - 决策结果解析用
decision字典承载; - 策略检查在执行前拦截;
- 工具异常会回传给模型,而不是直接中断;
- 循环有最大轮数控制。
5.4 模拟决策函数
文件路径:main.py
为了让代码不依赖外部 API 也能运行,我写了一个mock_llm_parse函数。它用简单的规则模拟大模型的决策:
""" 入口文件:组装各模块并启动交互。 默认使用模拟决策函数,无需外部服务即可运行。 """ import re from harness.core import MiniHarness, load_tool_descriptions from harness.policy import Policy from harness.tools import TOOL_REGISTRY SYSTEM_PROMPT = f"""你是一个智能助手助手,你可以使用以下工具: {load_tool_descriptions()} 请根据用户需求选择是否调用工具。 """ def mock_llm_parse(messages): """ 模拟大模型的决策过程。 真实场景中,这里会调用 LLM,并把模型输出解析成结构化字典。 """ # 获取最后一条用户消息 last_user_msg = "" for msg in reversed(messages): if msg["role"] == "user": last_user_msg = msg["content"] break # 规则1:包含“时间”或“几点”时,调用 get_current_time if "时间" in last_user_msg or "几点" in last_user_msg: return {"type": "tool_call", "tool": "get_current_time", "args": {}} # 规则2:包含“计算”时,提取数学表达式并调用 calculate if "计算" in last_user_msg: # 简单提取所有表达式,实际场景中由模型解析参数 match = re.search(r"[\d+\-*/() .]+", last_user_msg) if match: expr = match.group().strip() return {"type": "tool_call", "tool": "calculate", "args": {"expression": expr}} return { "type": "final", "content": "我理解你想让我计算,但没有找到合法的数学表达式。", } # 规则3:兜底情况,直接给最终回答 return {"type": "final", "content": f"收到你的消息:{last_user_msg}。模拟模式下我没有更多工具可调用。"} def main(): print("===== Mini Agent Harness Demo =====") print("这是一个极简 Agent Harness,模拟模式运行。") print("你可以输入:") print(" - 现在几点了") print(" - 计算 1 + 2") print(" - 计算 (3 + 5) * 2") print("输入 exit 退出。\n") policy = Policy(allowed_tools=None, max_turns=5) harness = MiniHarness(llm_parse_fn=mock_llm_parse, policy=policy) while True: user_input = input(">>> ").strip() if user_input.lower() in ("exit", "quit"): print("再见!") break result = harness.run(user_input) print(f"Assistant: {result}\n") if __name__ == "__main__": main()mock_llm_parse的目的不是演示模型能力,而是把 Harness 的骨架先跑通。当你想接入真实模型时,只需要把这个函数替换成真正的 LLM 调用,并解析返回值即可。
为了让目录结构完整,还需要创建:
文件路径:harness/__init__.py
from .core import MiniHarness, load_tool_descriptions from .policy import Policy __all__ = ["MiniHarness", "load_tool_descriptions", "Policy"]文件路径:requirements.txt
# 本文示例无需第三方依赖 # 接入真实 LLM 时,请根据所选服务自行添加6. 运行与验证
6.1 运行命令
在项目根目录执行:
python main.py预期交互效果如下:
===== Mini Agent Harness Demo ===== 这是一个极简 Agent Harness,模拟模式运行。 你可以输入: - 现在几点了 - 计算 1 + 2 - 计算 (3 + 5) * 2 输入 exit 退出。 >>> 现在几点了 Assistant: 2025-01-15 20:30:45 >>> 计算 1 + 2 Assistant: 3 >>> 计算 (3 + 5) * 2 Assistant: 16 >>> exit 再见!你可以观察到,Harness 内部执行了这样几步:
- 解析用户输入;
- 根据规则决定调用哪个工具;
- 执行工具;
- 把工具结果作为最终回答输出。
6.2 查看执行步骤
如果你想知道内部到底调用了哪些工具、结果如何,可以在main.py中加一行调试输出:
result = harness.run(user_input) print(f"Assistant: {result}\n") print("执行步骤:", harness.steps)这样每次运行后就能看到类似下面的内部记录:
执行步骤: [ {'turn': 1, 'tool': 'get_current_time', 'args': {}, 'result': '2025-01-15 20:30:45'} ]这个steps列表就是最简版的可观测数据。生产环境里,这些数据会被格式化写入日志系统或链路追踪平台。
6.3 如何接入真实 LLM
接入真实模型时,核心思路是替换mock_llm_parse:
- 将系统提示词、消息历史、工具注册表描述拼装成模型请求;
- 调用模型接口(不同厂商接口格式不同,以官方文档为准);
- 解析模型输出,返回结构化
decision字典。
代码骨架大致如下:
def real_llm_parse(messages): # 伪代码示例,具体 API 以所选模型的官方文档为准 response = call_llm( system=SYSTEM_PROMPT, messages=messages, tools=build_tools_schema(TOOL_REGISTRY), ) decision = parse_model_response(response) return decision这里不锁定任何具体厂商 SDK,是因为接口变化太快了。核心要点是:无论模型返回什么格式,最终都要转换成 Harness 内部的 decision 结构。这样整个执行循环完全不需要变动,就完成了从模拟模式到真实模型的切换。
7. 常见问题与排查思路
做 Agent Harness 开发时,下面这些问题是高频出现的。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 模型不调用工具,直接给出编造答案 | 工具描述不清晰,或上下文里没包含工具说明 | 检查 System Prompt 是否包含工具列表,优化工具描述 |
| 工具明明注册了,却提示未知工具 | 决策函数解析出的工具名与注册表 key 不一致 | 统一工具名,建议使用小写英文+下划线 |
| Agent 进入无限循环,一直调用同一个工具 | 没有设置最大执行轮数 | 在 Policy 中增加max_turns,单工具调用次数限制 |
| 上下文越来越长,最终请求超过模型限制 | 历史消息和工具结果没有做截断 | 实现滑动窗口、历史摘要压缩 |
| 工具调用报错后,整个流程中断 | 异常没有回传给模型,而是直接抛出 | 用 try-except 捕获异常,把错误信息追加到上下文中 |
| 模型返回 JSON 解析失败 | 输出格式不稳定 | 优先使用模型的函数调用机制;若无,则增加正则或模板兜底 |
| 权限被绕过,工具被非法调用 | 缺少策略层校验 | 所有工具调用前统一走 Policy 检查 |
排查时建议按下面顺序走一遍:
- 看日志:模型到底输出了什么?是没调用工具,还是调用格式不对?
- 看工具注册表:工具名、参数名和决策函数解析出的结果是否完全一致?
- 看策略配置:是否被白名单或次数限制拦截了?
- 看工具实现:单独执行这个工具是否能得到正确结果?
- 看上下文:是不是历史消息太长,把关键信息冲掉了?
这五步覆盖了 Agent Harness 从输入到输出的完整链路,能解决绝大部分问题。
8. 最佳实践与工程建议
8.1 最小权限原则
Agent 的能力越强,潜在风险就越大。在生产环境里,建议遵循最小权限原则:
- 只注册业务必需的工具;
- 策略层使用白名单控制,而不是黑名单;
- 敏感操作(销毁资源、删除数据、修改权限)必须二次确认;
- 工具执行前校验参数类型和取值范围。
不要把所有工具一股脑塞给 Agent。工具越多,模型选错工具的几率越高,被恶意指令利用的面也越大。
8.2 上下文管理是稳定性的生命线
很多 Agent 跑一段时间后效果变差,不是模型问题,而是上下文管理没做好。建议做到:
- 给所有消息标注 role 和来源(user、assistant、tool);
- 工具结果控制在合理长度,超长内容只回传摘要;
- 历史消息超过预算时,优先压缩旧的工具结果,而不是用户指令;
- 定期清理无用的中间步骤,降低 Token 消耗。
8.3 可观测性必须前置
第一次写 Harness 时,就要预留日志和追踪点位。至少记录:
- 每次模型输入的消息条数和 Token 估计;
- 每次决策的结构化结果;
- 每次工具调用的参数、耗时、返回结果、错误信息;
- 策略拦截记录。
生产环境里,没有日志的 Agent 等于黑盒,出问题根本没法定位。
8.4 安全边界
这里尤其要提醒两件事:
- 不要把用户输入直接拼进系统命令或代码执行环境;
- 警惕 Prompt Injection。工具返回结果中包含的可疑指令,不应被当作系统级指令执行。
一个稳妥的做法是:工具返回的结果一律视为不可信数据,只把它作为普通文本传给模型参考,不赋予它调用其他工具的权利。
8.5 尽量复用官方 Harness
如果是企业项目,不建议从零自研完整 Harness。更好的策略是:
- 优先使用官方或社区成熟的 Harness 框架;
- 通过自定义工具、自定义 Policy 扩展业务能力;
- 只对确实不满足需求的部分做二次开发。
官方框架经过大量用户验证,对极端情况的处理远比我们自己写的要完善。本文手写极简 Harness,目的是帮助理解原理,而不是鼓励大家在生产环境全部自己造轮子。
9. 总结与学习路线
这篇文章从概念、原理、代码实现、问题排查到工程建议,完整覆盖了 Harness Agent 的核心知识。读完你应该能回答下列几个问题:
- Agent 和 Harness 有什么区别?
- Harness 的核心组件有哪些?
- 一次工具调用循环是如何流转的?
- 如何从零实现一个最小可运行的 Harness?
- 上下文管理、策略控制、可观测性为什么重要?
接下来可以沿着这个方向继续深入:
- 学习 Function Calling 机制,理解模型如何输出结构化工具调用;
- 了解 MCP 等工具协议,看看工具注册如何标准化;
- 读一读 Codex Agent SDK 等官方 Harness 的源码或文档,对照本文的 MiniHarness,理解生产级设计的差距;
- 尝试给 MiniHarness 加上上下文压缩、日志落盘、真实模型接入,把它扩展成自己的练习项目。
如果你正在把自己的流程封装成 Agent,我的建议是:先从 Harness 入手,而不是一上来就堆功能。先把最小闭环跑通,再把工具、策略、可观测性一层层加进去,这个过程会比直接接手大而全的框架清晰得多。如果本文对你有帮助,可以先收藏备用,动手写代码时拿出来对照。欢迎在评论区聊聊你在 Agent 落地过程中遇到的坑。