Akemi

Langchain模块Memory组件常用用法

2025/12/22
  • 个性化对话前缀
  • 多输入memory
  • 实体记忆
  • 对话知识图谱记忆

个性化前缀

这个个性化只限于在memory中,如果是希望在对话中有前缀,直接在prompt中规定就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from langchain_deepseek import ChatDeepSeek
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain.prompts import PromptTemplate
from dotenv import load_dotenv
load_dotenv()

llm = ChatDeepSeek(model="deepseek-chat")

template = """
以下是一个人类与AI的友好对话。如果AI不知道问题的答案,它会诚实的说不知道

当前对话:
{history}
human:{input}
AI:"""

prompt = PromptTemplate(input_variables=["history","input"],template=template)

conversation = ConversationChain(
prompt=prompt,
llm=llm,
verbose=True,
memory=ConversationBufferMemory(ai_prefix="AI助手",human_prefix="亲爱的用户")
)

print(conversation.invoke(input="你好"))
print(conversation.invoke(input="元旦上海到杭州的票更贵"))

# 以下是一个人类与AI的友好对话。如果AI不知道问题的答案,它会诚实的说不知道

# 当前对话:
# 亲爱的用户: 你好
# AI助手: 你好!很高兴见到你。有什么我可以帮助你的吗?
# human:元旦上海到杭州的票更贵
# AI:

# > Finished chain.
# {'input': '元旦上海到杭州的票更贵', 'history': '亲爱的用户: 你好\nAI助手: 你好!很高兴见到你。有什么我可以帮助你的吗?', 'response': '是的,通常节假日期间,如元旦,上海到杭州的火车票或汽车票价格会比平时更高,并且票源也会更加紧张。如果您有出行计划,建议提前预订车票,以获得更好的价格和座位选择。'}

多输入记忆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from langchain.chains.question_answering import load_qa_chain
from langchain_deepseek import ChatDeepSeek
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.text_splitter import CharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.vectorstores.elastic_vector_search import ElasticVectorSearch
from langchain.docstore.document import Document
from dotenv import load_dotenv
load_dotenv()

with open("./story.txt") as f:
file_story = f.read()
text_splitter = CharacterTextSplitter(chunk_size=200,chunk_overlap=20)
texts = text_splitter.split_text(file_story)

embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-mpnet-base-v2",
model_kwargs={'device': 'cpu'}
)
db = Chroma.from_texts(texts,embeddings)

template = """你是一个聊天机器人,根据以下长文档的提取部分生成最终回答
根据以下长文档提取部分回答问题
{context}

{chat_history}
人类用户: {input}
聊天机器人:"""

prompt = PromptTemplate(template=template,input_variables=["context","input","chat_history"])
memory = ConversationBufferMemory(memory_key="chat_history",input_key="input")
chain = load_qa_chain(ChatDeepSeek(model="deepseek-chat"),chain_type="stuff",prompt=prompt,memory=memory)

query = "艾琳是谁"
docs = db.similarity_search(query)
chain({"input_documents": docs,"input": query},return_only_outputs=True)
query = "故事的结局是什么"
chain.invoke({"input_documents": "","input": query})
print(chain.memory.buffer)

# Human: 艾琳是谁
# AI: 艾琳是故事中的主角,一位来自遥远未来的年轻天文学家。她在废弃的月球观测站发现了一份古老的星图,并由此踏上了寻找传说中“星核”的冒险旅程。在旅途中,她与机器人伙伴K-7一同探索了火星、木卫二和土星环中的遗迹,最终揭示了关于人类文明与宇宙平衡的深刻真相。
# Human: 故事的结局是什么
# AI: 故事的结局是,艾琳在土星环的古老遗迹中找到了“星核”——它并非实体宝藏,而是一种宇宙平衡意识的载体。她选择将星核的力量用于修复地球生态,并建立星际知识网络,让人类文明与宇宙和谐共存。最终,她与K-7继续航行深空,成为连接不同文明的守护者,而她的旅程也启发了新一代探索者追寻星空与真相。

实体记忆

实体记忆(Entity Memory) 是一种更高级的记忆机制,它专注于识别和跟踪对话中提到的具体实体(人物、地点、事物等)及其属性,而不是仅仅保存原始的对话历史。

  • 结构化存储,使用结构化的数据
  • 长期记忆能力
  • 智能推理和关联
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from langchain.memory import ConversationEntityMemory
from langchain.chains import ConversationChain
from langchain_deepseek import ChatDeepSeek
from langchain.prompts import PromptTemplate

from dotenv import load_dotenv
load_dotenv()

prompt = PromptTemplate(
input_variables=["entities", "history", "input"],
template="""已知以下实体信息:
{entities}
对话历史:
{history}
当前输入:{input}
回答:"""
)

# 初始化
llm = ChatDeepSeek(model="deepseek-chat", temperature=0.3)
memory = ConversationEntityMemory(llm=llm)
conversation = ConversationChain(llm=llm, memory=memory,prompt=prompt)

print("实体记忆\n")
# 介绍角色
responses = [
conversation.invoke("小蓝是乐队的键盘手,是富家千金,行事果敢自信"),
conversation.invoke("小绿是乐队的吉他手,性格沉默寡言,喜欢种黄瓜"),
conversation.invoke("小黑是乐队的鼓手,性格耿直,在ring打工"),
conversation.invoke("小灰是乐队的主唱和作词,喜欢收集石头、观察虫子,性格敏感内敛"),
conversation.invoke("小粽是乐队贝斯手,做事沉稳")
]

# 建立关系
conversation.invoke("乐队名叫做苦来兮苦,他们的第一首歌叫做《春日影》")
conversation.invoke("小蓝和小绿是青梅竹马")
conversation.invoke("小黑和小蓝都喜欢小灰")
conversation.invoke("乐队一开始只有小蓝和小灰,小黑是跟着小灰进来的,小绿和小粽是小蓝拉进乐队的")

print("📝 提问测试:")
# for question in questions:
answer = conversation.invoke("小灰和小绿是什么关系")
# print(f"问:{question}")
print(f"答:{answer}\n")

我tm一问,它给我返回了几千个字的回答

知识图谱记忆

是一种使用知识图谱来复原记忆的方法

  • 关系中心化:关注实体间的连接
  • 结构化存储:使用三元组格式
  • 推理强大:支持路径查询、关系推断
  • 适合:关系查询、网络分析、复杂推理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from langchain.memory import ConversationKGMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv
load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 创建知识图谱记忆
kg_memory = ConversationKGMemory(llm=llm)

conversation = ConversationChain(
llm=llm,
memory=kg_memory,
verbose=True,
)

# 给信息
conversation.predict(input="小蓝是乐队的键盘手")
conversation.predict(input="小蓝和小绿是青梅竹马")
conversation.predict(input="小蓝、小黑都喜欢小灰")
conversation.predict(input="小蓝、小粽和小绿是同校生")

print(kg_memory.load_memory_variables({"input": "谁是小蓝?"}))

# > Finished chain.
# {'history': 'On 小蓝: 小蓝 是 乐队的键盘手. 小蓝 喜欢 小灰. 小蓝 是 同校生. 小蓝 与小绿 是同校生.'}
CATALOG
  1. 1. 个性化前缀
  2. 2. 多输入记忆
  3. 3. 实体记忆
  4. 4. 知识图谱记忆