How-to

携程4年研发月薪3万没涨薪但满足,附Agent面试题干货

携程员工:在携程4年,月薪3万左右,基本没涨薪了。不过挺满足的,毕竟稳定,福利也不错(附Agent面试题)

Why we picked it

想学Agent实现原理?这篇有9层prompt组装、三层上下文压缩等实战细节,比只看工具用法深不少。

一位携程研发员工分享4年月薪约3万未涨薪但满意稳定福利。文章随后给出Agent面试题详解,涵盖Claude Code与Codex对比、prompt分层组装(9层含身份层、模式层等)、ReAct循环、工具调用、MCP协议等核心模块。

Body

还解释了Prompt Caching原理和三层上下文压缩策略(工具结果截断、对话历史摘要、紧急降级)。

Original · 掘金本周最热

携程员工:在携程4年,月薪3万左右,基本没涨薪了。不过挺满足的,毕竟稳定,福利也不错(附Agent面试题)

看到这样一则爆料。 在携程4年,月薪30000左右,研发岗,基本是没有涨薪了。不过这么多年还是挺满足的,毕竟稳定,福利待遇也不错。 在如今这个快节奏的 AI 时代,能说出“满足”两个字的人,我是真的佩服。 看看你的周围,是不是每个人都在卷?早上出了个新模型要测测,中午出了个新 Work 要试试。整个行业的节奏快得像在赶末班车,每个人都马不停蹄地、拼了命地往前冲。 但这位老哥说,满足,稳定,福利不错。 深得我心啊。 这两年 AI 把节奏拉得太快了,快到大家忘了一件事—— 人还应该有生活 。准时下班、周末不加班、半夜不用回消息,这些更应该是我们追求的,不是吗? 要我说,稳定才是最好的学习姿势。反正,我只有在外界环境都顺风顺水的状态下才有心情工作,才想去学习新东西。 如果你也渴望稳定,同时又想在稳定的心态和节奏下学一些新的 AI 知识,那接下来这些 Agent 面试题,可以好好读一读。 (全文比较肝,保证大家能学到很多很多,系好安全带,我们粗粗粗粗发~) content PS:PaiCLI 是一个类 Claude Code 的终端 Agent,已开源。如果你想拥有一个 Agent 的项目经验,可以参考。 GitHub: github.com/itwanger/Pa… 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八股,搞起来。 加油吧,兄弟姐妹们。 下期见。

Industry Coordinates & Source Verification

This report is categorized under AITOP's "How-to" desk. Within our cross-regional analytical framework, it directly maps to AI developer toolchains, coding agents, and engineering workflows. Key entities and technical topics under continuous tracking include Claude Code, Codex, PaiCLI, 智能体.

Source attribution: curated from 掘金本周最热 (@沉默王二).