Skip to content

AI智能体应用开发面试题 ​

生成时间:2026-06-12 01:45


【面试题】1. Agent在调用大模型API时,你们是怎么做"模型降级策略"的?比如主力模型挂了或者响应太慢,怎么无缝切换? ​

【标准答案】

我们的模型降级分三层,核心原则是用户无感降级:

第一层:超时自动切换。 主力模型(比如GPT-4o)设置超时阈值,一般5-8秒。超时后自动路由到备选模型(GPT-4o-mini或国产模型如DeepSeek-V3)。切换逻辑封装在统一的LLM Gateway里,上层业务不感知。

第二层:任务分级。 不是所有任务都需要最强模型。我们把任务分成三级:

  • 核心任务(生成最终答案、复杂推理)→ 用强模型,失败重试+降级
  • 辅助任务(摘要、分类、改写)→ 直接用便宜快速的模型
  • 兜底任务(问候、简单QA)→ 用最小模型

第三层:熔断+告警。 如果某个模型连续N次超时或报错,触发熔断,一段时间内不再请求,直接走备选。同时触发告警通知运维。

实现关键是统一抽象层——所有模型调用走同一个接口,返回格式统一,切换时上层代码零改动。我们用的是自建的LLM Proxy,也可以用LiteLLM这类开源方案快速搭建。


【面试题】2. 你们做Agent项目时,Embedding模型怎么选的?不同的Embedding模型对RAG效果影响有多大? ​

【标准答案】

影响非常大,甚至比换大模型还明显。 我实际对比过,同样的检索逻辑,不同Embedding模型的召回准确率能差20-30%。

选型维度:

一、语言适配。 如果是中文场景,OpenAI的text-embedding-ada-002效果一般,中文语义理解不如BGE系列(BAAI出的)或者M3E。我们实测BGE-M3在中文问答场景的召回率最好。

二、维度和性能。 向量维度越高,精度越好但存储和检索成本越大。比如1536维vs1024维vs768维,要根据数据量和查询QPS权衡。BGE-M3支持1024维,Milvus检索速度快。

三、多语言需求。 如果要中英混检,BGE-M3和Cohere的multilingual模型都支持。

四、部署方式。 OpenAI Embedding API调用简单但要上云、有成本。BGE系列可以本地部署,用Sentence-Transformers框架加载,延迟更低、数据不出域。

实践建议:先花1-2天做Embedding模型对比测试——准备100个典型query和对应的ground truth文档,测不同模型的Recall@5和MRR,用数据说话,别拍脑袋选。


【面试题】3. 情景题:面试官说"我们公司的业务数据很敏感,不能上任何云,包括大模型API也不能调公有云。要搭一套纯本地的Agent系统,你会怎么设计架构?" ​

【标准答案】

完全可以做,而且现在本地化方案已经很成熟了。我的架构思路:

模型层:用开源模型本地部署。推理框架选vLLM或Ollama,模型选Qwen2.5-72B或DeepSeek-V3的量化版本(4bit够用,A100单卡能跑)。Embedding用BGE-M3本地部署。如果对效果要求高且GPU够,可以跑满精度版本。

框架层:Dify开源版私有化部署,或者用LangChain/LangGraph自己搭。Dify的优势是可视化编排,运维团队也能上手改流程。

向量库:Milvus本地Docker部署,数据完全不出网。

知识库更新:内网文档管理系统触发,通过内部消息队列推送到Embedding服务,增量更新向量库。不需要对外开放任何端口。

关键注意点:

  • GPU资源规划:推理+Embedding至少需要2张A100/H800,需要做显存隔离
  • 模型热更新:模型迭代时怎么不停机切换,用vLLM的model swap或者蓝绿部署
  • 降本:非高峰时段可以用小模型,高峰时段切换大模型

一句话总结:本地方案可行,关键是GPU资源和模型选型,框架和工程上没有太大障碍。


【面试题】4. 你在项目中是怎么做"结构化输出"的?大模型返回的JSON不稳定、字段缺失,怎么解决? ​

【标准答案】

这个问题我踩过很多坑,现在的方案已经比较稳定了:

方案一:JSON Schema约束(优先推荐)。 现在主流模型(GPT-4o、Qwen2.5、DeepSeek)都支持response_format=json_object + JSON Schema。直接把期望的输出结构定义成schema传进去,模型严格按照schema输出,字段缺失率能降到5%以下。

方案二:Pydantic + 重试。 用Pydantic定义输出模型,解析失败就重试,最多重试2-3次。每次重试把解析错误信息反馈给模型让它修正。LangChain的with_structured_output和Instructor库都封装好了这套逻辑。

方案三: Few-shot兜底。 在prompt里放2-3个标准输出的示例,比纯文字描述格式要求效果好很多。

方案四:后处理校验+修复。 最终加一层校验:必填字段是否存在、枚举值是否合法、数值范围是否合理。校验失败走默认值或重试。

实际经验:

  • 字段越少越稳定,超过15个字段就容易出现问题,必要时拆成多次调用
  • 枚举值在prompt里列全,比让模型"自由发挥"稳定得多
  • 复杂嵌套结构拆成多次简单调用,比一次输出大JSON更可靠

【面试题】5. Agent项目的"可观测性"你们怎么做?模型调用链路长、工具调用多层嵌套,出问题怎么快速定位? ​

【标准答案】

Agent系统的可观测性和传统Web应用完全不同,因为链路是动态的——每次调用的路径可能都不一样。

我们的方案分三层:

第一层:调用链追踪(Trace)。 每个用户请求生成一个trace_id,贯穿整个Agent执行链路。包括:LLM调用(模型、token消耗、延迟)、工具调用(工具名、参数、耗时、返回状态)、检索调用(query、召回数量、top-5文档)。全部记录到结构化日志里。

第二层:结构化日志。 不是写文本日志,而是写结构化JSON,包含:时间戳、trace_id、调用类型、输入摘要、输出摘要、token数、延迟、是否成功。用ELK或Loki采集,方便搜索和聚合。

第三层:关键指标看板。 核心监控指标:

  • 平均响应延迟(P50/P95/P99)
  • 工具调用成功率
  • LLM输出格式合规率
  • 每次请求的平均LLM调用次数和token消耗
  • 错误率(按错误类型分类)

工具上,如果用LangChain可以用LangSmith,自带trace能力。自建的话,OpenTelemetry+自定义span就行。

关键点:日志要截断——模型输入输出太长不能全存,存摘要+关键信息。token消耗和延迟必须每笔记录,这是成本控制和性能优化的数据基础。


【面试题】6. 你们Agent项目里,Prompt迭代是怎么管理的?几十个Prompt版本怎么避免混乱? ​

【标准答案】

早期吃过亏,prompt改来改去效果反而下降,还不知道是哪次改坏的。 后来建立了版本管理机制:

一、所有Prompt当代码管。 每个prompt单独存一个文件(.txt或.yaml),纳入Git版本控制。禁止在代码里硬编码prompt字符串。

二、版本号+变更记录。 每次修改prompt必须:升级版本号(v1.1→v1.2),在commit message里说明改了什么、为什么改、预期效果。用prompt_id标记每个prompt,方便溯源。

三、评估回归。 每次prompt修改后跑一次回归测试——准备固定的测试集(50-100条),对比修改前后的输出质量。用LLM-as-judge或人工打分。效果下降就回滚。

四、环境隔离。 开发环境用最新版prompt,生产环境绑定特定版本。上线走审批流程,不是随便改了就推。

五、Prompt模板化。 对于结构相似的prompt,用模板引擎(Jinja2)管理变量部分,减少重复维护。

工具推荐:如果是简单管理,Git+目录结构够了。如果prompt数量多、协作人多,可以用PromptLayer或Humanloop这类平台,有版本对比和A/B测试功能。


【面试题】7. 你怎么理解"Agent的安全性"?除了防Prompt Injection,还有哪些安全风险需要关注? ​

【标准答案】

安全是Agent落地的红线,比功能更重要。 除了常见的Prompt Injection,还有几个关键风险:

一、数据泄露。 Agent可能把内部数据(客户信息、商业机密)写入外部API调用、或者直接输出给不当的用户。对策:输出层做敏感信息脱敏(手机号、身份证、公司名),工具调用白名单制——Agent只能调用预注册的工具,不能随意访问外网。

二、越权操作。 Agent如果绑定了高权限的工具(比如发邮件、操作数据库),一旦被恶意诱导,后果严重。对策:工具权限分级,高危操作必须人工审批二次确认。工具执行前做意图校验——这个调用是否在合理范围内。

三、间接注入攻击。 攻击者把恶意指令藏在外部数据里(比如网页内容、上传的文档),Agent检索到后执行了恶意指令。对策:外部数据过安全清洗层,过滤掉可疑的指令模式。

四、模型侧信道。 不同的prompt长度、不同模型的回答差异,可能被用来推断系统使用的模型和内部prompt。对策:统一输出格式,不暴露内部系统信息。

五、对抗样本。 精心构造的输入让Agent绕过安全边界。对策:输入层做安全检测,加一层分类器判断输入是否可疑。


【面试题】8. 情景题:面试官问"Agent在你们线上跑了3个月后,效果开始下降,你怎么排查?怎么解决?" ​

【标准答案】

这个问题我实际遇到过,排查思路是分层定位:

第一步:看数据。 先对比3个月前后的关键指标:任务完成率、用户满意度评分、LLM输出格式合规率、工具调用成功率。定位是全面下降还是特定场景下降。

第二步:分场景分析。 效果下降一般几个原因:

  • 知识库过期:业务知识更新了,但RAG的知识库没同步 → 检查知识库最后更新时间,对比最新业务文档
  • 模型更新:模型厂商更新了版本,输出行为变了 → 检查模型版本是否变了,做回归测试
  • 流量变化:用户群体变了,查询分布偏移 → 分析查询日志,看是不是出现了新的高频query类型
  • 外部服务变化:Agent调用的第三方API变了(接口改版、限流) → 检查工具调用的错误率和响应时间

第三步:针对性修复。

  • 知识库问题 → 增量更新向量库,建立定期更新机制
  • 模型问题 → 锁定模型版本,或重新调优prompt适配新模型
  • 新query类型 → 补充训练数据,扩展prompt的覆盖范围

第四步:建立持续监控。 效果下降的根本原因是缺乏持续监控。我们后来做了:

  • 每日自动抽检50条对话,用LLM打分
  • 关键指标偏离基线超过10%自动告警
  • 知识库有TTL,超过N天未更新就提醒

【面试题】9. 你们Agent系统里,任务拆解(Task Decomposition)是怎么实现的?是模型自己拆还是人工预设流程? ​

【标准答案】

取决于任务类型的确定性程度,我们用的是混合方案:

高确定性任务 → 规则预设。 比如订单查询、报表生成这类流程固定的任务,直接用状态机或工作流定义好步骤。每一步做什么、下一步走哪条分支,都是预先设计好的。优点是稳定可控、可预测,不会出意外。

中等确定性任务 → 模型辅助拆解。 比如用户说"帮我分析这个月的运营数据",模型先判断需要哪些数据源、分析维度、输出格式,拆成子任务后按序执行。但拆解结果是可校验的——有预设的拆解模板,模型在模板范围内填充。

低确定性任务 → 模型自主拆解。 比如开放式的研究任务、创意任务,让模型自主规划。这类任务加执行约束:最大步数限制、每步必须产出中间结果、有检查点可以人工介入。

具体实现上,中等和低确定性任务我们用ReAct框架:模型输出Thought(思考当前进度)→ Action(决定下一步做什么)→ Observation(获取执行结果)→ 循环。加一个全局的步骤计数器和超时控制。

实践体会:能预设的就不要让模型自己规划。模型规划能力强但不稳定,而且每多一步规划就多一次LLM调用,成本和延迟都上去了。


【面试题】10. 你们Agent项目的技术栈是什么样的?为什么这么选?如果让你重新选一次,会有什么不同? ​

【标准答案】

我之前项目的技术栈:

  • 推理:主力用GPT-4o,辅助用GPT-4o-mini做分类和摘要
  • 框架:LangChain + LangGraph做核心编排,Dify做简单业务流程(运营可自助配置)
  • 向量库:Milvus,数据量百万级,支持标量过滤
  • Embedding:BGE-M3,中文场景效果好
  • 部署:K8s + Docker,Agent服务做成微服务
  • 可观测:LangSmith做调用链追踪,Grafana做指标看板
  • 缓存:Redis做query缓存,相同query直接返回(命中率约15-20%)

选型逻辑:技术栈选择主要看团队能力和场景需求,不追求最新最酷,追求可控、可维护、团队hold得住。

如果重新选,我会做几个调整:

  1. 引入本地模型作为降级方案。 纯靠API,厂商一旦涨价或限流就很被动。会加一套vLLM+Qwen本地部署做兜底。
  2. Dify的比重再提高。 很多简单场景不需要写代码,用Dify配置就行,开发和维护成本都低。
  3. Prompt管理工具早点上。 早期prompt散落在代码各处,后期整理很痛苦,一开始就应该用版本管理。
  4. 评估体系更早建设。 上线前就应该准备好测试集和评估流程,别等出了问题才补。

本题库由 AI 面试题生成器 自动生成 覆盖范围:技术基础、架构设计、工具使用、项目落地、场景实操、面试情景问答