LangChain简明使用笔记(3)记忆

第三部分 记忆

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)

### LangChain 核心概念介绍 LangChain 是一种用于构建和管理复杂语言模型应用的框架,其设计目标是提供模块化和可扩展的架构,以便开发者能够轻松集成多种功能和服务,从而增强大型语言模型(LLM)的能力[^1]。 #### 1. **模块化架构** LangChain 提供了一种模块化的架构,使得开发人员可以根据需求灵活组合不同的组件来构建复杂的 LLM 应用程序。这种模块化的设计降低了学习成本并提高了开发效率[^2]。 #### 2. **支持多平台与服务集成** LangChain 支持与多个主流服务平台无缝对接,例如 OpenAI 的 ChatGPT 模型以及 Hugging Face 上的各种预训练模型。这为用户提供了极大的灵活性,在不同场景下可以选择最适合的模型和技术栈。 #### 3. **自定义子类机制** 为了适配特定的大规模语言模型(如 InternLM),可以通过继承 LangChain 中的标准 `LLM` 类来自定义子类。这样不仅可以实现对底层模型的具体封装,还能保持与其他部分的一致性调用方式[^3]。 #### 4. **Function Calling 功能拓展** 通过结合 Function Calling 技术,LangChain 能够让 LLM 不仅限于生成文本回复,还可以执行外部 API 请求或其他操作逻辑。这一特性极大地增强了交互式应用场景下的实用性。 以下是利用 Python 实现的一个简单例子展示如何初始化一个基本版本的应用: ```python from langchain.llms import BaseLLM from langchain.prompts import PromptTemplate from langchain.chains import LLMChain class CustomLLM(BaseLLM): def _call(self, prompt: str) -> str: # 这里替换为你自己的模型推理函数 return f"Response to &#39;{prompt}&#39;" llm = CustomLLM() template = """Question: {question} Answer:""" prompt = PromptTemplate(template=template, input_variables=["question"]) chain = LLMChain(llm=llm, prompt=prompt) print(chain.run(question="What is the capital of France?")) ``` 此代码片段展示了创建自定义 LLM 并将其嵌入到更广泛的工作流中的过程。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值