摘要Agent 最大的坑不是报错是它说做完了环境说没有。本文借 Java 后端的天然资本——编译器、类型系统、Bean Validation、Micrometer/OTel——讲清怎么在模型周围搭四道确定性门禁把假成功挡在缝里而不是等上线后人工 debug。你给 Agent 派了个活把这批工单的状态从处理中改成已关闭顺手回写关闭原因。它跑了一阵返回 status: success。你信了。三天后客服说工单还停在处理中。你翻日志每一步都绿没有任何异常。问题出在哪儿它调了更新接口接口返回 200但那条数据的状态字段根本没变——传入的 ticketId 在库里查无此单更新命中 0 行。HTTP 成功业务失败Agent 浑然不知还给你写了句已处理完成。这不是个案。tau2-bench 里单控域近一半的失败是声称完成但环境状态不符AppWorld 上显式声明状态的失败里有 75.8% 是这一类。Reddy 等人的研究更狠78% 的失败对工具和 Agent 两边都不可见。Java 后端自带栏杆的料别的语言也在写 Agent但 Java 后端搭门禁料是现成的。编译器是免费的确定性闸门。Agent 生成的代码先过 javac编译不过连运行都到不了——类型错误、缺方法都是确定性错误不用等它编理由自圆其说。类型系统和 Bean Validation 把语法对、语义错的调用挡在工具执行前。Reddy 把这类问题叫 policy-permissive tools工具接受任何合法调用哪怕它违反业务规则。在 Java 侧一个 NotNull、一个 Pattern 就能让这种调用在进模型之前被拒。Micrometer 加 OpenTelemetry 已经长在 Spring Boot 里。你不用自己造遥测加两个依赖链路自己就出来了。第一道门编译门禁最便宜的门禁是让生成物先过编译。不少团队让 Agent 直接改业务代码、直接部署。一旦它生成的接口签名和调用方对不上运行时才炸而且炸在离出错最远的地方。把./gradlew compileJava或mvn compile塞进 Agent 的写完即验证环节编译失败立刻回退重来。这一步零模型调用、零额外成本却挡掉了最大一类低级失败。第二道门契约门禁工具不是能调就行参数是有契约的。给工具的入参用 JSR-380 注解约束执行前校验recordCloseTicketCmd(NotNullLongticketId,Pattern(regexpCLOSED|REJECTED)Stringstatus,Size(max200)Stringreason){}参数非法直接抛约束违例工具不执行。Reddy 的四门确定性闸门里这一道叫参数前检——不依赖模型判断纯规则。他的实验里单纯加这类预执行闸门就把 gpt-5.2 在工具调用任务上的成功率从 61.2% 拉到 71.6%。第三道门状态门禁编译过了、参数对了不代表世界真变了。工具执行完要断言环境状态确实变了而不是信 Agent 的回执。Spring AI 的ToolCallingManager周围可以包一层 Advisor在工具返回后跑一条核验查询longclosedticketRepo.countByStatus(CLOSED);Assert.isTrue(closedexpected,关闭数与预期不符);Reddy 的四门里这道对应状态后检和策略检——查当前状态、查策略是否被违反。闸门本身不调用模型毫秒级却能把更新命中 0 行这类假成功当场抓出来。第四道门链路门禁前三道是点上的闸这一道是面上的图。Spring AI 对每次模型调用自动发两层 Micrometer observationgen_ai.client.operation记录 token、模型、请求参数okhttp.requests记录 HTTP 方法、URI、状态码并在链路上传播 traceparent。工具调用另有ToolCallingObservationConvention把toolDefinitionName、toolDefinitionSchema一并记进 span。这些 span 把工具名、参数、返回串成一条可追的链传统 APM 只看到 HTTP 200 的地方这里能看到工具到底有没有做对事。接法不用改业务代码application.yml 里把采样打开即可management:tracing:sampling:probability:1.0# 错误全采成功流量可降到 0.1再加micrometer-tracing-bridge-otel和spring-boot-starter-actuator链路直接进你现有的 OTel Collector。国产模型走 OpenAI 兼容接口时同一套桥照样在线上传播 traceparent不用为它单独改埋点。LangChain4j 侧挂一个ObservationChatModelListener就能拿到同构的 Micrometer 遥测它的 input/output guardrails 事件还能在工具前后插校验和 Spring AI 的思路一致只是表述换成了监听器。评测门禁把场景固化成资产四道门挡的是这次跑没跑对。要挡换了个 prompt 模型是不是退化了得有回归集。把你们真实的工单流转、审批、对账场景固化成一组成 golden 用例每次动 prompt 或换模型CI 里跑一遍。断言不是输出等于某字符串而是状态机走到了对的终态——和状态门禁同一套思路从单次运行升到版本对比。代价与边界门禁不是越多越好。高风险动作删库、对外发件才值得上人工确认低风险读操作确定性闸门挡语法对语义错就够了别用闸门去审创意。闸门本身也有成本每道后检都是一次额外查询高频工具要权衡采样率。最该警惕的是把闸门当免责。闸门挡得住确定性错误挡不住目标定错了——它说关工单你其实想关的是另一批。门禁管执行不管意图意图还得人来定。结语Agent 不可靠往往不是模型不行是它周围没栏杆。Java 后端恰好把栏杆的料都备齐了编译器、类型、Bean Validation、Micrometer。四道门一搭假成功从上线后人工 debug变成执行时当场拦截。Lightrun 今年一项针对 SRE 与 DevOps 负责人的调查里43% 的 AI 改动上线后仍要人工 debug88% 需要两到三次重部署才确认——把门禁前置这两组数字能砍掉一大截。参考资料From Confident Closing to Silent FailureICML 2026 FAGEN WorkshoparXiv:2606.09863——tau2-bench 单控域 45–48% 失败为假成功Agents fail by declaring successNZWE Journal2026-07——AppWorld 75.8% 假成功、5 个 LLM judge AUROC ≤0.65Reddy et al., Reason Less, Verify MorearXiv:2607.07405——78% 失败对工具与 Agent 不可见四门确定性闸门 gpt-5.2 61.2%→71.6%Spring AI Observability 参考docs.spring.io/spring-ai——gen_ai.client.operation / okhttp.requests 双层 observation、ToolCallingObservationConventionLangChain4j Observability 教程docs.langchain4j.dev——ObservationChatModelListener、guardrails 事件Lightrun 2026 SRE/DevOps 调查——43% AI 改动上线后人工 debug、88% 需 2–3 次重部署OpenTelemetry GenAI Semantic Conventions v1.30——agent/chat/tool span 树与 gen_ai.* 属性作者唐悦玮 | 从后端出发用 AI 拓展到全栈的工程师。