第三部分 记忆
TypedDict
# TypedDic允许用户定义包含特定键和值类型的字典类型。
# 导入和定义
from typing import TypedDict
class Person(TypedDict):
name: str
age: int
address: str
# 创建符合类型的字典
user: Person = {
"name": "张三",
"age": 30,
"address": "北京市朝阳区"
}
# TypedDict 只在类型检查阶段起作用,在运行时它就是一个普通的字典
def print_type(obj):
print(type(obj))
person: Person = {"name": "李四", "age": 25, "address": "上海"}
print_type(person) # 输出: <class 'dict'>
Annotated
# 允许开发者为类型添加额外的元数据,而不影响运行时的类型行为。
from typing import Annotated
# 单个元数据
AgedInt = Annotated[int, "年龄值"]
# 多个元数据
UserID = Annotated[int, "用户ID", "必须为正整数"]
# 函数作为元数据
def validate_positive(x: int) -> bool:
return x > 0
ValidatedInt = Annotated[int, validate_positive]
简单应用
# 一个简单的内存应用系统
from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama import ChatOllama
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant. Answer all questions to the best of your ability."),
("placeholder", "{messages}"),
])
model = ChatOllama(model="deepseek-r1:32b", temperature=0)
chain = prompt | model
response = chain.invoke({
"messages": [
("human", "Translate this sentence from English to French: I love programming."),
("ai", "J'adore programmer."),
("human", "What did you just say?"),
],
})
print(response.content)
# I just repeated the French translation of your sentence: "J'adore programmer."
# If you'd like, I can provide additional information or examples!
添加记忆
# 建立一个图 实现简单的聊天机器人
from typing import Annotated, TypedDict
from langchain_core.messages import HumanMessage
from langchain_ollama import ChatOllama
from langgraph.graph import StateGraph, START, END, add_messages
# 使用TypedDict定义一个状态类型 并使用Annotated对其进行增强
class State(TypedDict):
messages: Annotated[list, add_messages]
# 创建状态图构建器
builder = StateGraph(State)
# 定义模型
model = ChatOllama(model="deepseek-r1:32b", temperature=0)
# 创建 节点通常是用函数表示
def chatbot(state: State):
answer = model.invoke(state["messages"])
return {"messages": [answer]}
# 添加聊天机器人节点
builder.add_node("chatbot", chatbot)
# 添加边
builder.add_edge(START, "chatbot")
builder.add_edge("chatbot", END)
# 编译状态图
graph = builder.compile()
input = {"messages": [HumanMessage("你好!")]}
for chunk in graph.stream(input):
print(chunk)
线程持久化
# 利用线程实现记忆持久化
from typing import Annotated, TypedDict
from langchain_core.messages import HumanMessage
from langchain_ollama import ChatOllama
from langgraph.graph import StateGraph, START, END, add_messages
from langgraph.checkpoint.memory import MemorySaver
# 定义状态类型
class State(TypedDict):
messages: Annotated[list, add_messages]
# 创建状态图构建器
builder = StateGraph(State)
# 定义模型
model = ChatOllama(model="deepseek-r1:32b", temperature=0)
# 定义聊天机器人函数
def chatbot(state: State):
answer = model.invoke(state["messages"])
return {"messages": [answer]}
# 添加聊天机器人节点
builder.add_node("chatbot", chatbot)
builder.add_edge(START, "chatbot")
builder.add_edge("chatbot", END)
# 设置在内存中保存数据 进行持久化
# 每个步骤结束后都会存储状态 下次调用时会从最近保存的状态继续,而不是重新开始
graph = builder.compile(checkpointer=MemorySaver())
# 配置线程
# 线程是独立的交互历史 在首次使用时自动创建
thread1 = {"configurable": {"thread_id": "1"}}
# 状态持久化示例
result_1 = graph.invoke({"messages": [HumanMessage("你好,我叫杰克!")]}, thread1)
print(result_1)
result_2 = graph.invoke({"messages": [HumanMessage("我叫什么名字?")]}, thread1)
print(result_2)
# 获取状态 返回的是包含所有历史状态的字典
print(graph.get_state(thread1))
# 简化的状态更新方式
from langgraph.graph import add_messages
from langchain_core.messages import SystemMessage
# 创建系统消息
system_message = SystemMessage("请使用尊敬的语气回复用户")
# 直接更新状态
graph.update_state(
thread1,
{"messages": [system_message]} # 添加单条消息
)
修改记录
修改聊天记录可以使历史记录处于最佳状态,提升模型的响应准确
修剪信息
大模型的上下文有限,过多的西南西会导致幻觉。修剪器帮助器允许指定我们想要从聊天历史记录中保留或删除多少令牌。
from langchain_core.messages import (
SystemMessage,
HumanMessage,
AIMessage,
trim_messages,
)
from langchain_ollama import ChatOllama
# 定义简单的消息历史
messages = [
SystemMessage(content="you're a good assistant"),
HumanMessage(content="hi! I'm bob"),
AIMessage(content="hi!"),
HumanMessage(content="I like vanilla ice cream"),
AIMessage(content="nice"),
HumanMessage(content="whats 2 + 2"),
AIMessage(content="4"),
HumanMessage(content="thanks"),
AIMessage(content="no problem!"),
HumanMessage(content="having fun?"),
AIMessage(content="yes!"),
]
# 创建修剪器
trimmer = trim_messages(
max_tokens=65, # 保留的最大token数量
strategy="last", # 修剪策略:保留最近的消息
token_counter=ChatOllama(model="deepseek-r1:32b"), # 用于计算token的模型
include_system=True, # 始终保留系统消息
allow_partial=False, # 不允许部分修剪消息
start_on="human", # 确保修剪后的历史从人类消息开始
)
trimmed = trimmer.invoke(messages)
print(trimmed)
过滤消息
消息过滤器可以按照类型、、ID或名称过滤聊天历史消息。
from langchain_core.messages import (
AIMessage,
HumanMessage,
SystemMessage,
filter_messages,
)
# 示例消息
messages = [
SystemMessage(content="你是一个好的助手", id="1"),
HumanMessage(content="示例输入", id="2", name="example_user"),
AIMessage(content="示例输出", id="3", name="example_assistant"),
HumanMessage(content="实际输入", id="4", name="bob"),
AIMessage(content="实际输出", id="5", name="alice"),
]
# 过滤人类消息
human_messages = filter_messages(messages, include_types="human")
# 过滤排除某些名字
excluded_names = filter_messages(
messages, exclude_names=["example_user", "example_assistant"]
)
# 按类型和ID过滤
filtered_messages = filter_messages(
messages, include_types=["human", "ai"], exclude_ids=["3"]
)
合并消息
from langchain_core.messages import (
AIMessage,
HumanMessage,
SystemMessage,
merge_message_runs,
)
# 示例消息,其中包含连续的同类型消息
messages = [
SystemMessage(content="你是一个好的助手。"),
SystemMessage(content="你总是用一个笑话来回应。"),
HumanMessage(
content=[{"type": "text", "text": "我想知道为什么它叫langchain"}]
),
HumanMessage(content="还有谁在追逐哈里森"),
AIMessage(
content='嗯,我猜他们认为“WordRope”和“SentenceString”没有同样的吸引力!'
),
AIMessage(
content="为什么,他可能在追逐办公室里的最后一杯咖啡!"
),
]
# 合并连续的消息
merged = merge_message_runs(messages)
print(merged)
2万+

被折叠的 条评论
为什么被折叠?



