LangChain 初探:模型调用、链式编排与运行机制
2026/6/4 1:23:32 网站建设 项目流程

一:Langchain快速上手

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

输入 → 组件1 → 组件2 → 组件3 → 输出

并且我们还需要明白一个前提:
LangChain 不是单纯帮你调接口,而是把 AI 开发流程拆成一个个“组件”,
再把组件串起来。

1.正常调用大模型

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

首先我们需要的就是配置环境,具体的配置环境我就不多bb了~
然后就是写代码调用模型~作参考~~

fromlangchain_deepseekimportChatDeepSeekfromlangchain_core.messagesimportSystemMessage,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的环境变量里面了

返回结果(整理过后)

//真正的大模型回答内容。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本次运行IDid='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

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

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

它常用于:

调试 日志记录 问题排查
  1. usage_metadata

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

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

它常用于:

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

你可以理解为:

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

3.输出解释器

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

fromlangchain_core.output_parsersimportStrOutputParser 。 。 。 。 parser=StrOutputParser()final_result=parser.invoke(result)print(final_result)

exmaple:

fromlangchain_deepseekimportChatDeepSeekfromlangchain_core.messagesimportSystemMessage,HumanMessagefromlangchain_core.output_parsersimportStrOutputParser# 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.链式调用大模型

fromlangchain_deepseekimportChatDeepSeekfromlangchain_core.messagesimportSystemMessage,HumanMessagefromlangchain_core.output_parsersimportStrOutputParser# 1. 定义模型model=ChatDeepSeek(model="deepseek-chat")# 2. 定义消息 列表messages=[SystemMessage(content="你是一个C++学习助手,请用简洁中文回答。"),HumanMessage(content="一加一等于几?")]parser=StrOutputParser()chain=model|parser result=chain.invoke(messages)print(result)

运行结果

一加一等于二。

2.三种构建链的方式

第一种:管道符 |

这是最常用的写法。

chain=model|parser

第二种:RunnableSequence

手动创建:

fromlangchain_core.runnablesimportRunnableSequence chain=RunnableSequence(first=model,last=parser)

第三种:pipe 方法

chain=model.pipe(parser)

三:LangChain 底层:Runnable 和 LCEL

1.Runnable

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

ChatDeepSeek 继承 BaseChatDeepSeek BaseChatDeepSeek 继承 Runnable 接口
model.invoke(...)parser.invoke(...)chain.invoke(...)

对象虽然功能不同,但它们都遵守同一套调用规范
不管你是模型、解析器、Prompt、还是链,只要你是 Runnable,就可以用统一方式运行
LangChain 解决了 原生大模型切换困难 的问题

Runnable 接口

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

2.LCEL -LangChain Expression Language

LangChain 表达式语言

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

chain=prompt|model|parser result=chain.invoke({"topic":"C++ RAII"})前一个组件的输出,自动作为后一个组件的输入

底层:
chain :

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

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

林外:chain 自己也是一个 Runnable

四:进阶使用Langchain的接口

init_chat_model()

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

fromlangchain.chat_modelsimportinit_chat_modelfromlangchain_core.messagesimportSystemMessage,HumanMessagefromlangchain_core.output_parsersimportStrOutputParser# 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
代码:

fromlangchain_deepseekimportChatDeepSeekfromlangchain.chat_modelsimportinit_chat_modelfromlangchain_core.messagesimportSystemMessage,HumanMessagefromlangchain_core.output_parsersimportStrOutputParser# 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 更多用于:
日志追踪 链路观测 调试分析 LangSmith 追踪

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

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

我们需要知道的一个前提就是:
LangChain 默认不会让你随便在运行时修改已有属性。
也就是你在init_chat_model定义的参数,在后面就绝对不能修改!!!

configurable_fields 和 config_prefix

这个其实就是让标记init_chat_model 里面的参数,告诉我们哪些可以修改
字面意思就是给那些上锁的门解锁

configurable_fields:声明哪些字段允许运行时修改
config_prefix:给配置项加前缀

老师还加了一个参数:
上代码:

fromlangchain_deepseekimportChatDeepSeekfromlangchain.chat_modelsimportinit_chat_modelfromlangchain_core.messagesimportSystemMessage,HumanMessagefromlangchain_core.output_parsersimportStrOutputParser# 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
代码:

fromlangchain_ollamaimportChatOllama 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 APIOllama + DeepSeek R1
是否需要 API Key通常需要通常不需要
是否依赖网络需要本地运行时不一定需要
模型能力通常更强取决于本地模型大小
隐私性数据发到远程服务数据留在本机
速度受网络和服务影响受本机配置影响
成本可能按 token 计费主要消耗本机算力

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询