langchain核心组件 Model I/O(1)-模型调用

134 阅读12分钟

1.5 LangChain 的核心组件

LangChain的核心组件主要涉及四个部分:Model I/O、Chains、RAG、Agents。

1) Model I/O

标准化大模型的输入和输出,包含提示模版,模型调用和格式化输出。

(1) Format(格式化): 通过模板管理大模型的输入。将原始数据格式化成模型可以处理的形式, 插入到一个模板中, 然后送入模型进行处理。

(2) Predict(预测): 调用 LLM 接收输入, 进行预测或生成回答。

(3) Parse(解析): 规范化模型输出。比如将模型输出格式化为 JSON。

2) Chains

“链条”用于将多个组件组合成一个完整的流程,方便链式调用。

3) Retrieval

对应RAG:检索外部数据,作为参考信息输入LLM辅助生成答案。

(1) Source: 多种类型的数据源:视频、图片、文本、代码、文档等。

(2) Load: 将多源异构数据统一加载为文档对象。

(3) Transform: 对文档进行转换和处理, 比如将文本切分为小块。

(4) Embed: 将文本编码为向量。

(5) Store: 将向量化后的数据存储起来。

(6) Retrieve: 从文本库中检索相关的文本段落。

4) Agents

Agent 自主规划执行步骤并使用工具来完成任务。

第2章Model I/O

2.1 Model I/O 介绍

Model I/O 部分是与语言模型进行交互的核心组件,包括输入提示(Prompt Template)、调用模型(Model)、输出解析(Output Parser)。简单来说,就是输入、处理、输出这三个步骤。

2.2调用在线模型

2.2.1大模型服务平台

LangChain 作为一个“工具”,依赖于第三方集成各种大模型。

有许多提供大模型API服务的平台,使用时只需要注册、充值并创建API-Key,之后即可使用API-Key与URL来调用平台提供的相应的模型的服务。

1) CloseAI: platform.closeai-asia.com/

API-Key 管理:platform.closeai-asia.com/developer/a…

API 文档: doc.closeai-asia.com/tutorial/ap…

模型:platform.closeai-asia.com/pricing

2) OpenRouter: openrouter.ai/

API-Key 管理:openrouter.ai/settings keys

API 文档: openrouter.ai/docs/commun…

模型:openrouter.ai/models

3)阿里云百炼:bailianconsole.aliyun.com/

API-Key 管理:https://bailian console.aliyun.com/?tab =model#/api-key

API 文档:https://bailian console.aliyun.com/?tab =doc#/doc/?type =model

模型:bailianconsole.aliyun.com/?tab =model#/model-market/all

4)百度千帆:console.bce.baidu.com/qianfan/ove…

API-Key 管理:console.bce.baidu.com/qianfan/ais console/apiKey

API文档:cloud.baidu.com/doc/qianfan…

模型:console.bce.baidu.com/qianfan/mod…

5)硅基流动:www.siliconflow.cn/

API-Key 管理:cloud.siliconflow.cn/me/account/…

API文档:docs.siliconflow.cn/cn/userguid…

模型:cloud.siliconflow.cn/me/models

2.2.2 OpenAI SDK 调用模型

OpenAI 的 GPT 系列模型影响了大模型技术发展的开发范式和标准。所以无论是 Qwen、ChatGLM 等模型,它们的使用方法和函数调用逻辑基本遵循 OpenAI 定义的规范,没有太大差异。这就使得能够通过一个较为通用的接口来接入和使用不同的模型。

    pip install langchain langchain-openai 
    from openai import OpenAI 
    client = OpenAI(
        base_url= "https://openrouter.ai/api/v1"#平台提供的URL 
        api_key="sk-...”,#平台提供的API-Key
        )
    completion = client.chat completions.create( 
    model="openai/gpt-oss-20b:free",  # 模型名称
    messages=[{"role": "user", "content": "'你好'翻译成意大利语"}],  # 用户输入
    )
    print(completion.choices[0].message.content)

2.2.3 API-Key 管理

通常有3种方式来管理API-Key:硬编码、写入env文件、写入环境变量。

刚才我们就是将 API-Key 硬编码仅代码中,这仅适用于临时测试,存在密钥泄露风险。

1)使用.env配置文件

使用python-dotenv加载本地配置文件,支持多环境管理。该方式有以下优势:

配置文件可加入.gitignore避免泄露

支持多环境配置(如.env.prod和/env.dev)

创建.env文件(项目根目录):

OPENAI_API_KEY="sk-..."  
OPENAI_BASE_url=" https://openrouter.ai/api/v1"

举例:显式读取 .env 中的环境变量

pip install python-dotenv  
import os  
from openai import OpenAI  
from dotenv import load_dotenv  
load_dotenv() # 默认加载 .env  
client = OpenAI(  
    base_url=os.getenv("OPENAI_BASE_URL"), # 平台提供的 URL  
    api_key=os.getenv("OPENAI_API_KEY"), # 平台提供的 API Key)  
completion = client.chat completions.create(  
    model="openai/gpt-oss-20b:free",  
    messages=[[{"role": "user", "content": "将'你好'翻译成意大利语}], ], 
    )
print(completion Choices[0].message(content)

举例:依靠OpenAI的默认行为读取.env环境变量

OpenAI 在创建时,会自动到环境变量中找 OPENAI_API_KEY 以及 OPENAI_BASE_url。如果在 .env 中配置的名字和上面的两个名字一样,无需再次赋值,只通过 dotenv.load_dotenv() 加载环境配置信息即可。

pip install python-dotenv   
from openai import OpenAI   
from dotenv import load_dotenv   
load_dotenv() #默认加载-env   
client = OpenAI()   
completion = client.chat completions.create( 
model = "openai/gpt-oss-20b:free", 
messages = ["role":"user","content":"将'你好'翻译成意大利语"}], 
)
print(completion Choices[O].message(content)

2)在环境变量中配置

通过系统环境变量存储API-Key,避免代码明文暴露。

终端设置变量(临时生效):

export OPENAI_API_KEY="sk-..." # Linux/Mac  
set OPENAI_API_KEY="sk-..." # Windows CMD

在代码中通过os.getenv()读取API-Key:

import os   
from openerai import OpenAI   
client=OpenAI( base_url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENAI_API_KEY"),   
)   
completion=client.chat completions.create( model="openai/gpt-oss-20b:free", messages=["role": "user", "content": "你好"}], )  
print(completion Choices[O].message(content)

2.2.4 LangChain API 调用模型

通常通过聊天模型接口访问LLM,该接口通常以消息列表作为输入并返回一条消息作为输出。

输入:接受文本 PromptValue 或消息列表 List[BaseMessage],每条消息需指定角色(如 SystemMessage、HumanMessage、AIMessage)

输出:返回带角色的消息对象(BaseMessage子类),通常是AIMessage

举例:

import os   
from langchain chat models import init chat model   
from langchain messages import SystemMessage, HumanMessage, AIMessage   
llm=init chat model( model="openai/gpt-oss-20b:free", modelprovider ="openai", base_url ="https://openrouter.ai/api/v1", api_key =os.getenv("OPENROUTER_API_KEY"),   
)   
messages=[ SystemMessage(content ="你是一个诗人"), HumanMessage(content ="写一首关于春天的诗"),   
]   
resp=llm.invoke/messages)   
print(type(resp)) # <class'langchain_core/messages.ai.AIMessage'>   
print(response.content)

2.2.5 模型初始化相关参数

初始化一个模型最简单的方法就是使用init chatting_model,并设置必要的参数,例如API-Key和模型名称。除此之外还有一些其他参数。

model模型名称或标识符
base_url发送请求的 API 端点的 URL。常由模型的提供商提供
api_key与模型提供商进行身份验证所需的 API 密钥
temperature控制模型输出的随机性。数字越高,回答越有创意;数字越低,回答越确定
timeout在取消请求之前,等待模型响应的最大时间(以秒为单位)
max_tokens限制响应中的总 tokens 数量,控制输出长度
max_retries请求失败时系统尝试重新发送请求的最大次数

Token 是什么?

大模型处理的最小单位是 token(相当于自然语言中的词或字),输出时逐个 token 依次生成。模型提供商通常也是以 token 的数量作为其计量或收费的依据。1 个中文 Token≈1-1.8 个汉字,1 个英文 Token≈3-4 字母。

Token 与字符转化的可视化工具:

OpenAI 提供:platform.openai.com-tokenizer

百度智能云提供:console.bce.baidu.com/support/#/t…

2.2.6 对话模型的 Message

对话模型的输入可以是文本提示、消息提示或是字典格式。

1)文本提示

文本提示是字符串,适用于不需要保留对话历史的直接生成任务。

resp = lvm.invoke("你好")

2)消息提示

将消息对象列表输入模型,方便管理对话历史,包含系统指令以及处理多模态数据。

messages = [
    SystemMessage("你是个诗人"),
    HumanMessage("写首关于春天的诗"),
]

3)字典格式

也可以按照 OpenAI 聊天补全格式创建字典列表组成消息。一条消息通常包含 role(角色)、content(内容)、metadata(元数据)。

messages = [
{"role": "system", "content": "你是个诗人"},{ "role": "user", "content": "写首关于春天的诗"}, ]   
resp=llm.invoke(messages)

4)消息类型

消息类型描述
SystemMessage代表一组初始指令,用于引导模型的行为。可以使用系统消息来设定语气、定义模型的角色,并建立响应的指导方针
HumanMessage表示用户输入
AIMessage模型生成的响应,包括文本内容、工具调用和元数据
ToolMessage表示工具调用的输出

HumanMessage、AIMessage 和 SystemMessage 是常用的消息类型。

ToolMessage 是在工具调用场景下才会使用的特殊消息类型。

2.2.7 调用方法

聊天模型提供了三种主要的调用方法:

invoke / ainvoke将单个输入转换为输出
batch / abatch批量将多个输入转换为输出
stream / astream从单个输入生成流式输出

带有“a”前缀的方法是异步的,需要与asyncio和await语法一起使用以实现并发。

2.2.7.1非流式/流式输出

在Langchain中,语言模型的输出分为了两种主要的模式:流式输出与非流式输出。

非流式输出:用户提出需求请编写一首诗,系统在静默数秒后突然弹出了完整的诗歌。如同一种“提交请求,等待结果”的流程,实现简单,但体验单调。

流式输出:用户提问,请编写一首诗,当问题刚刚发送,系统就开始一字一句(逐个token)进行回复,更像是“实时对话”,贴近人类交互的习惯。

1)非流式输出:

这是LangChain与LLM交互时的默认行为,是最简单、最稳定的语言模型调用方式。当用户发出请求后,系统在后台等待模型生成完整响应,然后一次性将全部结果返回。

举例:invoke()调用

import os   
from langchain chat models import init chat model   
llm=init chat model( model="openai/gpt-oss-20b:free", modelprovider="openai", base_url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENROUTER_API_KEY"),   
)   
messages=[ {"role": "system", "content": "你是一名数学家"}, {"role": "user", "content": "请证明以下黎曼猜想"},   
]   
resp=llm.invoke (messages)   
print (resp.content)

2)流式输出

流式输出是一种更具交互感的模型输出方式,用户不再需要等待完整答案,而是能看到模型逐个 token 地实时返回内容。适合构建强调“实时反馈”的应用。

举例:stream()流式输出

import os   
from langchain chat models import init chat model   
llm=init chat model( model="openai/gpt-oss-20b:free", modelprovider="openai", base_url   \coloneqq   "https://openrouter.ai/api/v1", api_key=os.getenv("OPENROUTER_API_KEY"),   
)   
messages={"role":"system","content":"你是一名数学家"}, {"role":"user","content":"请证明以下黎曼猜想"},   
]   
#使用stream()方法流式输出   
for chunk in llm.stream(messages): #逐个打印内容块,并刷新缓冲区以即时显示内容 print(chunk(content,end=""flush=True)

2.2.7.2 批量调用

将一组独立的请求批量发送给模型并行处理。

举例:batch()批量调用

import os   
from langchain.chat_models import init.Chat_model   
llm=init chatting_model( model="openai/gpt-oss-20b:free", modelprovider   \coloneqq   "openai", base_url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENROUTER_API_KEY"),   
)   
messages   = [   {{"role":"system","content":"你是一位诗人"}, {"role":"user","content":"写一首关于春天的诗"}, ], [ {"role":"system","content":"你是一位诗人"}, {"role":"user","content":"写一首关于夏天的诗"}, ], {{"role":"system","content":"你是一位诗人"}, {"role":"user","content":"写一首关于秋天的诗"}, ]   
resp=llm.batch (messages) #批量调用,返回一个消息列表 print(resp)

batch 默认没有依赖底层 API 的原生批量接口,而是使用线程池并行执行多个 invoke()。所以它对 IO 密集型任务(如调用远程 LLM API)很有效。

如果底层 API 自身提供批量接口(一次请求多个 prompt),那么子类可以重写 batch 方法来直接使用批量接口,这样效率会更高。

2.2.7.3 同步/异步调用

1)同步调用

每个操作依次执行,直到当前操作完成后才开始下一个操作,总的执行时间是各个操作时间的总和。

举例:使用 invoke() 同步调用

import os  
import time


from langchain chat Models import init chat model  
llm = init chat model(  
    model="openai/gpt-oss-20b:free",  
    modelprovider="openai",  
    base_url="https://openrouter.ai/api/v1",  
    api_key=os.getenv("OPENROUTER_API_KEY"),  
)  
message = [  
    { "role": "system", "content": "你是一位诗人" }, 
    { "role": "user", "content": "写一首关于春天的诗" }, ],
    { "role": "system", "content": "你是一位诗人" }, { "role": "user", "content": "写一首关于夏天的诗" }, ], 
    { "role": "system", "content": "你是一位诗人" }, { "role": "user", "content": "写一首关于秋天的诗" }, ],  
]  
start_time = time.time()  
resp = [llm.invoke/messages) for messages in messages]  
print(resps)  
end_time = time.time()  
print(f"Total time: {end_time - start_time}")  
# Total time: 17.789486169815063

2)异步调用

异步调用,允许程序在等待某些操作完成时继续执行其他任务,而不是阻塞等待。这在处理I/O操作(如网络请求、文件读写等)时特别有用,可以显著提高程序的效率和响应性。

举例:使用 ainvoke() 异步调用

import os  
import time  
import asyncio  
from langchain.chat_models import init chatting_model
llm = init chatting_model( model="openai/gpt-oss-20b:free", modelprovider="openai", base_url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENROUTER_API_KEY"), )   
messaging = [ { "role": "system", "content": "你是一位诗人" }, {"role": "user", "content": "写一首关于春天的诗" }, ], { "role": "system", "content": "你是一位诗人" }, {"role": "user", "content": "写一首关于夏天的诗" }, ], { "role": "system", "content": "你是一位诗人" }, {"role": "user", "content": "写一首关于秋天的诗" }, ],   
async def async.invoke(): tasks = [llm.ainvoke/messages) for messages in messaging] return await asyncio.gather(*tasks)   
start_time = time.time()   
resp = asyncio.run(asyncInvoke())   
print(resps)   
end_time = time.time()   
print(f"Total time: {end_time - start_time}") # Total time: 8.280137062072754

使用async.gather()并行执行时,因为多个任务几乎同时开始,它们的执行时间将重叠。理想情况下,如果多个任务的执行时间相同,那么总执行时间应该接近单个任务的执行时间。

2.3调用本地模型

2.3.1 Ollama 介绍

Ollama 是一个开源项目,其项目定位是:一个本地运行大模型的集成框架。目前主要针对主流的 LlaMA 架构的开源大模型设计,可以实现如 Qwen、Deepseek 等主流大模型的下载、启动和本地运行的自动化部署及推理流程。

目前作为一个非常热门的大模型托管平台,已被包括LangChain、Taskweaver等在内的多个热门项目高度集成。

Ollama 官方地址:ollama.com

Ollama Github 开源地址: github.com/ollama/olla…

2.3.2 Ollama 安装

Ollama项目支持跨平台部署,目前已兼容Mac、Linux和Windows操作系统。

无论使用哪个操作系统,Ollama项目的安装过程都设计得非常简单。

访问 ollama.com/download 下载对应系统的安装文件。

Windows 系统执行.exe 文件安装

Linux系统执行以下命令安装:

curl -fsSL https://ollama.com/install.sh | sh  
这行命令的目的是从https://ollama.com/网站读取install.sh脚本,并立即通过sh执行该脚本,在安装过程中会包含以下几个主要的操作:  
检查当前服务器的基础环境,如系统版本等;  
下载Ollama的二进制文件;  
配置系统服务,包括创建用户和用户组,添加Ollama的配置信息;  
启动Ollama服务;

2.3.3 模型下载

访问 ollama.com/search 可以查看 Ollama 支持的模型。使用命令行可以下载并运行模型,例如运行 deepseek-r1:7b 模型:

ollama run deepseek-r1:7b

因为文件比较大,所以直接用我给大家提供的资料,需要做如下配置

1)进入到 Settings

2)切换模型目录

3)运行模型ollama run deepseek-r1:7b

ollama run deepseek-r1:7b

2.3.4 调用本地模型

举例:

pip install langchain-ollama  
from langchain_ollama import ChatOllama  
ollama_llm = ChatOllama(model="deepseek-r1:7b")  
messages = {"role": "user", "content": "你好,请介绍一下你自己"}  
resp = ollama_llm.invoke/messages)  
print(resp(content)

若Ollama不在本地默认端口运行,需指定base_url,即:

pip install langchain-ollama  
from langchain_ollama import ChatOllama  
ollama_llm = ChatOllama(  
model="deepseek-r1:7b",  
base_url="http://your-ip:port", # 自定义地址)
messages = {"role": "user", "content": "你好,请介绍一下你自己"}
resp = ollama_llm.invoke/messages)
print(response.content)