百度 AI Agent 开发岗面经:记忆模块与上下文压缩
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
面经 01(面试时间 2026 年 8 月 20 日)
- 如果将 Agent 部署在本地机器,用于排查本机异常进程,实现该能力有哪些需要注意的点?
- 沙箱实例并发数量、需要考虑哪些问题?
- 如果给现有 Agent 扩展新能力,会考虑设计哪些功能?
- 当 Agent 遇到无法解决的场景,应该怎么处理?
- Agent 记忆模块如何设计?
- 长期记忆、短期记忆与当前上下文内容出现冲突,如何解决?
- 如果由你设计实现一套企业内部知识问答 Agent,整体方案怎么做?
- Agent 调用 Skill 工具的完整执行流程是什么?
- 简述大模型 token 生成原理。
- 大模型对话接口参数有哪些,分别什么意思?
- 大模型本身具备记忆能力吗?
- 查看机器 CPU、进程状态常用哪些命令?
- Docker 容器内运行程序,对比直接在宿主机运行进程,二者有什么区别?
- TCP 相关机制,发生丢包时如何处理?
- 程序访问下游 TCP 服务出现连接超时,完整排查思路是什么?
- 手撕:反悔贪心 & 堆。
- 请做一下自我介绍。
面经 02(面试时间 2026 年 8 月 18 日)
- 讲一下 Python 和 Java 写项目时的主要区别。
- 讲一下你的项目 Agent 的整体架构。
- 如何设计一个 ReAct 流程?
- 讲一下你这个项目的上下文设计;追问:怎么做的关键帧场景检测?
- 讲一下你说的向量检索的原理。
- 项目分片断点续传怎么做的?
- 讲一下 DB 里面的 MVCC。
- 讲一下 JVM 的垃圾回收机制。
- Java 为什么需要有线程池?
- 如果让你做一个类似 cc 或者 code 的 Coding Agent,你有什么思路?
- 给定最近 T 秒内的访问记录,统计每个用户最近一次访问时间,并按照最近访问时间从近到远返回用户列表。
- 讲讲上面这道题的算法思路。
- 介绍实习经历。
- 自我介绍。
面经 03(面试时间 2026 年 8 月 18 日)
- 平时怎么使用 AI 提效?
- 如何理解 Prompt Engineering → Context Engineering → Harness Engineering 的演进?三者有什么区别?
- Agent 上下文越来越长,快超过 Context Window 时一般怎么处理?
- 如果让你设计上下文压缩,会怎么设计?
- Claude Code 是怎么做上下文压缩的?是否了解 Claude Code 的「三层压缩」?
- 如果从零搭建一个团队内部的知识问答 RAG,完整流程是什么?主要分哪些步骤?
- 如果自己设计一套 Agent 教程 / 学习体系,会怎么划分章节?
- 什么样的 Agent 教程算比较好的教程?内容来源怎么组织?
- Claude Code 这类 Coding Agent 应该重点研究哪些东西?
- 数据库基础:了解数据库索引吗?实际项目里怎么使用索引?
- 如果设计一张存储 K 线数据的表,会怎么设计?
- 前端基础:有哪些前端开发经验?平时主要使用什么前端框架?
- 手撕:二叉树前序遍历 + 层序遍历。
面经 04(面试时间 2026 年 7 月 18 日)
- Explain 中各个 Type 有什么区别?
- 分库分表是怎么做的?
- 大表查询中的数据预聚合是怎么做的?
- 手撕:合并两个数组。
- 介绍实习期间承担的主要工作。
- 请做一下自我介绍。
面经 05(面试时间未知)
- 看你项目主要使用 Java 开发,视频平台项目技术栈和中间件较多,从技术架构角度介绍项目整体技术编排。
- 这个后端功能很丰富,项目大概做了多久?
- 项目是否部署到线上机器,可以直接访问吗?
- 视频平台如何实现视频上传?
- 怎么判断文件是否已经上传过?如果使用文件名作为 key,出现同名文件该怎么处理?
- 分片上传的这些分片信息是否考虑持久化?
- 分片数据、视频元信息,是用对象存储还是其他方式保存?
- 项目里 MySQL 和 ES 做数据同步,为什么要做数据同步,缓存在这里起到什么作用;追问:为什么 ES 查询效率比 MySQL 快很多?
- MySQL 检索查询的执行流程是什么样的?有索引时检索流程又是什么?
- 了解聚簇索引和非聚簇索引吗?
- 一对一私聊是使用第三方服务,还是自建消息表?
- 使用 WebSocket,服务端维护两条连接实现两个用户私聊,为什么选择这种架构?还有其他方案吗,为什么选 WebSocket?
- 用户鉴权是自己实现的吗?用户 ID 如何取值,怎么保证用户 ID 唯一?UUID 生成规则有了解吗?
- 当前是单表存储,如果用户访问量暴涨,千万级用户下单表性能下降,可以怎么扩展?
- 用户量到亿级,缓存也扛不住热数据,该怎么处理?
- 如果按 uid 维度做分片,该如何设计?
- 哈希分片后,线上服务持续运行,怎么完成新旧数据切换?数据迁移过程还有哪些需要考虑,整体流程怎么设计?
- 了解 RocketMQ 和 Kafka 的区别吗?
- 什么是分布式?了解分布式 CAP 理论吗?
- Nacos 是 CP 模型还是 AP 模型?除了 MySQL 之外,还有哪些中间件可以做服务注册与发现?
- Redis 属于 CP 还是 AP 模型?Redis 速度为什么很快?IO 多路复用和 Redis 单线程会不会矛盾?
- 什么是缓存穿透?除布隆过滤器外,还有什么解决办法?
- 算法题:岛屿数量,先说思路,然后编写核心代码。
- 请你先做个简单的自我介绍。
原帖为连载合集,面经 06 的正文在牛客服务端即被截断(仅剩自我介绍与半句残句),此处只保留已发布的部分。
《参考解析》
本地 Agent 排查异常进程与沙箱并发
这类需求的安全设计比功能设计重要。① 权限:Agent 用普通用户跑,kill、rm、chmod 这类写操作拆成单独的高权限工具并要求二次确认,只读的 ps/top/ss/lsof/读 /proc/<pid> 放在低权限档;② 命令注入:模型生成的命令绝不能拼进 shell 字符串,要用参数数组执行(subprocess.run([...], shell=False))或白名单命令模板,并对 ;、|、$()、重定向做校验;③ 输出量:繁忙机器上 ps aux 几万行,工具侧必须先按 CPU/内存排序取 topN 再回灌模型,否则上下文直接爆;④ 审计与幂等:每次动作记录「谁、何时、对哪个 pid、结果」,kill 不存在的 pid 要按成功幂等处理;⑤ 部署方式:容器或 namespace 隔离,drop 掉 CAP_SYS_ADMIN 等多余能力,cgroup 限 CPU、内存和 PID 数,只读挂载 /proc 的必要部分。沙箱并发数按 min(CPU 核数, 内存 / 单实例峰值) 定并留约 20% 余量,同时给队列设长度上限和排队超时,每个沙箱设 wall-clock 硬超时与输出上限,防止死循环或日志刷爆磁盘;跑不可信代码必须一次一实例(不能复用,避免状态污染),并监控沙箱就绪率、排队时长和 OOM 次数。
Agent 记忆模块与冲突解决
分三层:工作记忆(当前 context window 内的对话与工具结果)、短期记忆(本次会话的滚动摘要 + 结构化状态槽位)、长期记忆(跨会话落库,再分事实类如用户偏好与身份、经验类如成功方案与失败教训)。写入用触发式而不是每轮都写:用户显式纠正、任务完成、出现关键实体时才抽取写入,写前做去重和冲突检测。检索用混合召回(向量 + BM25 关键词 + 时间衰减 + 重要度打分)取 top-k 再按 token 预算裁剪。冲突解决的关键是定优先级而不是让模型自由裁量:本轮用户显式输入 > 近期会话 > 长期记忆 > 模型先验,同层按时间新旧裁决;实现上给每条记忆打 source(user_stated / agent_inferred / external)、updated_at、confidence,被覆盖的旧记忆标为 superseded 而不是物理删除,便于回溯。事实类冲突(上次说在北京、这次说在上海)直接以新为准,偏好类可以合并成多值而不是覆盖。
企业内部知识问答 Agent 整体方案
链路是「接入 → 解析切分 → 索引 → 检索 → 生成 → 兜底 → 评测」七步。数据接入打通 Confluence、飞书、SharePoint、工单系统,权限必须在检索时生效(先按用户身份过滤再召回,不能先召回后过滤,否则摘要里已经泄露了)。切分按文档结构走(标题层级切,表格单独处理),chunk 300800 token 带 10%300 条问答对,盯召回率、引用正确率、拒答率和端到端满意率,每周回归;点踩的 case 进 badcase 集,用来补文档或调切分。缓存要按用户权限维度分片,否则会串权限。20% overlap。索引用中文 embedding(bge-m3、bge-large-zh 之类)加全文索引双路,metadata 存来源、部门、密级、更新时间。检索先混合召回 top 50,再用 reranker 取 top 58,加时间和权限过滤。生成要求带引用(每条结论标注文档 id 和段落),检索不到就明确说不知道,不允许编。兜底做低置信度转人工或建工单。评测建 100
Skill 与工具调用的完整执行流程
① 请求组装:把工具定义(name、description、JSON Schema 参数)随用户消息一起发给模型;② 模型决策:输出结构化的 tool_call(id、name、arguments 字符串);③ 参数校验:按 schema 做类型、必填、枚举、范围校验(pydantic / jsonschema),失败就把错误回填让模型自修正,重试上限设 2~3 次;④ 策略检查:工具是否在当前用户的白名单内、参数是否命中危险规则(rm -rf、写系统路径)、是否需要人工确认;⑤ 执行:带超时、只对幂等操作重试、并发编排、长输出先摘要或分页;⑥ 结果回填:以 tool 角色消息带 tool_call_id 回填,错误也要结构化(error code + message),不要吞异常;⑦ 循环:模型基于结果继续决策,直到给出最终答复或触达最大步数、超时、token 预算;⑧ 收尾:全过程写 trace(每步输入输出、token 数、耗时)供回放和评测。有副作用的工具(下单、发消息、删文件)必须做成幂等——带幂等键并把「已执行」落库,否则重试就会重复动作。
上下文压缩怎么设计
按 token 用量触发(比如到窗口的 70%~80%),不要等超限报错再救。手段从轻到重:① 工具输出瘦身,只回灌结构化摘要和前 N 行,原始输出存外部按引用取回;② 滑动窗口加锚点保留,系统提示、原始任务目标、关键文件内容永远不压;③ 结构化摘要,把中间过程压成「已完成 / 待办 / 关键结论」,而不是让模型自由发挥写摘要;④ 分层压缩,类似 Claude Code 的「三层」——先裁单轮工具结果,再把历史段落摘要,最后整体重新生成摘要,越往后越贵;⑤ 外部记忆卸载,把压掉的内容写到文件或向量库,需要时按 key 取回,即卸载到磁盘而不是丢掉。要点是压缩有损,必须保证「任务目标 + 未完成待办 + 关键约束」在任何一次压缩后都还在,并且压缩本身要能被评测——压完接着跑同一批任务,看成功率掉了多少。
Docker 容器内进程与宿主机进程的区别
容器不是虚拟机,本质是共享同一内核的一组 namespace(pid、net、mnt、uts、ipc、user)加 cgroup 限额和 capability 裁剪。区别体现在:① 网络,默认 bridge 网络有独立 netns,容器里的 127.0.0.1 是容器自己,访问宿主机要走 host.docker.internal 或 host 网络;② 文件系统,镜像层加可写层,容器删了可写层就没了,持久数据必须挂 volume;③ 进程视图,容器内 PID 1 是主进程,ps 看不到宿主机进程(除非 --pid=host);④ 资源,受 cgroup 限制,free、nproc 可能显示宿主机数值而实际被限,要读 /sys/fs/cgroup;⑤ 权限,默认 drop 了部分 capability,sysctl、iptables、挂载在容器里会失败;⑥ 内核参数,uname -r 与宿主机一致,net.core.somaxconn 这类是全局共享的,改了影响整机。
下游 TCP 连接超时的排查顺序
① 分层确认:ping 通不代表 TCP 通(ICMP 可能被禁),用 nc -vz -w 3 ip port 或 telnet 判断是连不上还是连得慢;② DNS:dig / getent hosts 看解析结果,特别注意解析到了 IPv6 而服务只监听 IPv4;③ 路由与防火墙:traceroute、iptables -L -n、云安全组与 NACL;④ 服务端是否在听:ss -lntp | grep <port>,注意监听地址是 127.0.0.1 还是 0.0.0.0;⑤ 全连接队列溢出:ss -lnt 的 Send-Q 是队列上限,netstat -s | grep -i listen 看溢出计数,溢出会直接丢 SYN;⑥ 抓包定位:tcpdump -i eth0 host <ip> and port <port> -nn,看 SYN 是否到达、SYN-ACK 是否回来、是否按 1s/2s/4s 重传,据此区分网络丢包、服务端未响应还是客户端侧问题;⑦ 中间设备:SLB / NAT 的空闲超时(常见 900 秒)会悄悄断长连接,表现是「几十秒没有字节流动就被掐」,这也正是长调用必须用流式协议的原因;⑧ 客户端自身:连接池耗尽、并发过高导致排队超时,超时设成 1 秒而服务端 P99 是 2 秒这类配置不匹配最常见。
千万级到亿级的分库分表与迁移
单表千万级先别急分片,顺序是加索引 → 读写分离 → 加缓存 → 冷热分离与归档,这些都做完还有压力才分片。分片键选能覆盖大多数查询条件且分布均匀的字段(用户维度就用 uid),维度选错会出现跨库 join 和全路由扫描,比不分还慢。按 uid 分片一般用 uid % N 或一致性哈希,N 取 2 的幂便于后续翻倍扩容;哈希分片能让数据均匀,但扩容时要搬迁,所以更好的做法是一开始就用成倍数的逻辑分片(比如 1024 个逻辑分片映射到物理库),扩容时只搬逻辑分片。数据迁移用双写 + 灰度切读:新老库双写并做对账补偿 → 全量迁移历史数据 → 按 uid 灰度把读切到新库(先 1%、10%、50%)→ 观察无问题后停双写。亿级用户热数据缓存也扛不住时,靠「多级缓存(本地 Caffeine + Redis 集群)+ 热点探测与本地副本 + 请求合并(singleflight)」,同时对热点 key 做逻辑过期,避免同一时刻大量请求同时回源。
缓存穿透与其它防护
缓存穿透是查询不存在的数据,缓存永远不命中,请求全部打到 DB;布隆过滤器是最常用的解法(位数组 + 多个哈希,能判「一定不存在」,但有假阳性且不支持删除)。其他手段:① 缓存空值并设短 TTL(实现最简单,缺点是会占内存、且数据新增后有一小段时间不一致);② 参数校验前置,把明显非法的 id(负数、超长、不符合格式)在入口拦掉;③ 互斥锁 / singleflight 保证同一个 key 只有一个请求回源,其余等待,防止缓存击穿;④ 限流与降级兜底保护 DB;⑤ 分层布隆过滤器或计数器布隆(Counting Bloom)支持删除,减少误判累积。回答时最好把缓存击穿(热点 key 过期)和缓存雪崩(大批 key 同时过期)一起区分开,这三个概念面试官几乎必追问。