LangChain 初探:模型调用、链式编排与运行机制

一:Langchain快速上手

首先我们需要理解链式结构:

bash 复制代码
输入 → 组件1 → 组件2 → 组件3 → 输出

并且我们还需要明白一个前提:

LangChain 不是单纯帮你调接口,而是把 AI 开发流程拆成一个个"组件",
再把组件串起来。

1.正常调用大模型

bash 复制代码
1. 接入并定义大模型
2. 定义消息
3. 调用大模型
4. 输出结果

首先我们需要的就是配置环境,具体的配置环境我就不多bb了~

然后就是写代码调用模型~ 作参考~~

python 复制代码
from langchain_deepseek import ChatDeepSeek
from langchain_core.messages import SystemMessage, HumanMessage

# 1. 定义模型
model = ChatDeepSeek(model="deepseek-chat")
#这里其实可以天很多其他参数的
比如 temperature
max_tokens
Token

# 2. 定义消息列表
messages = [
    SystemMessage(content="你是一个C++学习助手,请用简洁中文回答。"),
    HumanMessage(content="一加一等于几")
]

# 3. 调用模型
result = model.invoke(messages)

# 4. 输出结果
print(result)#测试用
print("--------------")
print(result.content)

这个apikey是配置到了win的环境变量里面了

返回结果(整理过后)

bash 复制代码
//真正的大模型回答内容。
content='根据数学定义,1 + 1 = 2。'
//额外参数,表示模型可以回答。如果你问一些违规的内容,可能会拒绝-》"refusal":"我无法帮助完成该请求"
additional_kwargs={
    'refusal': None
}
//模型返回的元数据
// 1.token使用量
// 2.提供商
// 3.模型

response_metadata={
    'token_usage': {
        'completion_tokens': 12,
        'prompt_tokens': 23,
        'total_tokens': 35,
        ...
    },
    'model_provider': 'deepseek',
    'model_name': 'deepseek-v4-flash',
    'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402',
    'id': 'e0388115-b15d-4f1e-b073-28762491cd9f',
    'finish_reason': 'stop',
    'logprobs': None
}


//LangChain本次运行ID
id='lc_run--019e8d0a-c9ea-73a2-b4e7-221959f108b5-0'
//本次没有调用工具所以就是空
tool_calls=[]
//没有错误的工具调用
invalid_tool_calls=[]

//统计费用
usage_metadata={
    'input_tokens': 23,
    'output_tokens': 12,
    'total_tokens': 35,
    ...
}

这个返回结果是:AIMessage

result 返回的是一个对象

2.esponse_metadata 和 usage_metadata 区别

  1. response_metadata

它更关注这次响应本身的信息,比如:

bash 复制代码
请求 ID
模型版本
服务商返回的原始信息
结束原因
调试信息

它常用于:

bash 复制代码
调试
日志记录
问题排查
  1. usage_metadata

它更关注资源消耗,比如:

输入用了多少 token
输出用了多少 token
总共用了多少 token

它常用于:

成本统计
预算控制
接口调用监控

你可以理解为:

response_metadata:这次请求的身份证
usage_metadata:这次请求的消费账单

3.输出解释器

把模型返回的复杂对象,解析成我们想要的格式。 ~

使用方法:

python 复制代码
from langchain_core.output_parsers import StrOutputParser
。
。
。
。
parser = StrOutputParser()
final_result = parser.invoke(result)
print(final_result)

exmaple:

python 复制代码
from langchain_deepseek import ChatDeepSeek
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.output_parsers import StrOutputParser

# 1. 定义模型
model = ChatDeepSeek(model="deepseek-chat")

# 2. 定义消息 列表
messages = [
    SystemMessage(content="你是一个C++学习助手,请用简洁中文回答。"),
    HumanMessage(content="一加一等于几?")
]

# 3. 调用模型
result = model.invoke(messages)
parser = StrOutputParser()

fina_result = parser.invoke(result)
# 4. 输出结果
print(fina_result)
print("--------------")
print(result.content)

二:链式结构

前面的都是手动执行

链式结构是把组件串起来:chain = model | parser

这个 | 很关键。它是管道符。

可以理解成:前一个组件的输出,自动作为后一个组件的输入。

1.链式调用大模型

python 复制代码
from langchain_deepseek import ChatDeepSeek
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.output_parsers import StrOutputParser

# 1. 定义模型
model = ChatDeepSeek(model="deepseek-chat")

# 2. 定义消息 列表
messages = [
    SystemMessage(content="你是一个C++学习助手,请用简洁中文回答。"),
    HumanMessage(content="一加一等于几?")
]

parser = StrOutputParser()

chain = model | parser

result = chain.invoke(messages)

print(result)

运行结果

python 复制代码
一加一等于二。

2.三种构建链的方式

第一种:管道符 |

这是最常用的写法。

python 复制代码
chain = model | parser

第二种:RunnableSequence

手动创建:

python 复制代码
from langchain_core.runnables import RunnableSequence

chain = RunnableSequence(first=model, last=parser)

第三种:pipe 方法

python 复制代码
chain = model.pipe(parser)

三:LangChain 底层:Runnable 和 LCEL

1.Runnable

Runnable 可以理解成 LangChain 里面的一个 标准接口。

perl 复制代码
ChatDeepSeek 继承 BaseChatDeepSeek
BaseChatDeepSeek 继承 Runnable 接口
powershell 复制代码
model.invoke(...)
parser.invoke(...)
chain.invoke(...)

对象虽然功能不同,但它们都遵守同一套调用规范

不管你是模型、解析器、Prompt、还是链,只要你是 Runnable,就可以用统一方式运行

LangChain 解决了 原生大模型切换困难 的问题

Runnable 接口:

方法 作用
invoke() 单次调用,一个输入对应一个输出
batch() 批处理,多个输入一起处理
stream() 流式输出,一个字/词/token 慢慢返回
ainvoke() 异步调用
astream() 异步流式输出

2.LCEL -LangChain Expression Language

LangChain 表达式语言

LCEL让各个组件进行管道输出

python 复制代码
chain = prompt | model | parser
result = chain.invoke({"topic": "C++ RAII"})

前一个组件的输出,自动作为后一个组件的输入

底层:

chain :

看起来好像只是把两个对象用 | 连起来,但底层其实生成了一个新的对象:

powershell 复制代码
RunnableSequence 

可运行序列
chain = model | parser
理解成:
chain = RunnableSequence(first=model, last=parser)

林外:chain 自己也是一个 Runnable

四:进阶使用Langchain的接口

init_chat_model()

这个函数是 ChatDeepSeek()的进阶替代。

代码:

python 复制代码
from langchain.chat_models import init_chat_model
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.output_parsers import StrOutputParser

# 1. 定义模型
deepseek_model  = init_chat_model(model="deepseek-chat",model_provider="deepseek")
#model = ChatDeepSeek(model="deepseek-chat")

messages = [
    SystemMessage(content = "你是一个数学老师"),
    HumanMessage(content="5的负数")
]

parser = StrOutputParser()

chain = deepseek_model|parser

result = chain.invoke(messages)

print(result)

它的目的就是:

用一套写法初始化不同厂商的聊天模型

参数:

参数 作用
temperature 控制回答随机性
max_tokens 控制最大输出长度
timeout 控制请求超时时间
max_retries 控制失败重试次数
api_key 指定 API Key
base_url 指定请求地址

五:可配置模型写法

意思就是在init_chat_model里面不要填模型名称,在下面代码进行配置

invoke() 两个重要参数

参数 作用
input 输入内容,比如字符串或消息列表
config 本次调用的配置信息

config 可以理解成:

对本次 Runnable 调用进行补充配置

所以:config 给可配置模型补上 model 和 provider

代码:

python 复制代码
from langchain_deepseek import ChatDeepSeek
from langchain.chat_models import init_chat_model
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.output_parsers import StrOutputParser

# 1. 定义模型
deepseek_model  = init_chat_model(temperature=0.3)
#model = ChatDeepSeek(model="deepseek-chat")

messages = [
    SystemMessage(content = "你是一个数学老师"),
    HumanMessage(content="5的负数")
]

parser = StrOutputParser()

chain = deepseek_model|parser

result = chain.invoke(  messages,
                        config={
                                "configurable": 
                                {
                                    "model": "deepseek-chat",
                                    "model_provider": "deepseek"
                                }
                                }
)

print(result)

config其他参数:

字段 作用
configurable 配置模型运行时可变参数
run_id 本次运行的唯一标识
run_name 本次运行的名称
metadata 附加元数据
un_id、run_name、metadata 更多用于:
powershell 复制代码
日志追踪
链路观测
调试分析
LangSmith 追踪

六:带默认参数的可配置模型

初始化时已经有默认模型,但调用时想临时改参数。

我们需要知道的一个前提就是:

LangChain 默认不会让你随便在运行时修改已有属性。

也就是你在init_chat_model定义的参数,在后面就绝对不能修改!!!

configurable_fields 和 config_prefix

这个其实就是让标记 init_chat_model 里面的参数,告诉我们哪些可以修改

字面意思就是给那些上锁的门解锁

configurable_fields:声明哪些字段允许运行时修改

config_prefix:给配置项加前缀

老师还加了一个参数:

上代码:

python 复制代码
from langchain_deepseek import ChatDeepSeek
from langchain.chat_models import init_chat_model
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.output_parsers import StrOutputParser

# 1. 定义模型
deepseek_model  = init_chat_model(model="deepseek-chat",
                                model_provider="deepseek",
                                temperature=0.3,
                                configurable_fields=("max_tokens",),
                           config_prefix="first"
##########################                                )
#多次调用
configurable_fields=("model", "model_provider", "max_tokens"),
config_prefix="first"
#########################                           
#model = ChatDeepSeek(model="deepseek-chat")

messages = [
    SystemMessage(content = "你是一个语文老师"),
    HumanMessage(content="小猫在晒太阳 扩写100字")
]

parser = StrOutputParser()

chain = deepseek_model|parser

result = chain.invoke(  messages,
                        config={
                                "configurable": 
                                {
                                    "first_max_tokens": 10
                                }
                                }
)

print(result)

注意:

("max_tokens",),后面的逗号不能少。

如果你想让所有字段都能被运行时修改,可以设置成类似:

configurable_fields="any"

意思是:

所有可配置字段都允许运行时修改。

不过真实项目里我不建议一上来就这么干。

七:本地模型

前提是你的电脑下载了ollama

代码:

python 复制代码
from langchain_ollama import ChatOllama

model = ChatOllama(
    model="deepseek-r1:1.5b",
    base_url="http://127.0.0.1:11434"
)

result = model.invoke("你是谁?")

print(result.content)

这里的:127.0.0.1

表示本机地址,也就是 localhost。

11434

是 Ollama 默认服务端口。

远程模型和本地模型的对比

对比项 远程模型 本地模型
例子 OpenAI、DeepSeek API Ollama + DeepSeek R1
是否需要 API Key 通常需要 通常不需要
是否依赖网络 需要 本地运行时不一定需要
模型能力 通常更强 取决于本地模型大小
隐私性 数据发到远程服务 数据留在本机
速度 受网络和服务影响 受本机配置影响
成本 可能按 token 计费 主要消耗本机算力
相关推荐
moshuying31 分钟前
扩散模型开始写代码、开网页了:350 亿参数,速度比 Jev 快一倍
前端·算法
qq_401700411 小时前
100 个 IoT 小项目,给 ESP32 入门补上实操
前端·网络·stm32
输出输入1 小时前
学习前端主流书单推荐
前端
anyup1 小时前
uView Pro X 1.0.0 发布:全面支持 uni-app x 蒸汽模式,80+ 组件
前端·uni-app·ai编程
apollo_qwe1 小时前
大模型 API 接通了,AI 聊天页面为什么还是不好用?
前端·vue.js·人工智能
爱勇宝1 小时前
你可能成不了技术大佬,然后呢?
前端·后端·程序员
疯华整猫2 小时前
从 MVP 到 MVI,从 Java 到 Kotlin:老项目升级的避坑指南
前端
徐小夕@趣谈前端2 小时前
Web 端 OFD 编辑器踩坑记:从“只能预览”到“在线改”
前端·编辑器
前端小万3 小时前
想做个人副业别乱买服务器!我的 5 个月真实开销分享
前端·后端·github
用户69371750013843 小时前
我买的电视,我还不能研究它吗?
前端·后端·ai编程