第三章 边界定义原则:职责分离、最小泄漏、容错与隔离

Agent系统在运行时面临大量不确定性:外部API超时、模型推理异常、数据格式错误、资源争抢。如果没有为异常处理划定清晰的边界,一个组件的故障会像病毒一样扩散到整个系统。本章围绕三条核心原则——职责分离、最小泄漏、容错与隔离——建立异常处理的边界模型,并给出每一条原则在边界定义、分层职责、数据流/控制流/信任链路中的具体映射。

原则速览:三条原则并非并列选项,而是从谁处理、暴露什么、怎么隔离三个维度构成边界设计的完整约束。

3.1 边界定义与原则对比

边界是异常处理的责任划分点,也是信息传播的截止点。下表对比三条原则在边界上的不同含义:

原则边界定义核心约束典型违规
职责分离每个组件只负责自己能力范围内的异常异常类型与处理逻辑必须属于同一抽象层业务层直接捕获数据库连接异常
最小泄漏跨边界传递的异常信息仅包含必要上下文屏蔽内部堆栈、凭证、数据结构细节将Postgres驱动异常原文返回给前端
容错与隔离边界必须能阻止故障向相邻组件传播超时熔断、舱壁分隔、降级响应Agent A的OOM导致Agent B的线程池泄露

3.2 分层职责:边界在架构中的落地

典型的Agent系统分为通信层、编排层、能力层三层。每个层级对三条原则的权重不同:

  • 通信层:强职责分离(区分协议异常与业务异常)+ 强最小泄漏(对外仅返回标准化错误码)
  • 编排层:强容错与隔离(使用舱壁模式隔离不同Agent实例)+ 弱最小泄漏(内部传递可包含traceId)
  • 能力层:强职责分离(每个工具只处理自身异常)+ 强容错与隔离(工具超时自动熔断)
实践提示:不要在所有层级强行应用全部三条原则。通信层优先最小泄漏,能力层优先容错隔离,编排层侧重职责分离——分层赋予原则不同的优先级。

3.3 数据流、控制流与信任链路

异常处理边界直接影响三种流的走向。下面用一张SVG图展示三层边界如何协同工作:

异常处理边界三层原则协同模型 通信层边界(最小泄漏主导) 职责分离:区分HTTP错误、协议错误、业务拒绝 最小泄漏:统一ErrorBody结构,不暴露内部堆栈 容错隔离:连接池隔离,单个请求超时不会耗尽TCP连接 编排层边界(职责分离主导) 职责分离:Agent交互日志与业务决策日志分离 最小泄漏:跨Agent传递仅含错误码+traceId 容错隔离:舱壁模式隔离不同Agent实例的线程池 能力层边界(容错与隔离主导) 职责分离:工具异常与模型异常分别处理 容错隔离:熔断器保护内部函数调用,降级返回默认值 信任链路:下层边界向上层传递经过清洗的异常,上层信任下层已完成隔离

上图揭示了三个层次如何处理数据流、控制流与信任链路:

  • 数据流:异常信息从能力层向上传递,每经过一层边界就剥离一层细节(最小泄漏);
  • 控制流:编排层收到下层异常后,根据职责分离原则决定是重试、降级还是终止;
  • 信任链路:上层信任下层已经完成故障隔离,不需要重新检查下层组件的健康状态。

3.4 选型权衡

在真实系统中,三条原则之间存在资源与复杂度的矛盾。以下是常见权衡点:

权衡对倾向原则牺牲方向缓解策略
职责分离 vs 最少代码职责分离代码量增加20~30%使用通用异常处理框架(如Spring @ControllerAdvice)
最小泄漏 vs 调试效率最小泄漏生产故障排查难度上升在内部链路携带traceId,日志级别保留详细堆栈
容错隔离 vs 资源利用率容错隔离线程池/连接池资源预留,利用率下降动态舱壁大小(根据历史负载调整)
常见陷阱:不要为了追求“完全隔离”而让每个Agent单独部署进程。在容器化环境下,隔离粒度应控制在线程/协程池+熔断器级别,避免过度分割增加运维成本。

3.5 风险点

  • 职责模糊:没有明确“谁负责处理”,导致异常被多级捕获或无处捕获,最终由根节点吞没。
  • 信息爆炸:最小泄漏执行不到位,内部异常细节通过RPC泄露到外部客户端,造成安全漏洞和耦合。
  • 隔离失败:容错隔离只做了“捕获”没做“熔断”,故障线程持续占满线程池,最后拖垮整个Agent。
  • 信任链断裂:上层不信任下层已经隔离,自己又做一次重试/恢复,造成重复工作和状态混乱。

3.6 落地步骤

  1. 定义三层边界:按通信/编排/能力切割系统,明确每层所属的异常类型命名空间。
  2. 为每层选择主导原则:通信层选最小泄漏,编排层选职责分离,能力层选容错隔离。
  3. 编写边界适配器:在层间接口处插入异常转换/清洗中间件。例如业务层抛出的AgentTimeoutException在通信层转为标准503错误体。
  4. 实现容错基元:为每个能力组件配置熔断器、舱壁和超时参数。
  5. 编写边界测试:验证异常是否在正确层级被捕获,错误信息是否满足最小泄漏。
  6. 灰度与观察:在线上开启增量异常的日志标注,评审边界是否被绕过。
推荐工具:使用Resilience4j的CircuitBreaker和Bulkhead实现容错隔离;使用Jackson @JsonIgnore或protobuf field mask控制序列化泄露。

3.7 验收标准

检查项通过条件测试手段
职责分离所有异常均在最接近产生点的层级被捕获,且不被更上层直接Catch代码审查 + 静态分析(如ArchUnit)
最小泄漏外部接口返回的错误体中不包含嵌套异常、堆栈或内部IP/端口Mock对外接口,检查返回JSON字段
容错隔离单个Agent工具的超时或OOM不会导致其他工具的响应延迟超过10%混沌工程注入故障,测量p99延迟变化
信任链路下层熔断后,上层不需要额外的降级逻辑(信任下层已返回标准错误)观察熔断期间流量的处理路径日志
// 职责分离示例:能力层明确抛出工具异常,编排层不捕获具体技术异常
// 能力层
public class WeatherTool {
    public WeatherResult fetch(String city) {
        try {
            return httpClient.get(url + city);
        } catch (IOException e) {
            throw new ToolExecutionException("weather", "HTTP failure", e);
        }
    }
}

// 编排层只处理ToolExecutionException,不关心底层IOException
public class AgentOrchestrator {
    public Response handle(Request req) {
        try {
            return weatherTool.fetch(req.city);
        } catch (ToolExecutionException e) {
            return Response.error(e.getCode(), "weather service unavailable");
        }
    }
}
本章核心:边界不是代码中的一道if-else,而是架构中的契约。职责分离、最小泄漏、容错与隔离这三条原则定义了契约的内容——谁处理、暴露什么、怎么隔离。下一阶段将进入具体实现模式(第4章:异常分类与标准化错误码)。