面灵AI→

顺丰 AI 全栈一面:ReAct 循环、缓存命中率与知识库 pipeline

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 简单介绍一下 ReAct,它在具体实现上面的循环是怎么实现的?
  2. 在代码中怎么判断 AI 是否可以终止?除了最大迭代次数之外
  3. 如果 AI 没有输出 tool call,会表现为什么?是不是也是一种终止状态?
  4. 你设置的 20 次最大循环次数,是随便定的吗?
  5. 你实测的最复杂的任务大概是什么样的?
  6. 大模型 prompt caching、KV Cache 你有了解吗?在你的系统里面,如何提高 cache 的命中率?在 Spring AI 这一侧需要做哪些工程实现?
  7. 了解过 OpenAI 协议上的缓存控制吗?
  8. 你有没有做过大模型底层推理相关开发?
  9. 参与供应链知识库建设,只是做内容建设?有没有涉及知识库系统搭建?
  10. 怎么评估一个知识库的有效性、准确性?
  11. LM Wiki 有几层概念?它内部怎么从 raw 文档抽象出 concept、实体与边的关系?整个 pipeline 是怎么做的?
  12. 知识库做刷新/更新的时候,如果某一个节点变更,怎么评估相连的其他节点是否需要更新?
  13. 项目里的影响面分析是怎么做的?
  14. 多语言翻译插件里,为什么要用 ES 做语义召回?现在大模型翻译能力已经很强了。
  15. ES 里面召回几条记录?ES 里面总共有多少条翻译记录?每天新增多少?
  16. 日积月累不断新增翻译数据,翻译风格会趋于一致还是扩散?
  17. 谁来保证翻译入库的数据质量?翻译完成后的译文是直接写入 ES 吗?

《参考解析》

终止条件不能只有一个最大迭代次数。 面试官连续追问了「怎么判断可以终止」「没有 tool call 算什么」「20 次是不是随便定的」,指向的是同一件事:一个能上生产的 Agent loop 需要多路终止条件,而且要能解释每个阈值是怎么定的。可用的几条:模型给出最终答案或不再产生工具调用;达到预算上限(步数/总 token/总耗时/工具调用次数),强制收尾并回报「已完成什么、还差什么」;连续 N 轮没有产生新信息,或同一工具同参数反复报同样的错,判定为陷入循环主动中断;命中不可恢复错误或安全策略立即转人工。至于「没有输出 tool call」,它是一个终止信号但不是成功信号——可能是模型真的答完了,也可能是格式解析失败或模型退化,所以工程上要把它和「输出了最终文本」分开记账,并统计这类终止的占比。

「20 次是随便定的吗」这道题考的是工程判断。 合格答法是给出定阈值的依据:先看真实任务的步数分布(比如 P99 落在 8~12 步),再留出余量取整;同时说明这个上限是兜底而非目标,正常任务不该逼近它,所以还要配监控——如果大量任务卡在上限附近,说明该优化的是提示词/工具设计而不是把上限调大。没有依据的数字在面试里就是减分项。

prompt caching 与 KV Cache 要分层说。 KV Cache 是推理引擎内部的机制:自回归生成时把已算过的 Key/Value 张量缓存下来,避免每生成一个 token 就把整个前缀重算一遍,它存在于一次请求的生命周期内(跨请求复用要靠 prefix caching)。prompt caching 是服务侧/协议层的能力:如果相邻请求的前缀完全相同,这部分就可以命中缓存、按缓存价计费并跳过重复预填充。由此提高命中率的做法就很明确了:把稳定的内容(系统提示、工具定义、少样本示例、固定文档)放在最前面,把每次都变的内容(用户输入、时间戳、随机 ID)放到最后,并保证前缀字节级一致——一个动态的时间戳插在开头就会让后面全部 miss。Spring AI 侧的工程实现通常是:固定的 system message 与工具 schema 集中定义并复用以保证序列化结果稳定,避免在系统提示里拼时间/会话 ID,留意框架是否在请求前重排或注入字段,并把缓存命中 token 数暴露到监控里验证效果。OpenAI 协议上的缓存控制主要体现在响应里上报命中 token 数、以及部分厂商支持的显式缓存断点标记。

知识库的质量评估要落到可算的指标。 「怎么评估知识库的有效性和准确性」不该只答「人工检查」,可以分层:检索层看命中率、召回率和排序质量(用带标注的问题集测「该召回的文档有没有被召回、排在前几位」);内容层看事实准确率、覆盖率(业务问题里有多少能被现有条目覆盖)和一致性(同一概念在不同文档里的说法是否矛盾);应用层看端到端任务完成率与人工接管率。还要区分「检索不到」和「检索到了但答案错」——前者是覆盖问题,后者是内容或生成问题,责任层不同。

从 raw 文档到 concept/实体/边,本质是一条信息抽取流水线。 典型形态是:文档解析与切分(保留章节层级)→ 抽取(用模型抽实体、关系、以及更高层的概念,并强制结构化输出)→ 归一与消歧(同义词合并、同名实体区分)→ 关联与建图(生成边,落库或建向量索引)→ 人工校验与反馈回流。多层概念(如「概念—实体—关系」)的好处是检索时既能用高层概念做粗筛、也能落到具体实体上。这里最容易被追问的是归一化:不解决同义与歧义,图会迅速变脏。

节点变更的影响面分析。 面试官问的是「一个节点变了,怎么判断相邻节点要不要更新」。可行思路是把依赖关系显式化:建图时就记录边和引用来源,节点变更时沿这些关系做反向遍历拿到受影响集合,再用规则(引用强度、距离、节点类型)排序,最后只把候选送去重新抽取或人工复核,而不是整库重跑。判断「真的需要更新」还可以加一层内容比对——把新抽取结果与旧条目做相似度/一致性判断,只有在实质变化时才改动,这样能避免每次微调都引发全量重写。影响面分析之所以重要,是因为知识库的维护成本几乎全在「改一处、要连带改多少」上。

为什么还用 ES 做语义召回——这道题的答法要有取舍。 面试官的反问(「现在大模型翻译能力已经很强了」)是个陷阱,不能顺着说「确实没必要」。合理的辩护是:本地化翻译的核心诉求是术语一致性和可复用性,而不是单句翻译质量——同一个词在同一产品里必须始终译成同一个说法,历史译法要能被查到并复用,这属于「检索已有译文」而不是「重新生成」。ES 在这里承担的是记忆库的角色(可以是关键词加向量混合检索),召回后作为少样本或术语约束喂给模型,既保证一致性也降低成本。接着要能答出量级(召回几条、库多大、每天新增多少)——答不出量级就说明没真正负责过这条链路。

「翻译风格会趋同还是扩散」是个有意思的追问。 有明确结论可讲:如果每次都用「检索到的历史译法」作为参照并写回库,系统会形成正反馈,风格趋同(好的方面是术语稳定,坏的方面是错误也会被固化并放大);如果放任模型自由生成又不过滤,风格会扩散。所以质量门必须有:入库前做术语一致性校验、与现有记忆的冲突检测、低置信度人工复核,并定期抽样审计;译文不应该「翻译完直接写 ES」,而应经过校验环节再入库。