最近在终端里重度使用 Claude Code 做代码迁移和批量重构,发现很多同学对它的理解仍停留在“一个能聊天的命令行工具”。真正驱动它在仓库里读文件、跑命令、改代码的,是一套完整的 Agent Harness。本文不打算逐行搬运官方闭源代码,而是从工程视角把它的运行机制拆开,再动手写一个最小可运行的 Harness 示例,帮助你理解 Agent 循环、工具调用、权限模型与上下文管理。无论你是 AI Agent 初学者,还是想深入自定义工具链的开发者,这篇文章都能给你一套可复用的分析框架。
1. 背景与核心概念
1.1 Claude Code 到底做了什么
Claude Code 是 Anthropic 推出的终端 AI 编程助手,它不是一个简单的“对话机器人”,而是一个能在真实项目里完成读文件、写文件、执行命令、运行测试、提交代码等操作的 Agent。你可以把它理解成“住在终端里的开发搭档”。
从使用者的角度看,Claude Code 做的事情大致是:
- 接收用户的中文或英文自然语言指令。
- 分析当前目录下的项目结构,读取相关文件内容。
- 自主决定调用哪些工具,比如读取文件、执行 Shell 命令、编辑代码。
- 根据工具返回结果,继续推理下一步操作。
- 遇到需要用户确认的操作时暂停等待,或直接遵循预设的权限规则执行。
在这个过程中,Claude Code 的价值并不只是“模型很强”,更关键的是它把模型能力封装成了一整套可运行、可控制、可观测的工程系统。这套系统,就是本文要拆解的 Agent Harness。
1.2 什么是 Agent Harness
Harness 在英文里原本是“挽具、背带”的意思,在 AI Agent 工程中,它被引申为“把模型装进可控运行环境中的整套装置”。
很多人会把 Agent 理解成“大语言模型本身”,这是一个常见的误区。大语言模型本质上是一个文本生成器,它只能接收文字输入并输出文字。模型自己不会读文件、不会执行命令、不会循环尝试。真正让模型“动手做事”的,是模型外面包着的那层系统:
- 接收用户输入,并组装成模型能理解的上下文。
- 提供工具列表,让模型可以“选择”调用哪些函数。
- 执行模型选择的函数,并把结果回传给模型,进入下一轮推理。
- 控制循环次数、处理异常、记录日志、限制权限。
这一整套机制就是 Agent Harness。Claude Code 是 Harness + 模型 + 工具集 + 权限系统 + 上下文管理器的综合产品。理解 Harness,就等于理解 Agent 的核心骨架。
1.3 为什么要“拆开”看 Claude Code
需要先说明一点:Claude Code 的核心代码并未完全开源,我们无法做到逐行阅读官方源码。但源码级理解并不等于逐行阅读源码,我们可以通过三条路径做到:
- 行为观察:通过终端里的调试模式查看 Claude Code 发给模型的真实请求。
- 接口分析:观察工具调用格式、权限提示、结果回传格式。
- 原理复现:用代码实现一个最简 Harness,复现它的核心流程。
三种方式结合起来,就能从“会用 Claude Code”升级为“理解 Claude Code”,甚至能自己实现一个类似工具。在 AI Agent 开发中,这种能力是通用的:无论是 Claude Code、Codex 还是各种开源 Harness,核心架构都遵循相似的思路。
2. 环境准备与基础安装
2.1 安装 Claude Code 命令行工具
Claude Code 官方提供了 npm 包,安装之前需要确保本机有 Node.js 环境。Claude Code 对 Node 版本有要求,建议使用当前较新的 Node.js LTS 版本。如果你还不知道本机是否安装了 Node.js,可以先执行:
node -v npm -v确认 Node.js 环境可用后,使用 npm 全局安装 Claude Code:
npm install -g @anthropic-ai/claude-code安装完成后检查版本:
claude --version如果能够输出版本号,说明安装成功。如果提示命令找不到,可能是 npm 全局目录没有加入 PATH,需要根据你当前操作系统的 npm 配置来解决。
2.2 登录与授权
首次运行 Claude Code 需要登录账号并授权终端使用。在项目目录下执行:
claude根据提示完成登录授权。需要注意的是,Claude Code 的生态更新非常快,登录方式、模型选择、命令参数都可能随版本调整,如果执行过程中遇到差异,优先查看当前版本的官方帮助信息:
claude --help2.3 准备一个最小工作区
为了观察 Claude Code 在真实项目里的行为,建议准备一个最小工作区:
mkdir claude-demo cd claude-demo git init echo "Hello from README" > README.md这个工作区有一个 README 文件和一个空的 git 仓库。后续观察 Claude Code 如何读取文件、如何执行命令时,这个最小环境足够了。
2.4 通过调试模式观察 Harness 行为
Claude Code 支持调试模式,你可以通过命令行参数或终端内的调试命令开启。以--debug为例(具体参数名以当前版本claude --help输出为准),开启调试后,终端会输出更多内部日志,包括模型请求、工具调用、上下文压缩等信息。
这是理解 Agent Harness 最直接的方式:你能看到用户一句话是如何被组装成模型请求,又是如何触发工具调用并回传结果的。
在开始观察之前,我们先从原理层面拆解 Claude Code 背后的 Agent Harness 核心机制。
3. Agent Harness 核心机制拆解
3.1 主循环:Agent Loop
Agent Harness 的第一个核心机制是主循环(Agent Loop),可以理解为 Agent 的“心跳”。整个循环大致如下:
- 接收用户输入,组装系统提示、历史消息、工具定义。
- 调用语言模型,得到模型输出。
- 判断模型输出是普通文本还是工具调用。
- 如果是工具调用,执行对应工具,把结果追加到消息列表,回到第 2 步。
- 如果模型输出了最终答案,循环结束,把结果展示给用户。
这个循环就是 Agent 能够“多步思考、逐步行动”的底层原因。大模型单次推理只能给出一步决策,但通过循环,Harness 让模型可以反复观察工具结果并调整策略。Claude Code 之所以能完成“先读代码,再改代码,再跑测试”这种复杂任务,靠的就是这样一个循环。
从源码实现的角度看,这个循环通常需要控制几个关键参数:
- 最大步数(max steps),防止模型无限循环。
- 单次工具调用数量,有的 Harness 支持一次并行调用多个工具。
- 中止信号处理,例如用户按 Ctrl+C 时能优雅退出。
3.2 上下文工程:把什么塞给模型
模型本身没有“看到文件”的能力,它只能看到被放进 Prompt 里的文本。所以 Harness 需要做大量的上下文工程(Context Engineering),决定哪些项目信息进入模型视野。
Claude Code 的上下文管理大致包含这几层:
- 系统提示:定义 Claude 的身份角色、操作规范、输出约束。
- 工具定义:把每个可用工具的 JSON Schema 传给模型,让模型知道有哪些函数可调用。
- 对话历史:记录之前的用户指令、助手回复、工具结果。
- 文件内容:根据用户需求,选择性读取项目文件并写入上下文。
- 代码库索引:大型项目里通常会对代码做索引,避免每次把所有文件塞进模型。
在实际开发中,上下文管理是 Agent 工程质量的关键。如果上下文塞得太多,模型容易“迷失”,还会造成 Token 成本飙升;如果塞得太少,模型缺少必要信息,决策质量下降。
Claude Code 的另一个重要能力是上下文压缩,当对话历史过长时,它会自动总结历史内容,把较早的对话压缩成摘要,从而让上下文保持在一个可控范围内。
3.3 工具调用机制:Tools 与 Function Calling
Agent Harness 与普通聊天机器人的最大差异在于工具调用。Claude Code 具备一系列内置工具,比如读取文件、编辑文件、执行 Bash 命令等。它的实现原理是 Function Calling(函数调用):模型输出的不是普通文本,而是一段结构化指令,其中包括函数名和参数。
一次典型的工具调用流程如下:
- Harness 把工具列表以 JSON Schema 形式传给模型。
- 模型决定调用
ReadFile工具,并输出参数{"path": "README.md"}。 - Harness 解析模型输出,校验参数格式,调用真实的文件读取函数。
- 把读取结果以
tool角色消息回传给模型。 - 模型看到文件内容后,继续下一步推理。
在 Claude Code 中,你可以观察到模型调用工具时往往带有明确的权限判断。例如执行 Bash 命令前,Claude Code 会检查该命令是否在允许名单中,不在名单里就弹确认提示。
工具调用的设计质量直接影响 Agent 的实际效果。如果工具粒度太粗,模型无法精细控制;如果工具太多,模型会频繁选错工具;如果工具描述含糊,模型就更难做出正确选择。优秀 Harness 需要持续打磨工具 Schema 的定义和描述。
3.4 权限系统:Harness 的安全边界
Agent 一旦具备执行命令的权限,安全问题就会凸显。Claude Code 设计了一套权限控制机制,用来平衡“自动化”与“安全性”。
在交互模式下,Claude Code 遇到高风险操作会请求用户确认;在自动模式下,它依靠用户预设的 allow/deny 规则决定执行还是拒绝。常见的权限配置点包括:
- 哪些 Bash 命令允许自动执行。
- 哪些文件允许读取和编辑。
- 哪些网络请求允许发出。
- 是否允许跳过所有确认提示。
从工程角度看,权限系统是 Agent Harness 的“安全边界延伸”。一个合格的 Harness 应该在默认情况下采用最小权限原则,只授予完成当前任务所必需的权限,并在执行敏感操作前保留人工确认的入口。
3.5 Hook 与 Skill:扩展接口
Claude Code 还提供了 Hook 机制,允许用户在特定生命周期事件中插入自定义脚本。例如,在工具调用前执行安全检查,在会话开始时加载自定义配置,在输出结果后发送通知等。
从 Harness 架构角度看,Hook 本质上是一组事件监听器,Harness 在执行到特定阶段时会触发预定义的回调命令。这种设计让用户不用修改 Harness 核心代码,也能实现自定义逻辑。
Skill 机制则把提示词、工具、工作流封装成可复用的能力单元,适合将团队的最佳实践沉淀下来。这类扩展机制是 Agent Harness 走向工程化的标志。
4. 实战:手写一个最小可运行的 Agent Harness
理解了核心机制后,我们来手写一个最小可运行的 Agent Harness。这个示例会聚焦主循环、工具注册表、上下文组装、权限确认四部分,完整复现 Claude Code 的核心工作方式。
4.1 需求与设计
我们的最小 Harness 要支持以下能力:
- 通过 OpenAI 兼容接口调用语言模型。
- 让模型能够选择调用工具。
- 内置两个演示工具:读取文件和执行命令。
- 工具执行结果回传给模型。
- 敏感命令执行前进行拦截确认。
为了保证代码简洁,我们使用 OpenAI 的 Python SDK 作为模型客户端,模型服务只要兼容 OpenAI 协议即可接入。
4.2 项目结构
mini_harness/ ├── harness.py ├── requirements.txt └── README.mdrequirements.txt内容如下:
openai>=1.0.04.3 实现 Tool 注册表
工具注册表是 Agent Harness 的“工具箱”。它负责存储工具函数、维护工具 Schema 列表、执行模型指定的工具。
# 文件路径:mini_harness/harness.py import json from typing import Dict, List, Callable class ToolRegistry: def __init__(self): self._tools: Dict[str, Callable] = {} self._schemas: List[Dict] = [] def register(self, name: str, description: str, parameters: Dict): """注册一个可被模型调用的工具""" def decorator(func: Callable): self._tools[name] = func self._schemas.append({ "type": "function", "function": { "name": name, "description": description, "parameters": parameters, } }) return func return decorator def execute(self, name: str, arguments: Dict) -> str: if name not in self._tools: return json.dumps({"error": f"unknown tool: {name}"}, ensure_ascii=False) func = self._tools[name] result = func(**arguments) return json.dumps(result, ensure_ascii=False)这里把工具注册和工具执行分离,符合 Harness 常见的工具管理设计。后续要增加新工具,只需要用register装饰器注册函数即可。
4.4 定义两个内置工具
接下来我们注册两个演示工具。第一个工具负责读取文件,第二个工具负责执行命令。
# 文件路径:mini_harness/harness.py(接上面的代码) registry = ToolRegistry() @registry.register( "read_file", "读取指定路径的文本文件内容", { "type": "object", "properties": { "path": {"type": "string", "description": "文件路径"} }, "required": ["path"] } ) def read_file(path: str): try: with open(path, "r", encoding="utf-8") as f: content = f.read() return {"content": content[:2000]} except FileNotFoundError: return {"error": f"文件不存在: {path}"} @registry.register( "run_command", "在 shell 中执行命令并返回输出", { "type": "object", "properties": { "command": {"type": "string", "description": "要执行的 shell 命令"} }, "required": ["command"] } ) def run_command(command: str): import subprocess # 注意:这里仅用于演示,生产环境必须做白名单校验和沙箱隔离 result = subprocess.run( command, shell=True, capture_output=True, text=True, timeout=30 ) return { "stdout": result.stdout[-2000:], "stderr": result.stderr[-2000:] }需要特别注意,run_command执行真实系统命令是一个高风险操作。这个示例中我们加入了简单的危险命令拦截,但真实生产环境中,工具执行层必须运行在沙箱或容器里,并使用白名单机制。
4.5 实现主循环 Harness
主循环是整个 Harness 的核心。它组装消息、调用模型、解析工具调用、执行工具、回传结果,并且控制最大步数。
# 文件路径:mini_harness/harness.py(接上面的代码) import os from typing import List, Dict class MiniAgentHarness: def __init__(self, model: str = "gpt-4o-mini"): self.model = model self.messages: List[Dict] = [] self.registry = registry def _build_messages(self, user_input: str) -> List[Dict]: system_prompt = ( "你是一个运行在终端里的编程助手。" "你可以调用工具读取文件、执行命令,但要遵守最小权限原则。" "每次只能调用一个工具,观察工具返回结果后再决定下一步。" ) if not self.messages: self.messages.append({"role": "system", "content": system_prompt}) self.messages.append({"role": "user", "content": user_input}) return self.messages def _call_llm(self): from openai import OpenAI client = OpenAI( api_key=os.getenv("OPENAI_API_KEY"), base_url=os.getenv("OPENAI_BASE_URL"), ) response = client.chat.completions.create( model=self.model, messages=self.messages, tools=self.registry._schemas, tool_choice="auto", ) return response.choices[0].message def run(self, user_input: str, max_steps: int = 10): self._build_messages(user_input) for step in range(max_steps): print(f"\n===== Step {step + 1} =====") message = self._call_llm() # 没有工具调用,说明模型给出了最终回答 if not message.tool_calls: print("Assistant:", message.content) self.messages.append({"role": "assistant", "content": message.content}) return # 把 assistant 消息(包含工具调用指令)加入历史 self.messages.append({ "role": "assistant", "content": message.content, "tool_calls": [ { "id": tc.id, "type": "function", "function": { "name": tc.function.name, "arguments": tc.function.arguments, } } for tc in message.tool_calls ] }) # 逐个执行工具调用 for tc in message.tool_calls: fn_name = tc.function.name fn_args = json.loads(tc.function.arguments or "{}") print(f"Call tool: {fn_name}({fn_args})") # 权限确认:演示用敏感命令拦截 if fn_name == "run_command": result = self._safe_execute_command(fn_args) else: result = self.registry.execute(fn_name, fn_args) self.messages.append({ "role": "tool", "tool_call_id": tc.id, "content": result, }) print("达到最大步数,结束本轮任务。") def _safe_execute_command(self, fn_args: Dict) -> str: command = fn_args.get("command", "") dangerous_keywords = ["rm -rf", "sudo", "mkfs", "dd if="] if any(keyword in command for keyword in dangerous_keywords): print(f"危险命令被拦截: {command}") return json.dumps({"error": "用户拒绝执行该命令"}, ensure_ascii=False) return self.registry.execute("run_command", fn_args)这个主循环已经很接近真实 Agent Harness 的形态了。需要注意,在这个实现里,工具执行结果会以tool角色消息回传,并携带对应的tool_call_id,这是 OpenAI 兼容接口要求的字段,模型会根据它把工具结果和之前的工具调用请求关联起来。
4.6 入口与运行
最后添加一个程序入口,方便直接运行示例:
# 文件路径:mini_harness/harness.py(接上面的代码) if __name__ == "__main__": harness = MiniAgentHarness(model="gpt-4o-mini") harness.run("请读取当前目录下的 README.md,并告诉我第一行写了什么", max_steps=5)运行前需要安装依赖并配置环境变量:
pip install -r mini_harness/requirements.txt export OPENAI_API_KEY=your_api_key_here # 可选:如果使用兼容 OpenAI 协议的自建服务,可设置 base_url # export OPENAI_BASE_URL=https://your-endpoint.example.com python mini_harness/harness.py如果你的模型服务兼容 OpenAI 协议,可以通过OPENAI_BASE_URL环境变量切换。这里需要说明,不同模型对工具调用的支持程度不一样,示例代码以带工具调用能力的模型为前提。
4.7 预期运行结果与解释
当模型正确理解任务时,你会看到类似下面的输出:
===== Step 1 ===== Call tool: read_file({'path': 'README.md'}) ===== Step 2 ===== Assistant: README.md 的第一行内容是:Hello from README这个过程展示了 Agent Harness 最核心的闭环:
- 用户指令进入消息列表。
- 模型决策调用
read_file工具。 - Harness 执行工具并回传内容。
- 模型基于工具结果生成最终回复。
虽然这个 Harness 还非常简陋,但它已经具备了 Claude Code 的核心骨架:工具注册表、主循环、上下文消息维护、权限检查。在这个基础上继续扩展,就能逐步演进成一个可用的终端编程助手。
5. 从 Claude Code 中学习 Harness 的进阶设计
5.1 真实 Harness 的差距在哪里
对比我们写的最小 Harness,Claude Code 在工程化层面多出了很多关键设计:
- 会话管理:支持持久化会话,重启后能继续对话。
- 权限层级:拥有多种权限模式,支持细粒度的 allow/deny 规则。
- 上下文压缩:对话过长时自动摘要,防止上下文窗口溢出。
- 代码索引:大型代码库通过索引实现快速检索,而不是每次读取整个目录。
- 并行工具调用:一次推理可以同时调用多个工具,提升执行效率。
- Hook 事件:提供生命周期钩子,方便用户插入自定义脚本。
- MCP 生态:支持通过 MCP 协议接入第三方工具。
这些设计是真实 Agent 系统“能用”和“好用”之间的分水岭。如果你打算开发自己的 Agent Harness,建议优先补齐会话管理和上下文压缩,这两项对长任务体验影响最大。
5.2 利用调试模式持续分析
我们在环境准备阶段提到,Claude Code 支持调试模式。打开调试模式后,你能观察到模型请求体、工具调用参数、上下文压缩策略等内部信息。这是持续分析 Harness 行为的最佳入口。
建议你在实际项目中做一个小实验:开启调试模式,让 Claude Code 修改一个函数,然后观察它在一轮修改中发送了几次请求、每一步的工具参数是什么。这种观察比阅读任何源码分析文章都更直接。
5.3 从 Harness 到 Agent 平台
理解了 Harness 之后,再看 Agent 开发领域就会清晰很多。Harness 是 Agent 的单机运行内核,而 Agent 平台则是在 Harness 之上加入任务调度、队列、人工审批、知识库、模型路由等能力。Claude Code 本身更偏 Harness 层,而企业内部 Agent 平台通常是在 Harness 之上包装更多业务能力。
6. 常见问题与排查思路
在实际使用 Claude Code 或开发 Harness 的过程中,经常遇到以下几类问题。下面整理一个排查表格,并展开说明几个高频场景。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 启动报错提示模型无法识别 | CLI 版本与模型版本不匹配 | 升级 Claude Code,或检查模型名称配置 |
| Agent 长时间无响应 | 模型服务响应超时 | 检查网络连接、服务状态和超时设置 |
| 权限请求过多,任务频繁中断 | 默认权限策略过于严格 | 配置 allow 白名单,按需放行安全操作 |
| 工具执行结果不正确 | 工具 Schema 描述不清晰 | 检查工具参数定义和返回结果格式 |
| 长对话后模型“忘记”早期内容 | 上下文窗口溢出触发压缩 | 拆分子任务,减少不必要的历史消息 |
| 修改代码后未生效 | 文件编辑工具未保存或路径错误 | 检查工具返回结果和文件实际内容 |
6.1 模型不识别错误
很多用户在 Claude Code 升级后遇到类似“is not a model this version recognizes”的报错。这个问题的原因通常是:CLI 版本内部维护了一个模型白名单,新模型发布后,旧版 CLI 不认识新模型名称,或者用户通过配置强行指定了当前版本不支持的模型名。
排查思路:
- 执行
claude --version确认当前 CLI 版本。 - 执行命令查看当前版本支持的模型列表。
- 如果刚升级过模型,优先升级 Claude Code 到最新版本。
- 如果使用第三方模型网关,检查模型名称是否在网关支持的范围内,并确认是否与 CLI 的模型前缀兼容。
6.2 Agent 执行提供方响应超时
有时你会看到类似 “the agent execution provider did not respond in time” 的提示,意思是模型调用方超过预期时间没有返回结果。原因可能包括:
- 模型服务负载过高,生成时间过长。
- 网络链路不稳定或超时时间设置过短。
- 输入上下文过长,模型推理耗时增加。
- 使用了不兼容的模型服务,请求被挂起。
排查时建议先降低输入规模,例如把任务拆小,再看是偶发还是必然触发。如果必然触发,优先检查模型服务和网络状态。Harness 开发中也应设计合理的超时与重试机制。
6.3 权限请求过多
使用 Claude Code 时,如果执行的命令频繁触发确认提示,说明安全策略比较严格。这本身是安全设计,但如果任务确实需要多次执行同类操作,可以在配置中预设 allow 白名单,把安全检查前置到规则层,避免每次打断。
需要强调的是:放行规则必须严格,只能在充分理解命令风险后配置,不能为了省事把危险命令全部加入白名单。
7. 最佳实践与工程建议
7.1 从最小权限原则设计工具集
无论是使用 Claude Code 还是自研 Harness,工具集的设计都要遵循最小权限原则。只暴露当前任务必需的工具,不要给 Agent 提供它不需要的高危能力。每个工具的参数都应该限制边界,例如命令执行工具不允许使用shell=True之后再拼接用户输入,文件写入工具应该限制可写目录范围。
7.2 控制工具数量与质量
模型在工具选择上的准确率会随着工具数量增加而下降。工具数量不要贪多,每个工具的 Schema 描述要清晰准确,尤其是参数说明和返回值格式。如果一个工具描述模糊,模型会产生大量无效调用,拉低整个 Agent 的执行效率。
7.3 让上下文保持精简
上下文管理是 Agent 工程质量的分水岭。建议:
- 不相关文件不要自动读入。
- 单次工具结果不要无限制回传,可以截断到合理长度。
- 长任务定期总结中间结果,替换掉完整历史。
- 对大型代码库建立索引,而不是每次全量扫描。
这些策略不仅降低 Token 成本,也能提升模型在关键任务上的专注度。
7.4 建立日志与审计机制
Agent 会自主执行命令和修改文件,因此必须记录日志。至少需要记录:每次模型请求的时间、工具调用参数、工具执行结果、用户确认动作、最终输出。日志不仅能帮助定位问题,也能用于安全审计。在自研 Harness 中,建议在工具执行层统一埋点,不要散落在各个工具函数里。
7.5 加入超时、重试和熔断
真实环境中的模型服务不可能永远稳定。Harness 需要为模型调用和工具执行都设置超时时间,并在失败时进行有限次重试。如果连续失败超过阈值,应该停止任务并反馈错误,而不是盲目重试造成额外开销。
7.6 生产环境中使用沙箱隔离
如果你的 Harness 运行着来自模型动态生成的命令,强烈建议在沙箱或容器中执行。即使模型本身没有恶意,代码生成模型的偶发错误也可能产生破坏性命令。沙箱隔离是最后一层安全防线,不能省略。
7.7 为 Harness 编写测试用例
Agent 系统的行为随机性较大,更需要单元测试。可以给工具注册表、Tool Schema 生成、权限判断函数编写独立测试,保证核心机制稳定。对于模型调用层,则可以通过 mock 固定模型响应,验证 Harness 主循环在不同输出下的分支逻辑是否正常。
8. 结语:动手观察你的第一个 Agent 请求
Agent Harness 并不神秘,它本质上是把“模型决策 + 工具执行 + 上下文维护 + 流程控制”组装起来的一层工程代码。Claude Code 之所以强大,一方面来自底层模型能力,另一方面来自它对 Harness 细节的持续打磨。理解了这套架构之后,你再使用 Claude Code 时会更有底气,也知道如何把它的能力接入自己的项目。
如果你真的想深入“手撕源码”,我的建议是别急着找各种源码解析文章,先打开终端,进入一个真实项目的目录,执行claude并开启调试模式,然后下达一个“请帮我看看 xxx 文件为什么报错”的任务。观察它第一次发送给模型的请求体长什么样,工具列表如何定义,工具结果如何回传。这个动手实验,比读十篇源码分析文章都更有价值。
当你把这套观察方法迁移到代码生成、AI 编程助手、企业 Agent 平台等方向时,你就真正拥有了 Agent 工程的核心分析能力。