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 应用,需深度集成或私有化部署
相关推荐
kkkkkkkkkk_Z7 小时前
学嵌入式和C语言编程数据结构|学习日记Day22:栈,二叉树,哈希存储
c语言·数据结构·学习
咔咔学姐kk7 小时前
小白程序员必收藏:轻松入门AI Agent开发,大厂校招新风口!
人工智能·深度学习·ai·程序员·大模型·就业·大模型学习
for_ever_love__9 小时前
python基础语法学习: 闭包
开发语言·python·学习·闭包
Elastic 中国社区官方博客10 小时前
让大模型思考,让小模型执行:在 Elastic Workflows 中拆分 LLM 成本
大数据·运维·数据库·人工智能·elasticsearch·ai
皮卡丘不断更11 小时前
从遥操作示范到可复现训练:LeRobot 0.6.1 的机器人学习工作流
人工智能·学习·机器人·开源·开发工具
IZero0711 小时前
Elasticsearch 学习笔记筑基-文档操作篇
笔记·学习·elasticsearch
星辰AI11 小时前
全栈项目代码质量治理复盘:ESLint+Prettier+Husky的渐进式引入策略
人工智能·ai·语言模型
算AI12 小时前
基于LLM的无人机仿真测试:新方法竞赛夺佳绩
人工智能·深度学习·算法·机器学习·ai
小白说大模型13 小时前
AI驱动的个性化学习路径:知识图谱与知识点关联的存储与推理
大数据·人工智能·学习·mysql·机器学习·prompt·知识图谱
吃好睡好便好13 小时前
三伏天结束了
学习·生活·毕淑敏·心理游戏