上下文管理与中间件:Agent 的抦截器模式

Published by rcdfrd on 2026-02-19

上下文管理与中间件:Agent 的抦截器模式

对话多了,消息历史越来越长,token 开销涨上去了。SummarizationMiddleware 能自动压缩旧消息,保持上下文窗口可控。同时,自定义中间件让你能在 Agent 执行的各个阶段插入自己的逻辑。

SummarizationMiddleware

from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model=model,
    checkpointer=InMemorySaver(),
    middleware=[
        SummarizationMiddleware(
            model=model,
            trigger=("messages", 6),  # 超过 6 条消息触发摘要
            keep=("messages", 4),    # 保留最近 4 条
        )
    ]
)

工作原理很直观:对话历史超过 6 条消息时,自动把旧消息压缩成一条摘要,只保留最近 4 条。这样 token 数不会无限增长,但重要信息不会丢。

你可以用便宜的模型来做摘要,省钱。

自定义中间件

想在 Agent 调用模型前后加日志?写个中间件:

from langchain.agents.middleware import AgentMiddleware

class MyMiddleware(AgentMiddleware):
    def before_agent(self, state, runtime):
        print(f"准备调用模型,当前 {len(state.get("messages", []))} 条消息")
        return None  # 返回 None 表示继续正常流程

    def after_model(self, state, runtime):
        last = state.get("messages", [])[-1]
        print(f"模型已响应,类型: {last.__class__.__name__}")
        return None

agent = create_agent(
    model=model,
    checkpointer=InMemorySaver(),
    middleware=[MyMiddleware()]
)

before_agent 在模型调用前触发,after_model 在模型返回后触发。返回 None 表示不修改状态,返回其他值可以篡改输入输出。

小结

中间件是 Agent 的抦截器。内置的 SummarizationMiddleware 解决长对话的 token 膨胀问题,自定义中间件让你加日志、做监控、改写状态。HumanInTheLoopMiddleware 也是中间件的一种。