携程员工:在携程4年,月薪3万左右,基本没涨薪了。不过挺满足的,毕竟稳定,福利也不错(附Agent面试题)
看到这样一则爆料。
在携程4年,月薪30000左右,研发岗,基本是没有涨薪了。不过这么多年还是挺满足的,毕竟稳定,福利待遇也不错。
在如今这个快节奏的 AI 时代,能说出“满足”两个字的人,我是真的佩服。
看看你的周围,是不是每个人都在卷?早上出了个新模型要测测,中午出了个新 Work 要试试。整个行业的节奏快得像在赶末班车,每个人都马不停蹄地、拼了命地往前冲。
但这位老哥说,满足,稳定,福利不错。
深得我心啊。
这两年 AI 把节奏拉得太快了,快到大家忘了一件事——人还应该有生活。准时下班、周末不加班、半夜不用回消息,这些更应该是我们追求的,不是吗?
要我说,稳定才是最好的学习姿势。反正,我只有在外界环境都顺风顺水的状态下才有心情工作,才想去学习新东西。
如果你也渴望稳定,同时又想在稳定的心态和节奏下学一些新的 AI 知识,那接下来这些 Agent 面试题,可以好好读一读。

(全文比较肝,保证大家能学到很多很多,系好安全带,我们粗粗粗粗发~)
content
PS:PaiCLI 是一个类 Claude Code 的终端 Agent,已开源。如果你想拥有一个 Agent 的项目经验,可以参考。

01、Claude Code 与 Codex 各自有什么特别?
老王翻开面试题,直接问:“Claude Code 和 Codex 你都用过吗?各自有什么特别的地方?”
“都用过。这两个产品方向完全不一样。”
“Claude Code 是 Anthropic 做的终端 Agent,最大的特点是实时交互,和 AI 时代完美契合,不需要 IDE 就可以完成 Coding 工作。在终端里给它任务,然后读代码、改文件、跑命令,整个过程全程可见,并且随时可以打断、纠正。就目前来说,Claude Code 就是最强的终端 Agent,没有之一。”

“Codex 是 OpenAI 做的桌面端 Agent,走的是异步多线程,可视化比 Claude Code 更强。”
“我个人是两者的重度用户,Claude Code 配合 Opus 模型在文本领域更强,整体架构能力上更强。Codex 我更喜欢配合 GPT-5.6 Sol 做代码开发和生图,特别消耗 Token的任务也会交给它。”

02、输入到模型的 prompt 由哪些部分组成?
“你做的 Agent,输入到模型的 prompt 是怎么组装的?哪些部分是必须注入的,哪些不是?”
“prompt 组装用的是分层拼接,一共 9 层,按固定顺序拼进去。”

“前 4 层是静态的,整个会话期间不变。”
- 第一层是身份定义,包括工具的 schema、安全策略、行为守则,这一层是必须注入的,没有它模型连自己是谁都不知道,更不知道能用什么工具。
- 第二层是人格层,控制语气和风格。
- 第三层是模式层,根据当前执行路径加载不同的指令集,ReAct、Plan、Team 三种模式各一套。
- 第四层是审批层,定义哪些工具调用需要用户确认。
“后 5 层是动态的,每轮都可能变。运行时上下文(日期、时区)、项目记忆、Skills 索引、上下文管理策略、收尾指令。”
“必须注入的是身份层和模式层——模型必须知道自己是谁、当前在什么执行模式下工作。人格层、Skills 索引、项目记忆这些不是必须的,没有它们模型照样能干活,但体验会差不少。比如没有 Skills 索引,模型就不知道有哪些现成的技能可以加载,遇到问题只能靠自己硬想。”
为什么静态内容要排在最前面?
“因为 Prompt Caching。”

“Prompt Caching 会按最长公共前缀命中。前 4 层是静态内容,放在提示词最前面,每轮请求的前缀都一样,缓存命中率能拉到最高。如果把动态内容插到前面,前缀每轮都变,缓存基本不会中,token 成本会高出好几倍。”
03、你做的 coding agent 和 Claude Code 与 Codex 区别在哪?
“Claude Code 是终端 Agent 的标杆。”

但我在使用这些工具的过程中产生了一个疑问——这些工具底层到底是怎么工作的?
它是怎么理解我的指令的、怎么决定该读哪个文件的、怎么判断该调用什么工具的、多轮对话的上下文它是怎么管理的。
我发现如果我只会用这些工具但不理解它们的底层设计,遇到工具表现不好的时候(比如Agent选错了工具、上下文丢失了关键信息、生成的代码跟项目风格不一致)我只能试着换个说法重新问,而不能从原理层面判断问题出在哪里。
所以我决定自己从零实现一个Agent CLI,把ReAct推理循环、Tool Calling、Memory管理、MCP协议这些核心模块都自己写一遍。
做完之后我对Agent系统的每一层都有了源码级的理解,再回去用Claude Code的时候我能明显感觉到我对工具的驾驭能力提升了——我知道什么样的指令能让Agent更准确地理解我的意图、我知道在什么场景下应该手动压缩上下文、我知道怎么设计Tool的描述信息能提高调用准确率。
04、上下文压缩是怎么做的?
老王往前倾了倾身子,继续问:“你提到了上下文压缩,具体是怎么做的?”
“三层压缩,每一层处理不同粒度的内容。”
“第一层是工具结果截断。单次工具返回的内容如果超过阈值——比如 grep 一下出来几千行——直接截断,保留首尾和关键信息,中间用摘要替代。这一层是即时生效的,工具一返回就处理。”
“第二层是对话历史摘要。当整个对话的 token 数接近上下文窗口的上限时,保留最近几轮完整对话,把更早的历史用 LLM 做一次摘要压缩。摘要会保留四类关键信息:用户的核心诉求、Agent 已完成的操作、达成的共识、还没解决的待办。”

“第三层是紧急降级。如果摘要压缩之后 token 数还是超限,按优先级丢弃非核心上下文——Skills 索引、非关键记忆、项目记忆里优先级低的部分,给核心对话腾空间。”
05、为什么要采用三层压缩策略?每一层压缩的内容一致吗?
“设计思路是粒度从细到粗,触发条件从宽到严。”
“第一层处理的是单条消息级别的冗余,触发条件最宽松——每次工具返回都会检查,超了就截。成本几乎为零,不需要调 LLM。”
“第二层处理的是对话历史级别的膨胀,触发条件是 token 数超过上下文窗口的差不多 80%。200k 的窗口大概在 167k 左右触发。这一层要调一次 LLM 做摘要,有成本,所以不会太频繁。”

“第三层是最后防线,只在前两层都不够用的时候才启动。丢弃的是可恢复的辅助信息——Skills 索引可以重新加载、项目记忆可以重新检索——核心对话内容不到万不得已不动。”
“三层压缩的内容完全不一样。第一层压的是工具输出,第二层压的是对话历史,第三层丢的是辅助上下文。如果只用一层笼统地压缩,要么压得太早浪费上下文空间,要么压得太晚直接超限报错。”
06、压缩过度效果不理想,怎么发现,怎么处理?
“靠两个信号。”
“第一个是行为异常。模型开始重复做已经做过的事情——比如读一个文件,明明十分钟前已经读过了,又读了一遍。或者模型直接说'我不太清楚之前讨论了什么',这就是压缩把关键信息压丢了。”
“第二个是任务成功率下降。同样类型的任务,之前能完成,压缩几轮之后开始失败,大概率是上下文丢了关键内容。”

“处理有三个手段。”
第一,动态调整保留轮数。默认保留最近 3 轮不压缩,如果检测到异常,临时扩大到 5 轮。
第二,关键信息标注。用户明确给出的需求、已确认的技术方案,标记为不可压缩,摘要的时候跳过。
第三,压缩前备份原始历史,发现效果不好可以回滚到压缩前的状态,用更保守的策略重新压。
07、增量修改系统怎么做?需要重新注入哪些信息?
“走的是 Plan 审查机制。”
“Agent 生成执行计划之后,用户可以审查。如果需要加新功能,用户选择'补充需求',把新的需求描述传进去。系统拿着原计划和新需求一起交给规划器,让它重新生成一份计划。”

“重新注入的信息有三块:原始任务描述、已完成步骤的摘要、新需求的补充说明。已完成的步骤不会重新执行,规划器基于当前进度来安排后续的步骤。”
为什么不直接在原计划上追加,而要重新规划?
“因为新需求可能改变已有任务的依赖关系。”

“举个例子,原计划是'先创建数据库表,再写 CRUD 接口'。用户补充说'加一个缓存层'。这不是简单地在后面追加一个缓存任务——CRUD 接口的实现逻辑要改,读操作要先查缓存再查库,写操作要同步更新缓存。直接追加的话,前面已经写好的接口代码就不对了。”
“重新规划让规划器看到全貌,重新安排依赖和执行顺序,避免后续步骤建立在错误的前提上。”
08、工具调用的流程是怎样的?
老王翻了一页笔记,继续问:“工具调用这块讲讲,完整流程是什么?”
“三个阶段。”
“第一阶段,LLM 生成 tool_call。模型看到工具的 schema 定义之后,根据当前任务决定调哪个工具、传什么参数,输出一个结构化的 tool_call 请求。”
“第二阶段,策略审批。写操作(改文件、跑命令)会过一道安全检查——路径是否在允许范围内、命令是否在黑名单里。需要用户确认的操作会暂停等审批通过。”
“第三阶段,执行。单个工具直接执行,多个工具可以并行跑,线程池上限 4 个并发。执行结果作为 tool 消息追加到对话历史里,LLM 拿到结果之后再决定下一步。整个过程是一个循环:生成 → 审批 → 执行 → 结果回到模型 → 继续生成,直到模型认为任务完成。”

能不能用 Skill 替代工具?
不能,两个东西完全不一样。
| 维度 | Tool(工具) | Skill(技能) |
|---|---|---|
| 本质 | 可执行能力——读文件、跑命令、搜代码 | 决策知识——怎么用工具、什么策略、什么规范 |
| 调用方式 | LLM 通过 tool_call 协议调用 | LLM 调用 load_skill,内容注入下一轮消息 |
| 返回内容 | 结构化结果(文件内容、命令输出) | Markdown 指令(提示词级别的知识) |
| 生命周期 | 单次调用,用完即走 | 加载后驻留在上下文里,持续影响后续决策 |
“Tool 是手,Skill 是脑子里的经验。你不能用经验代替手去拧螺丝,也不能用手代替经验去判断该拧哪颗。两个是互补关系,不是替代关系。”
09、讲讲你的 Skills 有哪些?
“核心设计思路是渐进式披露,分三层加载。”
“第一层是索引。只把 Skill 的名称和一句话描述放进 system prompt,控制在 4KB 以内,最多 20 个 Skill。这一层常驻上下文,成本很低。”
“第二层是正文。LLM 看到索引后,判断当前任务需要哪个 Skill,调一个 load_skill 工具把完整指令拿进来,单个 Skill 正文上限 5KB。加载进来的 Skill 放在一个 LRU 缓冲区里,最多同时持有 3 个,超出的按最久未使用淘汰。”

“第三层是参考文档。部分 Skill 自带参考文档目录,只在 Skill 指令明确要求的时候才加载。”
为什么不一次性全量加载?
因为 system prompt 越长,Prompt Caching 命中率越低。绝大多数对话只会用到一两个 Skill,全量加载等于让用户为用不到的内容付 token 成本。
“Skill 来源有三个优先级:内置的、用户级的、项目级的,从低到高覆盖。项目级的 Skill 可以覆盖内置同名 Skill 的行为,不用改源码。”
10、工具调用时模型用了几次?Skill 用了几次?
“这个跟任务复杂度有关,说个典型场景。”

“比如'帮我在项目里加一个分页接口'这种任务,模型差不多要调 10 到 15 次工具——读项目结构、读已有接口代码、读数据库模型、写新接口、写测试、跑测试、修 bug,每一步都是一次工具调用。Skill 的话,可能就加载了一个代码规范相关的 Skill,一次。”
“工具调用频率远高于 Skill 加载,差不多 10:1 到 20:1 的比例。这也是为什么 Skill 要做渐进式加载——使用频率不像工具那么高,没必要全部常驻上下文。”
场景题
11、面向一个复杂任务,你的 coding agent 的 plan 是怎么做的?
老王合上笔帽,换了个方向:“来道场景题。如果来了一个复杂任务,你的 Agent 会怎么做 plan?”
“先判断任务是不是真的需要 plan。简单任务——比如'把这个变量名改一下'——直接走 ReAct 模式,一步到位,不需要规划。”
“复杂任务走 Plan-and-Execute 模式。规划器接收用户任务之后,生成一个带依赖关系的 JSON 计划。每个子任务有 id、描述、类型和依赖列表。”

“计划生成之后先做拓扑排序,确认没有环依赖。然后按依赖关系分批执行——没有依赖的任务可以并行跑,有依赖的等前置任务完成再启动。”
“用户可以在执行前审查计划,觉得不对可以调整,也可以补充需求让规划器重新出方案。”
多 Agent 编排具体是怎么做的?
“Team 模式下有三个角色。”

“规划器负责把任务拆解成带依赖关系的执行计划,只动脑子不动手,不调任何工具。Worker 是干活的角色,有独立的对话历史和完整的工具集,同一批没有依赖的任务可以分给不同的 Worker 并行执行,默认最多 2 个 Worker 同时工作。审查器负责质量把关,Worker 干完活之后审查器检查产出,不合格就打回重做,最多打回 2 次。”
每个子 Agent 的区别是什么?
“区别在两个维度:系统提示词和对话历史。”
“每个角色有专属的系统提示词,通过不同的模式加载——规划器的提示词告诉它'你只负责拆解任务,不许调工具',Worker 的提示词告诉它'你负责执行具体步骤,工具随便用',审查器的提示词告诉它'你负责检查质量,给出通过或打回的判断'。”

“对话历史完全隔离。每个角色只看得到自己的交互记录,Worker-1 不知道 Worker-2 在干什么,审查器也看不到规划器是怎么想的。每个角色只关注自己职责范围内的信息,上下文干净,不容易互相干扰。”
为什么这么设计?能不能所有的子 Agent 共享工具?
“工具本身是共享的。三个角色用的是同一个工具注册表,11 个核心工具加上 MCP 动态工具,技术上所有角色都能访问到。”
“但规划器和审查器不调工具,这是通过提示词约束的,不是技术上做不到。设计上故意不让它们碰工具,原因是角色隔离——如果审查器有工具执行权限,它发现 Worker 的代码有问题,可能会自己动手去改。改完之后它再审查自己改的代码,那就是既当运动员又当裁判了。”

“工具执行权集中在 Worker 手里,规划器和审查器只做判断。出了问题也好定位——代码写得不对找 Worker,计划拆得不合理找规划器,漏检了找审查器,职责边界清清楚楚。”
ending
以前我们找工作拼的是八股文,背并发、背中间件、背设计模式。现在面试官问的是 prompt 怎么组装、上下文怎么压缩、Tool 和 Skill 有什么区别、多 Agent 怎么编排。
【技术栈在变,面试题在变,但有一件事没变——心态稳的人,学什么都快。】
AI 正在重新划分工程师的能力版图,这个过程才刚开始。不要着急,每天进步一点点就足够了。
跟着二哥的Agent八股,搞起来。
加油吧,兄弟姐妹们。
下期见。
真诚点赞 诚不我欺
回复