找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4124

积分

0

好友

532

主题
发表于 1 小时前 | 查看: 3| 回复: 0

“让你负责一个生产级 Agent,你会怎么设计?”

如果要你来回答,你会怎么说?是不是一上来就开始背诵 ReAct、Function Calling、Skills 这些概念?如果真这么做了,面试官听了估计会直摇头。他要是没摇,我都要替他摇了(手动狗头)。

这道题其实只是冰山一角。下面是读者反馈来的真实面试题,有需要的小伙伴可以收藏起来慢慢琢磨。别光死记硬背,试着把它们背后的逻辑吃透。

面试题列表:包括长期记忆、上下文压缩、生产故障排查等详细的Agent工程化问题

(全程干货,系好安全带,我们出发了~)

文中项目用的是 PaiCLI,一个类 Claude Code 的终端 Agent,已在 GitHub 开源,感兴趣的小伙伴可以去看看。

PaICLI v0.1.0终端运行截图,展示其支持的MCP、Skills等组件及AI模型的思考过程

源码和面试题都在这儿了,主打就是一个真诚。

01. 设计思路:三条路径,一套基础设施

面试官老王开门见山:“上一个项目里,最大的技术挑战是什么?”

“是让三种 Agent 运行模式共享同一套基础设施。” 我解释道。拿 PaiCLI 来说,它支持 ReAct 主循环、Plan-and-Execute(先规划后执行)以及 Multi-Agent 多角色协作。这三条执行路径,从逻辑上看完全不同,但它们必须共用一套工具注册表、记忆系统、安全审批和审计日志。

三条Agent执行路径共享一套基础设施的架构图:ReAct、Plan-and-Execute、Multi-Agent共用工具、记忆及安全审批层

举个例子,文件写入操作在 ReAct 模式要触发审批弹窗,在 Multi-Agent 模式下同样也要。记忆机制也是如此,ReAct 里存下的用户偏好,如果切到 Plan-and-Execute 模式就读不出来了,那就说明底层的 Harness(协调层)没做好。

这一通分析下来,其实是在向面试官阐述你对 AI Agent 工程化架构的理解深度,而不是在背诵定义。

02. 上下文压缩:原始记录到底还要不要?

老王点点头,继续追问:“那咱们聊聊上下文压缩。假设前面10轮对话都被总结成了一个摘要,那原始的聊天记录还需要保留吗?”

“不需要了。” 我回答得很干脆。一旦压缩完成,旧的原始消息就会被清空,系统中只保留生成的摘要和最近几轮的完整对话记录。

Map-Reduce上下文压缩流程图:旧消息被分片、摘要、合并后,注入摘要并回补近期记录,最终完成上下文压缩

压缩策略采用 Map-Reduce(分片摘要),分三步走:

  1. 切片:把旧消息按每 5 条一组,切成多个小片段。
  2. Map(摘要):让模型分别对每个片段做摘要,要求它必须保留用户的需求与意图、已执行的操作与结果,以及做出的决策与结论。
  3. Reduce(合并):等所有片段的摘要都生成完,再把它们合并成一份最终的整体摘要。

压缩完成后,清空旧消息,将最终摘要作为一条新记录写回对话历史,然后把最近 3 轮完整对话原样拼回去。这样,模型在下一轮看到的上下文就是 “摘要 + 最近几轮完整对话”,既有全局记忆,又不超 Token 限制,还能保留最新的操作细节。

03. 长期记忆:爱吃辣还是不能吃辣?

“那这就有个很现实的问题了。”老王笑了笑,“用户一个月前跟你说他喜欢吃辣,一周前又说不能吃辣。现在你该怎么判断他到底能不能吃?”

“核心是‘时间戳加权’。”我先给出结论。两条看似矛盾的记忆都会被保留,不强行合并,也不直接删除旧的。关键在于检索时的排序 —— 按照时间衰减来打分,越新的记忆权重越高。

记忆时间衰减与新鲜度排序示意图:展示记忆权重随时间下降的曲线,以及根据新旧程度进行排序的列表

PaiCLI 的衰减逻辑是 24 小时内,记忆权重从满分衰减到一半。所以,一周前那条 “不能吃辣” 的记录在检索排序中,天然就会排在一个月前 “爱吃辣” 的记录前面。模型第一时间拿到的,永远是最新的状态。

不直接删旧记录,是因为删除操作不可逆。万一用户“不能吃辣”只是因为临时过敏,过两周又恢复了呢?保留变化轨迹,反而能让模型做出更准确的长线判断。

04. 记忆更新:一定要用向量数据库吗?

“既然记忆存在库里,你是怎么更新它们的?” 老王的节奏很快。

如果用向量数据库存记忆,更新流程通常是先语义检索找到旧记录,删掉旧向量,对新内容重新做向量化(Embedding),再把新向量写回去。这里有个工程坑:两个会话同时修改同一条记忆时,会发生版本冲突,需要加乐观锁或时间戳校验。

但 PaiCLI 的记忆系统并没有引入向量数据库。

记忆检索方式对比图:关键词匹配适合小规模记忆库,精确快速;向量检索适合大规模知识库,语义更强

记忆库里存的都是用户偏好、项目信息这类事实数据,总量通常在几百到上千条。这个体量下,用关键词匹配其实就够了 —— 毫秒级出结果,可解释、可调试,哪条记录被召回、为什么被召回,一目了然。

向量数据库更适合作 RAG 知识库,面对动辄几十个G的非结构化文档,只有语义检索才能应付。

05. 压缩的代价:如果“500元”丢了怎么办?

老王皱了皱眉,直击要害:“上下文压缩会不会丢掉关键信息?”

“会。”我坦白承认,“这是压缩的代价,世上没有真正的无损压缩。但我们可以通过三层防护机制,把信息丢失的风险控制在可接受的范围内。”

三层信息保护机制示意图:第一层事实提取、第二层摘要指令、第三层近期缓冲,层层递进保护关键信息

  • 第一层:事实提取。在触发压缩前,先从旧对话中把那些跨会话依然有价值的稳定事实提取出来,存进长期记忆。这部分数据不参与压缩,所以它不会丢。
  • 第二层:摘要指令。压缩的提示词会严格约束模型,要求它必须保留用户的意图、已完成的操作、做出的决策结论以及关键的技术细节。单片摘要控制在 200 字以内,合并摘要控制在 300 字以内,别让它自由发挥。
  • 第三层:近期缓冲。不管怎么压,最近几轮的完整对话原样保留,绝不压缩。确保最新的操作步骤和上下文始终在线。

他紧接着追问:“那给你一个具体场景,用户买商品花了 500 元,压缩后偏偏把‘500元’这个金额丢了,怎么办?”

“这就得回到第一层的‘事实提取’了。”

关键数据防丢失保护链示意图:展示压缩前通过事实提取存入长期记忆,压缩后通过摘要和恢复进行兜底的双保险机制

在压缩之前,系统会尝试从对话中提取稳定事实。像“花了500元购买了某商品”这种包含具体金额的交易行为,会被识别为持久事实,直接写进长期记忆。长期记忆不受上下文压缩的影响,模型随时都能调取。

退一步讲,就算事实提取阶段漏掉了这条信息,摘要提示词里“必须保留做出的决策和结论”这条兜底规则,也会引导模型在摘要中保留交易金额。长期记忆 + 摘要指令,这套双保险虽然不敢打包票万无一失,但比直接无脑压缩要可靠得多。

06. 重要信息筛选:三层过滤规则

“你怎么定义哪些内容算‘重要信息’?” 老王继续深挖。

“一句话就能概括:跨会话仍然成立、未来复用仍有价值的稳定事实。” 落地到系统中,PaiCLI 通过三层过滤规则来判断。

重要信息三层过滤规则图:先排除临时任务和推测性内容,最终只保留包含偏好、身份等持久信号的稳定事实

  1. 排除临时任务:句子开头如果是“帮我”、“创建”、“删除”、“本次任务”这类前缀,说明它是一次性指令,果断过滤掉。
  2. 排除推测性内容:包含“可能”、“应该”、“猜测”、“也许”等词的信息,不是确定事实,也过滤掉,避免噪声积累。
  3. 保留持久信号:包含“偏好”、“习惯”、“项目”、“配置”、“版本”、“技术栈”、“约定”等关键词的,十有八九是跨会话都有价值的核心事实,必须保留。

07. API 异常处理:重试也得讲策略

“线上环境,API 要是超时或者报错了,你怎么解决?” 老王的提问开始转向运维。

“核心机制是指数退避加重试,并引入随机抖动(Jitter)。”我把策略掰开来讲。默认重试 3 次,等待间隔呈指数级增长,比如 500ms、1s、2s,上限 30s。每次等待都加上约 20% 的随机抖动,防止多个客户端在发生故障的同一时刻集中重试,将服务端瞬间打垮。

重试不是万能的,必须严格区分可重试和不可重试的错误。

API重试策略决策流程图:从请求失败开始,根据错误类型和Retry-After头部信息决定重试策略,引入指数退避和随机抖动

可重试的情况

  • HTTP 状态码 408(请求超时)、429(被限流)、500/502/503/504(服务端故障)。
  • 网络层异常,如连接超时、连接被重置、DNS 解析失败、流式传输中断。

不可重试的情况

  • SSL 证书错误,这是安全问题,重试纯属浪费。
  • JSON 解析错误,说明返回的格式就是错的,重试毫无意义。
  • 线程中断,代表用户主动取消了任务。

另外还有一个工程细节值得留意:如果服务端返回了 Retry-After 头,重试间隔必须取“计算出的退避值”和“服务端指定值”中的较大者。服务端说等 5 秒,咱就老老实实等 5 秒。

08. Token 消耗排查:从监控到修复的完整链路

“如果发现 Token 消耗得特别快,你怎么排查?” 老王步步紧逼。

“先看数据,再定位原因。”PaiCLI 每轮模型调用结束,都会自动输出一份详细的 Token 统计报告,包含总输入、总输出、缓存命中以及可用预算等指标。

Token消耗排查流程图:展示从输出突增、上下文变长、历史消息重复注入三个方向进行排查和修复的路径

排查的思路就是从统计报告里找峰值异常。常见原因主要有三个:

  • 工具输出过长。某次 Shell 命令输出了几万字符全被塞进了上下文,Token 消耗瞬间拉满。排查时要去寻找这种“爆表”的直接调用。
  • 压缩触发太晚。系统默认在可用预算的 90% 才触发压缩,如果一轮里工具调用过多,可能在压缩前就超了。把触发阈值调低到 80% 就能缓解。
  • 上下文膨胀:同一份信息被反复检索、反复注入。这种情况需要去检查记忆检索的结果去重机制是否生效。

09. 渐进式披露:按需加载才是王道

“看过你们的 Skill 机制,讲讲它的‘渐进式披露’是怎么回事?” 老王抛出一个架构题。

“渐进式披露本质上就是按需加载。不用的 Skill 不占地方,用到时再展开,最大程度节省 Token。” 具体执行分三个阶段。

Skill渐进式披露三阶段图:从启动期的索引注入,到使用时的按需加载,再到运行中的缓冲注入,逐步展开

  1. 启动期,索引注入。Agent 启动时,只把所有启用 Skill 的名称和一句话描述注入 System Prompt。用最少的字数让模型知道“我有哪些能力”。
  2. 使用时,按需加载。模型在对话中判断当前任务需要用哪个 Skill,再主动调用 load_skill 工具,加载这个 Skill 的完整工作指引。
  3. 运行中,注入缓冲。加载过的完整指引会放入一个缓冲区,下一轮对话自动拼接到用户消息前面。缓冲区最多同时保留 3 个 Skill,超出的按 LRU(最近最少使用)算法淘汰。

那为什么不直接把所有 Skill 的完整指引都塞进上下文呢?我给他算了一笔账:假设 20 个 Skill,每个平均 2000 Token,全部常驻 System Prompt 就是 4 万 Token。

20个Skill的全量加载与渐进式披露对比图:全量加载消耗40000 Token/轮,渐进式披露仅需2000-4000 Token/轮

这 4 万 Token 是每轮对话都要花的,可实际上一轮对话可能就用到 1 到 2 个 Skill。渐进式披露只加载需要的,成本能降下一大截。

10. 智能客服架构:四层设计与四个维度

老王呼了口气,抛出了最终的场景题:“现在,你来设计一个智能客服 Agent,要求能根据用户提问,给出尽可能准确的回答。说说你的设计思路。”

“我会把它分为四层架构。”

智能客服Agent四层架构图:从意图识别、RAG知识检索到工具执行,最后低置信度任务由人工兜底处理

  1. 意图识别:用户的第一句话进来,先做个路由,分清他是来产品咨询、售后投诉、退换货还是查物流的。分类结果决定了后面该调哪些工具、查哪些知识库。
  2. RAG 知识检索:接上产品文档、FAQ、退换货政策等知识库。如果检索不到确凿的证据,模型绝对不能瞎编,必须回复“这个问题我不太确定,帮您转接人工客服”。
  3. 工具执行:查订单、查物流、发起退款这些操作,Agent 需要调用对应的后端接口。拿到的接口返回结果,再由模型组织成用户能看懂的大白话。
  4. 人工兜底:当模型连续两轮给不出有效回答,或用户明确表示要找人,立即无缝转接人工。自动处理是有边界的,人工兜底的安全绳不能少。

在四个层面的设计之外,还得兼顾四个维度的考量。

智能客服设计四维度清单:准确性、延迟、安全性和兜底策略是保障服务质量缺一不可的四个关键方面

  • 准确性:知识库的分块策略要合理,太大了语义模糊,太小了丢失上下文,通常 512 到 1024 Token 一个块,带 20% 重叠。并建议引入 Reranker(重排模型)做二次排序,因为语义相似不等于问题相关。
  • 延迟:流式输出是基本体验,不能让用户干等。高频问题的答案可以提前缓存起来,命中缓存直接返回,不走模型。
  • 安全性:严防提示词注入,所有工具返回的内容都要按不可信数据处理。对用户的手机号、地址等敏感信息,进行脱敏处理。
  • 兜底策略:意图分不清的、知识库查不到的、模型不确定的,全部走人工。宁可多转几次人工,也绝不让模型凭空编造答案。

11. 大促高并发:五道防线应对流量洪峰

“既然是电商场景,那大促的时候,流量尖刺你怎么解决?” 老王问出了最后一个,也是最考验架构功力的问题。

“核心思路就六个字:削峰、分流、兜底。”我拿起笔,在白板上画出五道防线。

大促流量应对五道防线图:通过消息队列削峰、模型分层、热点缓存、限流和熔断降级来保障核心服务稳定

  1. 消息队列,削峰填谷:用户请求先进消息队列,Worker 按容量慢慢消费。LLM 调用本身就慢,同步硬扛只会崩溃。队列解耦后,前端可以秒级响应“正在处理中”,后端按自己的节奏来。
  2. 模型分层:简单问题走小模型或规则引擎,复杂问题才上大模型。像“我的快递到哪了”这种查个接口就能回复的,根本无需动用“牛刀”。
  3. 热点缓存:大促期间,像“什么时候发货”、“满减规则是什么”这类高频问题,提前生成标准答案缓存起来。命中缓存直接返回,完全不消耗模型算力。但要记住,缓存的有效期不能设太长,活动规则随时会变,缓存必须支持手动失效。
  4. 限流保护:对每个用户每分钟的请求数设上限。超出上限就返回“当前咨询量较大,请稍后再试”。这提示虽然有点不近人情,但总比把系统搞崩了强。
  5. 熔断降级:当 LLM 服务端的响应延迟超过阈值或错误率飙高,自动触发熔断,切换到模板答案或直接转人工,保障核心服务不中断。

以前面试考的是 CRUD 和中间件参数,现在考的是上下文怎么压缩、记忆怎么管理、Token 怎么省、流量洪峰来了怎么扛。

概念谁都会背,但如何把这些概念落地成生产环境里跑得起来的工程细节,这才是面试官真正想听到的东西。Agent 的工程化之路才刚刚起步,许多问题还没有标准答案。谁先把系统里的坑都踩过一遍,谁就有了别人抢不走的底气。

加油吧。

如果你对 Agent 的工程实践、面试求职 心得或者 开源项目 的具体落地感兴趣,欢迎常来 云栈社区 看看,这里有跟你一样在技术上“死磕”的伙伴们。




上一篇:Claude Code系统提示词精简80%:模型越强,越需要给AI松绑
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-7-24 08:36 , Processed in 0.823275 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表