Files
deepseek-harness/docs/rfc/implemented/architecture/2026-06-11-structured-error-taxonomy.zh.md
T
Ziya 2565133af3 docs(i18n): RFC tree batch — 146 bilingual pairs via the committed pipeline
implemented(除 4 篇超长文档随后补)、proposed、rejected 全树配对;
同一流水线 + 二遍校验(paraphrase-back + 仓库上下文一致性)产出。
docs/rfc/implemented/AGENTS.md 与其 CLAUDE.md 符号链接列入排除
(agent 指令文件,与根 AGENTS.md 同策略)。
2026-07-15 23:25:06 -07:00

27 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RFC:结构化错误分类体系
Status: implemented
[English](2026-06-11-structured-error-taxonomy.md) | 中文
## 问题
错误跨越服务边界时只是裸字符串。工具错误被扁平化为一个文本块——name、code 和 stack 全部丢失——导致未来的沙箱/重试插件无法区分 ENOENT 和 EACCES,模型得到的反馈也不如本可以获得的那样可操作。非 Error 的 throw 退化得更严重:agent loop(智能体循环)将其包装为 `new Error(String(x))`,丢弃了所有 code。而 `LlmError` 是系统中唯一的类型化错误,没有共享基类,消费方无法对一个通用基类做 `instanceof`。
## 决策
在 `dsh-llm`(叶子包(package),所有其他包都已依赖它——不引入新的依赖边)中建立一个 `HarnessError extends Error` 基类:稳定的 `code`(与 `message` 分离)、通过 `ErrorOptions` 的 `cause` 链式传递、`name` 默认为子类名。`isHarnessError` 在服务边界处做类型收窄。
- `LlmError`、`ToolArgsError`(dsh-tools)和 `InvariantError`(dsh-invariants)现在继承该基类,保留各自既有的 code。
- `ToolExecutionResult` 新增可选字段 `error: { name, code }`,在注册表的 catch 中当抛出值为 `HarnessError` 时填充。agent loop 将其转发到 `tool/result` 会话事件(该事件也新增了同一可选字段),使结构化的失败信息存入日志,供重试/沙箱插件和回放使用。面向模型的文本块不变。
- agent loop 的 `toError` 将非 Error 的 throw 包装为 `HarnessError`(`code: 'UNKNOWN'`,原始值通过 `cause` 链接),而非裸 `Error`;这样即使是不规范的 throw 也能携带可路由的 code 进入会话的 `error` 事件(该事件已暴露 `code`)。
## 后果
- 错误在端到端链路上可被机器路由:插件可以按 `error.code` 分支,而非对 message 做子串匹配。
- 一个基类被广泛导入,但它位于所有包本已依赖的包中,代价只是一条 import 语句,而非一条新的依赖边。
- `deriveMessages` 不会将 `error` 字段呈现到模型历史中——模型仍然看到文本块;结构化字段服务于代码逻辑和回放。
- 参数校验与开发不变式保留各自既有的 code 和行为;共享基类添加了跨服务边界的路由元数据,不改变面向模型的文本。
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->