AI大模型企业应用实战-为Langchain Agent添加记忆功能

简介: 【8月更文挑战第18天】

本文已收录在Github关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

0 前言

在开发复杂的AI应用时,赋予Agent记忆能力是一个关键步骤。这不仅能提高Agent的性能,还能使其在多轮对话中保持上下文连贯性。本文详细介绍如何在Langchain框架中为Agent添加记忆功能,并深入解析每个步骤的原理和最佳实践。

Agent记忆功能的核心组件

Langchain构建具有记忆功能的Agent涉及核心组件:

  1. 工具(Tools): Agent用来执行特定任务的功能模块
  2. 记忆(Memory): 存储和检索对话历史的组件
  3. 大语言模型(LLM): 负责理解输入、决策和生成响应的核心智能体

协同工作,使得Agent在多轮对话中保持连贯性并做出明智决策。

1 构建Agent可用工具

定义Agent可用工具:

老版:

# 构建一个搜索工具,Langchain提供的一个封装,用于进行网络搜索。
search = SerpAPIWrapper()
# 创建一个数学计算工具,特殊的链,它使用LLM来解析和解决数学问题。
llm_math_chain = LLMMathChain(
    llm=llm,
    verbose=True
)
tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events or the current state of the world"
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math"
    ),
]
print(tools)

新版:

_ALLOWED_BIN_OPS = {
   
    ast.Add: operator.add,
    ast.Sub: operator.sub,
    ast.Mult: operator.mul,
    ast.Div: operator.truediv,
    ast.FloorDiv: operator.floordiv,
    ast.Mod: operator.mod,
    ast.Pow: operator.pow,
}
_ALLOWED_UNARY_OPS = {
   
    ast.UAdd: operator.pos,
    ast.USub: operator.neg,
}


def _safe_eval(node: ast.AST) -> Any:
    if isinstance(node, ast.Expression):
        return _safe_eval(node.body)
    if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
        return node.value
    if isinstance(node, ast.BinOp) and type(node.op) in _ALLOWED_BIN_OPS:
        return _ALLOWED_BIN_OPS[type(node.op)](_safe_eval(node.left), _safe_eval(node.right))
    if isinstance(node, ast.UnaryOp) and type(node.op) in _ALLOWED_UNARY_OPS:
        return _ALLOWED_UNARY_OPS[type(node.op)](_safe_eval(node.operand))
    raise ValueError(f"unsupported expression: {ast.dump(node)}")


@tool
def calculator(expression: str) -> str:
    """Evaluate a basic arithmetic expression, for example '18 * 23 + 7'."""
    try:
        return str(_safe_eval(ast.parse(expression, mode="eval")))
    except Exception as exc:
        return f"计算失败:{exc}"


tools = [calculator]

if os.getenv("SERPAPI_API_KEY"):
    try:
        from langchain_community.utilities import SerpAPIWrapper

        _search = SerpAPIWrapper()

        @tool
        def web_search(query: str) -> str:
            """Search the web for current or external information."""
            return _search.run(query)

        tools.append(web_search)
    except ImportError as exc:
        print(f"SerpAPI 搜索工具未启用:{exc}")
tools

2 增加memory组件

为Agent添加记忆功能。

老版:

from langchain.memory import ConversationBufferMemory

# 记忆组件
memory = ConversationBufferMemory(
    # 指定了存储对话历史的键名
    memory_key="chat_history",
      # 确保返回的是消息对象,而不是字符串,这对于某些Agent类型很重要
    return_messages=True
)

3 定义agent

有了工具和记忆组件,可初始化Agent。

老版:

agent_chain = initialize_agent(
    tools, 
    llm, 
    handle_parsing_errors=True,
    memory=memory
)
  • handle_parsing_errors=True: 自动处理解析错误,提高Agent的稳定性。
  • memory=memory: 将我们之前定义的记忆组件传递给Agent。

新版:

# 负责保存状态
checkpointer = InMemorySaver()

agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是一个中文助手。需要计算时优先调用 calculator 工具。回答要简洁。",
    checkpointer=checkpointer,
)
# thread_id决定每次调用归属于哪段会话
config = {
   "configurable": {
   "thread_id": "qwen-memory-demo"}}

相同 thread_id 会读取历史消息,不同 thread_id 彼此隔离。

4 查看默认的agents prompt

了解Agent使用的默认提示词模板非常重要,有助理解Agent的行为并进行调整:

print(agent_chain.agent.prompt.messages)
print(agent_chain.agent.prompt.messages[0])
print(agent_chain.agent.prompt.messages[1])
print(agent_chain.agent.prompt.messages[2])

输出Agent使用的默认提示词模板。包括系统消息、人类消息提示词模板和AI消息模板:

5 优化Agent配置

为了更好地利用记忆功能,修改Agent配置,确保它在每次交互中都能访问对话历史,让Agent每次决策时都能考虑到之前对话内容。

老版

需用agent_kwargs传递参数,将chat_history传入

agent_chain = initialize_agent(
    tools, 
    llm, 
    handle_parsing_errors=True,#处理解析错误
    # 通过该参数可自定义Agent的行为
    agent_kwargs={
   
        "extra_prompt_messages":
      # chat_history用于插入对话历史
      [MessagesPlaceholder(variable_name="chat_history"),
      # agent_scratchpad用于Agent的中间思考过程
      MessagesPlaceholder(variable_name="agent_scratchpad")],
    },
    memory=memory #记忆组件
    )

老版 memory 思路

这套写法依赖旧 agent 抽象,memory 必须和 prompt 变量名对齐,agent_scratchpad、chat_history 放错就容易失效。

而新版重点是 thread_id。同一个 thread_id 会继续读取历史消息,不同 thread_id 就是独立会话。这更接近现在 LangChain/LangGraph 的状态模型。

6 验证优化后的提示词模板

print(agent_chain.agent.prompt.messages)
print(agent_chain.agent.prompt.messages[0])
print(agent_chain.agent.prompt.messages[1])
print(agent_chain.agent.prompt.messages[2])

能看到新添加的chat_historyagent_scratchpad占位符。

7 总结

LangChain 1.x 主流写法:create_agent + InMemorySaver + thread_id。工具改成 @tool,数学工具不再依赖旧 chain。

为Langchain Agent添加记忆,使得Agent能够在多轮对话中保持上下文连贯性,大大提高其在复杂任务中的表现。

添加记忆功能只是构建高效Agent第一步。按需调整记忆组件的类型和参数,或实现更复杂的记忆管理策略。

注意平衡记忆的深度和Agent响应速度。过多历史信息导致决策缓慢或偏离主题。因此,你可能需实现某种形式的记忆修剪或总结机制。

目录
相关文章
|
10月前
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
3561 1
|
10月前
|
人工智能 自然语言处理 NoSQL
超越基础提示:用RAG为你的大模型注入“新鲜记忆”
超越基础提示:用RAG为你的大模型注入“新鲜记忆”
424 110
|
10月前
|
人工智能 自然语言处理 API
快速集成GPT-4o:下一代多模态AI实战指南
快速集成GPT-4o:下一代多模态AI实战指南
694 101
|
10月前
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
5610 58
|
9月前
|
存储 监控 算法
1688 图片搜索逆向实战:CLIP 多模态融合与特征向量落地方案
本文分享基于CLIP模型与逆向工程实现1688图片搜同款的实战方案。通过抓包分析破解接口签名,结合CLIP多模态特征提取与Faiss向量检索,提升搜索准确率至91%,单次响应低于80ms,日均选品效率提升4倍,全程合规可复现。
|
10月前
|
机器学习/深度学习 算法 数据可视化
从零开始训练推理模型:GRPO+Unsloth改造Qwen实战指南
推理型大语言模型兴起,通过先思考再作答提升性能。本文介绍GRPO等强化学习算法,详解其原理并动手用Qwen2.5-3B训练推理模型,展示训练前后效果对比,揭示思维链生成的实现路径。
1347 2
从零开始训练推理模型:GRPO+Unsloth改造Qwen实战指南
|
10月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
1523 12
|
10月前
|
人工智能 自然语言处理 算法
现代AI工具深度解析:从GPT到多模态的技术革命与实战应用
蒋星熠Jaxonic,AI技术探索者,深耕代码生成、多模态AI与提示词工程。分享AI工具架构、实战应用与优化策略,助力开发者提升效率,共赴智能编程新纪元。
|
10月前
|
人工智能 安全 数据库
构建可扩展的 AI 应用:LangChain 与 MCP 服务的集成模式
本文以LangChain和文件系统服务器为例,详细介绍了MCP的配置、工具创建及调用流程,展现了其“即插即用”的模块化优势,为构建复杂AI应用提供了强大支持。

热门文章

最新文章