19-day5-对比 有记忆 vs 无记忆

🧪 对比:有记忆 vs 无记忆

两个脚本:

  • agent_without_memory.py:每次对话都“失忆”
  • agent_with_memory.py:记住之前的对话(即你已有的程序)

第一步:准备两个脚本

✅ 脚本1:无记忆版(agent_without_memory.py

# agent_without_memory.py
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

load_dotenv()

llm = ChatOpenAI(
    model="qwen-max",
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
    temperature=0.7
)

# 注意:这里没有 MessagesPlaceholder,也没有历史
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个 AI 助手。"),
    ("human", "{input}")
])

chain = prompt | llm

if __name__ == "__main__":
    print("🤖 无记忆 Agent 启动!输入 'quit' 退出。\n")
    while True:
        user_input = input("👤 你: ")
        if user_input.strip().lower() == "quit":
            break
        response = chain.invoke({"input": user_input})
        print(f"🤖 Agent: {response.content}\n")

🔍 关键点:每次只传当前问题,不带历史 → 模型不知道之前聊过什么。


✅ 脚本2:有记忆版(agent_with_memory.py

就是你已经写好的那个(确保包含 .env 和依赖)。为方便对比,这里再精简确认一下核心逻辑:

# agent_with_memory.py(简化确认版)
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

load_dotenv()

llm = ChatOpenAI(
    model="qwen-max",
    openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
    openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
    temperature=0.7
)

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个有记忆的 AI 助手。请记住用户之前说过的话。"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}")
])

chain = prompt | llm

store = {}
def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

with_message_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history",
)

if __name__ == "__main__":
    print("🤖 有记忆 Agent 启动!输入 'quit' 退出。\n")
    while True:
        user_input = input("👤 你: ")
        if user_input.strip().lower() == "quit":
            break
        response = with_message_history.invoke(
            {"input": user_input},
            config={"configurable": {"session_id": "test123"}}
        )
        print(f"🤖 Agent: {response.content}\n")

第二步:运行对比测试

在终端中分别运行两个程序,用相同的对话流程测试

🔹 测试流程(对两个 Agent 都执行):

  1. 输入:我叫李明
  2. 输入:我叫什么名字?
  3. 输入:刚刚我说了什么?

第三步:对比

步骤 无记忆 Agent (agent_without_memory.py) 有记忆 Agent (agent_with_memory.py)
1. 我叫李明 👉 回复:“你好!” 或 “知道了。”(但不会记住) 👉 回复:“你好,李明!”
2. 我叫什么名字? ❌ 回复:“我不知道你的名字。”或瞎猜:“你没告诉我。” ✅ 回复:“你叫李明。”
3. 刚刚我说了什么? ❌ 回复:“我不记得了。”或胡说八道 ✅ 回复:“你刚刚说你叫李明。”

💡 这就是上下文缺失 vs 上下文完整的直接体现!


第四步:讨论点

  • 为什么无记忆版答不上来?
    → 因为它每次只看到当前一句话,像一个“金鱼记忆”的人。

  • 有记忆版是怎么做到的?
    → 它把之前的对话拼在新问题前面,一起发给大模型,相当于“复习聊天记录”。

  • 这种记忆是永久的吗?
    → 不是!程序一关,内存清空,记忆就没了(除非用数据库保存)。

  • 有没有代价?
    → 有!对话越长,发送的文本越多,消耗的 token 越多,速度变慢,费用增加。


✅ 小结

特性 无记忆 Agent 有记忆 Agent
实现复杂度 简单 中等
对话连贯性
适用场景 单次问答(如查天气) 多轮对话(如客服、助手)
Token 消耗 随对话指数级增长
posted @ 2026-01-29 23:04  船山薪火  阅读(13)  评论(0)    收藏  举报
![image](https://img2024.cnblogs.com/blog/3174785/202601/3174785-20260125205854513-941832118.jpg)