新闻详情

新闻详情

首页 / 资讯中心 / 详情

DeepSeek Harness 结构化错误分类体系:基于 `HarnessError` 的端到端机器可路由错误设计

发布时间:2026/9/19 23:41:10来源:尧图网络
DeepSeek Harness 结构化错误分类体系:基于 `HarnessError` 的端到端机器可路由错误设计
DeepSeek Harness 结构化错误分类体系基于HarnessError的端到端机器可路由错误设计【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness导读本篇文章围绕 DeepSeek Harness 仓库中的架构 Agent Note《Structured error taxonomy》展开讲解项目如何用一个统一的HarnessError基类取代跨越各能力 seam 的裸字符串错误让工具错误、LLM 调用失败、非 Error throw 等各类故障都携带稳定、可机器路由的code。读完你将掌握HarnessError的字段与构造函数设计、错误分类树LlmError、ToolArgsError等、错误跨工具执行结果与会话事件传播的完整链路以及插件如何基于error.code分支处理沙箱、重试、回放而不必对消息文本做子串匹配。问题背景故障跨越 seam 时沦为裸字符串在引入本方案之前DeepSeek Harness 中的失败信息在跨模块边界时会被扁平化工具错误被压成文本块工具执行失败时name、code和stack全部丢失只留下一段面向模型的文本。这意味着一个未来的沙箱/重试插件无法区分ENOENT和EACCES——两类错误需要的处理策略完全不同但消费方只能看到同一段文字。非 Error 的 throw 退化更严重当某处throw一个非Error值例如throw { reason: denied }时agent loop智能体循环会用new Error(String(x))包装它code信息被彻底丢弃连可读的cause链也丢了。缺少共享基类当时LlmError是系统中唯一的类型化错误没有公共基类消费方无法对任意错误做通用的instanceof判断也就无法在统一出口seam做类型收窄。于是决策落地为在dsh-llm包中引入一个HarnessError extends Error基类作为全系统错误的公共祖先。核心设计HarnessError基类基类实现位于 packages/llm/llm/src/error.ts核心代码如下export class HarnessError extends Error { /** Stable machine-routable failure class (e.g. RATE_LIMIT); route on this, never by parsing message. */ readonly code: string constructor(message: string, code: string, options?: ErrorOptions) { super(message, options) this.code code this.name new.target.name } }设计要点有三稳定的code与人类可读的message分离code是程序化的、稳定的失败类别标识如NO_ADAPTER、INVALID_ARGS、RATE_LIMIT、UNKNOWN与面向人的message彻底解耦。注释明确要求按code路由永远不要解析message——因为消息文本可能随供应商措辞变化而code是分类契约。通过标准ErrorOptions支持cause链构造函数透传ErrorOptions使得new HarnessError(msg, code, { cause: originalError })能保留底层根因配合errorChain()工具可以渲染完整因果链。name默认取子类构造器名通过new.target.name自动设置子类无需显式声明当然也可以像LlmError、ToolArgsError那样显式覆盖以固化名称。同文件配套的两个关键函数error.ts还导出了与错误体系配套的两个函数isHarnessError(value)error.ts#L161-L163类型守卫value instanceof HarnessError。注释特别强调只收窄真实实例duck-typed 或跨 realm 的错误不会误判用于各 seam 处的运行时边界收窄。errorChain(value)error.ts#L114-L154把任意抛出值渲染为带完整cause链的文本并处理AggregateError成员与循环引用渲染circular cause。它专门用于诊断面消息、通知、日志的渲染——注释明确只渲染绝不解析路由请走HarnessError.code。为什么放在dsh-llm叶子包决策的约束是不引入新的依赖边dsh-llm是所有其他包都已经依赖的叶子包把基类放这里任何包想继承或instanceof它都只需一条import语句而不是新增一个包依赖。正如 Agent Note 所述一个基类被广泛导入但它位于所有包已经依赖的包中代价仅是一条 import而非新的依赖边。这一点可从 packages/llm/llm/src/index.ts#L36-L39 看到export * from ./error.ts使基类从deepseek-ai/dsh-llm公开导出。供应商中立的规范 codeerror.ts中还定义了一批供应商中立的规范 code 常量与分类器进一步夯实稳定 code的语义CONTEXT_WINDOW_EXCEEDED_CODE CONTEXT_WINDOW_EXCEEDED请求超出模型上下文窗口。QUOTA_EXCEEDED_CODE QUOTA账户配额/余额耗尽区别于瞬时限流。EMPTY_RESPONSE_CODE EMPTY_RESPONSE响应正常结束但没有任何内容块视为可安全重试。INVALID_CREDENTIAL_CODE INVALID_CREDENTIAL凭据存在但不可用格式错误修复方式是修正存储值而非补充凭据且刻意不放入默认可重试集合——格式错误的凭据每次尝试都会同样失败。配套的isContextWindowExceededError(detail)error.ts#L80-L86和isQuotaExceededError(detail)error.ts#L94-L100用正则识别各 OpenAI 兼容供应商的措辞把某个供应商到底算不算上下文超限/配额耗尽统一收敛为规范 code。这些分类器与 adapter-failure.ts 的normalizeLlmFailure协同——后者只信任 Harness 自有的 codeerror instanceof HarnessError ? error.code : UNKNOWN第三方 SDK 的 code 不属于本分类体系。错误分类树现有子类HarnessError作为公共基类被两类既有错误继承且都保留了各自既有的 codeLlmErrorLLM 相关失败位于 packages/llm/llm/src/index.ts#L86-L120构造时强制校验message与code非空、status为 100–599 的整数、providerRetryAfterMs为正有限数、requestId非空并把可序列化的事实status、providerRetryAfterMs、requestId冻结进readonly failure: LlmFailure字段export class LlmError extends HarnessError { readonly failure: LlmFailure constructor(message: string, code: string, options?: LlmErrorOptions) { // ...参数校验... super(message, code, options) this.name LlmError this.failure Object.freeze({ message, code, /* status? providerRetryAfterMs? requestId? */ }) } }LlmError的code属于共享分类如AUTH、RATE_LIMIT、NO_ADAPTER携带的failure事实则供持久化与策略层使用。ToolArgsError工具参数校验失败位于 packages/core/tools/src/schema.ts#L461-L470是dsh-tools中的参数校验错误固定使用INVALID_ARGScode并保留逐条违规列表export class ToolArgsError extends HarnessError { readonly violations: string[] constructor(violations: string[]) { super(invalid arguments: ${violations.join(; )}, INVALID_ARGS) this.name ToolArgsError this.violations violations } }除此之外从 packages/core/tools/src/index.ts#L489-L491 附近可看到未知工具错误也继承了HarnessErrorcode: UNKNOWN_TOOL说明该分类树会随各包继续生长。跨 seam 的传播链路Agent Note 强调错误端到端可机器路由其关键在于三处 seam 的打通1. 工具执行结果ToolExecutionResult.errordsh-tools定义了结构化失败元数据 ToolErrorInfoexport interface ToolErrorInfo { name: string code: string } export interface ToolFailure { message: string // 人类可读消息无 Native Error: 前缀 info?: ToolErrorInfo // 供策略与持久化诊断使用的内部错误类别 }失败结果 ToolExecutionFailure 通过error: ToolFailure携带该信息与成功结果的value互斥readonly error?: never。注册表 catch 处toolErrorResult在抛出值为HarnessError时填充结构化信息function toolErrorResult(error: unknown): ToolExecutionResult { const info errorInfo(error) // error instanceof HarnessError ? { name, code } : undefined const message errorMessage(error) return { content: [{ type: text, text: Error: ${message} }], // 模型面文本块不变 isError: true, error: { message, ...info ? { info } : {} }, } }注意errorInfoindex.ts#L642-L647只对HarnessError实例产出结构化字段并用 try/catch 兜底——即使抛出值充满敌意instanceof被陷阱化也不会让错误归一化边界本身崩溃。2. 会话事件tool/result与turn/endagent loop 将结构化失败转发到tool/result会话事件该事件同样新增可选error字段使结构化失败信息进入持久化日志供重试/沙箱插件与回放使用。这一点有端到端测试直接印证crash-recovery.e2e.ts 验证崩溃恢复后重放的tool/result事件携带{ name: ToolOutcomeUnknownError, code: TOOL_OUTCOME_UNKNOWN }且模型面文本仍含Do not retry blindly.——证明结构化字段与模型文本并存的设计。3. agent loop 的toError归一化非 Error throw →UNKNOWNAgent Note 提到的toError归一化逻辑在 packages/core/agent-loop/src/agent.ts#L309-L322 的 turn catch 中可以看到对应实现// Every failure is structured: an LlmError keeps its facts, anything // else flattens to errorChain text under the UNKNOWN code. turnEnds { kind: error, error: error instanceof LlmError ? error.failure : { message: errorChain(error), code: UNKNOWN }, }即LlmError保留其结构化failure事实其他任意抛出值包括非 Error统一通过errorChain渲染为因果链文本并打上UNKNOWN兜底 code。会话的error事件此前已暴露code因此即使是糟糕的 throw也能携带可路由 code 进入日志而不是被new Error(String(x))抹掉全部类别信息。消费端实践插件如何基于error.code路由整个设计的收益在消费端兑现沙箱/重试插件从tool/result事件读出error.info.code直接分支处理。例如ENOENT类文件系统错误与EACCES类权限错误走不同策略QUOTA、INVALID_CREDENTIAL等 code 依据 error.ts 的规范语义决定是否可重试INVALID_CREDENTIAL刻意不在默认可重试集合内。通用消费方在任意 seam 用isHarnessError(value)收窄后读取.code无需知道具体是哪个子类抛出的。回放/崩溃恢复持久化的会话日志保留了结构化error字段重放时依然可以拿到失败类别见上文 crash-recovery 测试而不仅仅是一段不可解析的文本。边界与约束模型面与代码面分离Agent Note 在 Consequences 中明确了三个重要边界deriveMessages不把error暴露进模型历史——模型始终看到文本块Error: ...形式结构化字段服务于代码与回放。这保证模型的输入面保持稳定同时不牺牲机器可路由性。参数校验保留既有 code 与行为ToolArgsError的INVALID_ARGS与违规列表行为不变只是继承了共享基类。包自有诊断不变式独立携带稳定 code不变式注册表不导入产品包各包如llm-deepseek/src/invariant.ts、llm-retry/src/invariant.ts、token-meter/src/invariant.ts自有的诊断不变式各自携带稳定 code。共享基类只增加跨 seam 的路由元数据不改变模型面文本。总结HarnessError用最小的架构代价单一公共基类 一个code字段把 DeepSeek Harness 的错误从跨 seam 即失真的裸字符串升级为端到端机器可路由的结构化分类统一基类放dsh-llm叶子包零新增依赖边任何包一条 import 即可参与分类树code与message分离、ErrorOptions承载cause、name默认子类名isHarnessError在 seam 收窄工具失败经ToolExecutionResult.error与tool/result事件进入日志非 Error throw 归一化为UNKNOWNcode模型看到的文本块保持不变结构化字段只服务代码、策略与回放。对于希望扩展 Harness 生态沙箱策略、重试策略、回放分析的开发者这条链路给出了清晰的接入点读会话事件中的结构化error.info.code按 code 分支而不是解析消息文本。相关实现与验证可继续查阅packages/llm/llm/src/error.ts、packages/llm/llm/src/index.ts、packages/core/tools/src/schema.ts、packages/core/tools/src/index.ts、packages/core/agent-loop/src/agent.ts、packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts。【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

免费本地化降AIGC工具实测指南:10个真正可控的文本人类化方案 2026/9/20 0:20:16

免费本地化降AIGC工具实测指南:10个真正可控的文本人类化方案

1. 这不是“检测对抗”,而是内容可信度的自我校验最近在帮几家教育机构做课程文案优化,频繁遇到一个扎心问题:老师写的教学反思、学生提交的读书报告、教研组产出的课例分析,一贴到内部审核系统,AI检测标红率动辄60%以…

阅读更多 →
ComfyUI工作流资源搜索与高效使用指南:推荐网站与避坑技巧 2026/9/20 0:20:16

ComfyUI工作流资源搜索与高效使用指南:推荐网站与避坑技巧

1. 为什么ComfyUI的资源搜索比Midjourney更需要"仓储意识"很多人第一次接触ComfyUI,是被它那种节点连线式的操作给震住的。别的工具给个提示词就能出图,ComfyUI却要把加载模型、编码提示词、采样、解码、保存整个流程全拆成一个个节点&#xf…

阅读更多 →
AI学习路线图:从零基础到实战部署的完整指南 2026/9/20 0:20:16

AI学习路线图:从零基础到实战部署的完整指南

刚过去这半年,我的微信里至少有几十个朋友问过同一个问题:AI 这波热潮里,我到底该学什么?我当过后端开发、带过算法团队、做过 AI 产品的落地,也手写过本地推理服务,所以每次被问的时候都认真给了建议。聊得…

阅读更多 →
PyTorch与TensorFlow学术圈格局:动态图优势与迁移实战指南 2026/9/20 0:20:16

PyTorch与TensorFlow学术圈格局:动态图优势与迁移实战指南

1. 学术圈框架格局的现状拆解1.1 从一组数据说起:PyTorch与TensorFlow的真实占比如果你最近两年翻过顶会论文的开源代码,大概率会有这么一个直观感受:十篇里有八九篇是PyTorch写的,剩下那一两篇里,可能还有一半是JAX或…

阅读更多 →
Godot 4.x 场景编辑器效率翻倍:7个隐藏快捷键与操作技巧 2026/9/20 0:20:16

Godot 4.x 场景编辑器效率翻倍:7个隐藏快捷键与操作技巧

1. 为什么你总觉得 Godot 场景编辑器“不够顺手”刚接触 Godot 4.x 的人,十有八九会在场景编辑器里经历一段“手忙脚乱期”。鼠标在视口里拖来拖去,节点树越拉越长,改一个属性要来回切面板,摆一个关卡花掉半小时——然后你去看别人…

阅读更多 →
0x0000003B蓝屏真相:驱动越界而非系统崩溃 2026/9/20 0:17:15

0x0000003B蓝屏真相:驱动越界而非系统崩溃

1. 这个蓝屏不是“系统崩溃”,而是驱动程序在向你发求救信号SYSTEM_SERVICE_EXCEPTION(0x0000003B)这个蓝屏代码,我第一次见到是在帮客户处理一台刚升级Windows 11的Surface Pro 7时。它不像MEMORY_MANAGEMENT那样让人立刻想到内存…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞