淘天 AI应用开发 一面
1. 先做一个简短的自我介绍,重点讲你和 AI 应用开发最相关的经历
2. 讲一下你做的这个Agent项目介绍一下
核心链路一般是用户输入问题后,先做意图识别,再判断是走直接生成、知识检索还是工具调用。技术上可以拆成接入层、编排层、检索层、模型层和观测层。编排层负责 Prompt 模板、上下文管理和工具路由;检索层负责文档切片、向量检索、关键词检索和重排;模型层负责对接通用大模型和总结模型;观测层负责 trace、耗时、召回质量和最终答案质量。
public Answer handle(QueryReq req) {
Intent intent = intentService.detect(req.getQuestion());
if (intent == Intent.RAG) {
List<Chunk> chunks = retriever.search(req.getQuestion());
String context = contextBuilder.build(chunks);
return llmClient.chat(req.getQuestion(), context);
}
if (intent == Intent.TOOL) {
return toolExecutor.execute(req);
}
return llmClient.chat(req.getQuestion(), "");
}
3. 你在这个项目里具体做了什么,最难的点在哪
可以重点讲自己不是只调了个 API,而是把链路真正做起来了。比如负责了文档上传解析、Chunk 切分、Embedding 入库、混合检索、Rerank、上下文压缩、多轮会话和结果缓存,还做了线上指标埋点和失败重试。最难的点通常不在“模型能不能答”,而在“答得稳不稳、快不快、成本高不高、能不能追溯”。如果讲具体问题,可以说遇到过长文档召回不准、工具调用乱跳、多轮对话上下文失控、热点问题重复生成导致 RT 抖动这些问题,然后讲你怎么逐个解决。
4. 你是怎么设计 Agent 循环执行链路的
Agent 循环的核心是规划、执行、观察、再规划。一般会先让模型基于 system prompt 和当前上下文决定下一步动作,这个动作可能是直接回答,也可能是调用某个工具。工具执行后把 observation 回灌到上下文里,再让模型继续判断是否结束。线上不会无条件放开循环,通常会限制最大步数、最大 token、单步超时和总耗时,还会记录每一步的工具调用日志和中间推理状态,避免死循环和成本失控。
for (int i = 0; i < maxSteps; i++) {
Action action = planner.plan(context);
if (action.isFinish()) {
return action.getFinalAnswer();
}
Observation obs = toolExecutor.run(action);
context.append(obs);
}
throw new RuntimeException("agent step overflow");
5. 你这个 Agent 是基于 Spring AI 做的,还是自己封装的
如果用 Spring AI,可以说它帮你统一了模型接入、Prompt、Embedding、向量库适配和 Tool Calling,比较适合快速搭框架。但真正落地时通常还要自己封装一层,因为线上会涉及多模型路由、缓存、降级、埋点、灰度、审计和计费,这些业务逻辑往往不能直接靠框架原生能力解决。比较稳妥的回答方式是:底层用 Spring AI 做基础能力接入,上层自己做了一层业务编排和观测封装。
6. system prompt 你是怎么设计的,怎么防止它失控
system prompt 设计时最重要的是边界。要明确告诉模型身份、任务目标、输出格式、禁止事项、工具调用约束和拒答策略。不要把所有规则写成一大段,而是拆成角色说明、执行规则、工具规则、输出协议这几部分。防失控一般靠三层:Prompt 约束、工具层白名单、执行层熔断。比如限制只能调用注册工具、必须返回 JSON 结构、无法确认时优先澄清而不是编造。
你是一个企业知识助手。 你的目标是基于提供的上下文回答问题。 如果上下文不足,请明确说明信息不足,不要编造。 如需调用工具,必须输出标准 tool_call 结构。 最终答案需要简洁、可执行、避免主观猜测。
7. 调用 LLM 的完整链路你怎么讲
完整链路一般包括请求预处理、上下文组装、模型路由、推理调用、结果后处理和观测埋点。预处理阶段会做参数校验、敏感词过滤、会话信息补齐;上下文组装会拼接 system prompt、历史消息、检索内容和工具描述;模型路由会根据任务类型、成本和时延选择模型;结果返回后还会做格式校验、引用补全、敏感内容兜底和缓存写入。真正难的地方是链路上的每一跳都要可观测,不然线上出了问题很难定位。
8. tool 是什么时候交给模型的,什么时候真正执行
一般不会在一开始就执行工具,而是先把工具 schema 和描述告诉模型,让模型先判断当前任务是否需要调用工具。模型如果决定调用,会返回工具名和参数,服务端再做参数校验、权限校验和实际执行。也就是说,模型负责“决定调不调、调哪个、传什么”,服务端负责“能不能调、怎么调、调完怎么回灌”。这里一定不能把模型输出直接无脑执行,否则会有越权和误调用风险。
9. 模型返回工具调用结果后,你怎么判断接下来该调用哪个 tool,还是直接结束
一般有两种方式。一种是让模型继续根据 observation 自主规划下一步;另一种是由服务端加入状态机约束,比如某类任务最多只能调用一次检索工具,再调用总结工具,不能无限循环。线上更推荐“模型规划 + 服务端约束”结合。因为纯模型自治灵活,但不稳定;纯状态机稳定,但泛化能力差。真正可用的设计通常是给模型一定自由度,但关键路径由服务端兜底。
10. 多轮对话里的记忆压缩你是怎么做的,摘要怎么生成
多轮对话里不能把所有历史都原样塞进上下文,否则 token 会迅速膨胀。常见做法是保留最近几轮原始对话,再把更早的历史压缩成摘要。摘要不是简单截断,而是保留用户目标、关键事实、约束条件、已经执行过的动作和未完成任务。摘要生成可以在对话达到一定轮数后异步触发,也可以在 token 接近阈值时触发。为了减少摘要漂移,通常会固定摘要模板,不让模型自由发挥太多。
public String compressHistory(List<Message> messages) {
String prompt = """
请将下面的历史对话压缩为结构化摘要,保留:
1. 用户目标
2. 已知事实
3. 已执行动作
4. 待解决问题
""";
return llmClient.summary(prompt, messages);
}
11. 千问这类模型的上下文窗口大小会影响什么,工程上怎么处理
上下文窗口大小直接影响你能塞进模型的 system prompt、历史对话、检索内容和工具描述总量。窗口不够时最先受影响的是 RAG,因为召回到的高质量片段可能放不进去。工程上一般不会单纯追求大窗口,而是做内容裁剪、上下文压缩、chunk 去重、重排截断和摘要合并。还要考虑成本问题,因为上下文越长,输入 token 成本越高,延迟也会明显上升。
12. 你把文档上传到知识库后,RAG 检索的全流程是什么
标准流程是文档上传、解析清洗、切片、Embedding、入向量库、构建关键词索引、查询改写、多路召回、重排、上下文构造、答案生成和引用回显。这里每一步都可能影响最终效果。比如切片太大召回粒度不够,太小上下文又容易碎;Embedding 模型不匹配会导致相似度虚高;重排不做的话,很容易把相关性弱但向量距离近的片段塞进模型里。
13. 文档切分你是怎么做的,用的是什么工具,切分粒度怎么定
切分不是简单按固定字数截断,实际要结合标题层级、段落边界、表格、代码块和语义完整性。常见做法是先做结构化解析,再按“标题 + 段落”优先切,超长段再按句子滑窗切。粒度一般需要实验,不同场景不一样。知识问答如果资料偏规范文档,chunk 可以大一点;如果是 FAQ、产品说明、接口文档,chunk 通常要更细。工具上可以自己写,也可以基于 LangChain、Spring AI 或开源文本切片器做二次封装。
14. 你们检索效果怎么评估,有什么指标,分别是什么意思
检索侧常见指标有 Recall@K、Precision@K、MRR、NDCG。Recall@K 看前 K 条结果里有没有把正确片段召回上来;Precision@K 看前 K 条里有多少是真的相关;MRR 更关注第一个正确结果排得靠不靠前;NDCG 更适合评估有等级相关性的排序质量。线上不会只看一个指标,因为召回和排序往往要一起看。另外还会加人工评测,看答案是否忠于上下文、是否能引用到正确片段。
15. 你的第二个项目可以怎么讲,才能显得不是套壳应用
可以换成一
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏聚焦 AI-Agent 面试高频考点,内容来自真实面试与项目实践。系统覆盖大模型基础、Prompt工程、RAG、Agent架构、工具调用、多Agent协作、记忆机制、评测、安全与部署优化等核心模块。以“原理+场景+实战”为主线,提供高频题解析、标准答题思路与工程落地方法,帮助你高效查漏补缺.
查看18道真题和解析