Skip to main content
我最早把 Agent 当成会调 API 的聊天框,后来做长任务才明白,难的是循环怎么停、权限怎么控、崩了怎么恢复。

Q1: Agent 的历史?为什么要有它?

1

2022 年末: ChatGPT 引爆对话范式

ChatGPT 让大模型走进公众视野,但它的本质是对话——用户问一句,模型答一句。模型不能访问外部数据、不能执行操作、不能自主决策。所有”行动”都需要人类手动完成。
2

2023 年初: AutoGPT 引爆 Agent 概念

AutoGPT 是第一个现象级 Agent 项目——给定一个目标(如”帮我调研竞品并写报告”),它会自主规划步骤、调用工具、执行操作,直到完成目标。虽然 AutoGPT 本身不够实用,但它定义了 Agent 的核心范式:LLM + 工具调用 + 自主循环。
3

2023 年中: 框架和生态成熟

LangChain 引入了 Agent 抽象,OpenAI 发布了 Function Calling 规范,Anthropic 推出了 Tool Use。Agent 从”玩具”变成了”工程化组件”。Andrew Ng 系统性总结了 Agentic Design Patterns(Reflection、Tool Use、Planning、Multi-Agent),为 Agent 设计提供了方法论。
4

2024-2025: 企业级 Agent 落地

字节跳动 Coze、阿里百炼等平台把 Agent 编排平民化。AutoGPT / Devin 团队探索了长达数小时的自主执行(Autonomous Agent),涉及异步执行、状态快照与恢复、长期记忆等工程挑战。Agent 从”Demo”走向了”生产环境”。
从 ChatGPT 到 Agent 的范式转移:
Agent = 让 LLM 从”说话”变成”做事”——LLM 负责理解和决策,工具负责执行和获取信息,循环驱动直到任务完成。

没有 Agent

你问 ChatGPT “帮我写一份竞品分析报告”。它只能基于训练数据生成一段泛泛的文字,无法访问真实网站、无法读取最新数据、无法自动格式化输出。所有后续操作(搜索、整理、排版)都需要你手动完成。

引入 Agent

你对 Agent 说 “帮我写一份竞品分析报告”。Agent 自主规划:先调用搜索工具获取竞品信息,再调用数据提取工具分析关键指标,最后调用文档工具生成格式化报告。整个过程无需人类干预,Agent 自主循环执行直到任务完成。
没有 Agent 的 ChatGPT 就像一个传话筒——你说什么它就转述什么,但不能帮你做任何事(“我无法访问实时数据”)。有了 Agent,它变成了项目经理——你说”帮我写竞品报告”,它自己安排:先派调研员(搜索工具)收集资料,再派分析师(数据工具)提炼数据,最后派写手(文档工具)整理成报告。整个过程它自己决策、自己调度,你只需要验收结果。

AGENT.md 的历史与概念

随着 AI 编程工具的爆发,每个工具都引入了自己的 Agent 配置文件格式——Anthropic 的 CLAUDE.md、OpenAI 的 AGENTS.md、社区的 AGENT.md。理解这些配置文件的来龙去脉,是理解 Agent 工程化的关键一环。
1

2023-2024: AI 编程工具兴起,配置文件各自为政

2023-2024 年,AI 编程工具(Cursor、Copilot、Claude Code 等)快速崛起。每个工具都引入了自己的配置文件格式,用于告诉 Agent “你是谁、你能做什么、你要遵守什么规则”。但这些配置文件互不兼容——在 Claude Code 写的配置,Cursor 读不了;在 Copilot 写的配置,Claude Code 不认。开发者在不同工具之间切换时,需要反复重写配置。
2

2025: Anthropic Claude Code 引入 CLAUDE.md

Anthropic 在 Claude Code 中引入了 CLAUDE.md 作为 Agent 的配置文件。它放在项目根目录,定义了 Agent 的角色、可用工具、行为约束和项目上下文。CLAUDE.md 是最早被广泛使用的 Agent 配置文件格式,但它绑定在 Anthropic 的 Claude Code 生态中,是专有格式。
3

2025: OpenAI Codex 引入 AGENTS.md

OpenAI 在 Codex 中引入了 AGENTS.md 作为 Agent 配置文件,功能类似 CLAUDE.md——定义 Agent 的角色和行为规范。AGENTS.md 是 OpenAI 生态的专有格式,与 CLAUDE.md 互不兼容。
4

2025: Sourcegraph Amp 推动 AGENT.md 标准化

2025 年 5 月 7 日,Sourcegraph 宣布其 AI 编程工具 Amp 支持 AGENT.md 作为通用的 Agent 配置文件格式。AGENT.md 不绑定任何特定厂商,目标是成为跨工具的通用标准。社区开始推动 AGENT.md 的标准化,希望不同 AI 编程工具都能识别同一份配置文件。
三种配置文件的定位差异:
AGENT.md 的典型内容结构:
CLAUDE.md vs AGENTS.md vs AGENT.md 对比:
AGENT.md 是 AI 编程工具的通用配置文件标准——解决每个工具配置文件互不兼容的问题。它的核心内容包括 Agent 的角色定义、可用工具、行为约束和上下文信息,目标是一份配置文件在所有 AI 编程工具中通用。

Q2: Agent 的核心原理

Agent 的本质是 LLM + Tools + Memory + Planning 的组合,核心逻辑通过 ReAct 模式驱动循环执行。Anthropic 在《Building Effective Agents》中提出了五种核心构建模式:Prompt Chaining(串联)、Routing(路由)、Parallelization(并行)、Orchestrator-Workers(编排-工人)、Evaluator-Optimizer(评估-优化),这些模式可以组合成任意复杂的 Agent 架构。[1]
ReAct(Reasoning + Acting)是 Agent 的核心执行模式,来自 Yao et al. 2022 的论文:
  • Reasoning(推理):LLM 分析当前状态,思考下一步该做什么。这是 LLM 的”思考”过程。
  • Acting(行动):根据推理结果,调用具体的工具执行操作。这是 Agent 的”做事”过程。
  • Observing(观察):获取工具执行的结果,更新上下文。这是 Agent 的”感知”过程。
  • 循环:Reasoning → Acting → Observing → Reasoning… 直到任务完成或达到最大循环次数。
关键约束:必须设置最大循环次数(maxIterations),防止 Agent 陷入死循环。
Agent 就像一个项目经理。LLM 是项目经理的大脑(理解需求、规划步骤、决策下一步)。Tools 是项目经理的团队成员(搜索工具 = 调研员,代码工具 = 开发,文档工具 = 写手)。Memory 是项目经理的笔记本(记住之前做了什么、得到什么结果)。ReAct 循环是项目经理的工作方式:分析问题 → 分配任务 → 收集结果 → 再分析 → 再分配…直到项目完成。

工具调用(Function Calling / Tool Use)

工具调用是 Agent “做事”的核心能力。LLM 本身只能生成文本,但通过 Function Calling,LLM 可以”选择”要调用的工具并传入参数。

记忆系统(短期记忆、长期记忆)

Agent 的记忆系统决定了它能处理多复杂的任务、能记住多少上下文。

Planning(规划能力)

Planning 是 Agent 区别于简单工具调用的关键——Agent 能把复杂任务拆解为可执行的步骤。

Anthropic 的五种 Agent 构建模式

Anthropic 在《Building Effective Agents》中提出了五种可以组合使用的构建模式,这是目前最权威的 Agent 架构设计指南: Anthropic 的核心建议:从简单开始,只在简单方案不够用时才增加复杂度。 大多数场景用 Prompt Chaining 或 Routing 就够了,只有真正需要动态决策的场景才用完整的 Agent Loop。[1]

Q3: 如何实现企业级 Agent

企业级 Agent(Enterprise-grade Agent)和”玩具级 Agent”的核心区别在于:可控性、安全性、可审计性。
企业级 Agent 就像银行的柜员体系。权限收敛是每个柜员只有自己岗位的权限——普通柜员能办存取款,但不能审批大额转账(代码审查 Agent 只能读文件不能写文件)。审计日志是每笔业务都有录像和流水记录(操作留痕),出了问题能完整追溯。容错降级是系统故障时切换到手工记账模式(降级到规则引擎),不会因为系统崩溃停止服务。确定性边界是柜员理解你的需求(LLM 理解意图),但具体操作必须按银行规章制度来(规则引擎执行),不能随意发挥。

权限收敛(最小权限原则)

Agent 只拥有完成当前任务所需的最小权限。不同角色的 Agent 配置不同的工具集。

审计日志(Audit Logging)

企业级 Agent 的每一次操作都必须留痕,支持事后追溯和合规审计。

容错降级(Fallback)

Agent 必须有完善的降级策略,确保在 LLM 调用失败、工具不可用时仍能提供基本服务。

确定性边界(Deterministic Boundaries)

LLM 的输出天然是不确定的,但企业级系统需要确定性。解决方案是分层架构。

成本控制(Token 预算管理)

企业级 Agent 必须严格控制 Token 消耗,避免成本失控。

企业级 Agent 的设计原则

Anthropic 在《Building Effective Agents》中强调了三个关键设计原则:
  1. 保持简单:不要过度设计。大多数场景用 Prompt Chaining 或 Routing 就够了,只有真正需要动态决策的场景才用完整的 Agent Loop。
  2. 透明性:Agent 的每一步决策都应该可观察、可调试。用 LangSmith 等工具追踪 Agent 的完整执行轨迹。
  3. 工具设计优先:工具的描述质量直接影响 Agent 的调用准确率。工具名称要直观,参数描述要清晰,返回值要结构化。[1]

Q4: 长时间运行 Agent(5小时+)设计

长时间运行 Agent(Long-running Agent / Autonomous Agent)是指需要持续执行数小时甚至数天的 Agent 任务,例如大规模数据迁移、持续代码重构、自动化运维巡检等。
长时间运行 Agent 就像一个大型建筑工地。异步执行是施工队在后台干活,业主(用户)可以随时来看进度、拍照发朋友圈。进度追踪是把工程拆成”打地基→搭框架→砌墙→装修”等子任务,每个子任务有依赖关系(砌墙前必须搭好框架)。Checkpoint 是每完成一步就拍照存档,如果停电了(进程中断),来电后从上次存档的地方继续,不用推倒重来。长期记忆是施工日志——记录了所有关键决策(“承重墙用 C30 混凝土”),新工人看了日志就能无缝接续。

异步执行(Asynchronous Execution)

长时间运行的 Agent 不能阻塞主线程,必须用异步架构。

状态快照与恢复(Checkpointing & Recovery)

Checkpoint 是长时间运行 Agent 的生命线——中断后必须能从断点恢复,而不是从头开始。

长期记忆(Long-term Memory)

长时间运行的 Agent 会积累大量上下文,必须定期压缩记忆。

进度追踪与断点续传

长时间运行的 Agent 必须有完善的进度追踪和人工干预机制。

长时间运行 Agent 的工程挑战

长时间运行 Agent(5 小时+)面临三个独特的工程挑战,这些是普通 Agent 不会遇到的问题:
  1. 上下文窗口溢出:随着对话历史越来越长,128K/200K tokens 的上下文窗口会被耗尽。解决方案是”记忆分层”——近期对话保留完整内容,更早的对话用小模型压缩为摘要。
  2. 状态一致性:Agent 执行过程中可能遇到网络中断、服务重启等异常。Checkpoint 机制让 Agent 能从断点恢复,而不是从头开始。LangGraph 原生支持 Checkpoint。
  3. 成本失控:长时间运行的 Agent 可能消耗大量 Token。必须设置 Token 预算上限,超出时自动降级到更便宜的模型或暂停执行。[4]

Q5: Human-in-the-Loop 详解

Human-in-the-Loop(人机协同)是企业级 Agent 的关键机制——不是所有操作都能让 Agent 自主执行,高风险操作必须暂停等待人类审批。LangGraph 提供了原生的 interrupt + Command + Checkpoint 机制来实现这一模式。[3]
Human-in-the-Loop 就像银行的大额转账审批流程。普通柜员(Agent)可以自主处理 5 万元以下的转账(低风险操作),但超过 5 万元的转账必须暂停,等主管审批(人工审批)。审批时,主管会看到转账的完整信息(金额、收款人、用途),然后决定”批准”或”拒绝”。批准后系统继续执行转账,拒绝后柜员需要和客户重新确认。整个过程中,转账信息被完整保存(Checkpoint),即使审批过程中系统重启,也不会丢失任何数据。

LangGraph interrupt 机制

LangGraph 的 interrupt() 函数是 Human-in-the-Loop 的核心——它在 Agent 执行过程中暂停,把当前状态持久化到 Checkpoint,等待人类输入后用 Command(resume=...) 恢复执行。

审批流设计:哪些操作需要人工审批

不是所有操作都需要人工审批——审批过多会拖慢系统,审批过少会增加风险。核心原则是按风险等级分级。

暂停/恢复实现:interrupt + Command + Checkpoint 三件套

LangGraph 的 Human-in-the-Loop 依赖三个核心组件的协作:
interrupt() 依赖 Checkpoint 机制——没有 Checkpoint,图无法保存中断时的状态,也就无法恢复。开发环境用 MemorySaver(内存,重启后丢失),生产环境必须用 PostgresSaver 或 SqliteSaver(持久化存储)。thread_id 是 Checkpoint 的隔离键——同一个 thread_id 的多次调用共享同一个 Checkpoint,不同 thread_id 互不干扰。

审批通知与多渠道集成

生产环境中,审批请求需要通过多种渠道通知人类(前端界面、Slack、邮件、飞书),并支持在任意渠道审批后恢复执行。
Human-in-the-Loop 是企业级 Agent 的安全阀——通过 LangGraph 的 interrupt() + Command(resume=...) + Checkpoint 三件套,在 Agent 执行高风险操作时暂停等待人类审批,审批后无缝恢复执行。核心设计原则是按风险等级分级:低风险自动执行、中风险异步通知、高风险暂停审批、禁止操作硬编码拒绝。

Q6: Agent Skills vs RAG 区别

RAG(Retrieval-Augmented Generation,检索增强生成)和 Agent Skills(工具调用)是两种完全不同的技术,解决不同的问题。
RAG 和 Agent Skills 就像百科全书和瑞士军刀。RAG 是百科全书——给 Agent 一本厚厚的参考资料(知识库),遇到不懂的就翻书查(检索文档),减少”瞎编”的概率。Agent Skills 是瑞士军刀——给 Agent 一套工具(小刀、剪刀、螺丝刀),让它能真正动手做事(读文件、调 API、写代码)。一个完整的 Agent 既需要百科全书(知道怎么做),也需要瑞士军刀(能动手做)。光有书没有工具,Agent 只能”纸上谈兵”;光有工具没有书,Agent 可能”乱来”。

基础梳理

专家视角深度剖析

很多人会混淆 RAG 和 Skills,但它们是正交的两个维度。RAG 解决”知不知道”的问题,Skills 解决”做不做得到”的问题。 一个完整的 Agent 系统通常同时需要两者。

RAG 和 Skills 的协同


Q7: n8n 和 Dify 在 Agent 中的应用

n8n、Dify 和 LangGraph 就像三种不同的”造房子”方式。n8n 是乐高编程——拖拽积木块(节点)拼出工作流,不需要写代码,400+ 种现成积木(集成)随便用,适合快速搭建。Dify 是精装样板间——RAG、Agent、工作流都是现成的,上传文档就能用,适合不懂技术的产品经理。LangGraph 是自己画图纸盖房子——用代码定义任意复杂的图结构,灵活度最高,但需要建筑师(AI 工程师)才能搞定。

n8n:工作流编排平台

n8n 是一个开源的工作流自动化平台,用节点式 UI 编排复杂的工作流,天然适合 Agent 的任务编排。
n8n 的核心优势:
  • 节点式编排:拖拽节点构建 Agent 工作流,无需写代码
  • 外部 API 集成:内置 400+ 集成(Slack、GitHub、Google Sheets 等)
  • 触发方式多样:Webhook、定时触发(Cron)、事件触发、手动触发
  • 错误处理:内置重试、错误分支、超时控制

Dify:Agent 应用平台

Dify 是一个开源的 LLM 应用开发平台,内置了 Agent 能力,适合快速构建 Agent 应用。
Dify 的核心优势:
  • 内置 Agent 能力:支持 Function Calling、ReAct 等 Agent 模式
  • 可视化工具配置:拖拽添加工具,配置参数和认证
  • 多轮对话管理:内置对话记忆、上下文窗口管理
  • RAG 集成:内置文档上传、向量化、检索能力
  • 一键发布:生成 API 端点或嵌入式 Web 组件

LangGraph vs n8n vs Dify 对比

选择标准:需要极致灵活性和多 Agent 协作用 LangGraph(适合 AI 工程师),需要快速搭建业务流程自动化用 n8n(适合非技术用户),需要快速构建 Agent 应用用 Dify(适合产品经理和全栈开发者)。实际项目中,三者经常混合使用——Dify 做原型验证,LangGraph 做生产级 Agent,n8n 做周边自动化流程。

Q8: Agent 的错误处理与稳定性

生产环境的 Agent 必须有完善的错误处理机制,否则一个 LLM 调用失败就可能导致整个任务崩溃。
Agent 的错误处理就像客服的投诉处理流程。重试策略是”请稍等,我再帮您查一下”——第一次没查到等 1 秒再查,第二次等 2 秒,第三次等 4 秒(指数退避),但不会无限查下去。降级策略是”我帮您转接高级客服”——普通客服(gpt-4o-mini)搞不定,转给资深客服(gpt-4o),再搞不定转给主管(规则引擎),最后转给经理(人工处理)。死循环检测是”您已经打了 10 次电话了,我们安排专人跟进”——防止 Agent 在两个工具之间无限循环。

重试策略(指数退避)

降级策略(Fallback)

死循环检测

超时控制

Token 消耗优化


Q9: 高频面试题

Agent 面试的核心就像运营一个快递站。Agent 和 RAG 的区别是”快递员和仓库”——RAG 是仓库里的货架(存放知识),Agent 是快递员(执行操作),快递员既要会查货架(RAG 检索)也要会送货(工具调用)。企业级设计是”快递站管理规范”——权限控制(每个快递员只能送自己片区的件)、审计日志(每单都有签收记录)、容错降级(快递车坏了换一辆)、成本控制(不能每个包裹都派专车)。

问题:“Agent 和 RAG 的区别?如何设计一个企业级 Agent?”

及格回答(60-70分):
“RAG 是检索增强生成,给模型注入外部知识。Agent 是自主执行,让模型调用工具做事。企业级 Agent 需要权限控制和审计日志。”
问题出在:知道概念但不理解工程细节。 满分回答(90-100分):
“RAG 和 Agent 是正交的两个维度。RAG 解决’知不知道’——通过向量检索把相关文档注入 Prompt,让模型基于真实数据回答,减少幻觉。Agent 解决’做不做得到’——通过 Function Calling 让模型调用工具执行操作。一个完整的 Agent 系统通常同时需要 RAG(注入领域知识)和 Skills(执行操作)。[1]”
“企业级 Agent 的核心设计有五个维度:权限收敛(不同角色的 Agent 配置不同的工具集,代码审查 Agent 只有读权限没有写权限)、审计日志(每次工具调用记录输入/输出/token 消耗/耗时,支持事后追溯)、容错降级(主模型失败降级到备用模型,再失败降级到规则引擎,最后人工兜底)、确定性边界(LLM 只做理解和路由,执行层用规则引擎保证确定性)、成本控制(Token 预算管理 + 模型分级 + Prompt Cache)。[2]”
“长时间运行 Agent(5 小时+)还需要额外的工程保障:异步执行(不阻塞主线程)、状态快照(每步保存 Checkpoint,中断后从断点恢复,不需要从头开始)、长期记忆压缩(定期用小模型把 100K tokens 压缩为 5K 摘要)、进度追踪(实时汇报进度 + Human-in-the-Loop 高风险操作人工审批)。[3]“

常见追问

答题要点: 从”知不知道”和”做不做得到”两个维度区分,说明它们是正交关系。高分回答: “RAG 和 Agent 是正交的两个维度,不是替代关系:RAG 解决’知不知道’的问题:用户提问时,先从向量数据库检索相关文档片段,注入 Prompt 作为上下文,让 LLM 基于真实数据回答。典型场景:企业知识库问答、产品文档搜索。Agent 解决’做不做得到’的问题:LLM 通过 Function Calling 选择工具并传入参数,工具执行操作后返回结果。典型场景:发邮件、查数据库、调 API。两者协同:一个客服 Agent 既要 RAG(检索产品文档回答用户问题),又要 Skills(调用工单系统创建售后工单)。RAG 提供知识,Skills 提供能力,Agent Loop 把两者串联起来。”
答题要点: 说出五个核心维度:权限、审计、容错、确定性、成本。高分回答: “企业级 Agent 有五个核心设计维度:
  1. 权限收敛:最小权限原则,不同角色的 Agent 配置不同的工具集。代码审查 Agent 只有 readFileTool,没有 writeFileTool。高风险操作(删除数据、部署生产)必须 Human-in-the-Loop 审批。
  2. 审计日志:每次工具调用记录完整上下文——agentId、toolName、input、output、tokenUsage、duration、status。用 runId 关联同一次执行的所有操作,支持事后追溯。
  3. 容错降级:四层降级策略——主模型 → 备用模型 → 规则引擎 → 人工处理。不可重试的错误(参数错误)直接降级,可重试的错误(网络超时)指数退避重试。
  4. 确定性边界:LLM 只做理解和路由(不确定性),Schema 校验输出格式(半确定性),规则引擎执行操作(确定性)。不确定性被限制在理解层。
  5. 成本控制:Token 预算管理(每日/每请求/每 Agent 限额)+ 模型分级(简单任务用 gpt-4o-mini,复杂任务用 gpt-4o)+ Prompt Cache(节省 90% 输入 token)。”
答题要点: 说出四个关键机制:异步执行、状态快照、长期记忆压缩、进度追踪。高分回答: “长时间运行 Agent(5 小时+)需要四个关键机制:
  1. 异步执行:Agent 运行在独立的 Worker 进程中,不阻塞主线程。通过事件系统(task.started、task.progress、task.completed)通知前端进度。
  2. 状态快照(Checkpointing):每个关键步骤后保存状态快照到 PostgreSQL/Redis。中断后从最近的 checkpoint 恢复,不需要从头开始。LangGraph 原生支持 Checkpoint。
  3. 长期记忆压缩:上下文窗口有限(128K/200K tokens),长任务会溢出。定期用小模型把旧记忆压缩为摘要(100K → 5K),保留近期记忆的完整性。
  4. 进度追踪 + Human-in-the-Loop:实时汇报进度。高风险操作、Token 预算阈值、错误重试失败时暂停执行,等待人工审批。用 interrupt 节点实现。”
答题要点: 从定位、编排方式、适用场景三个维度对比。高分回答: “n8n 和 Dify 解决不同的问题:n8n 是工作流自动化平台:用节点式 UI 编排业务流程,内置 400+ 集成(Slack、GitHub、Google Sheets)。它的 AI Agent 节点是工作流的一个环节,适合把 Agent 嵌入到更大的业务流程中。例如:Webhook 触发 → AI Agent 分析 → 条件判断 → 发邮件或创建工单。Dify 是 LLM 应用开发平台:专注于构建 Agent 应用,内置 RAG、工具管理、对话记忆。适合快速构建独立的 Agent 应用。例如:上传产品文档 → 配置工具 → 发布为 API/Web 组件。选择标准:需要把 Agent 嵌入业务流程用 n8n,需要快速构建独立 Agent 应用用 Dify,需要极致灵活性和多 Agent 协作用 LangGraph。”
答题要点: 说出四个关键策略:模型分级、Token 预算、Prompt Cache、上下文压缩。高分回答: “Token 消耗控制有四个关键策略:
  1. 模型分级:大部分简单任务用 gpt-4o-mini(小模型单价显著更低),关键的决策任务用 gpt-4o。在 LangGraph 中,不同节点可以用不同模型。
  2. Token 预算:设置三级限额——每日全局预算(100 万 tokens)、单次请求预算(1 万 tokens)、单 Agent 预算(5 万 tokens)。超出预算时降级到更简单的处理方式。
  3. Prompt Cache:Anthropic 的 Prompt Cache 可以节省 90% 的输入 token 费用。把稳定的 System Prompt 放在前面,变化的用户输入放在后面。相同前缀的请求复用缓存的 KV Cache。
  4. 上下文压缩:定期压缩历史对话。用小模型把 100K tokens 的历史压缩为 5K tokens 的摘要。只保留近期 5 轮对话的完整内容,更早的对话用摘要替代。”
答题要点: 区分临时性错误和永久性错误,分别采用不同的处理策略。高分回答: “工具调用失败的处理策略取决于错误类型:临时性错误(网络超时、服务不可用):指数退避重试。1 秒 → 2 秒 → 4 秒,最多重试 3 次。加随机抖动防止惊群效应。永久性错误(参数错误、权限不足):不重试,直接记录错误并通知 LLM。LLM 会调整策略——例如参数错误时重新构造参数,权限不足时换一个工具或请求人工帮助。工具不可用(服务宕机):降级到备用工具。例如搜索工具不可用时,降级到本地缓存。所有工具都不可用时,降级到规则引擎或人工处理。关键原则:区分 isRetryable 和 nonRetryable 错误。在错误对象上标记 retryable: true/false,Agent 的重试逻辑根据这个标记决定是否重试。”
答题要点: 说出确定性边界的分层架构——理解层(LLM)、验证层(Schema)、执行层(规则引擎)。高分回答: “LLM 的输出天然是不确定的,但企业级系统需要确定性。解决方案是分层架构:
  1. 理解层(LLM,不确定性):LLM 只负责理解用户意图、提取结构化信息。这是不确定性的唯一来源,但影响范围被限制在理解层。
  2. 验证层(Schema,半确定性):LLM 的输出经过 JSON Schema 校验。如果输出不符合预期格式(如缺少必要字段、类型错误),触发重试或降级。用 Zod 做运行时校验。
  3. 执行层(规则引擎,确定性):具体的工具调用、数据操作、业务逻辑由规则引擎执行,不依赖 LLM 的输出。例如:LLM 输出 {"action": "delete", "target": "production"},规则引擎检查到 production 环境,自动拦截。
关键原则:不确定性只存在于理解层,执行层必须确定性。这和 Anthropic 的 ‘Building Effective Agents’ 理念一致。”
答题要点: 结合真实案例,说明 Agent 在生产环境的常见问题和解决方案。高分回答: “Agent 在生产环境常见的问题有四个:
  1. 死循环消耗 Token:Agent 在两个工具之间无限循环——调用工具 A 得到结果后,认为应该调用工具 B,B 的结果又让它调用 A。解决:设置最大循环次数(maxIterations: 10)+ 状态变化检测(连续 3 步输出相同则强制终止)。
  2. 工具调用参数错误:LLM 生成的工具参数格式错误(如日期格式不对、必填字段缺失),导致工具执行失败。解决:用 Zod Schema 校验参数,校验失败时让 LLM 重新生成。
  3. 上下文窗口溢出:长时间运行的 Agent 对话历史越来越长,超出上下文窗口限制。解决:定期压缩历史对话(用小模型生成摘要),只保留近期对话的完整内容。
  4. 成本爆炸:Agent 的循环次数过多或工具调用过于频繁,Token 消耗远超预期。解决:Token 预算管理 + 模型分级 + 循环次数限制。每次调用记录 token 消耗,设置告警阈值。“

Q10: Harness Engineering 到底是什么?(先纠正一个流行误读)

中文技术圈长期流传一种说法:OpenAI 发布了一个叫 “Harness Engineering” 的声明式多 Agent 编排框架,用 defineHarness({ agents, flow }) 描述 Agent 协作。这个说法不准确。 截至 2026 年 11 月,OpenAI 没有发布过名为 Harness Engineering 的编排框架,也没有 defineHarness 这个 API。把「Harness Engineering」当成一个 SDK,会在面试里直接暴露事实错误。 准确的说法是:Harness Engineering 是一套工程方法论的名字,指围绕模型设计执行环境——工具、上下文、约束、反馈回路——让 Agent 在无人监督下可靠工作。 它不是运行时,也不是编排 DSL。

事实时间线(均可核对)

三者的层次关系:

OpenAI 实验真正做对的五件事

1. AGENTS.md 是目录,不是手册。 他们先试了”一个大 AGENTS.md”,失败得很典型:上下文是稀缺资源,巨型指令文件会挤掉任务本身;什么都标”重要”等于没有重点;单体手册会迅速腐烂成过时规则;而且无法机械校验。最终 AGENTS.md 压到约 100 行,只做地图,真正的知识库放在结构化 docs/ 目录,配套 linter 和 CI 校验交叉链接与新鲜度,还有定期的 “doc-gardening” Agent 提交修复 PR。这叫渐进式披露(progressive disclosure)。 2. 约束机械化,而不是写进 Prompt。 每个业务域只能沿固定层次向前依赖:Types → Config → Repo → Service → Runtime → UI;鉴权、连接器、遥测、Feature Flag 等横切关注点只能通过单一 Providers 接口进入。违反规则由自定义 linter 和结构化测试报错,错误信息里直接写入修复指令,等于把”怎么改”喂回模型上下文。 3. 让应用本身对 Agent 可读。 每个 git worktree 都能独立启动一份应用实例,接入 Chrome DevTools Protocol,让 Agent 自己截屏、取 DOM、跑导航;每个 worktree 配一套临时的日志/指标/Trace 栈,Agent 可以用 LogQL、PromQL 查询。于是验收标准从”看起来对”变成可判定的”服务启动小于 800ms""四条关键链路的 span 不超过 2 秒”。 4. Agent 审 Agent。 让 Codex 先本地自审,再请求其他 Agent 在本地和云端审查,读完反馈后继续迭代,直到所有 Agent reviewer 满意;人类 review 从必需项变成可选项。这就是社区说的 Ralph Wiggum Loop:不追求一次做对,而是把”改到通过”做成循环。 5. 熵治理(garbage collection)。 Agent 会复制仓库里已有的模式,包括坏模式。OpenAI 最初每周五花 20% 时间人工清理 “AI slop”,不可扩展;后来把 “golden principles” 编码进仓库,用周期性后台 Codex 任务扫描偏差、更新质量评级、提交定向重构 PR,多数一分钟内可审完并自动合并。技术债像高利贷,持续小额偿还比集中爆发更便宜。

必须一起说出口的代价与边界

  • 不可直接照搬。 OpenAI 自己在文末强调:这套行为高度依赖该仓库的结构与工具链,“不应假设在没有同等投入的情况下可以泛化”。
  • 吞吐改变合并哲学。 他们的 PR 短命、阻塞性门禁极少、flake 用重跑而不是阻塞处理。作者同时承认这在低吞吐环境是”不负责任的”。照抄流程而不具备吞吐,只会放大事故。
  • 早期反而更慢。 进展慢的原因不是模型不行,而是环境未定义:缺工具、缺抽象、缺内部结构。harness 工程的前期投入是纯成本。
  • 基础设施不是免费的。 每 worktree 一套应用和一套可观测栈,意味着显著的计算与运维开销。
  • 安全边界要单独设计。 生成的代码所在的沙箱不能触达凭据;否则一次 Prompt Injection 就能拿到 token 并派生新的无限制会话。
  • 人的判断没有消失。 人负责排优先级、把用户反馈翻译成验收标准、验证结果;只是工作层级上移了。

三个容易混淆的概念

如果被问到”OpenAI Harness 和 LangGraph 怎么选”,正确做法是先澄清层次:Harness Engineering 是方法论,无法与 LangGraph 二选一;能对比的是 Codex/Agents API 这类托管 harness 与 LangGraph 这类编排框架。 托管 harness 提供循环、会话、沙箱,你用 API 驱动;LangGraph 提供图、状态、checkpoint,循环和工具都得自己写。前者省基础设施但受限于厂商,后者自由但要自己承担运行时。
Harness Engineering 不是 OpenAI 的编排框架,而是一种把”人工纠错”转化为”环境约束”的工程纪律。它的产出物是 AGENTS.md 地图、机械化 lint、可被 Agent 读取的应用与可观测性、Agent 互审循环和持续熵治理——而不是一段 defineHarness 配置。

Q11: OpenClaw 和 Hermes 是什么?

OpenClaw 更像一个把消息渠道、工具和模型接起来的”本地网关”——它运行在你自己的机器上,管理会话与记忆、加载技能(Skills),再把请求交给 Agent 处理。Hermes 是大脑,是负责思考和决策的模型。两者不是”框架 + 模型”的拼装关系:OpenClaw 是一个可本地部署的助手应用,Hermes 是可以被它调用的模型之一。至于 OpenClaw 内部具体怎么接模型、怎么划分模块,公开资料有限,不要凭想象补全。

OpenClaw:可本地部署的个人 AI 助手

OpenClaw 是一个开源的个人 AI 助手 / 本地网关(MIT 协议),它并不是一个”可组合的 Agent 框架”。按公开信息的描述,它大致由四块组成:Gateway(接入各类消息渠道、负责收发的本地网关)、Agent(实际执行任务的主体)、Skills(可插拔的能力扩展)和 Memory(会话与长期记忆)。用户把它部署在自己的机器上,通过熟悉的聊天渠道与它交互。 需要克制:公开资料对它的内部分层和编排细节披露有限,并不存在 SearchClaw、CodeClaw、FileClaw 这类公开子模块,也没有 openclaw 这样的 npm 编程 API。面试时不要把这些名字当作事实讲出来。

Hermes:Nous Research 的开源 LLM

Hermes 是 Nous Research 推出的开源大语言模型系列,专注于 Agent 场景的优化。和通用模型不同,Hermes 在训练时特别强化了工具调用、多轮对话、指令遵循等 Agent 核心能力。 Hermes 的特点:
  • 工具调用优化:原生支持 Function Calling,参数生成准确率高
  • 长上下文支持:支持 128K+ tokens 上下文窗口,适合长对话 Agent
  • 指令遵循:对 System Prompt 的遵循度高,适合 Agent 角色设定
  • 开源可部署:可以在本地部署,数据不出企业网络

OpenClaw vs Hermes 区别

OpenClaw 是可本地部署的 AI 助手 / 网关(怎么接入和运行),Hermes 是 LLM 模型(怎么推理)。前者是应用形态,后者是模型,二者不是”框架 + 模型”的拼装关系。

Q12: AI 编码工具的原理与多 Agent 协作

AI 编码工具正在从”代码补全插件”进化为”自主编程 Agent”。理解 Codex 和 Claude Code 的底层原理、以及多 Agent 协作的设计方法论,是 2025 年前端工程师的核心竞争力。
AI 编码工具的进化就像工具的升级。Codex 是自动铅笔——你写前半句,它帮你补后半句(代码补全),但不能自己写字。GitHub Copilot 是智能自动铅笔——能根据上下文猜你想写什么,但还是你握着笔。Claude Code 是机器人程序员——你给它一个任务(“重构这个模块”),它自己读代码、写代码、跑测试、提 PR,你只需要 Code Review。从”辅助写字”到”独立干活”,这就是从 Codex 到 Claude Code 的范式转移。

Codex 的原理

OpenAI Engineering 团队在 2021 年推出的 Codex 是代码生成大模型的开创性底座。Codex 基于 GPT-3 微调,在 159 GB 的 GitHub 开源代码上训练,专门为代码生成任务优化。它最直接的产物就是 GitHub Copilot——Codex 负责理解上下文并生成代码补全,Copilot 负责 IDE 集成和用户体验。
Codex 的关键设计:
  • 训练数据:从 GitHub 筛选 179 种编程语言的开源代码,去重后 159 GB
  • 上下文窗口:4096 tokens,通过”前缀拼接”把光标前后的代码都喂给模型
  • 沙箱执行:Codex CLI 用 OS 级沙箱执行模型生成的命令(macOS Seatbelt、Linux bubblewrap + Landlock、Windows 受限令牌/DACL),再叠加审批策略;这是 Agent 自主执行而不失控的工程基础,与「Harness Engineering」方法论不是同一个概念
  • 评测体系:HumanEval 基准测试(164 道编程题),定义了代码生成能力的行业标准

Claude Code 的原理

Anthropic Claude Code 团队打造的 Claude Code 是深度集成在终端 CLI 中的现代自主编程 Agent,与传统的 IDE 插件有本质区别。传统插件(如 Copilot)只能被动补全,而 Claude Code 能自主读写文件、执行命令、搜索代码库、管理 Git 操作。
Claude Code 与传统 IDE 插件的核心区别: Claude Code 的三大核心机制:
  • MCP 集成:通过 Model Context Protocol 连接外部工具和数据源,让 Agent 能访问数据库、API、文件系统等任意资源
  • Skills 系统:赋予 Agent 特定的主动执行能力(区别于被动的 RAG 知识检索),比如”自动写测试""自动重构”
  • Hooks 机制:在 Agent 执行的关键节点插入自定义逻辑(如执行前校验、执行后审计),实现企业级可控性

多 Agent 角色分工设计

Andrew Ng(吴恩达)在 Agentic Workflow 方法论中定义了四种核心设计模式:Reflection(自我反思)、Tool Use(工具调用)、Planning(任务规划)、Multi-Agent Collaboration(多 Agent 协作)。[2] 他的核心思想是:复杂任务不应该由单个 Agent 包办,而应该拆分为多个专业 Agent,各司其职,通过协作完成。 即使是较弱的模型,通过 Agentic 模式设计也能获得显著的性能提升。
每个 Agent 的职责、工具集和模型选择: 协作模式有三种:

企业级多 Agent 设计

多 Agent 系统在生产环境中面临四大核心挑战: 1. 权限边界收敛 不同 Agent 必须有严格的权限隔离。Code Agent 可以读写代码,但不能部署;Deploy Agent 可以部署,但只能操作 staging 环境,生产环境需要人工审批。
2. 审计日志(Audit Logging) 每个 Agent 的每次工具调用都必须记录完整上下文,支持事后追溯和合规审计。常见做法是用 runId 关联同一次任务的所有 Agent 操作。 3. 容错降级(Fallback) Agent 调用失败时的降级策略:主 Agent 失败 → 备用 Agent 接管 → 规则引擎兜底 → 人工处理。线上 Agent 的工具调用失败是常态,必须有完善的降级机制。 4. 确定性输出边界 LLM 的输出天然是不确定的,但企业级系统需要确定性。常见做法是:LLM 只做意图理解和路由(不确定性层),Schema 校验输出格式(半确定性层),规则引擎执行具体操作(确定性层)。

实战:用 Claude Code 实现多 Agent 协作

以一个真实的”代码重构 + 测试 + 审查”流水线为例,展示如何用 Claude Code 的 Skills 系统实现多 Agent 协作:
AI 编码工具从 Codex 的代码补全底座,进化到 Claude Code 的自主编程 Agent,再到 Andrew Ng 的多 Agent 协作方法论——核心范式是”LLM 决策 + 工具执行 + 角色分工”。企业级落地需要权限收敛、审计日志、容错降级和确定性输出边界四大工程保障。
答题要点: 从”单次补全”到”自主执行”的范式转移来区分,说明 Codex 是底座,Claude Code 是 Agent。高分回答: “Codex 和 Claude Code 代表了 AI 编码工具的两个时代:Codex 是代码生成底座:OpenAI Engineering 团队在 2021 年推出,基于 GPT-3 在 159 GB GitHub 代码上微调,参数量 12B,上下文窗口 4096 tokens。它的核心能力是根据上下文生成代码补全,最直接的产物是 GitHub Copilot。Codex 本身是被动的——你输入代码,它补全建议,不能自主执行任何操作。OpenAI 后来围绕 Codex 补上了沙箱执行环境和 HumanEval 评测体系,这些工程沉淀为后来的 Agent 能力奠定了基础。Claude Code 是自主编程 Agent:Anthropic Claude Code 团队在 2025 年推出,深度集成在终端 CLI 中。它不是被动补全,而是自主执行——给一个指令(如’重构这个模块并补充测试’),它会自主读写文件、执行命令、搜索代码库、管理 Git。核心区别是 Claude Code 有完整的工具调用能力(读写文件、执行命令、搜索代码、Git 操作),加上 MCP 协议、Skills 系统、Hooks 机制三大扩展能力。类比:Codex 像一个只能给你提建议的代码助手,Claude Code 像一个能独立干活的初级开发者。”
答题要点: 分别说明三个机制的定位和解决的具体问题,避免混淆。高分回答: “Claude Code 的三大扩展机制各司其职:MCP(Model Context Protocol)解决’连接’问题:标准化 AI 与外部数据源/工具的连接协议。没有 MCP 时,每个工具都需要单独集成;有了 MCP,Agent 可以通过统一协议访问数据库、API、文件系统等任意资源。比如通过 MCP 连接 PostgreSQL,Agent 就能直接查询数据库,不需要写额外的适配代码。Skills 解决’能力’问题:赋予 Agent 特定的主动执行能力。RAG 是被动的(给模型参考资料),Skills 是主动的(给模型做事的能力)。比如定义一个’auto-test’ Skill,Agent 就知道如何为新代码自动编写测试。Skills 的定义文件(SKILL.md)用自然语言描述 Agent 的行为规范,支持复用和组合。Hooks 解决’控制’问题:在 Agent 执行的关键节点插入自定义逻辑。比如 preToolUse Hook 可以在 Agent 执行命令前校验安全性(禁止 rm -rf),postToolUse Hook 可以在写文件后自动运行 lint。Hooks 是企业级可控性的关键——没有 Hooks,Agent 就是一个黑盒。”
答题要点: 从 Agentic Design Patterns 的四种模式出发,结合代码示例说明如何落地。高分回答: “Andrew Ng 定义了四种 Agentic Design Patterns,多 Agent 协作是其中最复杂的一种。落地时需要关注三个层面:角色定义层:每个 Agent 必须有明确的职责边界。Code Agent 只负责写代码,不负责测试;Test Agent 只负责写测试,不负责审查。职责越清晰,Agent 的 Prompt 越聚焦,输出质量越高。用 Andrew Ng 的话说,‘一个 Agent 做一件事,做到最好’。协作编排层:选择合适的协作模式。串行模式适合有依赖关系的流程(Code → Test → Review),并行模式适合独立任务(模块 A、B、C 同时开发),反馈循环模式适合质量敏感场景(Review 不通过则回到 Code)。LangGraph 的 State Graph 是实现这些模式的最佳工具。质量保障层:每个 Agent 的输出必须有验证机制。Code Agent 的输出由 Test Agent 验证,Test Agent 的输出由 Review Agent 验证,Review Agent 的输出由人工最终确认。这就是 Andrew Ng 强调的’agentic verification’——Agent 的输出不应该直接面向用户,而是经过另一层 Agent 或人工验证。”
答题要点: 对比三种通信模式(共享状态、消息传递、事件驱动),说明各自的适用场景。高分回答: “多 Agent 之间的通信有三种模式,选择取决于任务复杂度和延迟要求:共享状态模式(Shared State):所有 Agent 读写同一个状态对象。LangGraph 的 State Graph 就是这种模式——所有节点共享一个 State 对象,每个节点读取输入、写入输出。优点是实现简单,适合顺序执行的流水线;缺点是并发场景下需要加锁。消息传递模式(Message Passing):Agent 之间通过消息队列通信。Agent A 完成后,把结果发到消息队列,Agent B 从队列消费。优点是解耦,Agent 之间不需要知道彼此的存在;缺点是增加了消息中间件的复杂度。事件驱动模式(Event-driven):Agent 发布事件,其他 Agent 订阅感兴趣的事件。比如 Code Agent 发布 code.ready 事件,Test Agent 订阅这个事件后自动开始测试。优点是极度灵活,可以动态增减 Agent;缺点是调试困难。实际项目中,LangGraph 的 State Graph 最常用——它本质上是’共享状态 + 条件路由’的组合,简单场景够用,复杂场景可以嵌套子图。”
答题要点: 从模型选择、Prompt 优化、缓存三个维度说明成本控制策略。高分回答: “多 Agent 系统的成本比单 Agent 高 N 倍(N = Agent 数量),必须严格控制:模型分级策略:不同 Agent 用不同模型。Code Agent 和 Review Agent 需要强推理能力,用 Claude Opus 或 GPT-4o;Test Agent 的代码生成相对模式化,可以用 Sonnet;Deploy Agent 执行的是确定性操作,用 Haiku 或 GPT-4o-mini 就够。这样整体成本可以明显降低。Prompt 缓存:Anthropic 的 Prompt Cache 对多 Agent 场景效果显著。多个 Agent 共享的 System Prompt(如项目上下文、代码规范)放在 Prompt 前缀,相同前缀的请求复用缓存的 KV Cache,节省 90% 输入 token 费用。上下文裁剪:每个 Agent 只接收与其职责相关的上下文。Code Agent 需要看到需求文档和相关代码,但不需要看到测试报告;Test Agent 需要看到代码和已有测试,但不需要看到部署配置。通过上下文裁剪,单次调用的 token 消耗可以减少 40-50%。预算熔断:设置全局 Token 预算(如每日 50 万 tokens),每个 Agent 有独立的子预算。超出预算时自动降级到更便宜的模型或暂停执行。”
答题要点: 给出一个完整的实战架构,包括 Skills 定义、Hooks 配置、流程编排。高分回答: “用 Claude Code 实现开发流水线的核心是 Skills 系统。一个完整的流水线包含四个阶段:阶段 1:需求分析 Agent。读取 issue 描述,搜索代码库找到相关文件,生成实现方案。这个阶段用强模型(Claude Opus),因为需要深度理解需求和代码架构。阶段 2:代码实现 Agent。根据实现方案,逐文件修改代码。每修改一个文件就运行一次相关测试,确保不破坏已有功能。这个阶段用 Read/Write/Edit/Bash 工具。阶段 3:质量保障 Agent。运行完整的测试套件,检查覆盖率;执行 lint 和类型检查;审查代码安全性。如果有问题,自动回到阶段 2 修改。阶段 4:提交部署 Agent。生成 commit message,创建 PR,填写 PR 描述(包含变更摘要、测试结果、影响范围)。这个阶段用轻量模型,因为操作是确定性的。关键工程细节:用 Hooks 在阶段 2 的每次文件写入后自动运行 lint,在阶段 4 的 PR 创建前自动运行 CI 检查。这样即使 Agent 出错,Hooks 也能及时拦截。”
答题要点: 结合真实案例,说明多 Agent 系统特有的坑——单 Agent 不会遇到的问题。高分回答: “多 Agent 系统在生产环境有四个特有的坑:1. Agent 间循环调用:Test Agent 发现 bug,通知 Code Agent 修复;Code Agent 修复后引入新 bug,Test Agent 又发现;两个 Agent 陷入无限循环。解决:设置全局最大循环次数 + 每个 Agent 的独立重试上限 + 状态变化检测(连续 3 次输出相同则强制终止)。2. 上下文膨胀:每个 Agent 都往共享状态中写入数据,状态越来越大,超出上下文窗口。比如 Code Agent 写了 10 个文件的变更,Test Agent 又加了 50 个测试结果,Review Agent 的输入已经 80K tokens 了。解决:每个 Agent 只写入结构化的摘要到共享状态,完整数据存在外部存储中按需加载。3. 权限泄漏:Code Agent 在执行过程中获取了 Deploy Agent 的权限(比如通过 Bash 命令直接调用了部署脚本)。解决:每个 Agent 运行在独立的沙箱环境中,工具白名单严格隔离,Hooks 在每次工具调用前校验权限。4. 失败传播:一个 Agent 的错误输出被下游 Agent 当作正确输入,导致错误级联放大。比如 Code Agent 生成了有安全漏洞的代码,Test Agent 没有安全测试用例所以测试通过,Review Agent 又漏审了安全问题,最终漏洞代码被部署到生产环境。解决:每个 Agent 的输出必须有独立的验证机制,不能’自检自’。”
答题要点: 这是争议性问题,需要从多个角度分析,给出有层次的判断。高分回答: “短期内不会取代,但会深刻改变前端工程师的工作方式。表面上的答案:AI 编码工具能自动生成代码、写测试、做 Code Review,看起来前端工程师要失业了。反面的证据:第一,Claude Code 在复杂架构决策上的表现还不够好——它能写代码,但不确定应该用什么架构、如何做技术选型。第二,AI 生成的代码需要人来审查和验证,尤其在安全敏感的场景(支付、认证)中,完全信任 AI 是危险的。第三,前端工程师的核心价值不只是写代码,还包括理解业务需求、设计用户体验、做性能优化、协调团队协作——这些都是 AI 目前做不到的。你的判断:AI 编码工具会取代’写代码’这个动作,但不会取代’工程师’这个角色。就像 Excel 取代了手工计算,但没有取代会计师——会计师的工作从’算数’变成了’分析和决策’。前端工程师的工作会从’写代码’变成’设计架构 + 审查 AI 输出 + 处理 AI 搞不定的复杂问题’。升华:真正有风险的不是’前端工程师’这个职位,而是’只会写代码、不会思考’的工程师。掌握多 Agent 协作设计、理解企业级 Agent 架构、能驾驭 AI 工具的工程师,反而会因为 AI 而变得更值钱。“

Q13: Harness 运行时:状态机、事件与崩溃恢复怎么做?

前面的章节讲的是”Agent 应该具备什么能力”,这一节讲”这些能力靠什么运行时结构撑住”。如果被追问”你说的 Agent Loop 到底怎么落地”,答不上状态机、事件和恢复,就还是概念层。

一次 run 的四层状态

DeepSeek Harness 公开文档把 turn 和 step 明确分开:一个 step 包含一次模型请求、该请求产生的工具调用及其结果;一个 turn 可以包含零到多个 step。Anthropic 的 Managed Agents 则把运行时拆成三个可独立替换的接口:session(只追加的事件日志)、harness(调模型并把工具调用路由出去的循环)、sandbox(执行代码和改文件的环境)[16]。两个设计指向同一个结论:循环可以无状态,状态必须外置。

事件要分”耐久”和”瞬时”两类

这是很多自研 Harness 会踩的坑:把所有东西都塞进一个事件流,结果回放时被流式 token 淹没。 DeepSeek Harness 的公开资料明确区分 session events(必须活过 reload 和 replay 的持久事实)与 agent events(描述进行中的工作,可被观察或拦截)[17]。Pi 的会话文件是 JSONL,每行一个条目,通过 id / parentId 组成树,条目类型包括会话头、消息、模型切换、思考等级切换、压缩、分支摘要和自定义条目[18]。

事件溯源:状态是事件的折叠

事件溯源带来三个能力,也带来三个必须付的代价:

回放不是重跑:区分 record-replay 与 re-execute

模型调用和工具副作用都不是确定性的。同一个 Prompt 重跑,模型可能给出不同答案;bash 重跑可能重复写文件。所以生产级回放必须区分两种模式:
  • record-replay(审计/调试):只读日志,复用记录下来的模型输出和工具结果,不再真正调用外部系统。适合复现”当时到底看到了什么”。
  • re-execute(回归/评测):模型重新推理,但工具执行打上 replay_mode=strict,对写操作返回 replayed 而不是真的执行;或整体切到隔离沙箱。
如果把两者混为一谈,回放会变成”带副作用的第二次执行”,这是事故的常见来源。

Checkpoint 应该存在哪一层

LangGraph 的 checkpointer 按 thread_id 持久化图状态快照,支持对话连续性、Human-in-the-Loop、time travel 和容错;MemorySaver 只存在内存,生产必须换 PostgresSaver 或 SqliteSaver,并且要设保留策略,否则 checkpoint 无界增长[19]。事件日志方案则更适合需要审计和跨 Agent 共享的场景。

崩溃恢复协议(最容易被忽略的部分)

一个可用的恢复流程至少要回答四个问题:
  1. 谁有权恢复? 用租约(lease)+ fencing token。旧 worker 即使还活着,写事件时 token 过期也会被拒绝,避免两个 harness 同时跑同一个 run。
  2. pending tool call 怎么办? 恢复时先查工具侧账本(按 idempotency_key),已完成的直接补写 tool/completed,未完成的重新执行或标记为失败。
  3. 半写文件怎么办? 产物先写临时路径再原子 rename,并用 checksum 校验;沙箱崩溃后不信任任何未提交的产物。
  4. 从哪条事件继续? 记录 last_applied_event_id,恢复时只重放其后的事件;快照作为加速,不作为真相。
什么场景会坏: 事件写入成功但进程在副作用完成前崩溃,恢复时重复执行写操作;两个 worker 因网络分区同时认为自己是 owner;压缩摘要覆盖了原始事件,回放无法还原;事件 schema 升级后老日志解析失败。 怎么验证: 在 step/tool 边界做故障注入(kill -9、断网、磁盘满),断言恢复后事件序列无重复、无丢失;用固定事件集跑 fold,对比快照与全量重放的结果;对每个工具做”执行两次结果一致”的幂等测试。

Q14: 上下文工程:预算、压缩和 Prompt Cache 怎么一起设计?

上下文工程不是”把资料塞进 Prompt”,而是在有限窗口里做资源分配,并且让分配结果对缓存友好。

组装顺序与预算

一个可解释的组装顺序(顺序本身就是契约):
预算不是平均分配。以一个 200K 窗口为例(具体数字随模型变化,这里只演示方法):

四种上下文操作,不要只会”压缩”

Anthropic 的上下文工程文章把操作分为 write、select、compress、isolate 四类[20]。落到 Harness 上: Anthropic 在长任务实践中进一步区分了 compaction 与 context reset:compaction 是原地摘要,保留连续性;reset 是清空窗口、换一个新 Agent,靠结构化交接物承接状态。他们观察到某些模型会在接近上下文上限时”提前收工”(context anxiety),reset 能解决这个问题,但代价是交接物必须足够完整,且增加编排复杂度、token 开销和延迟[21]。更关键的是,当模型换代后这个补丁可能变成死重——harness 的假设会过期[16]。

前缀稳定与 Prompt Cache 的真实影响

Prompt Cache 的命中条件是前缀逐字节一致。几个容易踩的细节(以 Anthropic 公开文档为例):
  • 缓存默认 5 分钟 TTL,可选用 1 小时;命中读取按基础输入价的约 0.1 倍计费,写入按约 1.25 倍计费[22]。
  • 最多 4 个显式断点;缓存读取会向前回看最多 20 个内容块,找不到就 miss[22]。
  • 在断点之前插入时间戳、随机 ID、动态排序的工具数组,会让整个前缀哈希变化,每次都在写缓存却永远读不到。
Pi 的显式上下文组装让这件事可审计:你能看见放进去的每一条内容,从而主动维护”稳定前缀”这个不变量。反过来,如果 Harness 偷偷注入当前时间、随机排序工具、每轮重写系统提示,长任务成本可能翻几倍。 什么场景会坏: 多租户共用系统提示但拼进了租户名;工具列表按使用频率动态排序;压缩摘要每轮重写导致断点前的历史变化;把大工具结果放在历史中间而不是末尾。 怎么验证: 在响应里采集 cache_read_input_tokens / cache_creation_input_tokens(或 Provider 等价指标),计算缓存命中率与单任务成本;做 A/B:固定前缀 vs 动态前缀,对比同一任务集的 token 账单;把”前缀哈希”作为回归测试断言。

Q15: 工具运行时与产物:怎么让 Agent 的动作可控、可重放、可交接?

工具是 Harness 的”手”。手的设计决定了三件事:模型会不会用错、出错后能不能恢复、产物能不能被下一步消费。

工具注册与动态挂载

Pi 的实现细节值得参考:工具注册是 eager 的,没有 unregisterTool,但可以通过 pi.getAllTools() / getActiveTools() / setActiveTools(names) 切换模型可见的子集,切换在下一轮生效[23]。这避免了”运行时删除工具”带来的状态不一致,代价是注册表只增不减,需要额外的治理。

并发、超时与取消

超时和取消必须端到端传递:
只设 Promise.race 超时而不真正取消子进程,会留下僵尸进程继续写文件;bash 工具必须杀进程组,而不是只杀父进程。

结果截断:不要丢掉”被截断”这个事实

一个 cat 可能输出几十万字符。正确做法不是简单截断,而是截断 + 溢出到产物 + 返回指针:
只返回 head 和 tail 也有用,但模型经常需要中间那段;产物指针把”看多少”的决定权交回给模型,同时保证信息不丢。Pi 的示例扩展里对 ripgrep 输出做了 50KB / 2000 行的截断[24],可以作为量级参考。

错误契约:错误是写给模型看的

关键原则:可重试性由工具声明,不由模型猜。 参数错误、权限不足不重试;超时、429、5xx 可重试,但要指数退避 + 抖动,并遵守 Retry-After。错误信息要可执行,例如”路径不在允许的 workspace 内,请改用相对路径 src/...”,而不是”操作失败”。

幂等:副作用工具的生命线

工具侧维护 key -> result 账本,命中直接返回旧结果。没有幂等键,恢复重试就可能重复发邮件、重复扣款、重复创建工单。

沙箱:三层边界,不要混为一谈

Claude Code 的沙箱基于 OS 原语(Linux bubblewrap、macOS seatbelt),同时做文件系统隔离和网络隔离:网络只允许通过一个运行在沙箱外的代理,由代理做域名白名单和确认[25]。Codex CLI 则把策略映射到 Seatbelt / bubblewrap + Landlock / Windows 受限令牌,并把 .git、.codex 等元数据目录强制只读[26]。OpenAI 在生产中强调”沙箱与审批配合”:沙箱定义技术边界,审批策略决定何时必须停下来问人,凭据存放在 OS keyring 而不是沙箱内[27]。 Anthropic Managed Agents 还补了一个结构性教训:不要把凭据和模型生成的代码放在同一个容器里。 他们的做法是仓库访问令牌只在沙箱初始化时用于 clone 并写入本地 git remote,Agent 全程不接触 token;MCP 的 OAuth token 放在 vault,由沙箱外的代理代取[16]。

产物:从会话落到工作区,再被下一个 Agent 读取

Agent 在会话里生成的文件,不能只留在沙箱磁盘上。一个可用的产物链路是:
产物设计里最容易出错的六个点: 怎么验证: 在产物提交前后注入 kill;用第二个 Agent 真实读取产物并跑 schema 校验;做路径穿越与越权读取的负向测试;对 GC 跑”引用中的产物不能被删”的断言。

Q16: 模型路由、降级与可观测性接点怎么设计?

路由不是一个 if-else,而是一张能力表

一个常被忽略的点:路由要”粘”住缓存。 同一个 run 内频繁换模型会让前缀缓存全部失效,省下的单价可能被缓存 miss 吃掉。

降级阶梯

什么场景会坏: 跨 Provider 的 tool schema 不兼容导致工具调用静默丢失;把 429 当永久错误直接失败;hedged request(对冲请求)在成本敏感场景把账单翻倍;降级后模型不知道工具变少,继续请求不存在的工具。 怎么验证: 用故障注入代理制造 429/500/超时;断言降级路径与最终错误码;统计每档的成功率、P95 延迟、单任务成本;对工具 schema 做跨 Provider 的契约测试。

可观测性接点:Harness 应该暴露什么

Harness 不需要自己实现完整观测,但必须把事件暴露得足够细。建议的最小事件集: 对接方式:
  • OpenTelemetry:把 run 作为 root span,step 作为 child span,tool 作为更深一层;模型调用记录 GenAI 语义约定字段(模型名、token 用量、TTFT)。DeepSeek Harness 已有社区插件把原生事件转成 OTLP Trace/Metric[28],说明”事件流 → Span 投影”是可行路径。
  • Langfuse:走 OTLP 或 SDK,把 observation 映射到 generation/span,重点是保留 runId、stepId、toolCallId 作为关联键。
  • 日志 vs Trace:日志回答”发生了什么”,Trace 回答”时间花在哪、调用关系是什么”。只有日志时,很难回答”这 47 秒是模型慢还是工具慢”。
两个纪律:默认不记录完整 Prompt 和工具输出(敏感数据面),需要时按租户开关;采样要分层,错误与高成本 run 全采,成功短任务低采样。

Q17: 横向对比与”自研 vs 采用”决策树

决策树

判断”自研”是否值得,只看四个约束:是否需要私有化/数据不出域、是否需要深度改造循环与上下文、是否有平台团队长期维护、是否能在 6 个月内补齐权限/沙箱/审计/评测。 四个里有两个否,就应该采用现成方案。

Q18: 深度面试追问(Harness 运行时方向)

及格回答:“从 checkpoint 恢复,继续跑没完成的步骤。”满分回答:“先分清状态在哪。会话事件日志是真相,进程只是无状态执行器。恢复时用租约 + fencing token 保证只有一个 worker 拥有这个 run;读日志 fold 出状态,找出已请求但没有结果的 tool call。每个副作用工具都有幂等键(runId + stepId + tool + 参数哈希),恢复前先查工具侧账本:已有结果就直接补写事件,没有才重新执行。产物先写临时文件再原子提交,校验 sha256,避免半写文件被下游读到。最后做故障注入测试,断言恢复后事件序列无重复、无丢失。”
及格回答:“回放就是把历史消息再发给模型一次。”满分回答:“回放有两种。record-replay 是审计模式,复用日志里记录的模型输出和工具结果,不再产生真实副作用,用来回答’当时系统看到了什么’。re-execute 是评测模式,模型重新推理,但工具执行要进隔离沙箱或返回 replay 标记,否则会重复写文件、重复下单。混淆两者是事故来源。另外,回放依赖事件 schema 稳定,压缩摘要不能覆盖原始事件,否则回放会失真。”
及格回答:“用摘要压缩历史,保留最近几轮。”满分回答:“看失败模式。如果只是 token 超限,压缩早期消息、裁剪旧工具结果(保留产物指针)成本最低。如果模型出现’接近上限就草率收尾’的 context anxiety,压缩不够,需要 context reset:清空窗口,换新 Agent,用结构化交接物承接目标、约束、进度、决策和未完成项。reset 的代价是交接物必须完整,且增加编排复杂度和延迟;而且模型换代后这个补丁可能变成死重。无论哪种,都要保证前缀稳定以命中缓存,并保留原始事件在会话日志里可回查。”
及格回答:“截断到固定长度,避免撑爆上下文。”满分回答:“直接截断会丢掉’信息存在但被隐藏’这个事实,模型可能基于残缺输出做出错误判断。正确做法是截断 + 溢出到产物 + 返回指针:保留头尾和一段摘要,把完整内容写成 artifact,返回 artifact://id 和读取方式,让模型按需读取行范围。同时标记 truncated: true,并在错误/成功契约里说明。还要注意截断发生在工具层还是上下文组装层:工具层截断会影响后续重试和审计,所以完整结果必须落盘。”
及格回答:“有沙箱就够了,反正出不去。”满分回答:“不够,两者回答不同问题。沙箱限制破坏半径:即使 Prompt Injection 成功,也读不到宿主机文件、连不上任意域名。权限决定动作是否被允许:删生产库、部署、发邮件,沙箱可能允许执行,但策略层必须拦截或要求人工审批。生产要两层都有,再加第三层凭据隔离:模型生成的代码所在的沙箱不能触达 token,Git 用短时令牌在初始化时 clone,MCP 走沙箱外的代理取凭据。沙箱防’攻破后能做什么’,权限防’该不该做’。”
及格回答:“把系统提示放前面就能命中缓存。”满分回答:“缓存要求前缀逐字节一致,所以 Harness 必须把’稳定性’当成架构约束,而不是优化技巧。系统提示、工具定义、项目上下文放最前面,工具数组顺序固定,断点前不放时间戳和随机 ID;变化内容只追加到断点之后。以 Anthropic 为例,最多 4 个断点、回看 20 个块、默认 5 分钟 TTL,写入约 1.25 倍、读取约 0.1 倍计费,所以在断点前插入动态内容会导致’每次写缓存、永远读不到’。验证要看 cachedTokens 占比和单任务成本,而不是凭感觉。”
及格回答:“把文件路径告诉下一个 Agent。”满分回答:“交接的应该是产物引用 + 契约,不是裸路径。产物先 stage 再 commit 到对象存储,生成 manifest:artifactId、sha256、mediaType、bytes、owner、producedBy(run/step/tool)、inputs lineage、TTL。下一个 Agent 通过 artifact_read 按 id 和范围读取,鉴权按租户和 visibility 做,读取时校验 checksum。路径只在同一个 workspace 内可信,跨 Agent 用 URI 更安全。还要有生命周期:TTL、引用计数、合规保留,以及 GC 时’被引用的产物不能删’的约束。”
及格回答:“跑几个任务看看效果,感觉更好了。”满分回答:“控制变量:同一模型、同一温度、同一任务集、同一工具权限,只改 Harness。指标分三层:结果(任务成功率、验收通过率)、过程(平均 step 数、工具误调用率、重试率、人工接管率)、成本(单任务 token、缓存命中率、P95 延迟)。用固定 fixture 和事件回放做回归,避免任务漂移。还要做消融:分别去掉压缩、产物指针、权限拦截,看哪个改动真正贡献了提升。如果成功率不变但 step 和成本下降,也是有效提升;如果只是某几个 case 变好,要检查是否过拟合。“

延伸阅读与引用参考