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响应速度。过多历史信息导致决策缓慢或偏离主题。因此,你可能需实现某种形式的记忆修剪或总结机制。

目录
相关文章
|
8月前
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
3263 1
|
8月前
|
人工智能 自然语言处理 NoSQL
超越基础提示:用RAG为你的大模型注入“新鲜记忆”
超越基础提示:用RAG为你的大模型注入“新鲜记忆”
393 110
|
9月前
|
人工智能 自然语言处理 算法
提升LangChain开发效率:10个被忽视的高效组件,让AI应用性能翻倍
LangChain作为主流大语言模型应用框架,其高级组件常被忽视。本文详解10个高价值但低使用率的核心组件,如语义检索、多模板路由、智能查询转换等,结合技术原理与实践案例,助开发者构建更高效、智能、适应性强的AI系统,提升应用性能与业务价值。
632 0
|
8月前
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
4930 58
|
8月前
|
人工智能 安全 数据库
构建可扩展的 AI 应用:LangChain 与 MCP 服务的集成模式
本文以LangChain和文件系统服务器为例,详细介绍了MCP的配置、工具创建及调用流程,展现了其“即插即用”的模块化优势,为构建复杂AI应用提供了强大支持。
|
9月前
|
SQL 人工智能 Java
用 LangChain4j+Ollama 打造 Text-to-SQL AI Agent,数据库想问就问
本文介绍了如何利用AI技术简化SQL查询操作,让不懂技术的用户也能轻松从数据库中获取信息。通过本地部署PostgreSQL数据库和Ollama模型,结合Java代码,实现将自然语言问题自动转换为SQL查询,并将结果以易懂的方式呈现。整个流程简单直观,适合初学者动手实践,同时也展示了AI在数据查询中的潜力与局限。
1216 8
|
存储 人工智能 自然语言处理
AI经营|多Agent择优生成商品标题
商品标题中关键词的好坏是商品能否被主搜检索到的关键因素,使用大模型自动优化标题成为【AI经营】中的核心能力之一,本文讲述大模型如何帮助商家优化商品素材,提升商品竞争力。
1763 62
AI经营|多Agent择优生成商品标题
|
机器学习/深度学习 人工智能 自然语言处理
Gemini 2.0:谷歌推出的原生多模态输入输出 + Agent 为核心的 AI 模型
谷歌最新推出的Gemini 2.0是一款原生多模态输入输出的AI模型,以Agent技术为核心,支持多种数据类型的输入与输出,具备强大的性能和多语言音频输出能力。本文将详细介绍Gemini 2.0的主要功能、技术原理及其在多个领域的应用场景。
1522 20
Gemini 2.0:谷歌推出的原生多模态输入输出 + Agent 为核心的 AI 模型
|
人工智能 自然语言处理 前端开发
Director:构建视频智能体的 AI 框架,用自然语言执行搜索、编辑、合成和生成等复杂视频任务
Director 是一个构建视频智能体的 AI 框架,用户可以通过自然语言命令执行复杂的视频任务,如搜索、编辑、合成和生成视频内容。该框架基于 VideoDB 的“视频即数据”基础设施,集成了多个预构建的视频代理和 AI API,支持高度定制化,适用于开发者和创作者。
1167 9
Director:构建视频智能体的 AI 框架,用自然语言执行搜索、编辑、合成和生成等复杂视频任务

热门文章

最新文章