盗墓笔记启程冒险玩法详解盗墓笔记启程自由探索与解谜机制解析
2026-07-29 3432637
2026-07-29 0
大家好,我是二哥呀。
如果你愿意相信努力、过程和脚踏实地,也相信自己能在 AI 时代获得机会,那么希望你认真读完下面这份内容扎实的面经。
(系好安全带,我们粗粗发~全文比较肝,但保证大家能学到很多很多)
概念题是老王的第一问。他让我说明:“LLM 和 Agent 有什么区别,又存在什么联系。”
“联系放在前面讲:每次做出决策时,Agent 都交由 LLM 完成。”
“是否调用工具、选择哪个工具、怎样填写参数以及任务是否完成,都由模型决定,Agent 框架自身不负责判断。”
“两者的差异体现在职责边界上。LLM 是无状态文本生成服务,每次调用输入一段上下文、输出一段文本;调用结束后不会保留记忆,也无法改变外部世界。”
“Agent 是以 LLM 为核心搭建的执行系统,为模型补足了三类能力:”
“一句话概括,LLM 负责思考,Agent 则把思考结果真正付诸行动。”
“网页版的对话助手是否也属于 Agent?”老王随即追问。
“要看它是否包含 ReAct 循环。纯问答只有一次调用,输入一段话再输出一段话,并不算;当它能够自主联网检索、运行代码,并根据中间结果继续推进时,就已经属于轻量级 Agent。”
“判定依据并非产品形式,而是有没有形成『决策、行动、观察结果、再次决策』的闭环。下一题正好具体说明 ReAct 如何运转。”
“ReAct Agent 由哪些部分构成,你了解吧?”老王点点头后接着问。
“推理加行动(Reasoning + Acting)不断循环,就是 ReAct。具体到我自己写的 PaiCLI-Python,五个部分分别对应具体模块,可以逐项拆开来看:”
老王又追问:“用户交给它一个问题后,整个流程怎样运转?”
“先准备两件事:把匹配到的 Skill 候选列表注入上下文,并检查消息总量是否需要压缩。”
“接着启动循环,将消息历史和工具清单同时发送给模型。模型会流式返回结果,可能直接输出文本回答,也可能发起工具调用。”
“如果是工具调用,执行器完成操作后,以 tool 消息形式把结果追加到历史,再次调用模型。模型读取工具结果后继续决策,或继续调用工具,或给出最终回答。”
“两个条件会触发退出:到达 20 轮上限便强制收尾;若模型已不请求工具,则正常结束。”
“执行时还要注意两个细节。只读工具最多允许 4 个并发运行,写操作必须严格串行,避免相互覆盖;在流式场景中,工具调用参数分片到达,必须按照序号拼成完整参数,再解析为 JSON 交给执行器。过早拼接只会得到半截 JSON,解析会直接失败。”
“一个 Agent 框架若让你从零设计,会怎样划分模块?”老王说着向椅背靠去。
“核心分为六层:”
“安全层经常被遗漏,需要特别说明。Agent 确实会执行命令,因此黑名单中都是高风险对象,sudo、rm -rf 等命令会被直接拦截。”
“文件写入和命令执行,要么标注危险等级,要么要求人工确认;所有执行过程都会写入审计日志。系统能力越强,越要提前设计好约束方式。”
“同一张工具注册表会在启动时接收入口层合并注册的 MCP 工具与内置工具,完成组装后再交给 Agent。”
“结果写回消息历史后,下一轮再次流转。运行时,消息历史由 Agent 持有并逐轮送入模型层;调用请求经模型返回后,改由工具层执行。”
“文本增量、用量统计、思考增量和工具调用,统一表现为流式事件,这是关键的设计决定。各模块对外都只输出这一种格式;入口层不介入逻辑,只承担渲染。”
“这样每一层都能独立替换:更换模型仅修改模型层,新增工具只改注册表,调整界面只动入口层。”
“tool 与 MCP 各自有什么区别,又怎样联系?谈谈你的理解。”老王边问边在本子上记了一笔。
“区别在于归属。tool 是应用内部函数,由我编写并注册,随代码运行,其他应用无法直接使用。”
“M 个应用与 N 个工具对接时出现的组合爆炸问题,可由 MCP 解决。它让工具脱离应用,转为独立服务进程;凡是支持 MCP 的客户端,都可以接入使用。”
“两者最终目标相同。MCP 工具连接后,会封装成与内置工具一致的形式,注册到同一个工具注册表,最终以函数调用(Function Calling)格式共同提供给模型。”
“模型既不知道,也不需要了解某项工具究竟是本地函数还是远端服务。”
“实现时我处理了三件事:”
“配置采用分层合并:用户目录保存全局配置,项目目录保存局部配置;服务同名时后者覆盖前者,路径支持展开环境变量。”
“其他工具的正常注册不会受到牵连;某个 server 若连接失败,只需隔离该项并把错误记下。”
“还有个容易被忽略的点。MCP 除了工具还有资源和提示词模板,我把它们也映射成了虚拟工具,列资源、读资源和调用普通工具走的是同一条路径,模型侧不用学新动作。”
老王翻到简历下一页:“项目中的智能问答,短期记忆和长期记忆分别怎样实现?”
“会话中的消息历史构成短期记忆,存储形式是一个列表;它与上下文压缩配合运行,数量上限为 100 条。”
“当内容达到可用输入预算的 80%时触发压缩,压缩目标为 55%;最近 6 条消息保持原样,更早轮次采用提取式摘要。分割边界设置在用户消息处,确保工具调用与结果成对保留。”
“长期记忆通过 SQLite 保存于用户目录,能够跨会话生效,并按项目路径划分作用域。具体有以下设计细节:”
“还要守住一条边界:压缩产生的摘要只用于当前会话,它属于模型生成的二手信息,不能升级为长期记忆。”
“只有用户明确提出要保存的事实,才允许进入长期记忆。否则一旦放松限制,模型自己的转述很快就会污染记忆库。”
老王继续追问:“业界常见的三层记忆系统如何划分?每层分别保存什么?”
“主流方式是按照作用域划分三层:”
| 层次 | 存什么 | 在 PaiCLI-Python 里 |
|---|---|---|
| 会话层 | 当前对话的消息 | 内存消息列表,容量上限 100 条 |
| 项目层 | 仓库规范与构建命令 | 项目根的 PAI.md,跟着 Git 走 |
| 全局层 | 跨项目个人偏好 | 用户目录中的记忆库与全局配置 |
“文件记忆另设本地覆盖层 PAI.local.md,用于存放仅属于本机且不进入版本库的配置。加载同样受到预算限制:单个文件截断至 6000 字符,合并总量不超过 16000 字符,避免记忆耗尽窗口。”
建议保存这张表,回答记忆相关问题时基本都能套用。
下一问被老王抛了出来:“Skill 所采用的渐进式披露(progressive disclosure)机制,你是否清楚?”
“了解,核心可以概括为八个字:索引常驻,正文按需。整个过程分成两段。”
“第一段的常驻内容仅是索引,而且总量不超过 4000 字符。每次收到用户输入,匹配度最高的 5 个 Skill 会被选中,但注入上下文的只有名称和描述,每条描述最多 300 字符;所以模型此时只知道可用技能有哪些,正文连一个字都尚未加载。”
“第二段才会读取 SKILL.md 正文,前提是模型判断某个 Skill 与当前任务匹配,并主动调用加载工具,读取上限为 5000 字符。读出的正文先进入缓冲区,不会立即放进当前轮,而要到下一轮才随工具结果注入。为避免持续累积,缓冲区只保存最近 3 条。”
“Skill 目录同样分为内置、用户级和项目级三层;名称相同时,项目级覆盖用户级,与记忆文件采用相同的分层逻辑。”
“收益可直接量化:若把 20 个 Skill 全量加载,每篇按 5000 字符上限计算,总计就是 10 万字符。采用渐进式披露后,常驻的只有 4000 字符索引,两种成本相差 25 倍。”
老王追问:“候选内容是如何匹配的?”
“打分采用加权方式:显式点名的 Skill 直接获得最高分,否则就看命中位置;其中名字权重最高,随后是标签,描述最低。为改善中文召回,还加入了三元、二元分词。”
“检索对象只是从网页变为技能,本质上仍是一个微型搜索引擎。”
最后一道正题随即由老王问出:“输出内容的质量在使用 AI 时该怎样保证?”
“可以分三层回答,先介绍我已经实现的部分。”
老王追问。“这些都是工程手段,提示词层面呢?”
“三条实践。把验收标准直接写进提示词,让模型知道什么叫合格;复杂任务要求模型先复述一遍理解再动手,提前暴露偏差;重要产出让模型对照标准自查一轮再交付。”
“也需要坦白,通用钩子机制和结构化输出校验尚未实现,主循环同样没有自动重试。面试中最忌讳把没做的功能说成已经完成——保证质量的第一条,就是先确保自己的陈述真实。”
老王笑了笑,随后合上本子。
项目名称:PaiCLI-Python
项目简介:支持计划执行、多 Agent、ReAct 三种模式,是用 Python 编写并对标 Claude Code 的 Agent 命令行工具
技术栈:Python、asyncio、httpx、MCP、SQLite
核心职责:
面试接近结束,轮到我提问:“结合刚才的表现,能给我一些后端和 Agent 方面的学习建议吗?”
老王思考片刻,给出的建议包含大量信息。兄弟实在太用心,我都想向他鞠躬。把原话拆开后,就是一份完整自查清单:
清单中的每个项目,都可以结合一个真实项目的源码完整学习一遍。
过去后端面试比拼并发与中间件,如今则比拼对模型、工具调用、记忆和上下文的理解。
我们有机会置身 AI 发展的前沿,把 Agent 从术语转变为写进简历且经得住追问的项目。挑战虽然不少,其中也蕴含着无限可能。
兄弟姐妹们,一起加油。
下期再见。