当工具返回空结果时,如何采用候补 API 保证任务继续?

解读

在大模型落地场景中,工具调用链路往往依赖外部接口(如搜索、图谱、数据库、支付、地图等)。一旦主 API 返回空结果,就会触发**“幻觉风险”“任务中断”**,直接影响用户体验与业务指标。面试官想考察的是:

  1. 你是否能在毫秒级延迟内感知空结果;
  2. 能否不破坏上下文一致性地切换到候补 API;
  3. 能否在LLMOps 闭环里把这次降级沉淀为可观测数据,用于后续微调或提示优化。

知识点

  1. 空结果判定策略:HTTP 200 + 空数组、HTTP 204、HTTP 404、字段缺失、字段为 null、字段为 "",均需正则+JSONPath 双校验
  2. 候补 API 选型原则
    • 语义等价性:返回结构体字段必须能被后续 Prompt 模板兼容;
    • SLA 降级容忍:候补接口 P99 延迟不得超过主接口 1.5 倍;
    • 成本可控:候补若按量计费,需配置单次预算上限日累计上限
  3. 级联重试框架:Spring Retry、Resilience4j、阿里巴巴 Sentinel,均支持熔断-降级-限流三件套;在 Python 侧可用 Tenacity。
  4. Prompt 层兼容:候补数据字段若缺失,需在提示模板里用 Jinja2“默认值”语法补齐,防止 LLM 误判。
  5. 可观测性:每一次空结果与降级动作都要写统一日志格式(traceId、场景码、主/候补 API 耗时、是否兜底成功),并打到Prometheus + Loki,方便后续做微调数据蒸馏

答案

我采用“三级降级漏斗”方案:

  1. 实时感知:在工具调用层封装统一代理,利用 JSONPath 断言“$.data.length>0”,若为空则抛出自定义异常 EmptyResultException耗时 <5 ms
  2. 内存级候补:把候补 API 列表预加载到Caffeine 本地缓存(带权重评分),异常触发后同步线程立即按权重轮询,若 200 ms 内返回非空则继续;若仍空则进入下一步。
  3. 最终兜底:启动异步线程调用“生成式候补”(让大模型基于上下文Few-shot 生成模拟数据),同时给前端先返回“数据加载中”状态,保证对话不中断;待异步线程拿到模拟数据后,通过WebSocket 推送补全答案,并在日志里打标“synthetic_data=true”,用于后续数据清洗。

整个链路通过OpenTelemetry注入 traceId,Prometheus 记录“empty_result_total{api=“main”,scene=“kb_search”}”指标,每晚离线任务把带标数据回流到标注平台,用于RLHF 微调,持续降低空结果率。

拓展思考

  1. 多模态场景:若主 API 返回空图片,候补可用文生图模型实时生成,但需水印+免责声明,防止版权纠纷。
  2. 合规风险:候补 API 若来自境外服务,必须通过跨境数据安全评估;生成式兜底数据涉及用户隐私时,要本地私有化模型推理,避免出境。
  3. 成本博弈:可引入强化学习动态调整候补策略,让“空结果率”与“调用成本”在Pareto 前沿上自动寻优,实现业务 KPI 与财务 KPI 双达标