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 计费 主要消耗本机算力
相关推荐
Eric.464 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
小此方4 小时前
LangChain/LangGraph(二)大模型接入篇一:API接入,从API Key到API请求报文,使用Apifox完成大模型接口调用
ai·langchain
库拉镜像AI牛牛5 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别
律宏阔5 小时前
Flutter 列表图片内存优化:CachedNetworkImage 与 ClipRRect 的取舍
前端·flutter
行者全栈架构师5 小时前
【鸿蒙心迹】相册文搜图工程化落地:HarmonyOS 7.0 端侧 AI 检索全链路实战与 5 个踩坑解法
前端
律宏阔5 小时前
Dart 3 Record:解决 Future.wait 异构返回值的类型问题
前端·flutter
Seraphina365 小时前
DVWA(XSS Reflected/Stored High,CSRF Low)
前端·xss·csrf
默_笙6 小时前
🍔 中间件不只是打日志:四个钩子、一次短路,和自带的工具
前端·javascript
程序员老赵7 小时前
Docker 部署 Dolibarr:轻松搭建开源 ERP/CRM 平台
运维·前端·后端
星禾元亨7 小时前
同一件事有三份资料,AI 该信哪一份?冲突判定、优先级链与处置流程
前端·人工智能