当前位置: 首页 > wzjs >正文

地方o2o同城网站源码系统开发总结

地方o2o同城网站源码,系统开发总结,做网站中app客户端,校园网站建设必要性1. 为什么需要内存? 大型语言模型(LLM)本身是无状态的。这意味着每次你向 LLM 发送一个请求(Prompt),它都会独立处理这个请求,完全不记得之前任何的交互。这在构建一次性问答应用时没问题&#…

1. 为什么需要内存?

大型语言模型(LLM)本身是无状态的。这意味着每次你向 LLM 发送一个请求(Prompt),它都会独立处理这个请求,完全不记得之前任何的交互。这在构建一次性问答应用时没问题,但在需要多轮对话(比如聊天机器人、智能客服)的场景中,LLM 需要“记住”之前的对话内容,才能理解上下文并做出连贯的回复。

内存就是 LangChain 解决这个问题的方案。它允许你在 LLM 应用中注入和管理对话历史,让 LLM 具备“长期”记忆的能力。

简单来讲就是存储历史记录,然后在每次使用 LLM 时,不仅传入当前输入,还有历史记录

2. 内存的基本工作原理

在 LangChain 中,内存通常扮演着连接用户输入LLM 提示的桥梁。

  1. 保存历史:每次用户和 LLM 进行交互后,内存组件都会捕获并存储这次对话的输入和输出。
  2. 加载历史:在下一次 LLM 调用之前,内存会根据需要从其存储中加载相关的对话历史。
  3. 注入提示:加载的对话历史会被格式化并注入到 LLM 的提示(Prompt)中,作为上下文的一部分。这样,LLM 就能“看到”之前的对话内容,从而理解当前问题的背景。

3. 最简单的内存:对话缓冲区(ConversationBufferMemory)

ConversationBufferMemory 是 LangChain 中最基础也是最常用的内存类型。它非常简单粗暴:记住所有对话的原始文本。它会将完整的对话历史原封不动地存储起来,并在每次调用时将所有历史添加到提示中。

ConversationBufferMemory 流程
发送给LLM
保存到内存
从内存加载
添加到Prompt
LLM Chain/Agent
用户输入
LLM
LLM 输出
ConversationBufferMemory
# memory_buffer_example.pyfrom langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
import os# --- 配置部分 ---
# os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"if not os.getenv("OPENAI_API_KEY"):print("错误:请设置环境变量 OPENAI_API_KEY 或在代码中取消注释并设置您的密钥。")exit()print("--- ConversationBufferMemory 示例开始 ---")# 1. 定义 LLM
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)# 2. 定义内存
# memory_key 是在 Prompt 中用来引用对话历史的变量名
# return_messages=True 表示内存返回的是消息对象列表,而不是单个字符串
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
print("已创建 ConversationBufferMemory。")# 3. 定义带有历史占位符的 Prompt
# MessagesPlaceholder 用于告诉 Prompt 在这里插入消息列表 (chat_history)
prompt = ChatPromptTemplate.from_messages([("system", "你是一个友好的AI助手,擅长进行多轮对话。"),MessagesPlaceholder(variable_name="chat_history"), # 聊天历史的占位符("human", "{input}") # 当前用户输入
])
print("已创建包含 chat_history 占位符的 Prompt。")# 4. 创建 ConversationChain
# ConversationChain 是 LangChain 提供的一个预构建的链,专为处理对话而设计
# 它会自动处理内存的注入和更新
conversation = ConversationChain(llm=llm,memory=memory,prompt=prompt,verbose=True # 打印详细日志,可以看到内存注入到 Prompt 的过程
)
print("已创建 ConversationChain。")# 5. 进行多轮对话
print("\n--- 开始对话 ---")# 第一轮
print("\n用户: 你好,我叫小明。你叫什么名字?")
response1 = conversation.invoke({"input": "你好,我叫小明。你叫什么名字?"})
print(f"AI: {response1['response']}")# 第二轮
print("\n用户: 很高兴认识你!我之前告诉你我叫什么名字了?")
response2 = conversation.invoke({"input": "很高兴认识你!我之前告诉你我叫什么名字了?"})
print(f"AI: {response2['response']}")# 第三轮
print("\n用户: 帮我写一句关于编程的诗。")
response3 = conversation.invoke({"input": "帮我写一句关于编程的诗。"})
print(f"AI: {response3['response']}")print("\n--- 对话结束 ---")
print("\n--- ConversationBufferMemory 示例结束 ---")
  • ConversationBufferMemory 将所有交互都作为 HumanMessageAIMessage 存储起来。
  • MessagesPlaceholder 是一个非常关键的组件,它告诉 LangChain 在构建最终发送给 LLM 的提示时,应该将 chat_history 这个变量的内容(即内存中的消息列表)插入到这里。
  • ConversationChain 是一个便利的链,它自动处理了内存的读写,简化了对话应用的构建。

4. 限制历史长度:对话缓冲区窗口内存(ConversationBufferWindowMemory)

ConversationBufferMemory 的一个缺点是,如果对话很长,内存中的历史会不断增长,导致每次发送给 LLM 的提示越来越长,最终可能超出 LLM 的上下文窗口限制(Context Window Limit),并增加 API 成本。

ConversationBufferWindowMemory 解决了这个问题,它只记住最近 N 轮的对话

ConversationBufferWindowMemory 流程
发送给LLM
保存到内存 (仅保留最新N轮)
从内存加载 (仅加载最新N轮)
添加到Prompt
LLM Chain/Agent
用户输入
LLM
LLM 输出
ConversationBufferWindowMemory
# memory_window_example.pyfrom langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferWindowMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
import os# --- 配置部分 ---
# os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"if not os.getenv("OPENAI_API_KEY"):print("错误:请设置环境变量 OPENAI_API_KEY 或在代码中取消注释并设置您的密钥。")exit()print("--- ConversationBufferWindowMemory 示例开始 ---")llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)# 定义窗口大小为 2,表示只记住最近 2 轮(4条消息:2用户+2AI)对话
memory = ConversationBufferWindowMemory(memory_key="chat_history", return_messages=True, k=2)
print("已创建 ConversationBufferWindowMemory,窗口大小 k=2。")prompt = ChatPromptTemplate.from_messages([("system", "你是一个友好的AI助手,只记得最近的对话。"),MessagesPlaceholder(variable_name="chat_history"),("human", "{input}")
])conversation = ConversationChain(llm=llm,memory=memory,prompt=prompt,verbose=True
)
print("已创建 ConversationChain。")# 5. 进行多轮对话,观察内存如何截断
print("\n--- 开始对话 ---")# 第一轮
print("\n用户: 我喜欢吃苹果。")
response1 = conversation.invoke({"input": "我喜欢吃苹果。"})
print(f"AI: {response1['response']}")# 第二轮
print("\n用户: 你呢?你喜欢什么水果?")
response2 = conversation.invoke({"input": "你呢?你喜欢什么水果?"})
print(f"AI: {response2['response']}")# 第三轮 - 此时第一轮对话(用户说“我喜欢吃苹果”)应该被“遗忘”
print("\n用户: 我之前喜欢什么水果来着?")
response3 = conversation.invoke({"input": "我之前喜欢什么水果来着?"})
print(f"AI: {response3['response']}") # AI可能无法准确回答,因为它忘记了第一轮# 第四轮 - 此时第二轮对话应该被遗忘
print("\n用户: 你呢?你刚才喜欢什么水果?")
response4 = conversation.invoke({"input": "你呢?你刚才喜欢什么水果?"})
print(f"AI: {response4['response']}")print("\n--- 对话结束 ---")
print("\n--- ConversationBufferWindowMemory 示例结束 ---")
  • k=2 参数控制了窗口大小。这意味着内存将只保留最近的 2 轮完整的对话(即 2 条用户消息和 2 条 AI 消息)。
  • 你会发现,在第三轮对话中,模型可能无法回忆起第一轮用户提到的“苹果”,因为它已经超出了窗口范围。

5. 总结历史:对话摘要内存(ConversationSummaryMemory)

ConversationBufferWindowMemory 虽然限制了历史长度,但可能会丢失早期对话的关键信息。ConversationSummaryMemory 旨在解决这个问题:它不直接存储所有历史,而是使用一个 LLM 对对话历史进行摘要,然后将这个摘要作为上下文提供给主 LLM。

这样,无论对话多长,每次传递给 LLM 的都是一个简洁的摘要,既能保持上下文,又不会超出令牌限制。

ConversationSummaryMemory 流程
发送给LLM
添加到历史
LLM生成摘要
摘要添加到Prompt
LLM Chain/Agent
用户输入
LLM
LLM 输出
完整对话历史
ConversationSummaryMemory
# memory_summary_example.pyfrom langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationSummaryMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
import os# --- 配置部分 ---
# os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"if not os.getenv("OPENAI_API_KEY"):print("错误:请设置环境变量 OPENAI_API_KEY 或在代码中取消注释并设置您的密钥。")exit()print("--- ConversationSummaryMemory 示例开始 ---")# 定义一个用于生成摘要的 LLM
# 摘要LLM可以是一个更小的、成本更低的模型,或者与主LLM相同
summary_llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
main_llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)# 1. 定义内存
# memory_key 和 return_messages 类似之前的内存
# llm 参数指定了用于生成摘要的 LLM
memory = ConversationSummaryMemory(llm=summary_llm, memory_key="chat_history", return_messages=True)
print("已创建 ConversationSummaryMemory。")prompt = ChatPromptTemplate.from_messages([("system", "你是一个友好的AI助手,能记住所有对话的重要摘要。"),MessagesPlaceholder(variable_name="chat_history"), # 这里传入的是摘要("human", "{input}")
])conversation = ConversationChain(llm=main_llm,memory=memory,prompt=prompt,verbose=True
)
print("已创建 ConversationChain。")# 5. 进行多轮对话,观察内存如何进行摘要
print("\n--- 开始对话 ---")# 第一轮
print("\n用户: 我的项目遇到了一个问题,需要你的帮助。我正在开发一个Python脚本,它需要处理大量文本数据。")
response1 = conversation.invoke({"input": "我的项目遇到了一个问题,需要你的帮助。我正在开发一个Python脚本,它需要处理大量文本数据。"})
print(f"AI: {response1['response']}")# 第二轮
print("\n用户: 具体来说,我需要对文本进行分词和词性标注。你有什么建议的库吗?")
response2 = conversation.invoke({"input": "具体来说,我需要对文本进行分词和词性标注。你有什么建议的库吗?"})
print(f"AI: {response2['response']}")# 第三轮
print("\n用户: 好的,我会试试 NLTK 和 SpaCy。你认为哪个更适合大型项目?")
response3 = conversation.invoke({"input": "好的,我会试试 NLTK 和 SpaCy。你认为哪个更适合大型项目?"})
print(f"AI: {response3['response']}")# 第四轮 - 此时内存会包含前三轮的摘要
print("\n用户: 好的,谢谢你的建议。我的项目主要是关于中文文本处理。")
response4 = conversation.invoke({"input": "好的,谢谢你的建议。我的项目主要是关于中文文本处理。"})
print(f"AI: {response4['response']}")print("\n--- 对话结束 ---")
# 打印最终的摘要内容
print("\n当前内存中的摘要:")
print(memory.buffer)print("\n--- ConversationSummaryMemory 示例结束 ---")

说明:

  • ConversationSummaryMemory 需要一个 llm 参数来执行摘要任务。这个 llm 可以是与主 LLM 相同的模型,也可以是专门为摘要优化的模型。
  • 通过 verbose=True 观察输出,你会发现每次调用时,LLM 接收到的 chat_history 变量会是一个不断更新的摘要字符串,而不是原始的完整消息列表。

6. 其他常用内存类型

LangChain 还提供了其他更高级或更具体用途的内存类型:

  • ConversationSummaryBufferMemory: 结合了 ConversationBufferWindowMemoryConversationSummaryMemory 的特点。它会保留最近 N 轮的完整对话,而将 N 轮之前的对话进行摘要。这样可以在短期内提供精确上下文,同时长期保持摘要记忆。
  • VectorStoreRetrieverMemory: 这种内存将对话历史存储在向量数据库中。当需要回忆信息时,它会像 RAG 那样,根据当前查询在向量数据库中检索最相关的历史片段,而不是全部或摘要。这对于需要记忆超长对话或从大量历史中检索特定信息非常有用。
  • EntityMemory: 专注于从对话中识别和记忆特定的实体(如人名、地点、概念),并将其存储在一个结构化(通常是 JSON)的知识图中。当对话中再次提到这些实体时,LLM 可以直接引用其存储的信息。

7. 选择合适的内存策略

  • ConversationBufferMemory: 适用于短对话、简单场景或调试。
  • ConversationBufferWindowMemory: 适用于需要限制上下文长度、但仍需保持一定近期对话完整性的场景。
  • ConversationSummaryMemory: 适用于长对话,需要保持核心上下文但又不能超出 LLM 上下文窗口的场景。
  • ConversationSummaryBufferMemory: 结合了短期精确记忆和长期摘要记忆的优点。
  • VectorStoreRetrieverMemory: 适用于需要从海量、复杂对话历史中智能检索相关片段的场景,或构建具备“知识库”的聊天机器人。
  • EntityMemory: 适用于需要记忆和跟踪特定实体信息(如客户档案、产品属性)的对话场景。

文章转载自:

http://t6iy2ZwS.dmfdL.cn
http://DJiK7k8n.dmfdL.cn
http://94pKxsdF.dmfdL.cn
http://izm5eU8I.dmfdL.cn
http://ABdezQaV.dmfdL.cn
http://HhUhKczp.dmfdL.cn
http://ioTEmLCR.dmfdL.cn
http://We7diYMi.dmfdL.cn
http://Y844Ud85.dmfdL.cn
http://74gHblFJ.dmfdL.cn
http://i9mtkp83.dmfdL.cn
http://1IUIBlzx.dmfdL.cn
http://xSUNLNzS.dmfdL.cn
http://Ye7eZHz7.dmfdL.cn
http://uNs77JNn.dmfdL.cn
http://1SKGMwVq.dmfdL.cn
http://UOoY16LP.dmfdL.cn
http://ph84OMJ7.dmfdL.cn
http://6oDvvvb5.dmfdL.cn
http://aUpzBLSH.dmfdL.cn
http://E2aRXL63.dmfdL.cn
http://RcKuMaRv.dmfdL.cn
http://taysicnO.dmfdL.cn
http://Umi9aaMn.dmfdL.cn
http://jQk6doVy.dmfdL.cn
http://K3tmDeFT.dmfdL.cn
http://INYHXyUq.dmfdL.cn
http://QkQlIBbF.dmfdL.cn
http://L0Re4Q8W.dmfdL.cn
http://Qzo65IXH.dmfdL.cn
http://www.dtcms.com/wzjs/636661.html

相关文章:

  • 广州微信网站建设市场网站管理助手v3.0
  • 靖江网站定制淘宝天猫网上购物商城
  • win8风格 网站模板装饰公司门头
  • 好网站建设公司哪里好国家高新技术企业官网
  • python做网站入门网站开发交什么税
  • 网站访问量咋做2022年深圳在建工程查询
  • 英山县城乡建设规划局网站做物流网站费用多少
  • 有口碑的中山网站建设wordpress免费商城模板下载
  • 网站的push运营怎么做开发一个app价目表
  • 营销型网站建设公司是干嘛的wordpress api 发贴
  • 网站开发如何共用菜单栏企业负责人电话名录
  • 徐汇科技网站建设网站建设方案书 模板
  • 山西省住房建设厅网站房屋建筑定额西安网站建设公司有哪些
  • 南阳做网站优化wordpress 插件 前端
  • 常用的电子商务网站开发技术东营企业网站制作
  • 服装网站策划设计二手书交易网站开发背景分析
  • 网站建设模板源码特效网站域名密码忘了
  • 青海西宁学做网站在哪上海网页制作服务
  • 郴州网站建设哪家比较好建筑网78
  • 网站建设288网站被360拦截怎么办
  • 网站semseo先做哪个网站 审批号
  • 深圳网站见企业网站建设电话
  • 凡科网做网站收费吗吃什么补肾最快
  • 淘宝客网站哪里可以做导购网站如何做淘宝客
  • 石狮网站建设公司哪家好网络信息安全公司排名
  • 深圳市做网站设计wordpress 调整页面布局
  • 兰州交通发展建设集团公司网站互联网营销师资格证
  • 个人可做网站需要什么材料如何租用服务器做网站
  • 泰格豪雅手表官方网站网络规划设计师教程第二版 pdf
  • 简述网站开发的5个步骤照片书哪家网站做的好