完美世界 AI-Agent开发 一面
1、实时生成的聊天代理模型,如果线上出问题了,怎么定位
这种问题一般先按链路拆。如果是实时生成类聊天代理,通常一条请求会经过网关、会话层、Prompt 拼装、模型推理、工具调用、结果后处理和流式返回几个阶段。线上出问题时,先判断是全量故障还是部分故障,是所有请求都失败,还是只有某一类请求延迟高、返回空、内容异常。
定位时先看监控和日志。监控上看 QPS、平均延迟、P95/P99、错误率、超时率、GPU 利用率、显存占用、容器重启次数。日志上重点看 request_id,把一次请求链路串起来,看是卡在 Prompt 构造、模型推理、下游工具调用,还是 SSE/流式返回阶段。如果是模型输出异常,要回看原始输入、系统提示词、采样参数和上下文长度。如果是服务异常,要看是不是线程池打满、连接池耗尽、GPU OOM、依赖接口超时或者限流。
常见处理顺序是先止损,再定位,再复盘。止损包括降级到小模型、关闭复杂工具链、限制最大上下文长度、切换备用服务或者直接熔断非核心功能。定位完之后再补监控项和告警阈值。
2、给一个电路板串联,每段有测试点,怎么快速判断哪个点位出了问题
这个题本质上考的是 二分定位思路。如果多个模块串联,知道输入正常、输出异常,那最直接的方法不是一个点一个点顺序排查,而是优先找中间测试点。如果中间点正常,说明问题在后半段;如果中间点异常,说明问题在前半段。这样每次把排查范围缩小一半,效率比线性扫描更高。
如果一共有 6 个点位,可以先测中间,比如第 3 或第 4 个点。通过输入输出和中间点状态,不断缩小可疑区间。这和排查服务链路也很像,比如一条请求经过网关、业务层、检索层、推理层、后处理层,也可以用这种方式快速定位瓶颈或者故障段。
def find_first_bad(points):
left, right = 0, len(points) - 1
ans = -1
while left <= right:
mid = (left + right) // 2
if points[mid] == "bad":
ans = mid
right = mid - 1
else:
left = mid + 1
return ans
points = ["good", "good", "good", "bad", "bad", "bad"]
print(find_first_bad(points))
3、模型回复速度慢的原因有哪些
模型回复慢一般分成三类原因。第一类是 推理前 的问题,比如 Prompt 太长、历史上下文太多、RAG 检索返回内容太多、请求排队严重。第二类是 推理中 的问题,比如模型参数量大、GPU 资源不足、batch 不合理、KV Cache 使用不佳、并发高导致显存抖动、量化和算子优化没做好。第三类是 推理后 的问题,比如工具调用链太长、结构化解析失败重试、流式输出实现不好、后处理逻辑过重。
如果从指标上看,首 token 慢通常更偏前处理和排队问题;如果首 token 正常但整体输出慢,更多是解码速度慢或者 max_tokens 过大。另外 temperature、top_p 这些采样参数不会决定性影响速度,但上下文长度、模型大小、并发数、显卡类型影响会非常明显。
4、聊天代理为什么会拆成多个模块
聊天代理拆模块主要是为了职责清晰、便于扩展和便于排障。单体式实现虽然一开始写起来快,但线上一复杂就很难维护。通常会拆成输入处理、会话管理、Prompt 构造、模型推理、工具调用、记忆管理、结果后处理几个模块。
比如输入处理负责清洗用户输入和多模态内容;会话管理负责上下文拼接和状态维护;Prompt 模块负责系统提示词、角色设定和工具描述;推理模块负责和大模型服务交互;工具模块负责搜索、数据库、知识库、业务接口;后处理模块负责格式化、敏感内容过滤和结果裁剪。拆开之后每一层都能单独监控、单独测试,也更适合服务化部署。
5、前端、后端、大模型三个模块一般怎么协作
前端主要负责用户交互、输入展示、流式渲染和多轮会话承接。后端主要负责业务编排、鉴权、日志、状态管理、工具调用和请求转发。大模型模块负责理解、生成、规划和必要时的函数调用决策。
常见架构是前端把请求发到后端,后端完成上下文组装、业务校验和工具注册,再调用模型服务。如果模型决定调工具,后端执行工具后把结果回填,再继续让模型生成最终答案。所以严格来说,前端不应该直接和大模型深度耦合,核心编排通常在后端。
一个极简流程可以写成这样:
def frontend_send(user_input):
return backend_handle(user_input)
def backend_handle(user_input):
prompt = f"用户问题: {user_input}"
llm_result = call_llm(prompt)
return llm_result
def call_llm(prompt):
return f"模型返回: {prompt}"
print(frontend_send("帮我生成一个游戏 NPC 设定"))
6、两个地方访问服务,法国返回速度正常,美国响应慢,可能哪里有问题
这种问题要从网络路径和服务负载两边一起看。如果法国正常、美国慢,先怀疑跨区域链路质量、DNS 解析、CDN/边缘节点策略、机房距离、出口带宽、TLS 握手延迟和中间代理转发问题。如果只有美国慢,而服务端资源整体正常,网络链路问题概率更高。如果美国请求量更大,也可能是某个区域入口负载不均、限流策略、WAF 或网关配置不同导致的。
排查一般看几个指标:客户端到服务端的 RTT、TCP 重传率、握手时间、DNS 时间、TTFB、区域流量分布、不同节点的错误率。再结合 traceroute、mtr、ping、curl 分阶段测。如果是应用层问题,还要看是不是美国区请求命中了某个慢节点或者缓存未命中。
7、介绍一下你对 Docker 的理解
Docker 本质上是一种容器化技术,用来把应用和它的运行环境一起封装,保证“开发环境能跑,测试环境也能跑,线上环境还一样能跑”。它不是虚拟机,不需要完整模拟一套操作系统,而是利用 Linux 的 namespace 和 cgroup 做资源隔离和限制,所以启动更快、资源更轻。
对 AI 服务来说,Docker 的价值很明显。一是能把 Python 版本、依赖库、CUDA 环境、推理框架一起打包,减少环境不一致问题;二是方便部署和扩容;三是适合和 Kubernetes 配合做弹性调度。不过 Docker 只是容器,不负责真正的集群治理,服务治理、滚动更新、自动扩缩容一般是编排系统负责。
一个简单的 Dockerfile 例子:
FROM python:3.10-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"]
8、Docker 代码分治是怎么实现的
如果这里说的是 Docker 里的“分层”和“模块化构建”,本质上是通过镜像分层和多阶段构建来实现的。Docker 镜像不是一个整体大文件,而是一层一层叠起来的。比如基础环境一层、依赖安装一层、业务代码一层。这样如果代码改了但依赖没变,就只需要重建后面的层,前面的层可以复用缓存,加快构建速度。
如果是从服务设计角度理解“分治”,那就是把不同职责拆到不同容器。比如网关容器、Agent 编排容器、检索容器、推理容器、监控容器分别独立部署。这样某个模块出问题不会直接影响全部服务,也方便独立扩缩容。
一个多阶段构建例子:
FROM python:3.10 AS builder WORKDIR /app COPY requirements.txt . RUN pip install --prefix=/install -r requirements.txt FROM python:3.10-slim WORKDIR /app COPY --from=builder /install /usr/local COPY . . CMD ["python", "app.py"]
9、全栈地思考,怎么构建生成式乙女游戏
这种题更偏业务架构理解。如果做生成式乙女游戏,不能只盯着大模型本身,要把内容生成、角色设定、剧情推进、用户状态、资产生成和前端交互一起考虑。
最上层是产品层,包括角色卡、世界观、剧情线、互动方式和付费点。中间是 AI 能力层,包括人物对话生成、情绪建模、长期记忆、剧情分支控制、语音合成、立绘或 3D 角色生成。下面是工程层,包括会话状态管理、Prompt 编排、剧情状态机、审核过滤、缓存、日志和推荐系统。如果是 3D 方向,还要有动作生成、表情驱动、场景资源管理和实时渲染。
这里最难的不是“能不能生成”,而是“生成内容是否稳定、角色是否一致、长期互动是否连续”。因为乙女游戏用户很在意角色设定一致性和情绪连续性,所以必须有角色记忆、剧情约束和人格设定,不能完全放任模型自由发挥。
10、在现实生活中,像 deepseek 那样的深度思考例子是什么
深度思考本质上不是回答得长,而是把复杂问题拆开,逐步验证,最后得出更可靠的结论。现实里比较像的例子是排查线上故障。比如服务突然变慢,不能直接拍脑袋说是模型不行,而是要先看监控,再拆链路,再看区域差异、上下游依赖、资源占用、日志异常,最后定位根因。这和大模型里的 reasoning 类过程很像,都是先分析,再推断,再验证。
再比如做技术选型。不是看到一个新框架火就直接上,而是先分析业务场景、团队能力、成本、维护复杂度、性能收益和迁移风险,再决定要不要用。这种“分解问题—列出假设—逐步验证”的过程,本质上就是深度思考。
11、RAG 是什么,核心问题有哪些
RAG 是 Retrieval-Augmented Generation,也就是检索增强生成。它的核心思想是先从外部知识库里检索相关内容,再把检索结果和用户问题一起喂给大模型,让模型基于证据回答问题。这样做的主要价值是补充模型参数里没有的知识、接入私有数据、降低幻觉、支持知识实时更新。
完整流程一般包括文档解析、分块、向量化、索引构建、检索、重排和生成。其中最容易出问题的地方有三个。第一是 chunk 切分不合理,信息被切碎或者上下文过长;第二是 embedding 模型不匹配,召回不准;第三是生成阶段约束不够,模型明明没检索到证据却还在编答案。
一个简化版检索示例:
documents = [
"角色A是学院学生会会长,性格冷静。",
"角色B擅长音乐,设定是温柔型人物。",
"主线剧情发生在未来都市。"
]
def retrieve(query, docs):
scored = []
for doc in docs:
score = sum(1 for ch in query if ch in doc)
scored.append((score, doc))
scored.sort(reverse=True)
return [x[1] for x in scored[:2]]
query = "学生会会长是谁"
print(retrieve(query, documents))
12、Function Calling 和 AI Agent 的关系是什么
Function Calling 是让模型先输出结构化的函数调用请求,比如函数名和参数,再由程序执行真实工具。AI Age
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏聚焦 AI-Agent 面试高频考点,内容来自真实面试与项目实践。系统覆盖大模型基础、Prompt工程、RAG、Agent架构、工具调用、多Agent协作、记忆机制、评测、安全与部署优化等核心模块。以“原理+场景+实战”为主线,提供高频题解析、标准答题思路与工程落地方法,帮助你高效查漏补缺.

查看17道真题和解析