标准回答
本质是什么
Hook / 中间件模式是在 Agent 的执行流程上预留一系列可插拔的拦截点,在固定节点触发注册好的逻辑。它和 Web 框架里的 middleware(如 Express、Koa)思路一致:请求顺着一条洋葱式的链穿过若干层,每层都能在前后做事,再决定放行还是短路。
典型拦截节点
放在 Agent 一次完整回合的关键边界上:消息进入/产出前后、LLM 请求前后、工具调用前后。在这些点上,中间件能读到当前上下文,可以改写输入、加工输出、放行、提前短路返回,或直接中止整条链。
典型场景
横切关注点几乎都能用它承载:鉴权与限流(请求入口校验身份、控制并发与配额)、日志与链路追踪(记录每步的输入输出、耗时、token,串成一条 trace)、上下文注入与裁剪(请求前补齐系统提示、记忆、按预算裁剪历史)、敏感词过滤与护栏(输入输出两侧拦截违规内容)、缓存(命中相同请求直接返回)、重试(捕获瞬时失败自动重发)、成本统计(累计 token 与费用)、人工审批(高危工具调用前挂起转人工)。
为什么值得这样做
核心价值是解耦:Agent 的推理循环只管"想下一步、调工具",而鉴权、日志、护栏这些与业务正交的关注点全部下沉到中间件,可组合、可复用、可按环境增删。生产环境开全套监控与护栏,本地调试只挂日志,核心代码一行不用动。
常见误区
⚠️ 常见踩坑
别把业务核心逻辑硬塞进中间件——中间件应只承载横切关注点,塞进主流程会让链路变成隐式的"魔法",难以追踪。另外注意中间件有顺序:限流应在昂贵的 LLM 调用之前、缓存应在请求之前命中、护栏需要包住输入和输出两侧,顺序错了会失效或浪费成本。
追问
追问 1:中间件链的执行顺序如何设计?洋葱模型和管线模型有何区别?
洋葱模型里每个中间件能在 next() 前后各做一次(先入后出),适合需要"包裹"语义的场景,如计时、护栏、事务;管线模型是单向顺序处理,更简单但拿不到后置时机。Agent 多用洋葱模型:注册顺序决定入站顺序,出站则逆序,因此限流/鉴权放外层,缓存和成本统计放靠近 LLM 调用的内层。
追问 2:中间件如何短路(提前返回)而不继续往下走?
约定中间件不调用 next() 即视为短路,直接返回当前结果或抛出中止信号。典型用途:缓存命中时不再请求模型、限流超额时直接返回 429、护栏判定违规时拦截并返回兜底回复。短路要保证已注册的后置清理(如关闭 trace、释放并发额度)仍能执行,通常靠 try/finally 或洋葱出站阶段兜底。
追问 3:众多中间件叠加会增加延迟,如何控制开销?
把轻量、确定性的中间件(鉴权、限流、正则过滤)前置快速放行或拒绝,重的(LLM 审核、向量检索)只对高风险或必要路径启用;能并行的与流式生成并行执行;按环境与风险分级配置,非关键场景精简链路;并为每个中间件单独埋点统计耗时,发现瓶颈再针对性优化。
🔗 相似问题
同一考点的不同问法,面试官可能换着问,一起刷更稳
没找到想看的面试题?把你想看的告诉我们 →
延伸学习
按主题分类的相关资源,便于系统复习