LangChain 1.0-Agent中间件-删除消息

发布时间:2026-03-02 21:55:42编辑:123阅读(27)

    LangChain 1.0 Agent中间件删除消息

    删除是一种更主动的上下文管理方式。它允许开发者通过RemoveMessage机制,精确指定要删除哪些消息,例如清除最早的2条消息、只删除tool调用类消息、或直接重置整个会话。这种方法通常配合@after_model 钩子使用,也就是说在模型回复后清理历史消息,保证下次调用上下文简介干净。删除策略通常用于长周期运行的Agent或工作流系统中,既能防止上下文爆炸,又能在关键节点(如新任务开始)重置状态,实现“会话阶段化”管理。

    from langchain.agents import create_agent, AgentState
    from langchain.agents.middleware import before_model, after_model
    from langchain.messages import RemoveMessage
    from langgraph.checkpoint.memory import InMemorySaver
    from langgraph.runtime import Runtime
    from langchain_ollama import ChatOllama
    import requests
    import time
    from lxml import etree
    from langchain.tools import tool
    
    
    # 初始化模型
    model = ChatOllama(
        model="qwen3:8b",
        temperature=0.2,
        top_p=0.95,
    )
    
    @tool
    def get_weather(city):
        """
        查询即时天气函数
        :param city: 必要参数,字符串类型。用于表示查询天气的具体城市名称
        :return: 返回即时天气的结果,dict类型
        """
        today_time = time.strftime("%Y-%m-%d",time.localtime())
        url = f'https://www.ks121.com/history/?location={city}&startdate={today_time}&enddate={today_time}'
        headers = {
            "sec-ch-ua": '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
            Chrome/144.0.0.0 Safari/537.36"
        }
        response = requests.get(url=url, headers=headers, timeout=10)
        html = etree.HTML(response.text)
        res = html.xpath("//div[@class='box']/div[2]/div[1]/div/table/tbody/tr")
        ret = {}
        for i in res:
            one = i.xpath("./td[1]/p[2]/text()")[0]
            two = i.xpath("./td[2]/p[2]/span/text()")[0]
            three = i.xpath("./td[3]/p/text()")[0]
            four = i.xpath("./td[4]/p/text()")[0]
            ret.setdefault('日期', one)
            ret.setdefault('气象', two)
            ret.setdefault('温度', three)
            ret.setdefault('风级', four)
        print(f"工具调用:{today_time}:{city}天气信息:{ret}")
        return ret
    
    @after_model
    def delete_old_messages(state: AgentState, runtime:Runtime):
        """模型调用后,删除最早的两条消息"""
        messages = state["messages"]
        if len(messages) > 4:
            removed = [m.id for m in messages[:2]]
            print(f"删除前两条消息,ID:{removed}")
            return {"messages": [RemoveMessage(id=m.id) for m in messages[:2]]}
        return None
    agent = create_agent(
        model=model,
        tools=[get_weather],
        middleware=[delete_old_messages],
        checkpointer=InMemorySaver(),
    )
    
    config = {
        "configurable":{
            "thread_id":"3"
        }
    }
    
    resp1 = agent.invoke(
        {"messages":"今天上海的天气? 你好,我叫张三。"},
        config=config,
    )
    print(resp1["messages"][-1].content)
    
    
    resp2 = agent.invoke(
        {"messages":"你还记得我叫什么吗?"},
        config=config,
    )
    print(resp2["messages"][-1].content)
    
    resp3 = agent.invoke(
        {"messages":"一天喝多少水比较健康?"},
        config=config,
    )
    print(resp3["messages"][-1].content)
    
    resp4 = agent.invoke(
        {"messages":"介绍下你自己"},
        config=config,
    )
    print(resp4["messages"][-1].content)
    
    resp5 = agent.invoke(
        {"messages":"帮我写一句每日格言"},
        config=config,
    )
    print(resp5["messages"][-1].content)
    
    print('历史消息')
    for i in agent.get_state(config).values["messages"]:
        print(i.content)

    运行结果:

    工具调用:2026-03-02:上海天气信息:{'日期': '2026-03-02', '气象': '阴', '温度': '6℃\n~ 10℃', '风级': '南风转西北风<3级转3-4

    级'}

    张三,今天是2026年3月2日,上海天气阴,气温在6℃到10℃之间,风向由南风转为西北风,风力从3级转为3-4级。建议根据

    温度变化适时增减衣物哦!

    删除前两条消息,ID:['83d9d6bf-3152-4688-91d4-72a4a7573e08', 'lc_run--019caed3-c5c7-7cb2-bf0b-93922d2ba1d8-0']

    记得啊,你叫张三,之前还和你聊过天气呢!有什么我可以帮你的吗?

    删除前两条消息,ID:['67e2cfa7-08b2-43e5-bdfb-e1bad7bfc359', 'lc_run--019caed3-d7ed-7f32-adf3-f81c24722b15-0']

    每日饮水量因人而异,但一般建议成年人每天摄入约 **1500-2000毫升**(约6-8杯)水,具体可参考以下因素:


    1. **体重**:每公斤体重约需30-35毫升水(如60kg体重约需1800-2100ml)。

    2. **活动量**:运动或出汗多时需额外补充。

    3. **气候**:炎热/干燥环境需增加摄入。

    4. **健康状况**:如肾功能异常、心脏病等需遵医嘱调整。


    **提示**:可通过尿液颜色判断(淡黄色为佳),但不要强迫饮水,自然口渴时补充即可。

    删除前两条消息,ID:['21ac88ff-cfc8-48cf-81c8-e8cc09c88d93', 'lc_run--019caed3-ec94-7e62-8e3f-602bd2f1a348-0']

    你好!我是一个大型语言模型,可以帮你解答各种问题、提供建议和进行有趣的话题讨论。你可以随时问我:


    - 生活常识(比如如何做菜、健康建议)

    - 学术知识(数学物理、文学历史等)

    - 技术问题(编程、硬件、网络)

    - 轻松聊天(分享趣事、讨论电影书籍)

    - 多轮对话(比如规划旅行路线、分析小说情节)


    需要什么帮助吗?😊

    删除前两条消息,ID:['373131f7-7c4e-422c-8707-495aeb6b9f2a', 'lc_run--019caed3-f757-7c92-89cc-a035d5cbdb8e-0']

    愿你如晨曦中的种子,不惧风雨,静待花开,每一步成长都是对时光最好的回答。

    历史消息

    介绍下你自己

    你好!我是一个大型语言模型,可以帮你解答各种问题、提供建议和进行有趣的话题讨论。你可以随时问我:


    - 生活常识(比如如何做菜、健康建议)

    - 学术知识(数学物理、文学历史等)

    - 技术问题(编程、硬件、网络)

    - 轻松聊天(分享趣事、讨论电影书籍)

    - 多轮对话(比如规划旅行路线、分析小说情节)


    需要什么帮助吗?😊

    帮我写一句每日格言

    愿你如晨曦中的种子,不惧风雨,静待花开,每一步成长都是对时光最好的回答。


关键字