基于LangChain 实现提示词链、工具调用与多轮对话记忆系统

LangChain 0.3 核心组件实战:从零搭建 AI 智能应用

本文将基于阿里云 DashScope + qwen-max 模型,手把手带你用 LangChain 0.3 实现 LLMChain、Tools、Agents、Memory、LCEL 五大核心组件,帮助你快速理解 LangChain 的设计思想与实战用法。


一、环境准备

1.1 技术栈选型

组件 选型 说明
大模型 阿里云 DashScope(qwen-max) 国内可直接访问,兼容 OpenAI 接口格式
框架 LangChain 0.3 最新版,推荐使用 LCEL 语法
环境管理 Conda(llmops 环境) 隔离依赖,避免版本冲突
配置管理 python-dotenv + .env 文件 安全管理 API 密钥,不硬编码

1.2 安装依赖

bash 复制代码
# 激活 conda 环境
conda activate llmops

# 安装核心依赖
pip install langchain-openai langchain-core python-dotenv

1.3 配置环境变量

在项目根目录创建 .env 文件,存放敏感配置:

env 复制代码
DASHSCOPE_API_KEY=sk-your-api-key-here
BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1

为什么用 .env 文件? 将密钥与代码分离,避免泄露到 Git 仓库,是工程实践中的基本安全规范。在 .gitignore 中添加 .env 即可防止误提交。


二、项目整体架构

整个项目按功能拆分为 6 个演示模块 ,由 main() 函数依次调用:

复制代码
main()
 ├── 1. demo_llm_chain()       → LLMChain:提示词模板 + LLM 链式调用
 ├── 2. demo_tools()           → Tools:自定义工具注册与调用
 ├── 3. demo_simple_agents()   → Agents:LLM 智能选择工具
 ├── 4. demo_memory()          → Memory:多轮对话记忆管理
 ├── 5. demo_lcel()            → LCEL:LangChain 表达式语言
 └── 6. demo_langchain_features() → 核心特点总结

三、步骤详解

步骤 1:加载环境变量 & 初始化 LLM

python 复制代码
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

# 加载 .env 文件(注意路径指向父目录)
load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), '..', '.env'))

api_key = os.getenv('DASHSCOPE_API_KEY')
base_url = os.getenv('BASE_URL')

# 初始化 LLM
llm = ChatOpenAI(
    base_url=base_url,
    api_key=api_key,
    model="qwen-max",
    temperature=0.7
)

关键点说明:

  • ChatOpenAI 是 LangChain 提供的统一 LLM 接口,只要目标服务兼容 OpenAI 格式(DashScope 的 /compatible-mode/v1 端点完全兼容),就可以直接替换使用。
  • temperature=0.7 控制输出的随机性,值越高回答越发散,值越低越确定性。
  • os.path.join(os.path.dirname(__file__), '..', '.env') 确保从子目录正确找到父目录的 .env 文件。

步骤 2:LLMChain --- 提示词模板 + LLM 链式调用

什么是 LLMChain? 它是 LangChain 最基础的模式:Prompt → LLM → Output,将提示词模板化,支持变量注入,实现一次定义、多次复用。

python 复制代码
from langchain_core.prompts import PromptTemplate

# 定义模板,{topic} 和 {style} 是变量占位符
prompt_template = PromptTemplate(
    input_variables=["topic", "style"],
    template="请以{style}的风格,写一段关于{topic}的介绍。要求:简洁明了,不超过100字。"
)

# LangChain 0.3 推荐用 LCEL 的 | 操作符组合
chain = prompt_template | llm

# 注入变量,执行链
result = chain.invoke({"topic": "人工智能", "style": "科普"})
print(result.content)

核心思想:

  • PromptTemplate 将提示词抽象为模板,变量用 {} 包裹
  • | 操作符(pipe)将模板和 LLM 串联,数据从左向右流动
  • invoke() 是 LCEL 的统一调用接口,传入字典即完成变量替换

步骤 3:Tools --- 自定义工具系统

为什么需要工具? LLM 本身无法获取实时时间、执行精确计算。Tools 机制让 LLM 能"调用外部能力"来弥补自身短板。

python 复制代码
from langchain_core.tools import Tool
import datetime

# 工具 1:获取当前时间
def get_current_time(query: str) -> str:
    return f"当前时间是:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"

# 工具 2:简单计算器
def calculate_simple(expression: str) -> str:
    allowed_chars = set('0123456789+-*/.() ')
    if all(c in allowed_chars for c in expression):
        result = eval(expression)
        return f"计算结果:{expression} = {result}"
    return "错误:包含不允许的字符"

# 注册工具:name 供 LLM 识别,description 供 LLM 理解用途
tools = [
    Tool(name="get_time", func=get_current_time, description="获取当前的日期和时间信息"),
    Tool(name="calculator", func=calculate_simple, description="执行简单的数学计算"),
]

设计要点:

  • 每个 Tool 需要三要素:名称 (name)、函数 (func)、描述(description)
  • description 非常重要,它是 LLM 判断"何时使用这个工具"的依据
  • 工具函数接收字符串参数,返回字符串结果,保持接口统一

步骤 4:Agents --- LLM 智能选择工具

Agents 的核心价值: 不是人告诉 LLM 用哪个工具,而是 LLM 自己分析问题后自主选择工具。这就是"智能代理"的含义。

本示例采用简化版实现,手动模拟 Agents 的决策过程:

python 复制代码
from langchain_core.prompts import ChatPromptTemplate

# 系统提示词:告知 LLM 可用工具列表和输出格式
tool_selection_prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一个智能助手,可以使用以下工具:
    1. get_time - 获取当前时间
    2. calculator - 执行数学计算
    
    请分析用户问题,选择合适的工具并说明原因。
    只回答工具名称和原因,格式:工具名称|原因"""),
    ("human", "{question}")
])

tool_chain = tool_selection_prompt | llm

# LLM 分析问题,选择工具
selection = tool_chain.invoke({"question": "帮我计算 15 * 8 + 20"})
# 输出:calculator|需要进行数学计算来得出结果。

# 根据选择结果,手动执行对应工具
if "calculator" in selection.content.lower():
    result = calculate_simple("15 * 8 + 20")

完整流程(三步走):

复制代码
用户提问 → LLM 分析并选择工具 → 执行工具函数 → 返回结果

生产环境建议: 实际项目中应使用 LangChain 的 create_react_agentAgentExecutor 实现全自动的工具选择和执行,本示例为教学演示目的做了简化处理。


步骤 5:Memory --- 多轮对话记忆管理

为什么需要 Memory? LLM 本身是无状态的,每次调用互相独立。Memory 机制将历史对话注入到提示词中,让 LLM "记住"之前说过什么。

python 复制代码
conversation_history = []  # 手动维护对话历史

memory_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个友好的助手,能够记住之前的对话内容。以下是对话历史:{history}"),
    ("human", "{input}")
])

memory_chain = memory_prompt | llm

# 多轮对话测试
conversations = [
    "我叫张三,今年25岁",
    "我喜欢编程和阅读",
    "你还记得我的名字吗?",   # LLM 将基于历史回答"张三"
    "我的爱好是什么?"         # LLM 将回忆出"编程和阅读"
]

for user_input in conversations:
    # 将历史拼接为字符串,注入到提示词
    history_str = "\n".join([
        f"用户: {h['user']}\n助手: {h['assistant']}" 
        for h in conversation_history
    ])
    
    response = memory_chain.invoke({"history": history_str, "input": user_input})
    
    # 将本轮对话追加到历史
    conversation_history.append({
        "user": user_input,
        "assistant": response.content
    })

记忆的核心原理:

复制代码
第1轮:history=""             → LLM 只知道当前输入
第2轮:history="第1轮对话"    → LLM 知道之前说了什么
第3轮:history="第1+2轮对话"  → LLM 能回忆更早的内容

进阶方向: LangChain 提供了 ConversationBufferMemoryConversationSummaryMemoryWindowMemory 等多种记忆策略,可应对超长对话场景。


步骤 6:LCEL --- LangChain 表达式语言

LCEL(LangChain Expression Language) 是 LangChain 0.3 的核心语法,用 | 操作符将组件像流水线一样串联起来。

python 复制代码
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = PromptTemplate.from_template("请用{language}语言解释什么是{concept}")

# 基础链:prompt → llm
chain = prompt | llm
result = chain.invoke({"language": "简单易懂的中文", "concept": "区块链"})
# result 是 AIMessage 对象,需要 .content 取内容

# 增强链:prompt → llm → output_parser
output_parser = StrOutputParser()
complex_chain = prompt | llm | output_parser
result2 = complex_chain.invoke({"language": "技术术语", "concept": "机器学习"})
# result2 直接是字符串,无需 .content

LCEL 的优势:

特性 说明
语法简洁 `a
组件可插拔 任意实现 Runnable 接口的组件都能用 `
自动批处理 支持 batch()stream() 方法
易于调试 每个环节可单独查看输入输出

四、运行结果展示

执行命令:

bash 复制代码
conda activate llmops
python week_01/01-langchain.py

各模块输出摘要:

复制代码
🔗 LLMChain:以科普风格介绍"人工智能",输出约100字
🛠️ Tools:时间工具返回 "2026-06-16 22:57:51",计算器返回 "10 + 5 * 2 = 20"
🤖 Agents:LLM 自动为"现在几点了"选择 get_time,为"15*8+20"选择 calculator
🧠 Memory:第3轮对话时 LLM 正确回忆出"你叫张三",第4轮回忆出"爱好是编程和阅读"
🔗 LCEL:基础链输出 AIMessage,增强链(加 StrOutputParser)直接输出字符串

五、完整代码结构一览

复制代码
all_agents/
├── .env                      # API 密钥(不提交到 Git)
├── week_01
└── 01-langchain.py       # 主文件:6 个演示函数

代码核心导入:

python 复制代码
from dotenv import load_dotenv           # 环境变量管理
from langchain_openai import ChatOpenAI  # LLM 统一接口
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate  # 提示词模板
from langchain_core.tools import Tool    # 工具注册
from langchain_core.output_parsers import StrOutputParser  # 输出解析

六、总结与延伸

LangChain 0.3 的五大核心组件:

组件 解决的问题 核心代码模式
LLMChain 提示词模板化复用 `prompt
Tools 让 LLM 调用外部能力 Tool(name, func, description)
Agents LLM 自主选择工具 prompt → LLM 决策 → 执行工具
Memory 多轮对话保持上下文 手动维护 history 并注入 prompt
LCEL 简洁的组件串联语法 `prompt

下一步建议:

  1. 尝试将 Agents 升级为 create_react_agent 全自动版本
  2. ConversationSummaryMemory 替换手动历史管理,支持超长对话
  3. 接入 LangSmith 实现链路追踪和可观测性
  4. 探索 RAG(检索增强生成),结合向量数据库构建知识库
相关推荐
奋飛2 小时前
从 Prompt 到 Agent:LangChain 究竟解决了什么问题
ai·langchain·prompt·agent
倾颜15 小时前
从本地 Ollama 到线上多模型 Runtime:接入 DeepSeek / Qwen 的实战复盘
langchain·next.js·deepseek
伊布拉西莫16 小时前
LangChain LCEL源码深度剖析
python·langchain
沪漂阿龙17 小时前
《LangChain 系列》Human-in-the-loop:什么时候必须让人工介入?
人工智能·架构·langchain
桜吹雪18 小时前
所有智能体架构(3):Planning(计划任务)
javascript·人工智能·langchain
技术达芬奇20 小时前
开启你的 Agent 时代:LangChain + LangGraph 项目开发入门与语言堆栈抉择
langchain·agent
小陈phd21 小时前
LCEL(LangChain Expression Language)语法全解
服务器·网络·langchain
沪漂阿龙21 小时前
Context Engineering:比 Prompt Engineering 更重要的上下文工程
人工智能·langchain·prompt
沪漂阿龙21 小时前
《LangChain 系列》用 LangGraph 搭建智能客服 Agent
人工智能·架构·langchain