
人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习【免费下载链接】agent-coreopenJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力项目地址https://gitcode.com/openJiuwen/agent-core点击查看免费下载本篇技术指南以 errors.md 为骨架深入剖析 openJiuwen agent-core 框架的统一异常体系以BaseError为唯一基类、以StatusCode为语义主键、以消息模板驱动错误文本渲染的设计以及异常类如何表达是否可重试、是否致命的控制语义。读完本文你将掌握如何正确抛出、构建、序列化与判断框架级异常理解错误码区间分配与异常类自动映射规则并能在自己的 Agent / 工作流代码中规范地接入这套体系。一、为什么需要统一异常体系Agent 应用链路长、组件多工作流编排、模型调用、工具执行、记忆存取、多智能体协作、检索、安全护栏……任何一个环节都可能失败。如果每个模块各自抛出裸Exception或RuntimeError下游的 API 网关、RPC 调用方和日志系统将无法获得结构化的错误信息——没有统一错误码就无法定位是哪个模块、哪种失败没有统一异常类型就无法判断该重试中止还是正常终止。openJiuwen agent-core 在 openjiuwen/core/common/exception 目录下建立了一整套解决方案包含五个文件各司其职文件职责errors.pyBaseError异常基类、完整异常层级与build_error/raise_error工厂codes.pyStatusCode枚举全局错误码的单一真相源近千条status_mapping.pyStatusCode→ 异常类的自动解析规则code_template.py错误码命名与消息模板的生成辅助工具CLAUDE.md模块设计约定与使用禁忌核心设计思想是StatusCode 是语义主键异常类表达控制语义——两者解耦再通过映射表绑定。选异常类 选控制流retry? abort? terminate gracefully?选 StatusCode 选错误身份哪个模块、哪种失败。二、BaseError框架统一异常基类BaseError是所有框架异常的祖先类定义于 errors.py。原文档给出的完整签名如下class openjiuwen.core.common.exception.errors.BaseError( status: StatusCode, # 必选位置参数 *, msg: Optional[str] None, # 自定义错误消息覆盖模板渲染结果 details: Optional[Any] None, # 结构化上下文任意类型 cause: Optional[BaseException] None, # 链式异常记录原始根因 **kwargs: dict[str, Any], # 模板参数填充 StatusCode 消息占位符 )各参数含义与行为status必选StatusCode枚举成员用于标识异常的具体类型和错误消息模板。它是唯一的位置参数其余均为关键字参数。msg可选自定义错误消息。若提供则覆盖从 StatusCode 模板渲染出的默认消息。details可选结构化上下文信息可以是任意类型数据如字典、对象快照用于附加更多错误细节方便排查与审计。cause可选链式异常记录引发当前异常的原始异常对象。源码中同时将其赋给self.cause和self.__cause__见 errors.py保证 Python 原生异常链与框架字段一致。kwargs可选模板参数用于填充 StatusCode 错误消息模板中的{placeholders}并保存在self.params中供结构化日志使用。从源码看BaseError初始化时还做了三件关键事从status提取self.code self.status.code整数错误码调用_render_message()基于模板渲染默认消息并同时保存在self._template_message与self.message中调用super().__init__(self._template_message)确保str(exception)也有可读内容。2.1 实例属性速览属性类型说明statusStatusCode语义主键枚举成员codeint整数错误码如100102paramsdict模板参数来自**kwargsdetailsAny结构化附加信息causeBaseException \| None链式异常根因messagestr自定义消息若有或模板渲染消息_template_messagestr始终由模板渲染的消息recoverablebool类级标记是否可重试 / 重规划fatalbool类级标记是否必须中止当前执行其中recoverable与fatal是类属性由各异常子类声明而非实例传入——这正是异常类 控制语义这一设计的落点。2.2 模板渲染是 lazy-safe 的_render_message()errors.py调用_format_template()进行渲染。_format_template使用_SafeDict继承dict覆写__missing__配合str.format_map模板缺失某个占位符 key 时不会抛KeyError而是原样渲染为missing:key渲染过程中发生任何格式化异常兜底逻辑会返回未填充的原始模板最坏情况用户看到占位符原文但调用栈不会被二次污染参数值统一str()化后注入 SafeDicterrors.py。这是刻意设计错误路径上不能再产生新的异常。因此项目约定也明确写入 CLAUDE.md不要在_render_message/_format_template里抛异常。2.3 字符串与序列化BaseError.__str__返回[{code}] {message}格式例如[100102] workflow execution has error, errorxxx, workflowwf。更重要的是源码为BaseError实现了__reduce__与类方法_reconstructerrors.py使异常对象支持pickle 跨进程传递。这保证了在multiprocessing、分布式 Runner 或消息队列场景下status / message / details / cause / params完整无损地往返。三、结构化输出to_dict 与 to_jsonBaseError提供两个标准输出方法用于 API 响应、RPC 调用或日志记录3.1 to_dict()def to_dict(self) - Dict[str, Any]: return { code: self.code, # 整数错误码 status: self.status.name, # StatusCode 枚举名字符串 message: self._template_message, # 模板渲染消息 params: self.params, # 模板参数字典 raw_message: self.message, # 自定义消息或渲染消息 details: self.details, # 详细附加信息任意类型 }原文档列出的六字段与源码 errors.py 完全一致。各字段的用途字段类型用途codeint程序可分支判断的稳定错误码statusstr人类可读的枚举名如WORKFLOW_EXECUTION_ERRORmessagestr模板渲染出的默认消息用于日志与用户提示paramsdict渲染时传入的模板参数便于结构化检索raw_messagestr自定义msg若提供否则等于渲染消息detailsAny任意结构化上下文供审计与排障注意区分message与raw_message前者始终来自模板渲染_template_message后者可能是调用方传入的自定义msg。3.2 to_json()def to_json(self) - str: return json.dumps(self.to_dict(), ensure_asciiFalse)将to_dict()结果序列化为 JSON 字符串ensure_asciiFalse保证中文等非 ASCII 字符以原文输出UTF-8便于跨语言 API 网关与前端直接消费。3.3 典型输出示例假设工作流执行失败err build_error( StatusCode.WORKFLOW_EXECUTION_ERROR, reasonmodel call timeout, workflowcustomer_service_wf, ) print(err.to_json())输出大致为{ code: 100102, status: WORKFLOW_EXECUTION_ERROR, message: workflow execution has error, errormodel call timeout, workflowcustomer_service_wf, params: {reason: model call timeout, workflow: customer_service_wf}, raw_message: workflow execution has error, errormodel call timeout, workflowcustomer_service_wf, details: null }四、异常类层级用类型表达控制语义BaseError之下框架按可恢复性与致命性划分出四个一级分支完整层级见 errors.py 与 CLAUDE.mdBaseError ├── FrameworkError # fatalTrue, recoverableFalse —— 基础设施/依赖损坏必须中止 │ └── ConfigurationError ├── ValidationError # fatalFalse, recoverableFalse —— 输入/约束错误重试无意义 │ └── GuardrailError ├── ExecutionError # fatalFalse, recoverableTrue —— 执行期错误可重试/重规划 │ ├── ApplicationError / ExternalServiceError / ExternalDataError │ ├── WorkflowError / ComponentError / AgentError / RunnerError │ ├── GraphError / ModelError / ToolError / ContextError │ ├── ToolchainError / SessionError / SysOperationError / StoreError └── Termination # fatalFalse, recoverableFalse —— 正常控制流终止非错误 └── RunnerTermination各分支的控制语义与典型适用场景异常类recoverablefatal适用场景处理策略FrameworkErrorFalseTrue基础设施 / 环境 / 依赖故障连接、初始化、服务不可用必须中止当前执行ConfigurationErrorFalseTrue配置错误FrameworkError子类中止并修复配置ValidationErrorFalseFalse约束校验、非法输入、不支持的能力不重试、不重规划直接反馈GuardrailErrorFalseFalse安全护栏拦截errors.py记录风险详情并阻断ExecutionErrorTrueFalse工作流 / Agent / 工具执行期错误通常可重试或重规划TerminationFalseFalse正常停止、取消、完成等非错误终止按正常流程收尾RunnerTerminationFalseFalseRunner 被取消/终止额外携带reason字段优雅退出4.1 领域异常类在四个一级分支之下框架按业务域划分了大量领域异常类全部继承自ExecutionError或ValidationError/FrameworkErrorWorkflowError/ComponentError工作流编排与组件执行AgentError/RunnerError单 Agent、分布式 RunnerGraphError/ModelError/ToolError/ContextError图引擎、模型调用、工具执行、上下文引擎ToolchainError/SessionError/SysOperationError/StoreError调优工具链、会话、系统操作、持久化层内存 / 向量 / 检查点 / 图存储CryptError加解密失败继承FrameworkError。其中ToolError是唯一的带特殊构造参数的异常类它额外接收card: BaseCard参数将工具卡片Card深拷贝后并入details并提供card()访问器errors.py。RunnerTermination则额外携带reason字段用于取消场景真实使用见 response_collector.py 与 mq_server_adapter.py。五、StatusCode错误码的单一真相源StatusCode 是一个带(code: int, msg: str)二元值的高级 Enum共约 930 条见 CLAUDE.md。每个成员由两个字段构成code整数错误码按模块区间严格分段errmsg英文错误消息模板支持str.format风格占位符如{reason}、{workflow}、{timeout}、{error_msg}。枚举值的__init__会做类型校验codes.pycode 必须是int、msg 必须是str否则抛TypeError。code与errmsg均以只读 property 暴露保证枚举不可变——线程安全正依赖于此。5.1 错误码区间分配错误码按模块严格分段每段在 codes.py 中用注释块标明 scope 与 failure 类别。分配表与 code_template.py 的_code_range_by_scope保持一致Scope区间WORKFLOW100000–100999COMPONENT101000–119999AGENT120000–129999RUNNER130000–139999GRAPH140000–149999CONTEXT150000–154999RETRIEVAL155000–157999MEMORY158000–159999TOOLCHAIN160000–179999PROMPT180000–180999MODEL181000–181999TOOL182000–182999COMMON188000–188999SESSION190000–198999SYS_OPERATION199000–199999区间内再做细分例如工作流校验类错误集中在100000-100099执行类在100100-100199编排类在100200-100299Agent 编排在120000-123999其中 ReAct Agent 在120000-120999、Agent Controller 在123000-123010、DeepAgent 在123020-123031。新增错误码前必须确认所属区间不得跨段塞入且需同步修改status_mapping.RANGE_RULES。5.2 命名与消息模板规范错误码命名遵循{SCOPE}_{SUBJECT}_{FAILURE_TYPE}格式如WORKFLOW_COMPONENT_ID_INVALID、MODEL_CALL_FAILED、GUARDRAIL_BLOCKED。code_template.py定义了受控词表SCOPE∈ALLOWED_SCOPESWORKFLOW / COMPONENT / AGENT / TOOL / MODEL / SESSION / GRAPH / CONTROLLER / RUNNER / PROMPT / COMMON / CONTEXT / TOOLCHAIN / MEMORY / RETRIEVAL / SYS_OPERATIONFAILURE_TYPE∈ALLOWED_FAILURE_TYPES按语义分三组Validation 语义INVALID / NOT_FOUND / NOT_SUPPORTED / CONFIG_ERROR / PARAM_ERROR / TYPE_ERRORFramework 语义INIT_FAILED / CALL_FAILEDExecution 语义EXECUTION_ERROR / RUNTIME_ERROR / PROCESS_ERROR / TIMEOUT / INTERRUPTED。failure_type直接决定后续异常类映射的关键字匹配结果——命名对了分类就对了。消息模板约定统一英文、小写 scope/subject占位符用{name}形式不用{0}或%s超时类模板必须带{timeout}通用错误类模板带{error_msg}或{reason}。5.3 典型错误码示例# 工作流校验类 WORKFLOW_COMPONENT_ID_INVALID ( 100010, the component id is invalid for component {comp_id}, reason{reason}, workflow{workflow}) # 工作流执行类 WORKFLOW_EXECUTION_ERROR ( 100102, workflow execution has error, error{reason}, workflow{workflow}) # Agent 工具类 AGENT_TOOL_NOT_FOUND (120000, agent tool not found, reason: {error_msg}) # 模型调用类 MODEL_CALL_FAILED (181001, model call failed, reason: {error_msg}) # 安全护栏类 GUARDRAIL_BLOCKED ( 190000, guardrail blocked: risk_type{risk_type}, risk_level{risk_level}, event{event}) # 系统操作类 SYS_OPERATION_SHELL_EXECUTION_ERROR ( 199004, shell operation execution error, execution: {execution}, reason: {error_msg})六、StatusCode → 异常类自动映射规则日常开发中你无需手工选择异常类——build_error/raise_error会通过 status_mapping.py 构建的STATUS_TO_EXCEPTION表自动选类。解析规则为四级优先级MANUAL_OVERRIDES手工覆盖_MANUAL_OVERRIDES_RAW中写死的特例如TOOL_EXECUTION_ERROR → ToolError、AGENT_RL_PROCESSOR_NOT_FOUND → ValidationError、COMMON_ENCRYPTION_ERROR → CryptError、PREGEL_GRAPH_SUPER_STEP_EXECUTION_ERROR → GraphError等status_mapping.pyKEYWORD_RULES关键字规则按 StatusCode 名称关键字匹配如INVALID/VALIDATE/NOT_SUPPORTED/PARAM/MISSING/DUPLICATED→ValidationErrorINIT/CONNECT/SERVICE/QUEUE/PROVIDER→FrameworkErrorTIMEOUT/EXECUTE/EXECUTION/RUNTIME/PROCESS/STREAM/RESPONSE→ExecutionErrorstatus_mapping.pyRANGE_RULES数值区间兜底按 code 区间映射如100000-119999 → WorkflowError、120000-129999 → AgentError、180000-189999 → FrameworkError、190000-198999 → SessionErrorstatus_mapping.py绝对兜底以上均未命中时回退到ExecutionError。值得注意的工程细节是StoreError规则被有意放在关键字规则最末尾最低优先级以避免与INVALID/CONFIG/INIT等前置规则冲突将持久化层错误统一收编到StoreErrorstatus_mapping.py。新增 StatusCode 时映射会在build_status_exception_map()被调用时即errors.py模块级STATUS_TO_EXCEPTION build_status_exception_map()见 errors.py自动并入无需手工登记若默认解析不符合预期优先通过调整命名命中关键字规则实在不行才增加_MANUAL_OVERRIDES_RAW条目。status_mapping.py中还有一个必须遵守的约束_get_exception_class_registry()采用函数内 lazy import来避免与errors.py的循环依赖status_mapping.py不要把它改成模块级 import否则会破坏导入顺序。七、使用入口三个工厂函数与两种直接构造原文档聚焦BaseError本身而实际业务代码通过三个模块级工厂函数与之交互errors.py7.1 raise_error立即抛出最常见from openjiuwen.core.common.exception.codes import StatusCode from openjiuwen.core.common.exception.errors import raise_error raise_error( StatusCode.WORKFLOW_EXECUTION_ERROR, reasonstr(e), workflowwf_id, )工厂内部通过STATUS_TO_EXCEPTION自动选择异常类并raise。模板占位符以**kwargs传入多余的 key 会保存在self.params用于结构化日志。7.2 build_error构建而不抛出from openjiuwen.core.common.exception.errors import build_error err build_error(StatusCode.TOOL_EXECUTION_ERROR, causee, reasonstr(e)) return Result.fail(err)适用于延迟抛出或把错误对象包进 Result / 消息队列等场景。源码中build_error的选类逻辑为STATUS_TO_EXCEPTION.get(status, FrameworkError)errors.py即未知状态码兜底为FrameworkError。它在框架中被广泛使用例如 llm_controller.py 在模型调用失败时raise build_error(...)。7.3 直接构造具体异常类仅当需要传入特殊字段时才直接构造目前只有两类异常有此需求from openjiuwen.core.common.exception.errors import ToolError # ToolError 额外携带工具卡片 raise ToolError(StatusCode.TOOL_EXECUTION_ERROR, cardtool_card, reasonstr(e))以及RunnerTermination携带reason字段。除此之外不要自己拼FooError(status, ...)统一走build_error/raise_error。7.4 特殊入口system_error(status, cause...)快速抛FrameworkErrorvalidate_error(status, cause...)快速抛ValidationErrorterminate(status, **kwargs)快速抛Termination正常控制流终止非错误。八、实战异常判断与处理模式判断异常应基于控制语义而非错误码数字。框架约定CLAUDE.md# 正确按类型 / 语义字段判断 except ExecutionError as e: if e.recoverable: # 重试或重新规划 pass else: # 上报并退出 pass except BaseError as e: # 结构化落日志 log.error(e.to_json())# 错误直接在业务代码里拿 code 做分支 # except BaseError as e: # return e.status.code # 不要这样做单元测试中同样遵循此模式例如 test_llm_agent_with_interrupt.py 通过except BaseError捕获框架异常test_evolution_store.py 同时导入BaseError与build_error用于断言与构造。分布式 / 跨进程场景则依赖__reduce__的 pickle 序列化能力保证status / details / cause / params完整传递。九、最佳实践与禁忌速查结合原文档、源码与 CLAUDE.md 的设计约定总结如下最佳实践框架内部抛异常必须走 StatusCode 体系外部库抛出的异常在边界处转换为BaseError优先使用raise_error/build_error让映射表自动选类只有ToolError带card与RunnerTermination带reason可考虑直接构造模板占位符通过**kwargs传入多余参数保存在params供结构化日志使用动态、易变的运行时数据放入details或**kwargs → params不要写入 StatusCode 枚举常量需要跨进程传递异常时利用内置的 pickle 支持__reduce__/_reconstruct。禁忌不要raise Exception(...)/raise RuntimeError(...)——项目内部抛异常必走 StatusCode 体系不要在业务代码里except BaseError as e: return e.status.code——请用isinstance(e, ExecutionError)/e.recoverable/e.fatal判断控制语义不要给 StatusCode 塞运行时数据——枚举是不可变常量线程安全依赖于此不要重复定义 code 数值——Python Enum 对重复值会静默 alias新增前先 grep不要在_render_message/_format_template中抛异常——错误路径不能产生新的错误不要修改status_mapping._get_exception_class_registry的 lazy import——会破坏循环依赖规避。十、扩展阅读errors.pyBaseError 基类、完整异常层级与工厂函数实现codes.pyStatusCode 枚举与全量错误码区间status_mapping.py异常类自动解析规则code_template.py错误码命名与消息模板生成工具CLAUDE.md模块设计约定、使用入口与禁忌清单框架内实际使用示例llm_controller.pybuild_error调用链、response_collector.pyRunnerTermination测试参考test_llm_agent_with_interrupt.py、test_evolution_store.py赞分享人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习【免费下载链接】agent-coreopenJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力项目地址https://gitcode.com/openJiuwen/agent-core点击查看免费下载相关推荐Moonshine Micro 特征生成模块解析面向 MCU 的无堆 log-mel 前端批量 流式Moonshine Micro 特征生成模块解析面向 MCU 的无堆 log mel 前端批量 流式 本指南围绕 micro/feature gene人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习Wagmi React 错误体系全解析从 BaseError 到 WagmiProviderNotFoundError 的实战指南Wagmi React 错误体系全解析从 BaseError 到 WagmiProviderNotFoundError 的实战指南 Wagmi 为以太坊应用提区块链Web3前端SQLAlchemy Core 异常体系全解从 sqlalchemy.exc 源码读懂异常分类、错误码与 DBAPI 包装机制SQLAlchemy Core 异常体系全解从 sqlalchemy.exc 源码读懂异常分类、错误码与 DBAPI 包装机制 SQLAlchemy 将整个框数据库后端ORM上一篇GG-CNN如何判断抓取成功IoU指标与25%阈值完整解读下一篇PySC2 Bazel 构建实战从 C 扩展编译到目标运行与测试的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考