大家好,我是二哥呀。
“让你负责一个生产级 Agent,你会怎么设计?”
如果要你来回答,你会怎么回答,如果你上来就开始背 ReAct、Function Calling、Skills 这些,那面试官听了准摇头。
如果他不摇头,我就要对他摇头了(狗头保护。
来来来,这道题还只是冰山一角。
以下是读者真实的面试题目,有需要的小伙伴可以收藏一波慢慢背,哦不,慢慢理解、慢慢学,😄

(全文比较肝,保证大家能学到很多很多,系好安全带,我们粗粗粗粗发~)
content
PS:项目用的 PaiCLI,已在 GitHub 上开源,这是一个类 Claude Code 的终端 Agent,有需要的小伙伴可以学习。

源码和面试题都给你,不藏着不掖着。
咱就这么实诚做人。
01、PaiCLI 项目中遇到的最大挑战是什么?
老王开门见山。“PaiCLI 项目中遇到的最大挑战是什么?”

“PaiCLI 有三种运行模式——ReAct 主循环、Plan-and-Execute 先规划后执行、Multi-Agent 多角色协作。三个模式要共用一套工具注册表、记忆系统、安全审批、审计日志等。”
“举个例子,同一个文件的写入操作在 ReAct 模式下要弹审批,换到 Multi-Agent 模式也要弹。Memory 机制也一样,ReAct 模式下存进去的用户偏好,切到 Plan 模式如果读不到,就是 Harness 没做好。”
02、前 10 轮对话都变成了总结,原始上下文还需要吗?
老王点了点头。“聊一下上下文压缩。如果前 10 轮对话都变成了总结,原始上下文还需要吗?”
“不需要了。压缩完成后,原始的旧消息会被清空,只保留摘要和最近几轮的完整记录。”

PaiCLI 的压缩策略是 Map-Reduce 分片摘要,分三步走。
- 切片。把旧消息按每 5 条一组切成若干片段
- Map 摘要。每个片段独立生成一段摘要,保留用户的需求和意图、已执行的操作和结果、做出的决策和结论
- Reduce 合并。多个片段摘要再合并成一份整体摘要
“压缩完成后,清空旧消息,把摘要作为一条新记录写回对话历史,再把最近 3 轮完整对话原样补回来。模型下一轮看到的就是'摘要 + 最近几轮完整对话',既不超窗口,又保留了最新的操作上下文。”
03、用户一个月前说喜欢吃辣,一周前又说不能吃辣,怎么判断?
“时间戳加权。两条记忆都存着,不强行合并,不强行删旧的。”
“检索的时候按时间衰减打分,越新的记忆权重越高。”
“PaiCLI 的衰减曲线是 24 小时从满分衰减到半分。一周前的'不能吃辣'在检索排序里天然排在一个月前的'喜欢吃辣'前面,模型拿到的第一条就是最新的状态。”

“不直接删旧记录,是因为删除不可逆。万一'不能吃辣'是临时过敏,过两周又恢复了呢?保留旧记录,模型能看到变化轨迹,做出更准确的判断。”
04、记忆存储在向量数据库里,怎么更新已有记忆?
“如果用向量数据库存记忆,更新流程是先按语义检索找到旧记录,删掉旧向量,把新内容重新做向量化(embedding),生成新向量写回数据库。中间要注意版本冲突——两个会话同时改同一条记忆时,需要加乐观锁或者时间戳校验。”
“PaiCLI 的记忆系统没用向量数据库。”

“记忆库里存的都是用户偏好、项目信息这类事实信息,总量可能也就几百上千条。这个量级用关键词匹配就够了——毫秒级出结果,可解释、可调试,哪条被召回、为什么被召回一眼就能看懂。”
“向量数据库适合 RAG 知识库,动辄几十个 G 的文档,只有语义检索才能处理得了。”
05、上下文压缩会不会丢失关键信息?
老王皱了皱眉。“上下文压缩会不会丢失关键信息?”
“会,这是压缩的代价,没有无损压缩这回事。”
“但可以做三层防护,把丢失控制在可接受范围内。”

“第一层,事实提取。压缩之前,先从旧对话里把跨会话仍然有价值的稳定事实提取出来,存进长期记忆。”
“这些事实不参与压缩,不会丢。”
“第二层,摘要指令。压缩的提示词会明确要求保留用户的需求和意图、已执行的操作和结果、做出的决策和结论、重要的技术细节。”
“模型生成摘要时有据可依,单片摘要控制在 200 字以内,合并摘要控制在 300 字以内。”
“第三层,近期缓冲。最近几轮完整对话原样保留,不压缩。”
“最新的操作步骤和上下文都在。”
用户购买商品花了 500 元,压缩后把 500 元丢失了怎么办?
“那具体一点。用户购买商品花了 500 元,压缩后把 500 元丢失了怎么办?”
“回到第一层,事实提取。”

“压缩之前,系统会从对话中提取稳定事实。'用户花了 500 元购买了某商品'这种包含金额的交易信息,会被识别为持久事实,写入长期记忆。”
“长期记忆不受上下文压缩的影响,模型随时能查到。”
“退一步讲,就算事实提取没有捞到这条,摘要提示词里'做出的决策和结论'这条兜底规则也会引导模型在摘要里保留交易金额。双重保护,虽然没法保证万无一失,但比直接压缩可靠得多。”
06、如何定义哪些内容属于重要信息?
“一句话——跨会话仍然成立、未来复用仍有价值的稳定事实。”
PaiCLI 用三层过滤来落地这个定义。

- 排除临时任务。句子开头是“用户想”“帮我”“创建”“删除”“本次任务”这类前缀的内容,属于当前会话的一次性指令,过滤掉
- 排除推测。包含“可能”“应该”“猜测”“推测”这类词的内容,不是确定事实,过滤掉
- 保留持久信号。包含“偏好”“习惯”“项目”“仓库”“配置”“版本”“技术栈”“约定”“规则”这类关键词的内容,大概率是跨会话有价值的事实,保留
07、API 超时和报错怎么解决?
“核心机制是指数退避重试加随机抖动。”
“默认最多重试 3 次。第一次等 500 毫秒,第二次翻倍到 1 秒,第三次到 2 秒,上限 30 秒。”
“每次等待时间加一个 20% 的随机抖动,避免多个客户端在同一时刻集中重试把服务端再次打挂。”
“重试有适用范围,要区分可重试和不可重试的错误类型。”

可重试的情况:
- HTTP 状态码 408(请求超时)、429(限流)、500/502/503/504(服务端故障)
- 网络层异常,连接超时、连接被重置、DNS 解析失败、流式传输中断
不可重试的情况:
- SSL 证书错误,安全问题重试没用
- JSON 解析错误,响应格式有问题,重试拿到的还是同样的错
- 线程中断,说明用户主动取消了任务
“还有一个工程细节。如果服务端返回了 Retry-After 头,重试间隔会取退避计算值和服务端指定值中的较大值。”
“服务端说等 5 秒就等 5 秒,不提前重试。”
08、消耗 Token 过快怎么排查?
“先看数据。PaiCLI 每轮调用结束后会输出一份 Token 统计,包含调用次数、总输入 token、总输出 token、缓存命中 token、平均每次输入 token 和可用预算。”

“排查思路就是从统计里找异常峰值。常见原因有三个。”
- 工具输出太长。一次 shell 命令输出了几万字符全塞进上下文,Token 一下子就上去了。
- 压缩触发太晚。默认在可用预算的 90% 才触发压缩,如果一轮工具调用特别多,可能在触发之前就已经超了。把触发阈值调低到 80% 可以缓解
- 上下文膨胀。同一份信息被反复检索、反复注入。这时候要检查记忆检索的结果去重机制是不是到位
09、Skill 的渐进式披露机制是什么?
“渐进式披露就是按需加载——不用的 Skill 不进上下文,用到的时候再展开。”
具体分三个阶段。

- 启动时索引注入。Agent 启动时,把所有启用 Skill 的名称和一句话描述注入 system prompt。只放名称和简介,单条描述控制在 500 字符以内,最多 20 个 Skill
- 按需加载。模型在对话过程中判断当前任务匹配哪个 Skill,主动调用 load_skill 工具加载完整指引
- 注入缓冲。加载的完整指引写入一个缓冲区,下一轮对话时自动拼到用户消息前面。缓冲区最多同时保留 3 个 Skill 的指引,超出的按最近最少使用淘汰
为什么不把所有 Skill 的完整指引直接放进上下文?
“假设有 20 个 Skill,每个完整指引平均 2000 token,全部常驻 system prompt 就是 4 万 token。”

“每轮对话都要加载这 4 万 token,但实际用到的可能也就 1 到 2 个。渐进式披露只加载用到的 Skill。”
10、设计智能客服 Agent,该如何设计?
老王舒了口气,抛了个场景题。“现在需要设计一个智能客服 Agent,根据用户的提问来尽可能准确地回答,该怎么设计?”
“分四层来设计。”

“第一层,意图识别。用户进来的第一句话,先分清是产品咨询、售后投诉、退换货还是物流查询。”
“分类决定了后面调哪些工具、查哪些知识库。”
“第二层,知识检索。RAG 接产品文档、FAQ、退换货政策这些知识库。”
“用户问'这款手机支不支持 NFC',检索命中产品参数页面,模型基于检索结果回答。检索不到的,模型必须回复'这个问题我不太确定,帮您转接人工客服',不能瞎编。”
“第三层,工具执行。查订单、查物流、发起退款这些操作,Agent 调用对应的后端接口。”
“工具调用结果回传给模型,模型组织成用户看得懂的回复。”
“第四层,兜底升级。模型连续两轮没有给出有效回答,或者用户明确表示要找人工,立即转接人工客服。”
还需要考虑哪些方面?
“四个方面。”

①、准确性。分块(chunk)切分策略要合理,太大的语义模糊检索会不准确,太小会丢失上下文。一般按 512 到 1024 token 一个 chunk,带 20% 重叠。再加一层重排模型(Reranker)做二次排序,向量检索的结果不一定是最优的,语义相似不等于问题相关
②、延迟。流式输出是基本要求,用户不能干等。高频问题的答案可以缓存,下次直接命中不过模型
③、安全性。防提示词注入——工具返回的内容按不可信数据处理,不能当指令执行。用户的手机号、地址这些敏感信息做脱敏处理
④、兜底。意图分不清的、知识库里查不到的、模型不确定的,全部走人工。宁可多转几次人工,也不让模型编答案
11、电商大促流量尖刺怎么解决?
“这样的 Agent 服务,电商大促的时候流量大,有流量尖刺,怎么解决?”
“核心思路是削峰、分流、兜底,五道防线。”

①、请求队列异步化。用户请求先进消息队列,Worker 按容量消费。LLM 调用本身就慢,同步处理扛不住尖峰。队列解耦后,前端秒级响应“正在处理中”,后端按节奏调模型
②、模型分层。简单问题走小模型或者规则引擎,复杂问题才走大模型。“我的快递到哪了”这种查个接口就能回答的,不需要过大模型
③、热点缓存。大促期间被问频率最高的问题,比如发货时间、退换货政策、满减规则,提前生成标准答案缓存起来。命中缓存直接返回,不消耗模型算力
④、限流保护。每个用户每分钟的请求数设上限。超出的返回“当前咨询量较大,请稍后再试”,比让系统崩掉强
⑤、熔断降级。当 LLM 服务端响应延迟超过阈值或者错误率飙升,自动熔断,切换到模板答案或者直接转人工
“有一点要注意,大促场景下缓存的有效期不能设太长。活动规则可能中途调整,缓存必须支持手动失效。”
ending
以前面试考 CRUD 和中间件参数,现在考的是上下文怎么压缩、记忆怎么管、Token 怎么省、流量来了怎么扛。
【概念谁都会背,但能把概念落成生产环境里跑得起来的工程细节,这才是面试官真正想听到的。】
Agent 工程化才刚刚起步,很多问题还没有标准答案。谁先把坑踩过一遍,谁就有了别人没有的底气。
加油吧,兄弟姐妹们。
下期见。
回复