一: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 区别
- response_metadata
它更关注这次响应本身的信息,比如:
bash
请求 ID
模型版本
服务商返回的原始信息
结束原因
调试信息
它常用于:
bash
调试
日志记录
问题排查
- 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 计费 | 主要消耗本机算力 |