大模型学习·第42天:LangChain进阶——自定义函数入链与对话记忆

一、RunnableLambda:自定义函数加入Chain

普通函数不能直接用 | 加入链,需要用 RunnableLambda 包装(也可直接传入lambda,会自动转换)。

python 复制代码
from langchain_core.runnables import RunnableLambda

# 函数接收AIMessage,返回dict
my_func = RunnableLambda(lambda ai_msg: {"name": ai_msg.content})

# 直接传lambda也可以,自动转换
chain = first_prompt | model | (lambda ai_msg: {"name": ai_msg.content}) | second_prompt | model | str_parser

两种入链方式 :封装为 RunnableLambda 对象再入链,或直接将函数入链自动转换。函数在链中接收上一个组件的输出,返回值传给下一个组件。可以在链中用自定义函数做数据格式转换、打印调试信息等。

二、Memory临时会话记忆

RunnableWithMessageHistory 在原链基础上创建带历史记录的新链,InMemoryChatMessageHistory 在内存中存储历史。

python 复制代码
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.chat_history import InMemoryChatMessageHistory

store = {}

def get_history(session_id):
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

conversation_chain = RunnableWithMessageHistory(
    base_chain,                            # 被增强的原链
    get_history,                           # 通过session_id获取历史记录对象
    input_messages_key="input",            # 用户输入在模板中的占位符名
    history_messages_key="chat_history"    # 历史记录在模板中的占位符名
)

# 调用时需传入session_id
session_config = {"configurable": {"session_id": "user_001"}}
res = conversation_chain.invoke({"input": "小明有2个猫"}, session_config)

工作流程 :每次调用时根据 session_id 获取该用户的历史记录,把历史填入模板的 chat_history 位置,模型结合历史回答问题,新的问答自动追加到历史中。不同 session_id 的历史互不影响。InMemoryChatMessageHistory 存在内存中,重启程序后消失,适合临时测试。

三、Memory长期会话记忆:FileChatMessageHistory

继承 BaseChatMessageHistory,重写三个方法,以 session_id 为文件名存到本地。

python 复制代码
from langchain_core.chat_history import BaseChatMessageHistory

class FileChatMessageHistory(BaseChatMessageHistory):
    def __init__(self, session_id, storage_path):
        self.session_id = session_id
        self.file_path = os.path.join(storage_path, session_id)
        os.makedirs(os.path.dirname(self.file_path), exist_ok=True)

    def add_messages(self, messages):
        all_messages = list(self.messages)
        all_messages.extend(messages)
        new_messages = [message_to_dict(m) for m in all_messages]
        with open(self.file_path, "w", encoding="utf-8") as f:
            json.dump(new_messages, f)

    @property
    def messages(self):
        try:
            with open(self.file_path, encoding="utf-8") as f:
                return messages_from_dict(json.load(f))
        except FileNotFoundError:
            return []

    def clear(self):
        with open(self.file_path, "w", encoding="utf-8") as f:
            json.dump([], f)

只需把 get_history 函数换成 return FileChatMessageHistory(session_id, "./chat_history"),历史记录就能持久化到磁盘文件。@property 装饰器让 messages 方法像属性一样访问。

四、两种记忆方案对比

方案 存储位置 重启后 适用场景
InMemoryChatMessageHistory 内存 丢失 临时测试
FileChatMessageHistory(自实现) 本地文件 保留 持久化存储

核心流程base_chain(原有链)→ RunnableWithMessageHistory(增强为带记忆的链)→ 调用时传 session_config 指定会话ID。

今日核心总结

  1. RunnableLambda:将自定义函数转为Runnable实例入链,lambda可直接传入
  2. 临时记忆RunnableWithMessageHistory + InMemoryChatMessageHistory,按session_id隔离
  3. 长期记忆 :继承 BaseChatMessageHistory,实现文件读写,持久化保存
  4. 调用格式 :invoke时传 {"configurable": {"session_id": "xxx"}},自动关联历史
  5. 调试技巧:链中加入自定义函数print信息,原样返回不破坏业务
相关推荐
Q26433650232 小时前
【有源码】基于 Hadoop 生态的化妆品销售数据存储分析与可视化 面向化妆品行业的用户画像构建与销售机会识别研究
大数据·hadoop·python·机器学习·spark·毕业设计·课程设计
2601_962078198 小时前
Python中calendar.weekday用法
python·编程技巧·calendar·日期处理·weekday
sunshine22 girl8 小时前
Java学习二 基本语法2, 算术运算符
java·学习
2601_962218618 小时前
万象生鲜系统业财一体化底层打通技术自动生成经营账单
大数据·数据库·人工智能·python·算法
2601_966949658 小时前
为什么量化策略需要大量历史股票数据?从回测可信度理解数据规模
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
2601_962885728 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
李高钢9 小时前
Python FastAPI 框架入门:从零搭建你的第一个高性能 API 服务
数据库·python·fastapi
ocean21039 小时前
2025-2026年Python面试高频知识点洞察
开发语言·python·面试·python八股文
Warson_L9 小时前
Python的OrderedDict
python
隐擎fox10 小时前
高性能网络爬虫架构设计:基于 Python 的长连接复用与分布式会话池调度实践
分布式·python·网络协议·tcp/ip·高并发·网络爬虫、