Skip to content

RFC: 简洁的 Feedback 错误反馈机制与 proto 类型收敛 #173

Closed

Description

@M09Ic

问题

基础工具、搜索和 subagent 的普通执行失败,应作为自然语言反馈交给模型纠正,而不是终止父 Agent loop。当前转换分散在注册表、Agent、AOP 和 JEV;部分输出可能遮住错误原因,后台子任务也需要独立完成通知。与此同时,proto 之外的重复 DTO 和转导出类型别名增加了理解与维护成本。

设计约束:足够简洁

优先复用 Go 标准 error、errors.New、fmt.Errorf("...: %w", err)、errors.Is / errors.As。Feedback 是模型可见的错误反馈语义,不应发展成一套新的错误框架。

允许引入一个极简 Feedback 类型,但必须有标准 error 包装无法清楚表达的实际需求,例如区分可读纠错提示与底层 cause。候选结构仅供讨论:

type Feedback struct {
    Message string
    Cause   error
}

func (f *Feedback) Error() string { return f.Message }
func (f *Feedback) Unwrap() error { return f.Cause }

若采用该类型,需要明确 nil / 空消息行为;普通 error 必须同样可用。不得要求工具实现额外接口,不新增错误分类注册表、策略配置、平行 DTO 或 JSON 错误信封。纠错建议由工具给出,公共层不根据错误文本猜测重试或操作。

参考标准库 errors / fmt 的错误链,以及 os.PathError 的上下文与 Unwrap 模式。不要照搬大型开源错误体系;只有实际需要的能力才引入。

统一反馈行为

  • 工具正常返回 (*aop.ToolResult, error);模型入口自动调用 Error() 生成文本、设置 IsError,父 loop 继续。
  • 保留部分输出、媒体、关联字段和原始 error;原始错误供日志、hooks、直接调用方及 errors.Is/As 使用。
  • 同一失败不重复展示;普通错误不自动设置 Terminate。用户取消整个 Run、预算耗尽、模型调用失败和显式终止仍按控制流程处理。
  • sync 子 Agent 失败反馈给父模型;async/fork 创建错误走工具反馈,运行失败通过已有 Inbox 通知,包含只有 error 没有 result 的情况。
  • 覆盖 read/write/ls/glob、skill 读取、bash/tmux、web_search、subagent、JEV。搜索必须验证真实搜索执行,不能把普通模型回答作为联网结果。
  • 收敛重复转换为一个小函数或等价的单一边界机制,不增加多层包装。

尽可能消除 proto 之外的 DTO 和别名

  • 删除 tool.Result = aop.ToolResult、tool.Definition = aop.ToolDefinition、agent.ToolDefinition,直接使用 proto。
  • 删除 agent.Provider、agent.ChatCompletion* 等转导出别名,直接引用定义包。
  • 删除仅复制 proto 字段的平行 DTO 和往返转换;协议数据以 proto 为唯一表示。
  • 保留确有独立语义的运行时状态、配置、资源所有者、局部参数结构及 vendor wire 适配结构;不为消除 struct 而机械新增 proto。
  • 不新建 FeedbackResult / FeedbackResponse 等包装。现有 proto wire 字段不因这次整理改变;Go 源码 API 的迁移需覆盖调用方、示例和测试。

验收

  • 普通 error 与可选 Feedback 均能自动成为模型可读反馈;错误链仍支持 errors.Is/As。
  • 部分结果与失败原因同时可见,错误反馈不打断父 loop。
  • 基础工具、sync/async/fork、子 Agent panic、无结果后台失败和 JEV 有回归覆盖。
  • Run 取消和显式终止保持有效;不隐式重试或重复副作用。
  • 用真实 LLM 验证其能理解反馈并继续或纠正调用。
  • 设计保持小而直接,无新增错误框架、冗余 DTO 或兼容别名层。

本地 RFC:reports/rfc-feedback-20261010.md(尚未推送,本文提供可独立讨论的完整提案)。已有基础实现和测试不代表上述类型收敛迁移已完成。

Activity

  1. M09Ic commented on Oct 25, 2026

    @M09Ic
    ContributorAuthor

    已完成真实模型验收,关闭此 issue。

    • 实现已由 PR refactor: compose optional tools by import and preserve failure feedback #188 合入 master,提交 c289e3c820d196b92e3144b172ead2abee150b20;关联 CI 的 17 项检查全部通过:https://github.com/chainreactors/cyber-harness/actions/runs/40205246139。

    • 2026-10-26 使用实际 OpenAI 兼容服务和 deepseek-flash,启用 CYBER_FEEDBACK_LIVE=1 后运行:

      go test -count=1 -v ./agent -run '^TestLiveModelCorrectsToolFailure$' -timeout 3m
      
    • TestLiveModelCorrectsToolFailure 实际通过(2.98 秒,未跳过)。测试断言模型先收到 missing.txt 的读取失败,再成功读取 correct.txt,并在最终回答中返回夹具内容,验证普通工具失败后父 loop 继续且模型能纠正调用。

    • 部分输出/媒体、原始 Go 错误链、sync/async/fork、panic、后台无结果失败、搜索执行校验及 JEV 的离线回归已在实现与 CI 中覆盖;未引入新错误框架或修改 proto wire schema。

    本次在线验收使用仅进程可见的凭证,未将密钥或临时报告提交到仓库或本 issue。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions