准备工作

  1. 使用 ollama 本地部署 LLM

  • 官网下载 exe 文件

打开安装包后,会发现只能安装到 C 盘

在安装包所在的文件夹下进入命令行,执行这行命令即可

OllamaSetup.exe /DIR="你想安装的目录地址"

  • 再配置系统环境变量,文件地址到 ollama 的根目录即可

  • 进入 cmd 命令行,输入 ollama -v 出现版本号即代表配置成功

复制到命令行就可以拉取模型了

  1. 获取商业大模型的key(阿里云百炼

  1. 前往我的API-KEY页面,单击创建我的API-KEY

  2. 在已创建的API Key操作列,单击查看,获取API KEY

  3. 在CMD中运行以下命令。

setx DASHSCOPE_API_KEY "YOUR_DASHSCOPE_API_KEY"
  1. 打开一个新的CMD窗口,在新的CMD窗口运行以下命令,检查环境变量是否生效。

echo %DASHSCOPE_API_KEY%

  1. 安装 langchain 库包

# 创建虚拟环境
conda create -n langchain python=3.12

# 安装langchain
conda install langchain -c conda-forge

# 安装社区包
pip install -U langchain langchain-community langchain-openai langchain_ollama

第 1 阶段:基础入门(了解核心概念)

1️⃣ PromptTemplate(提示模板)

  • 功能:用于格式化输入提示,支持参数化、结构化构建 prompt. 统一设计 prompt 样式,支持动态插入参数,适配多任务模板

from langchain.prompts import PromptTemplate
template = "给定一个问题,请提供简明的回答。\n问题:{question}\n答案:"
prompt = PromptTemplate.from_template(template)
formatted = prompt.format(question="LangChain 是什么?")
print(formatted)

2️⃣ LLMs / ChatModels(语言模型)

  • 功能:调用 OpenAI、Anthropic、Qwen、本地 LLM 等模型,完成生成任务

from langchain_ollama import OllamaLLM

# 建议不要开梯子运行, 容易报错 502
llm = OllamaLLM(
    model="qwen2.5:latest",
    base_url="http://localhost:11434",
    temperature=0.2
)

response = llm.invoke("hello, world!")
print(response)

3️⃣ Chains(链)

  • 没有 chain 的代码:

document = "LangChain 是一个用于构建基于大语言模型应用的框架..."
question = "它可以用来做什么?"

prompt = f"请总结这段话:{document}"
response = llm(prompt)
new_prompt = f"根据总结回答这个问题:{response} + {question}"
response2 = llm(new_prompt)

手动写流程,而且不好维护

  • chain 可以把这些步骤封装成一个流程链,一行调用整个逻辑,参数统一传入,代码结构更清晰

from langchain_ollama import OllamaLLM
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnableParallel

# 初始化本地模型
llm = OllamaLLM(
    model="qwen2.5:latest",
    base_url="http://localhost:11434",
    temperature=0.2
)

# Step 1: 总结 prompt + 模型 + 输出解析器
summary_prompt = PromptTemplate.from_template("请总结这段文字:{document}")
summary_chain = summary_prompt | llm | StrOutputParser()

# Step 2: QA prompt + 模型 + 输出解析器
qa_prompt = PromptTemplate.from_template("根据总结回答问题:\n总结:{summary}\n问题:{question}")
qa_chain = qa_prompt | llm | StrOutputParser()

# 组合两个步骤:先生成 summary,再输入到 QA 阶段
full_chain = (
    RunnableParallel({"summary": summary_chain, "question": lambda x: x["question"]})
    | qa_chain
)

# 输入示例
inputs = {
    "document": "安装nvidia驱动遇到的问题,很多带图形化界面的 Ubuntu 都自带了 Nouveau(应该是系统自带的显卡驱动)解决办法:1. 创建 blacklist 配置文件禁用 Nouveau:sudo nano /etc/modprobe.d/blacklist-nouveau.conf2. 内容添加:blacklist nouveauptions nouveau modeset=03. 更新 initramfs:sudo update-initramfs -u4. 重启系统:sudo reboot5. 重启后确认 nouveau 是否被禁用:lsmod | grep nouveau6. 没有任何输出才是正常的。并且在执行安装过程时,将图形化界面服务停用掉,切换到 命令行 的方式进行安装sudo systemctl stop gdm后边所有服务都安装好,再启动图形化界面就ok了sudo systemctl start gdm ",
    "question": "安装nvidia驱动应该怎么解决?"
}

# 执行链
result = full_chain.invoke(inputs)
print("最终回答:", result)

4️⃣ Tools(工具)

  • 功能:LLM 在 Agent 中可调用的实际工具,例如:搜索、计算、爬虫、数据库等。给模型“插件”能力

from langchain.tools import tool

@tool
def add(x: int, y: int) -> int:
    return x + y
  • 使用 @tool 装饰函数生成工具

函数名称作为工具名称、函数注解作为工具描述

from langchain_core.tools import tool


@tool
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b


print(multiply.name)
print(multiply.description)
print(multiply.args)

"""
    multiply
    Multiply two numbers.
    {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}
"""
  • @tool 装饰 async def 函数:让 Tool 在异步系统中非阻塞运行,提升性能和并发能力。

import asyncio
from langchain_core.tools import tool

# 用 @tool 装饰一个 异步函数(async def) 来创建一个异步的 LangChain Tool。
@tool
async def amultiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b
    
async def main():
    result = await amultiply.ainvoke({"a": 3, "b": 5})
    print(result)  # 输出 15

asyncio.run(main())
  • 使用 Pydantic 模型结构化参数(类似json的格式作为参数,将其传入 tool 工具中)

方法一

from pydantic import BaseModel, Field
from langchain_core.tools import tool

class CalculatorInput(BaseModel):
    a: int = Field(description="first number")
    b: int = Field(description="second number")

# 在 tool 这里填写
@tool("multiplication-tool", args_schema=CalculatorInput, return_direct=True)
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b


print(multiply.args)
"""
{'a': {'description': 'first number', 'title': 'A', 'type': 'integer'}, 'b': {'description': 'second number', 'title': 'B', 'type': 'integer'}}
"""

方法二

from pydantic import BaseModel, Field

# 结构化参数
class AddInput(BaseModel):
    x: int = Field(..., title="第一个数", description="请输入第一个加数")
    y: int = Field(..., title="第二个数", description="请输入第二个加数")

# 定义工具
@tool
def add(data: AddInput) -> int:
    """ add two numbers """
    return data.x + data.y

# 打印工具中的参数
print(add.args_schema.model_json_schema())

"""
{'$defs': {'AddInput': {'properties': {'x': {'description': '请输入第一个加数', 'title': '第一个数', 'type': 'integer'}, 'y': {'description': '请输入第二个加数', 'title': '第二个数', 'type': 'integer'}}, 'required': ['x', 'y'], 'title': 'AddInput', 'type': 'object'}}, 'description': 'add two numbers ', 'properties': {'data': {'$ref': '#/$defs/AddInput'}}, 'required': ['data'], 'title': 'add', 'type': 'object'}
"""

# 调用工具
result = add.invoke({
    "data": {
        "x": 3,
        "y": 5
    }
})
print(result)  # 输出:8
  • 使用结构化工具StructuredTool.from_function 构造 tool

from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field

# 使用 pydantic 声明参数
class CalculatorInput(BaseModel):
    a: int = Field(description="first number")
    b: int = Field(description="second number")

# 定义函数(后边用来作为工具)
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    return a * b

# 结构化工具构造 tool
calculator = StructuredTool.from_function(
    func=multiply,    # 指定函数
    name="Calculator",    # 工具名称
    description="multiply numbers",    # 工具描述
    args_schema=CalculatorInput,    # 指定参数
    return_direct=True,
    # coroutine= ... <- you can specify an async method if desired as well
)

print(calculator.invoke({"a": 2, "b": 3}))
print(calculator.name)
print(calculator.description)
print(calculator.args)

"""
6
Calculator
multiply numbers
{'a': {'description': 'first number', 'title': 'A', 'type': 'integer'}, 'b': {'description': 'second number', 'title': 'B', 'type': 'integer'}}
"""

美观形式打印工具参数的方法:

def print_tool_args(tool):
    schema = tool.args_schema.model_json_schema()

    # 提取顶层参数引用信息
    props = schema.get("properties", {})
    defs = schema.get("$defs", {})

    for param_name, param_info in props.items():
        # 判断是否是引用
        ref = param_info.get("$ref")
        if ref:
            # 解析引用名,比如 "#/$defs/AddInput" -> "AddInput"
            ref_name = ref.split("/")[-1]
            def_info = defs.get(ref_name, {})
            def_props = def_info.get("properties", {})

            print(f"\n🔧 Tool 参数:{param_name}(结构化模型: {ref_name})")
            for field_name, field_info in def_props.items():
                print(f"  - 参数名: {field_name}")
                print(f"    - 类型: {field_info.get('type', '未知')}")
                print(f"    - 标题: {field_info.get('title', '')}")
                print(f"    - 描述: {field_info.get('description', '')}")
        else:
            # 非结构化字段
            print(f"\n🔧 Tool 参数:{param_name}")
            print(f"  - 类型: {param_info.get('type', '未知')}")
            print(f"  - 标题: {param_info.get('title', '')}")
            print(f"  - 描述: {param_info.get('description', '')}")

5️⃣ Agents(智能体)

  • 功能:LLM 自主决定调用哪些工具,进行推理与行动

第 2 阶段:RAG(检索增强生成)

LangChain 文档中的 RetrievalQAConversationalRetrievalChain

自建 RAG 系统:配合 Qdrant / FAISS / Chroma + HuggingFace Embeddings

第 3 阶段:Agents & Tools

1️⃣ 天气应用

  • 准备一个实况天气的 api ,这里采用的是 易客云天气 ,新用户有 3000 次免费调用的额度

http://gfeljm.tianqiapi.com/api?unescape=1&version=v61&appid=你的账户&appsecret=你的密钥&city=查询的城市

各个参数在 接口文档 中有清楚的解释,appidappsecret控制台查看

  • 使用 langchain 编写代码

from langchain_core.tools import StructuredTool
from pydantic import BaseModel, Field
from langchain_ollama import OllamaLLM
from langchain.agents import initialize_agent, AgentType
import requests

# 使用 pydantic 构造参数
class WeatherInput(BaseModel):
    city:str = Field(..., title="city", description="To check the weather for the city")

# 使用该 api 构造函数
# http://gfeljm.tianqiapi.com/api?unescape=1&version=v61&appid={}&appsecret={}&city={}
def get_weather(city: str) -> str:
    """ use city to get weather """
    url = "http://gfeljm.tianqiapi.com/api"
    params = {
        "unescape": "1",
        "version": "v61",
        "appid": "your_id",
        "appsecret": "your_secret",
        "city": city,
    }

    response = requests.get(url, params=params).json()

    # 提取你需要展示的信息
    wea = response["wea"]
    tem = response["tem"]
    tem1 = response["tem1"]
    tem2 = response["tem2"]
    wind = response["win"]
    wind_speed = response["win_speed"]
    humidity = response["humidity"]
    air_level = response["air_level"]
    air_tips = response["air_tips"]

    return (
        f"{city}当前天气:{wea},温度 {tem}℃(最高{tem1}℃,最低{tem2}℃),"
        f"{wind}{wind_speed},湿度 {humidity},空气质量为「{air_level}」。\n"
        f"空气建议:{air_tips}"
    )

# 结构化构建 tool
weatherTool = StructuredTool.from_function(
    func=get_weather,
    name="get_weather",
    description="To check the weather for the city",
    return_direct=False,    # True:让调用工具的输出作为结果直接返回
    args_schema=WeatherInput
)


# 定义大模型
llm = OllamaLLM(
    model="qwen2.5:latest",
    base_url="http://localhost:11434",
    temperature=0.2
)

# 使用 Agent 来绑定工具
agent = initialize_agent(
    tools=[weatherTool],
    llm=llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,  # 更适合本地模型的 agent 类型
    verbose=False    
)

response = agent.invoke("请问现在南京的天气怎么样?")
print(response["output"])

AgentExecutorinitialize_agent

工具链自定义:比如你可以让 Agent 查天气、调用 Python 函数、搜索网页等

LangGraph:LangChain 的新“状态机”工具

第 4 阶段:进阶优化 & 项目集成

多模型适配(OpenAI / Qwen / GLM / Claude)

LangServe(将 LangChain 快速部署为 Web API)

LangSmith(用于调试链、监控和评估)

和 FastAPI / Gradio / Streamlit 等前端结合