LangChain学习

1、概述

LangChain是开源大模型应用开发框架,核心作用是把大语言模型(LLM)和外部数据、工具、业务流程连接起来,快速构建智能问答、自动推理、私有知识库等应用。

安装:pip install langchain

从清华源安装:pip install langchain -i https://pypi.tuna.tsinghua.edu.cn/simple

2、Langchain是由多个组件组成的

1、Models(模型集成)

LangChain 给各种大模型做了一层统一包装,不管用哪个模型,代码写法都一模一样。

2、Prompts(提示词管理)

包括提示管理,提示优化,提示序列化

提示词管理

把提示词抽成可复用模板

支持变量注入(如 {question}、{context})

统一管理系统提示、用户提示、历史对话结构

提示词优化与结构化

内置少样本模板、思维链(CoT)模板

自动格式化对话历史、适配不同模型的格式(ChatML、 Alpaca 等)

帮助写出更稳定、效果更好的提示

提示序列化与加载

支持把提示存为文件:JSON / YAML

可以从文件加载、版本化、共享

方便工程化、配置化,不写死在代码里

3、Memory

记忆,用来保存和模型交互的上下文

4、Indexes

索引,用于结构化文档,方便和模型交互

Index = 文档处理 + 向量化 + 存储 + 检索的整套模块

专门用来让 AI 能 "查你的私有数据"。

用户问题 → Index 检索相关文档 → Prompts 组装上下文 → LLM 生成回答

5、Chains

把多个模块串在一起,形成一个固定流程,就叫 Chain。

一步接一步执行,顺序确定、逻辑固定。

6、Agents

代理,决定模型采取哪些行动,执行并且观察流程,直到完成为止。

让模型自主决定下一步采取什么行动,执行动作,观察结果,循环往复直到任务完成。

例子:

问:"帮我查今天天气,再写个出行建议"

Chain模式:查天气 → 写建议(chain模式按固定步骤)

Agent模式:先想 "我需要查天气"→ 调用工具 → 拿到结果 → 再想 "可以写建议了"→ 完成(自主模式,边走边决策)

3、基础案例

1、将 Prompt 模板和 LLM 组合成可执行链

PromptTemplate:做一个带占位符的问题模版,方便重复使用,不用每次重复写完整的提示词问题。

Tongyi = 纯文本模型,不支持工具调用

python 复制代码
from langchain_core.prompts import PromptTemplate # 提示词模版
from langchain_community.llms import Tongyi  # 导入通义千问Tongyi模型
import dashscope
import os

# 从环境变量获取 dashscope 的 API Key
api_key = os.getenv('DASHSCOPE_API_KEY')
 
# 加载 Tongyi 模型
llm = Tongyi(model_name="qwen-turbo", dashscope_api_key=api_key)  # 使用通义千问qwen-turbo模型

# 创建Prompt Template
prompt = PromptTemplate(
    input_variables=["product"], # 声明:我有一个变量叫product
    template="为生产{product}的公司起3个简洁、好听的公司名。",
)

# 新推荐用法:将 prompt 和 llm 组合成一个"可运行序列"
chain = prompt | llm

# 使用 invoke 方法传入输入
result1 = chain.invoke({"product": "手工香薰蜡烛"})
print("香薰蜡烛公司名:")
print(result1)

result2 = chain.invoke({"product": "品牌LOGO设计"})
print("LOGO设计公司名:")
print(result2)

2、Agent+工具(langchain自带的)

langchain中集成了一些常用的工具,也可以自定义工具。

示例代码:

构建了一个通义千问 AI 智能体,集成数学计算 + 百科查询两个 LangChain 自带工具,AI 能自动判断并调用工具,精准回答数学题和百科知识。

python 复制代码
import os
from langchain_community.agent_toolkits.load_tools import load_tools
from langchain_community.chat_models import ChatTongyi
from langchain.agents import create_agent
from langchain_core.prompts import ChatPromptTemplate

# 从环境变量获取 dashscope 的 API Key
api_key = os.getenv('DASHSCOPE_API_KEY')

# 加载模型 (使用 ChatModel 以支持 tool calling)
# ChatTongyi = AI大脑(会思考、决定用什么工具)
llm = ChatTongyi(model_name="qwen-turbo", dashscope_api_key=api_key)

# 加载llm-math(计算)、wikipedia(百科)工具
tools = load_tools(["llm-math", "wikipedia"], llm=llm)

# LangChain 1.x 新写法
agent = create_agent(llm, tools)

# 运行 agent
result = agent.invoke({"messages": [("user", "3 的 5 次方")]})
print(result["messages"][-1].content)

3、Agent + 自定义工具

除了预置工具,还可以用 @tool 装饰器创建自定义工具,把普通函数变成AI能用的工具

Agent自动判断什么时候用,用哪个工具

示例代码:实现了 AI 智能体 + 自定义加减乘工具,让 AI 能自动调用你写的函数完成计算任务。

python 复制代码
import os
from langchain_community.chat_models import ChatTongyi
from langchain.agents import create_agent
from langchain.tools import tool  #自定义工具核心装饰器

# 配置大模型
api_key = os.getenv('DASHSCOPE_API_KEY')
llm = ChatTongyi(model_name="qwen-turbo", dashscope_api_key=api_key)

# ====================== 自定义工具 1:加法 ======================
@tool
def add(a: int, b: int) -> int:
    """做加法计算 a + b"""
    return a + b

# ====================== 自定义工具 2:乘法 ======================
@tool
def multiply(a: int, b: int) -> int:
    """做乘法计算 a * b"""
    return a * b

# 把自定义工具放进列表
tools = [add, multiply]

# 创建 Agent
agent = create_agent(llm, tools)

# 运行
result = agent.invoke({"messages": [("user", "3 加 5 等于几?再乘以 2 等于几?")]})
print(result["messages"][-1].content)

4、带记忆的对话链

相当于创建了一个带记忆的对话链,然后用这个链去invoke

示例代码中:InMemoryChatMessageHistory代表内存级别的存储,重启程序,记忆全部消失

python 复制代码
import os
from langchain_community.chat_models import ChatTongyi
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
import dashscope

# 从环境变量获取 dashscope 的 API Key
api_key = os.getenv('DASHSCOPE_API_KEY')

# 加载模型
llm = ChatTongyi(model_name="qwen-turbo", dashscope_api_key=api_key)

# 创建带历史记录的 prompt, 定义带记忆的提示词
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."), # 系统提示:告诉AI你是谁
    MessagesPlaceholder(variable_name="history"), # 记忆存放的地方
    ("human", "{input}") # 用户说的话
])

# 创建 chain,构建基础链
chain = prompt | llm

# 存储会话历史
store = {}

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

# 创建带记忆的对话链
conversation = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history"
)

# 配置会话ID(记忆隔离用)
config = {"configurable": {"session_id": "default"}}

# 第一轮对话
output = conversation.invoke({"input": "Hi there!"}, config=config)
print(output.content)

# 第二轮对话 (会记住上一轮)
output = conversation.invoke({"input": "I'm doing well! Just having a conversation with an AI."}, config=config)
print(output.content)

5、搭建本地知识智能客服示例

原理:给 LLM 配备一堆工具 → 交给 Agent 管理 → Agent 自己判断什么时候用、用哪个工具

python 复制代码
import os
import time
import textwrap

from langchain_community.chat_models import ChatTongyi
from langchain_core.tools import tool
from langchain.agents import create_agent

# ----------------------
# 打字机逐字输出效果
# ----------------------
def print_typing(text):
    for line in textwrap.wrap(text, width=55):
        for char in line:
            print(char, end="", flush=True)
            time.sleep(0.06)
        print()
    print("-" * 60)

# ----------------------
# 1. 加载模型
# ----------------------
api_key = os.getenv("DASHSCOPE_API_KEY")
llm = ChatTongyi(model_name="qwen-turbo", dashscope_api_key=api_key)

# ----------------------
# 2. 自定义工具 1:查手机价格
# ----------------------
@tool
def get_phone_price(phone_name: str) -> str:
    """用于查询手机价格。输入手机型号,例如:iPhone 15、Mate 70、小米14"""
    price_list = {
        "iPhone 15": "5999元起",
        "Mate 70": "4299元起",
        "小米14": "3999元起",
        "Galaxy S24": "5499元起"
    }
    return price_list.get(phone_name, "暂时没有这款手机的价格")

# ----------------------
# 3. 自定义工具 2:查店铺营业时间
# ----------------------
@tool
def get_store_hours(question: str) -> str:
    """用于查询店铺营业时间。输入用户的问题即可"""
    info = "我们的营业时间:周一至周五 9:00-21:00,周末 10:00-22:00"
    return info

# ----------------------
# 4. 创建 Agent
# ----------------------
tools = [get_phone_price, get_store_hours]
agent = create_agent(llm, tools)

# ----------------------
# 5. 主程序:循环对话
# ----------------------
if __name__ == "__main__":
    print("欢迎来到智能客服!输入 '退出' 结束对话\n")
    
    while True:
        user_msg = input("请输入问题:")
        
        if user_msg in ["退出", "exit", "quit"]:
            print("再见!")
            break
        
        # AI 回答
        result = agent.invoke({"messages": [("user", user_msg)]})
        answer = result["messages"][-1].content # -1取最后一条消息,AI的最终答案
        
        # 打字机输出
        print_typing(answer)

6、LangChain LCEL多工具串行与并行执行

1、基于 LCEL(LangChain Expression Language) 构建工具链

2、自定义 3 大类实用工具:

a、文本分析(字数、字符数、情感判断)

b、数据格式转换(CSV ↔ JSON 互转)

c、文本处理(统计行数、查找文本、替换文本)

3、使用 RunnableLambda 将普通函数封装为 LCEL 标准链

4、实现 3 种工具执行模式:

a、单个工具调用

b、串行链式执行(流水线)

c、并行执行(多任务同时处理)

5、纯手动编排流程,不依赖 Agent 自动决策

python 复制代码
from langchain_core.runnables import RunnableLambda, RunnableMap, RunnablePassthrough
import json
import os

# ==============================
# 工具1:文本分析工具
# ==============================
class TextAnalyzer:
    """文本分析工具,用于分析文本内容"""
    def __init__(self):
        self.name = "文本分析"
        self.desc = "分析文本长度、字符数、情感倾向"

    def analyze(self, text: str) -> str:
        word_num = len(text.split())
        char_num = len(text)

        positive_keywords = ["好", "优秀", "喜欢", "满意", "棒", "顺利"]
        negative_keywords = ["差", "坏", "糟糕", "讨厌", "失败", "不满"]

        pos_score = sum(1 for w in positive_keywords if w in text)
        neg_score = sum(1 for w in negative_keywords if w in text)

        if pos_score > neg_score:
            sentiment = "积极"
        elif neg_score > pos_score:
            sentiment = "消极"
        else:
            sentiment = "中性"

        return (
            f"文本分析完成\n"
            f"词语数量:{word_num}\n"
            f"字符总数:{char_num}\n"
            f"情感判断:{sentiment}"
        )

# ==============================
# 工具2:数据格式转换工具
# ==============================
class DataConverter:
    """数据转换工具,用于在不同格式之间转换数据"""
    def __init__(self):
        self.name = "数据转换"
        self.desc = "支持 CSV 与 JSON 互相转换"

    def convert(self, data_str, input_fmt, output_fmt):
        try:
            if input_fmt.lower() == "csv" and output_fmt.lower() == "json":
                lines = data_str.strip().splitlines()
                if len(lines) < 2:
                    return "数据格式错误"
                headers = lines[0].split(",")
                result = []
                for line in lines[1:]:
                    values = line.split(",")
                    item = dict(zip(headers, values))
                    result.append(item)
                return json.dumps(result, ensure_ascii=False, indent=2)

            elif input_fmt.lower() == "json" and output_fmt.lower() == "csv":
                data = json.loads(data_str)
                if not isinstance(data, list):
                    return "仅支持数组格式的JSON"
                headers = list(data[0].keys())
                csv = ",".join(headers) + "\n"
                for item in data:
                    row = [str(item.get(h, "")) for h in headers]
                    csv += ",".join(row) + "\n"
                return csv
            else:
                return "不支持该格式转换"
        except:
            return "转换失败,请检查数据格式"

# ==============================
# 工具3:文本处理工具
# ==============================
class TextProcessor:
    """文本处理工具,用于处理文本内容"""
    def __init__(self):
        self.name = "文本处理"
        self.description = "处理文本内容,如查找、替换、统计等"

    def process(self, op, content, **kwargs):
        if op == "line_count":
            return f"总行数:{len(content.splitlines())}"

        elif op == "search":
            keyword = kwargs.get("keyword", "")
            if not keyword:
                return "请输入要查找的内容"
            lines = content.splitlines()
            matched = [f"第{i+1}行:{line}" for i, line in enumerate(lines) if keyword in line]
            if matched:
                return f"找到 {len(matched)} 处匹配\n" + "\n".join(matched)
            else:
                return f"未找到关键词:{keyword}"

        elif op == "replace":
            old = kwargs.get("old_str", "")
            new = kwargs.get("new_str", "")
            new_content = content.replace(old, new)
            count = content.count(old)
            return f"替换完成,共替换 {count} 处\n新内容:\n{new_content}"
        else:
            return "不支持的操作"

# ==============================
# 实例化工具
# ==============================
analyzer = TextAnalyzer()
converter = DataConverter()
processor = TextProcessor()

# ==============================
# 使用 LCEL 封装为可运行链
# ==============================
tool_analyze = RunnableLambda(lambda x: analyzer.analyze(x["text"]))
tool_convert = RunnableLambda(lambda x: converter.convert(x["data"], x["input_fmt"], x["output_fmt"]))
tool_linecount = RunnableLambda(lambda x: processor.process("line_count", x["content"]))
tool_search = RunnableLambda(lambda x: processor.process("search", x["content"], keyword=x.get("keyword")))
tool_replace = RunnableLambda(lambda x: processor.process("replace", x["content"], old_str=x.get("old"), new_str=x.get("new")))

# 工具集合
tool_collection = {
    "文本分析": tool_analyze,
    "格式转换": tool_convert,
    "统计行数": tool_linecount,
    "文本查找": tool_search,
    "文本替换": tool_replace,
}

# ==============================
# 调用单个工具
# ==============================
def run_single_tool(tool_name, params):
    if tool_name not in tool_collection:
        return "无效工具"
    return tool_collection[tool_name].invoke(params)

# ==============================
# 链式执行:先分析,再统计行数
# ==============================
def chain_analyze_and_count(text):
    chain = (
        RunnablePassthrough.assign(
            analysis=lambda x: tool_analyze.invoke({"text": x["text"]})
        )
        | RunnableLambda(lambda x: {
            "分析结果": x["analysis"],
            "行数统计": tool_linecount.invoke({"content": x["text"]})
        })
    )
    return chain.invoke({"text": text})

# ==============================
# 并行执行:同时分析 + 统计行数
# ==============================
def parallel_run(text):
    parallel_chain = RunnableMap({
        "文本分析": RunnableLambda(lambda x: tool_analyze.invoke({"text": x["text"]})),
        "行数统计": RunnableLambda(lambda x: tool_linecount.invoke({"content": x["text"]}))
    })
    return parallel_chain.invoke({"text": text})

# ==============================
# 测试示例
# ==============================
if __name__ == "__main__":
    print("===== 示例1:文本分析 =====")
    print(run_single_tool("文本分析", {"text": "这个产品真的很棒,我非常喜欢!"}))

    print("\n===== 示例2:CSV 转 JSON =====")
    csv_data = "name,age,city\n小明,25,北京\n小红,23,上海"
    print(run_single_tool("格式转换", {"data": csv_data, "input_fmt": "csv", "output_fmt": "json"}))

    print("\n===== 示例3:统计行数 =====")
    print(run_single_tool("统计行数", {"content": "第一行\n第二行\n第三行"}))

    print("\n===== 示例4:链式执行 =====")
    res = chain_analyze_and_count("今天天气真好,适合出行!\n心情非常愉快。")
    print(res["分析结果"])
    print(res["行数统计"])

    print("\n===== 示例5:并行执行 =====")
    res2 = parallel_run("学习AI非常有趣!\n每天都有新收获。")
    print(res2["文本分析"])
    print(res2["行数统计"])

3、AI Agent 框架对比

工具 核心定位 架构特点 适用场景
LangChain 开源 LLM 应用开发框架 基于链(Chain)的线性 / 分支工作流,支持 Agent 模式 快速构建 RAG、对话系统、工具调用等线性任务
LangGraph LangChain 的扩展,专注于复杂工作流 基于图(Graph)的循环和条件逻辑,支持多 Agent 协作 需要循环、动态分支或状态管理的复杂任务(如自适应 RAG、多 Agent 系统)
Qwen-Agent 通义千问的 AI Agent 框架 基于阿里云大模型,支持多模态交互与工具调用 开源,集成多种工具,MCP 调用
Coze 字节跳动的无代码 AI Bot 平台 可视化拖拽界面,内置知识库、多模态插件 快速部署社交平台机器人、轻量级工作流
Dify 开源 LLM 应用开发平台 API 优先,支持 Prompt 工程与灵活编排 开发者定制化 LLM 应用,需深度集成或私有化部署
相关推荐
citi1 小时前
OpenViking 本地搭建指南
开发语言·python·ai
知识分享小能手1 小时前
ECharts入门学习教程,从入门到精通,综合实战——ECharts电商数据可视化完整知识点+案例代码(8)
学习·信息可视化·echarts
程序员老邢2 小时前
【产品底稿 06】商助慧V1.2实战复盘:Milvus向量库重构+RAG仿写升级+前端SSE排版彻底修复
java·人工智能·经验分享·spring boot·ai·milvus
.柒宇.2 小时前
RAG与RAGFlow详解:从原理到应用
ai·知识库·rag·ragflow
空空潍2 小时前
Claude Code从安装到国内模型配置(含DS/CC-Switch)
ai·claude
噜噜噜阿鲁~2 小时前
python学习笔记 | 7.2、高级特性-迭代
笔记·python·学习
Trouvaille ~2 小时前
零基础入门 LangChain 与 LangGraph(七):真正理解 LangGraph——从工作流、状态图到三个核心案例
python·langchain·agent·workflow·langgraph·ai应用开发·智能体开发
ybdesire2 小时前
codex报错解决 Error loading config.toml: `wire_api = “chat“` is no longer supported
人工智能·ai·codex·智能体
AI算法沐枫2 小时前
从客服转行AI Agent:半年学习与求职复盘
人工智能·深度学习·学习·大模型·agent·智能体·ai应用开发