Code Agent 使用 SEARCH/REPLACE 或 patch 修改文件时,最常见的失败不是模型完全不懂代码,而是搜索块与当前文件无法精确匹配。缩进、空格、换行、注释或前一次编辑造成的细小差异,都可能让补丁返回“未找到匹配”。如果工具只给出一句泛化错误,模型只能重新读取文件、猜测偏差并再次尝试,既浪费工具调用,也容易重复犯错。
NousResearch 的 Hermes Agent issue 536 提议引入自我纠错反思循环。核心流程是:解析编辑、应用编辑、验证结果;任何阶段失败时,将结构化错误作为新的用户消息反馈给模型,再让模型生成修正版。默认最多重试三次,防止无法修复的问题形成无限循环。
该 issue 截至当前仍是开放的功能请求,不代表 Hermes Agent 已经实现完整流程。文中列出的 Aider 行为是参考设计,Hermes Agent 现有 patch 工具已有多种模糊匹配策略和基础语法检查,但缺少统一的自动反思闭环、详细候选片段以及完整的 lint 集成。
一次 patch 至少包含目标文件、搜索文本和替换文本。匹配失败时,真正有用的问题包括:文件是否正确、搜索块与真实内容差在哪一行、附近是否存在相似代码、文件是否已被其他编辑改变。只返回布尔失败无法回答这些问题。
模型随后通常会调用读取工具获取文件,再自己定位相似片段。这一过程把工具内部已经拥有的匹配信息丢掉了。既然 patch 实现已经计算模糊相似度,就应直接返回最佳候选、行号和上下文,让下一次生成建立在确定证据上。
适合 Agent 消费的错误对象应包含稳定的错误代码,而不是只依赖自然语言。例如使用 SEARCH_NO_EXACT_MATCH 表示搜索块未精确出现,并附带文件路径、原始搜索块、建议候选、候选起止行、相似度和文件版本标识。
同时保留一段面向模型的简洁文本:“你尝试匹配以下内容,但文件中没有精确匹配;最接近的实际内容如下。”然后分别展示请求的 SEARCH、拟议 REPLACE 和文件中的候选片段。结构化字段便于程序判断,文本说明则便于模型直接修正。
若存在多个相似候选,不应擅自应用。工具可以返回前三个候选及上下文,要求模型扩大搜索块或选择唯一位置。相似度过低时,应明确建议重新读取目标区域,而不是给出误导性“你是否想匹配”。
反思循环的第一道门是补丁能否安全应用。工具先验证路径是否在允许范围、文件版本是否与模型读取时一致,再进行精确匹配。精确匹配失败后可以计算候选,但候选只用于诊断,不应自动替换,除非匹配策略具有明确且可审计的安全保证。
反馈消息需要同时显示模型原先的意图和真实文件内容。模型由此可以修正缩进、更新过时的函数签名,或发现目标代码已被删除。下一轮应重新生成完整补丁,而不是在旧补丁字符串上进行脆弱的二次替换。
成功应用后还应记录变更文件和差异摘要,为后续验证限定范围。若同一补丁包含多个编辑块,可以报告哪些已经成功、哪些失败;但重试前必须防止重复应用已成功部分。更稳妥的方案是事务式应用,任一块失败就不提交整组修改。
补丁匹配成功不代表代码正确。Aider 的参考流程会在编辑后运行语法与 lint 检查,例如使用解析器发现通用语法错误,再调用语言专用工具。Python 可以运行编译检查和静态检查,TypeScript 可运行类型检查,JSON 可使用解析器验证。
诊断反馈应包含工具名称、退出状态、文件、行列号、错误代码和必要的源代码上下文。日志要截断无关部分,保留首个根因及相关错误。把数千行构建输出原样塞回模型,会增加 Token 成本并掩盖真正问题。
还要区分编辑引入的错误和仓库原有错误。理想实现会在修改前保存基线诊断,只把新增或发生变化的问题作为自动重试触发条件。否则历史 lint 债务会让 Agent 对无关代码反复修改。
语法正确仍可能破坏行为。启用自动测试后,系统运行经过配置的最小相关测试,将失败用例、断言差异、堆栈中首个项目代码位置和命令退出状态反馈给模型。下一轮模型根据错误修补,而不是让用户重新下达指令。
测试命令必须有超时、输出上限和工作目录限制。对于大型仓库,先运行受影响模块或目标测试,成功后再扩大范围。反思预算应由编辑、lint 和测试阶段共享,例如总计最多三次,而不是每个阶段各自重试三次导致九轮调用。
一种简单做法是把错误包装成新的用户消息,追加到当前对话。模型能够看到自己的失败补丁、结构化诊断与真实上下文,然后再次输出符合格式的编辑。每次反思增加计数,未超过预算就回到模型调用,超过后停止并向用户报告未解决原因。
长对话中,模型可能忘记 patch 格式。参考设计会在消息末尾再次加入精简格式提醒,形成提示词“书挡”。提醒只重复必要约束,例如搜索块必须精确复制、不得省略缩进、一次只修改指定文件,避免引入大量无关系统文本。
状态需要绑定一个编辑事务 ID,记录模型调用次数、每轮补丁、诊断和最终结果。这样既能防止跨任务串扰,也方便分析哪些错误最常触发反思、哪类反馈最有帮助。
硬性重试上限是第一道保护,但还不够。系统应识别连续两轮生成相同补丁、相同错误代码没有改善、候选相似度持续下降等停滞信号。出现停滞时提前终止,比机械耗尽预算更合理。
每次反思都是完整模型往返,会增加延迟与 Token。反馈应尽量局部,只包含相关文件片段和诊断;复杂任务可以使用强模型规划、较快模型生成机械编辑,但两阶段模式本身也有额外成本,只适用于大范围重构。
自动重试还需尊重副作用边界。patch、lint 和纯测试通常可重复执行,但数据库迁移、部署或外部 API 操作未必幂等。反思循环应限定在可回滚的本地编辑事务,不能因测试失败自动重复危险操作。
单元测试应覆盖空格差异、缩进差异、重复候选、文件已变化、部分块成功和完全无候选。断言错误对象字段稳定、行号准确、候选内容来自当前文件,并验证低相似度时不会误应用。
集成测试可以让模型故意生成一次错误搜索块,确认系统在预算内根据候选修正;再构造语法错误和测试失败,检查它们分别进入对应阶段。还要验证第三次失败后确实停止,并保留工作区的一致状态。
效果指标不应只有最终成功率。还要测量平均反思次数、额外 Token、完成延迟、误触发率、原有错误干扰率和每次成功编辑成本。结构化反馈若提高成功率却让所有简单编辑都经历昂贵验证,也需要调整触发策略。
第一阶段只增强 patch 错误:复用现有模糊匹配,返回候选、行号和上下文。这项改动不要求重构消息循环,却能立即减少重复读取。第二阶段加入编辑后的增量诊断,并对工具缺失做优雅降级。
第三阶段再实现自动反思状态机、共享预算和事件日志。等基础闭环稳定后,才考虑规划模型与编辑模型分离的架构模式。这样可以分别评估每项改动带来的成功率和成本变化。
Code Agent 的 patch 匹配失败后,可靠的自动重试不能只靠“再试一次”。系统应把搜索块、真实候选、行号和文件上下文组成结构化错误,再依次接入语法检查与测试诊断,通过统一反思循环反馈给模型。
最多三次的共享预算、事务式编辑、基线诊断和停滞检测是安全边界。先改善错误信息,再逐步加入 lint、测试和自动反思,可以在控制 Token 与副作用的同时,提高代码编辑成功率。Hermes Agent issue 536 描述的是这一方向的开放提案,实际使用前仍需以项目当前实现和测试结果为准。
MCP Server 的工具和资源发生变化时,客户端如何重新发现能力?
DeepSeek Harness 系列(07):Capability Seam 如何通过配置切换能力
MCP Server 能否按需改变工具列表并通过 listChanged 控制工具膨胀?
MCP Server 动态增删工具时如何让客户端更新可用能力?
.NET中的MassTransit分布式应用框架详解
ASP.NETIdentity的基本用法