← AI Agent

Agent 给出的最终结论能直接落库吗?怎么让它可信?

高频 中等 ReAct 循环 · 第 2 / 2 问 更新于 2026/09/29
AI Agent结果校验结构化输出可信度ReAct
本题落地项目AI Agent 智慧医院智能导诊就诊系统

简化版

不能直接落库。Agent 的最终结论是模型生成的文本,可能引用不存在的实体、给出越界的数字、漏掉关键风险信号,甚至一个工具都没调就凭记忆作答。可信的做法是「模型负责选,代码负责核」:先要求模型按固定结构输出;执行完先反查过程,确认它真的调用过工具;关键实体(科室、商品、人员)回数据库核对,能由代码确定的字段(比如具体推荐哪位医生)直接由代码按规则选;数值夹到合法区间、枚举归一;安全相关的信号从工具返回的原始数据里由代码判断,不采信模型的自述;给用户看的解释文字,也基于核验过的事实再生成。核验不通过就判失败并说明原因,而不是把不可信的结论写进业务表。

详细版

Agent 循环结束
  ├─ 1. 过程反查:实际调用了几次工具?0 次 → 失败
  ├─ 2. 安全信号:从工具返回里查危险标记 → 命中走固定的安全分支
  ├─ 3. 解析结构:模型输出的 JSON(实体名、分数、等级、依据)
  ├─ 4. 实体核验:实体名回库查,找不到 → 失败
  ├─ 5. 代码决定:能按规则确定的字段由代码选
  ├─ 6. 数值归一:分数夹到区间,等级归一到枚举
  └─ 7. 生成解释:基于核验后的事实写理由,失败用代码兜底文案
落库:每个字段标明来源(模型给 / 代码核 / 代码定)
字段类型谁给代码做什么
实体(科室、商品)模型选回库核对存在性和状态
可按规则确定的实体(医生、库存)代码按规则直接查出来,不让模型填
数值(置信度、金额)模型给夹到合法区间;金额由代码重算
枚举(等级、类型)模型给归一到固定取值
安全信号(危急、违规)代码从工具返回的原始数据里判断
解释文字模型写素材只给核验过的事实,失败有兜底

完整版教学

一、模型的结论会错在哪

即使模型每一步都调了工具、看到了真实数据,最终结论仍然可能出错,常见的有四类:

错误例子后果
编造实体推荐一个医院里不存在的「胃肠外科」患者按推荐去挂号,挂不上
数值越界置信度写成 135页面显示异常,统计口径错乱
漏判风险工具已经返回「胸痛属危急征象」,结论却写「普通门诊」危急病人被当成普通门诊放走
没查就答一个工具都没调,凭训练记忆写了一段像模像样的结论结论和系统数据毫无关系

这些错误的共同点是:结论读起来很合理,靠人工抽查很难发现。所以核验不能依赖「看起来对不对」,要依赖代码逐项检查。

二、先把结论变成结构

自由文本没法核验。第一步是规定输出结构,只允许模型返回一个 JSON:

{"deptName": "消化内科", "confidence": 82, "urgencyLevel": "普通", "evidence": "上腹隐痛三天伴恶心,症状标签指向消化内科"}

结构里只放模型擅长给的东西:选哪个方向、有多大把握、依据是什么。不要让模型填它不可能知道准确值的字段,比如具体排班、号源、价格,这些由代码查。结构越小,需要核验的面就越小。

三、执行完先反查过程

在看结论之前,先确认模型真的干了活:

本次运行的工具调用步骤数 = 0  →  判失败:「Agent 没有调用任何工具」

模型完全可能一个工具都不调,直接输出一段格式正确的 JSON。只看结论字段,这种情况完全发现不了。反查的依据是代码记录的步骤表,而不是模型自己说「我查过了」。这一节核验的是最终结论;每一次工具调用的返回怎么验证,见「Agent 如何验证工具调用结果?」。

记忆钩子:先问「查过没有」,再问「查得对不对」。

四、实体回库,能定的由代码定

模型给出的实体名要回数据库核对。匹配可以先精确再放宽:先按全名精确匹配,匹配不上再按包含关系匹配(模型写「消化科」也能对上「消化内科」),仍然找不到就判失败。

更进一步,凡是能按规则确定的字段,就不要让模型选。比如「推荐哪位医生」:规则是「这个科室从今天起、可挂号、余号大于 0 的排班里取第一条」,代码一条 SQL 就能查出来,而且一定挂得上;让模型选,它可能选一个当天没出诊的医生。模型只负责代码判断不了的那部分(根据症状选科室),其余的由代码决定。

五、安全信号从原始数据里判断

有些信号关系到安全,比如危急征象、违规内容。这类判断不能采信模型在结论里的自述,而要回到工具返回的原始数据里由代码检查:

遍历本次运行里「症状检索」步骤的返回 JSON
  └─ 任何一条匹配结果带有危急标记 → 直接走急诊分支
       科室 = 急诊科,医生为空,置信度为空,危急提示取工具返回的文案
这一步放在解析模型 JSON 之前:命中危急时,模型怎么写都不影响结果

顺序很关键:先做安全检查、再解析模型结论。如果先解析,一旦模型写了「普通门诊」而代码又忘了覆盖,风险就漏过去了。

六、数值夹紧、枚举归一

模型给的数值和枚举要落到合法范围:

confidence:135 → 100;-5 → 0;82 → 82
urgencyLevel:「紧急情况」「较紧急」→ 归一到 普通 / 紧急 / 危急 三者之一

夹紧和归一保证落库的数据能被统计:看板要按等级分组,如果库里同时有「紧急」「紧急情况」「比较紧急」,分组就乱了。

七、解释文字基于核验后的事实

给用户看的推荐理由也是模型写的,但素材要换成核验过的事实:科室的擅长病种和位置、选定医生的出诊日期和余号、分诊依据。再调一次模型把这些写成通顺的话。如果模型答非所问(反问患者、说没收到资料)或调用失败,就用代码拼一段兜底文案,保证落库的理由至少是事实的直接陈述。

这样落库的每个字段都能说清来源:哪些是模型选的、哪些是代码核验过的、哪些是代码直接定的。

八、常见误区与追问

  • 误区:模型调过工具,结论就是可信的。 看过真实数据的模型仍会编造实体、漏判风险,结论要逐项核验。
  • 误区:让模型把所有字段都填上最省事。 能按规则确定的字段(医生、库存、金额)交给代码,模型填的越少核验面越小。
  • 误区:安全信号让模型在结论里标出来就行。 安全判断要从工具返回的原始数据里由代码检查,且放在解析结论之前。
  • 误区:核验不通过就退回模型的原始输出。 不可信的结论不能落库,应判失败并写明原因,让用户可以重试。
  • 误区:解释文字不重要,模型写什么存什么。 理由也要基于核验后的事实,失败时用代码兜底,否则会出现理由和结论对不上。
  • 追问:实体名对不上时怎么匹配? 先精确、再包含匹配,仍找不到就判失败,不要猜一个相近的实体。
  • 追问:怎么证明 Agent 真的查过数据? 数代码记录的工具调用步骤,而不是相信模型的自述。

九、加强记忆

Agent 结论落库记「先查过程、再查安全、后核实体」:先数工具调用步骤,0 次直接失败;再从工具返回的原始数据里由代码判断危急这类安全信号,放在解析结论之前;然后解析小而固定的 JSON,实体回库先精确后包含匹配,找不到就失败,能按规则确定的字段(医生、号源、金额)由代码直接定。数值夹到区间、枚举归一到固定取值,解释文字只用核验过的事实生成、失败用代码兜底。落库的每个字段都能说清是模型选的、代码核的还是代码定的。

项目实战落地

项目里怎么做的

《AI Agent 智慧医院智能导诊就诊系统》的分诊 Agent 跑完 ReAct 循环后,TriageAgentService 按固定顺序核验,核验通过才写 triage_result:

  • 反查过程:按运行 ID 取步骤,数工具编码非空的步骤,一个都没有就判运行失败,提示「分诊Agent没有调用任何工具」;
  • 危急拦截在前:遍历工具编码为 symptom_tag_search 的步骤返回 JSON,只要匹配结果里有 is_red_flag = 是,直接走急诊分支:推荐科室 = 急诊科,医生和置信度留空,危急等级 = 危急,提示文案用工具返回的;这一步先于解析模型 JSON;
  • 模型只给四样:普通路径下模型只允许输出科室名、置信度、危急等级和依据;
  • 科室核验、医生由代码定:科室名用和科室查询工具同款的 SQL 回库,先精确匹配再退化为包含匹配;医生不由模型决定,代码从该科室今天起可挂号且余号大于 0 的排班里取第一条;
  • 数值与枚举:置信度夹到 0–100,危急等级归一到普通、紧急、危急;
  • 推荐理由:用推荐理由模板再让模型写一遍,素材全部是核验过的事实(科室擅长和位置、医生出诊日期时段余号、分诊依据);模型答非所问或调用失败时,用代码拼的兜底文案。

triage_result 的每个字段都对应「谁填」:科室和医生是代码核验或选定后填的,置信度和危急等级是模型给、代码规整的,是否危急是代码从工具返回反查的。

《AI 多Agent智能相亲交友匹配平台》收尾时不采信模型说的数:

  • 交付人数现数。 主管收尾时写「已经有 8 个人通过了」不作数,代码从候选池里数审核结论为「通过」的行,交付人数取它和要求人数中较小的那个;一个都没有就判这次匹配失败,不在页面上显示一个空的「匹配成功」。审核官被停用时,按候选池里的全部候选交付,并在结论里写明这批人没有经过反向审核。
  • 每一轮都从库里数。 筛选官每一轮新增了几人,按任务和轮次从候选池里数;这一轮放宽了什么,取写候选池那次工具调用带的放宽说明,不采信模型结论里另报的那一份;审核官每一批审了几位、通过几位也从库里数;模型报的审核人数和库里实际回填的条数对不上时,把这件事写进这一批的结论。
  • 判通过的再核一遍。 审核官判「通过」的候选,代码拿候选方标为必须、而且确实有约束的条件,逐项核对申请方的档案;核不过的,把候选和维度写进这一批的结论。审核状态本身不改。

为什么这样取舍

  • 核验是底线:模型生成是概率性的,可能编造不存在的科室、推荐一个当天没出诊的医生、把危急病人当成普通门诊放走;这些错了患者就白跑一趟甚至延误病情,必须由代码兜底。
  • 医生由代码定:推荐的医生必须当天真的有号,模型只说科室,医生是谁由代码按排班余号决定。

面试官还会追问

  • 分诊结果为什么要有「已挂号」这个状态?它还支撑了哪个指标?
  • 两个患者同时挂同一个排班的最后一个号,余号会被扣成负数吗?怎么保证?
  • 发起分诊时交给 Agent 的输入由哪几部分组成?会话里 AI 的追问算不算主诉?

学完《AI Agent 智慧医院智能导诊就诊系统》,上面这些追问你都会迎刃而解。

本题落地项目地狱锤炼AI Agent 智慧医院智能导诊就诊系统项目简介:基于医学知识库 RAG、向量检索、数据库驱动工具中心、Spring Boot + LangChain4j、Function Calling,实现文档切分与 Embedding 向量化、按库收窄的内存余弦 topK 检索、SSE 真流式多轮预问诊、数据库驱动 ReAct 分诊 Agent 多轮自主取证、工具注册表真开关与调用日志、科室医生查库核验、挂号乐观锁扣减、Agent 执行时间线与 AI 调用观测、就诊运营,覆盖从预问诊、智能分诊、在线挂号到接诊写病历与运营复盘的完整就诊闭环。SpringbootLangChain4JAgentMCPRAG源码+SQL喂饭学习教程配套面试文档环境安装文档项目运行文档 学习这个项目 也可以学AI 多Agent智能相亲交友匹配平台地狱锤炼 查看项目