【LangChain Model I/O 02】

介绍

 Modle I/O模块是与语言模型(LLMs)进行交互的核心组件包括:输入提示(Pormat)、调用模型(Predict)、 输出解析(Parse);简单来说就是输入、模型处理、输出这三个步骤

 

图片

 针对每个环节,LangChain都提供了模版和工具,可以快捷的调用各种语言模型的接口

一、模型调用

1、Model I/O 调用模型

LangChain作为一个工具,不提供任何LLMs,而是依赖与第三方集成的各种大模型 

1)模型调用的分类

简单来讲,就是用谁家的API已什么方式调用那种类型的大模型

角度1:按照模型功能的不同

  • 非对话模型(LLMs、Text Model)
    • LLMs也叫Text Model、非对话模型,是许多语言模型应用程序的支柱。主要特点:
    • 输入:接受文本字符串或者PromptValue对象
    • 输出:总是返回文本字符串
    • 使用场景:仅需单次文本生成任务(如:摘要生成、翻译 、代码生成、单次问答)或对接不支持消息结构的旧模型(如部分本地部署模型)
    • 不支持多轮对话上下文,每次调用单独处理输入,无法自动关联历史对话(需要手动拼接历史文本)
    • 局限性:无法处理角色分工或复杂对话逻辑
  • 对话模型(Chat Model)(推荐)
    • 大语言模型调用,以ChatModel为主,主要特点:
    • 输入:接收消息列表List[BaseMessage]或PromptValue,每条消息需指定角色(如:SystemMessage、HumanMessage、AIMessage)
    • 输出:总是返回带角色的消息对象(BaseMessage子类),通常是AIMessage
    • 原生支持多轮对话。通过消息列表维护上下文,模型可基于完整对话历史生成回复
    • 适用场景:对话系统(如客服机器人、长期交互的AI助手)
  • 嵌入模型(Embedding Models)
    • 也叫文本嵌入模型,这些模型将文本作为输入并返回浮点数列表,也就是Embedding

角度2:模型调用时,重要参数存放的位置不同(api-key、base_url、model-name)

  • 硬编码:写在代码文件中 
  • 使用环境变量
  • 使用配置文件(推荐)
相关方法及属性:
  • OpenAI(...)  chatOpenAI(...):创建一个模型对象(非对话类/对话类)
  • model.invoke(xxx):执行调用,将用户输入发送给模型
  • .content:提起模型返回的实际文本内容
模型调用函数使用时需初始化模型,并设置必要的参数
1)必须设置的参数:
  • base_url:大模型API服务的根地址
  • api_key:用于身份验证的密钥,由大模型服务商(如:OpenAI、阿里百炼)提供
  • model/model_name:指定要调用的具体大模型名称(如:gpt-4-turbo等)
2)其他参数:
  • temperature:温度,控制生成文本的“随机性”,取值范围为0~1
    • 值越低 -->输出越确定、保守(适合事实回答)
    • 值越高 -->输出越多样、有创意(适合创意写作)

   通常,根据需要设置如下:

  1. 精确模式(0.5或更低):生成的文本更加安全可靠,但可能缺乏创意或多样性
  2. 平衡模式(通常是0.8):生成的文本通常既有一定的多样性,又能保持较好的连贯性和准确性
  3. 创意模式(通常是1):生成的文本更有创意 、但也更容易出现语法错误或者逻辑不合理的内容
  • max_tokens:限制生成文本的最大长度,防止输出过长
    • Token是什么?----->简单可理解为Byte(字节)
          • 基本单位:大模型处理文本的最小单位是token,输出时逐个token依次生成
          • 收费依据:大预言模型(LLM)通常也是以token的数量作为其计量(或收费)的依据
            • 1个Token≈1-1.8个汉字,1个Token≈3-4个英文字母
            • Token与字符转化的可视化工具:
              OpenAI提供:https://platform.openai.com/tokenizer
              百度智能云提供:https://console.bce.baidu.com/support/#/tokenize
  • max_tokens设置建议:
    • 客服短回复:128-256。比如:生成一句客服回复(如“订单已发货,预计明天送达”)
    • 常规对话、多轮对话:512-1024
    • 长内容生成:1024-4096。比如:生成一篇产品说明书(包含功能、使用方法等结构

角度3:具体调用的API

  • LangChain的统一方式调用API(推荐)
  • OpenAI提供的API
  • 其他大模型自家提供的API

结合角度1、2、3代码示例:

 在实际的工作中,常常使用的是配置文件+对话模型的形式

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
load_dotenv()
'''
采用配置文件的方式加载对话模型
1、在项目根目录创建.env文件,添加如下配置项
OPENAI_API_BASE_URLL=你的openai api base url
OPENAI_API_KEYY=你的openai api key
2、在代码中通过os.getenv()方法获取配置项的值
3、将获取到的值传递给ChatOpenAI类的base_url和api_key参数
'''

llm=ChatOpenAI(
    model="gpt-4o-mini",
    base_url=os.getenv("OPENAI_API_BASE_URLS"),
    api_key= os.getenv("OPENAI_API_KEY1"),
    temperature=0.7,
    max_tokens=200
)

res=llm.invoke("RAG技术的核心流程")
print(res.content)

# 当然可以给os内部环境变量赋值 -->如果model采用默认的模型,ChatOpenAI()初始化时可以不传base_url和api_key参数

os.environ["OPENAI_BASE_URL"]=os.getenv("OPENAI_BASE_URLS")
os.environ["OPENAI_API_KEY"]=os.getenv("OPENAI_API_KEY1")

chat = ChatOpenAI()
response = chat.invoke("请简要介绍一下RAG技术的核心流程")
print(response.content)

2、Model I/O 调用模型2

1)关于对话模型的Message(消息)

对话模型除了将字符串作为输入后,还可以使用“聊天信息”作为输入,并返回聊天信息作为输出

LangChain有一些内置的消息类型:

  • SystemMessage:设定AI行为规则或背景信息。比如设定AI的初始状态,行为模式或对话的总体目标。比如:作为一个代码专家,或者返回json格式。通常作为输入信息序列中的第一个传递
  • HumanMessage:表示来自用户输入。比如:实现一个快速排序方法
  • AIMessage:存储AI回复的内容。这可以是文本,也可以是调用工具的请求
  • ChatMessage:可以自定义角色的通用信息类型
  • FunctionMessage/ToolMessage:函数调用/工具消息,用于函数调用结果的消息类型
注意:
FunctionMessage和ToolMessage分别是在函数调⽤和⼯具调⽤场景下才会使⽤的特殊消息类
型,HumanMessage、AIMessage和SystemMessage才是最常⽤的消息类型。

举例:

from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI
import os
import dotenv

dotenv.load_dotenv()
base_url = os.getenv("OPENAI_BASE_URLS")
api_key = os.getenv("OPENAI_API_KEY1")

chat = ChatOpenAI(
    model="gpt-4o-mini",
    base_url=base_url,
    api_key=api_key
)

message = [
    SystemMessage(content="你是一个擅长人工智能的相关学科的专家"),
    HumanMessage(content="请用中文解释一下什么是机器学习")
]
response = chat.invoke(message)
print(response.content)
print(type(response)) #打印查看到大模型执行后返回的对象类型=AIMessage

2)关于模型调用的方法

LangChain组件实现了Runnable协议,也就是一个类,它实现了包括聊天模型、提示词模版、输出解析器、代理(智能体)等

Runnable类定义公共的调用方法如下:

  • invoke:处理单条输入、等待LLM完全推理完成后在返回调用结果
  • stream:流式响应,逐字输出LLM的响应结果
    • 非流式输出:即当用户发出请求后,系统在后台等待模型生成完整响应,然后一次将全部结果返回
    • 流式输出:即当用户发出请求后,用户不需要等待完整答案,而是能看到模型逐个token地实时返回内容---->langchain中通过streaming=True启动流式输出
  • batch:处理批量输入

这些也也有相应的异步方法,应该与asyncio和await语法一起使用以实现并发:

  • astream : 异步流式响应
  • ainvoke : 异步处理单条输入
  • abatch : 异步处理批量输入
  • astream_log : 异步流式返回中间步骤,以及最终响应
  • astream_events : (测试版)异步流式返回链中发生的事件(在 langchain-core 0.1.14 中引入)

|-- 流式输出案例:

from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI
import os
import dotenv

dotenv.load_dotenv() #加载配置文件
base_url = os.getenv("OPENAI_BASE_URLS")
api_key = os.getenv("OPENAI_API_KEY1")

chat = ChatOpenAI(
    model="gpt-4o-mini",
    base_url=base_url,
    api_key=api_key,
    streaming=True
)

message = [
    SystemMessage(content="你是一个擅长编程的专家"),
    HumanMessage(content="请用Python写一个冒泡排序的代码")
]
# 流式输出,模型执行返回的结果是一个生成器对象,所以可以使用for循环进行迭代输出
response = chat.stream(message)
for chunk in response:
    print(chunk.content, end='', flush=True)
print(type(response)) #打印查看到大模型执行后返回的对象类型=Generator

|-- 批量处理

#批量处理
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI
import os
import dotenv

dotenv.load_dotenv() #加载配置文件
base_url = os.getenv("OPENAI_BASE_URLS")
api_key = os.getenv("OPENAI_API_KEY1")

chat = ChatOpenAI(
    model="gpt-4o-mini",
    base_url=base_url,
    api_key=api_key
)

message1 = [
    SystemMessage(content="你是一个擅长编程的专家"),
    HumanMessage(content="请用Python写一个冒泡排序的代码")
]
message2 = [
    SystemMessage(content="你是一个擅长历史的专家"),
    HumanMessage(content="请简要介绍一下二战的起因")
]
messages = [message1, message2]
response=chat.batch(messages)  #批量处理多个输入

print(type(response)) #打印查看到大模型执行后返回的对象类型<class 'list'>

for chunk in response:
    print(chunk.content) 

二、Model I/O之Prompt Template 提示词模版 

1、介绍与分类

prompt Template 提示词模版,接受用户的输入,返回一个信息传递给LLM

在实际的开发应用中,传递一个固定的提示词本身就是不够灵活也很局限,所以prompt Template是一个模版化的字符串,可以将变量插入到模版中,从而创建出不同的提示词

调用时:

  • 已字典作为输入
  • 已PromptValue输出,传递给LLM或ChatModle,并且还可以转换为字符串或消息列表

分类:

  • promptTemplate:LLM提示词模版,用于生成字符串提示。它使用python的字符串来模版提示
  • ChatPromptTemplate:聊天提示模版,用于组合各种角色的消息模版,传入聊天模型xxxMessagePromptTemplate:消息提示词模版,包括:SystemMessagePromptTemplate、HumanMessagePromptTemplate、AIMessagePromptTemplate、ChatMessagePromptTemplate等
  • FewShotPromptTemplate :样本提示词模板,通过示例来教模型如何回答
  • PipelinePrompt :管道提示词模板,用于把几个提示词组合在一起使用。
  • 自定义模板 :允许基于其它模板类来定制自己的提示词模板。

2、promptTemplate使用

2.1、使用说明:

PromptTemplate类,用于快速构建包含变量的提示词模版,并通过传入不同的参数值,生成自定义的提示词

主要参数:

  • template:定义提示词模版的字符串,其中包含文本和变量占位符
  • input_variables:列表,指定了模版中使用的变量名称,在调用模版时被替换
  • partial_variables:字典,用于定义模版中的一些固定的变量名,这些值不需要再每次调用时被替换

函数介绍:

  • forma():给input_variables变量赋值,并返回提示词。利用format()进行格式化时就一定要赋值,否则会报错。当在template中未设置input_variables,则会自动忽略

2.2、PromptTemplate如何获取实例

from langchain_core.prompts import PromptTemplate

## 方式一:使用构造方法

# 1、定义模版
tempalte=PromptTemplate(
    template="请用中文介绍一下{product}。",
    input_variables=["product"],
)
# 2、传入多个变量,生成最终的提示词
final_prompt=tempalte.format(product="LangChain")
final_prompt1 = tempalte.format(product="大模型")

print(final_prompt+'\n'+final_prompt1) # 执行结果: 请用中文介绍一下LangChain。
print(type(final_prompt)) # 执行结果: <class 'str'>

## 方式二:使用from_template类方法
# 1、定义模版
prompt_tempalte=PromptTemplate.from_template(
    template="你是一个{role}专家,请用{language}介绍一下{product}。"
)
# 2、传入模版中的变量名
prompt=prompt_tempalte.format(role="人工智能", language="中文", product="机器学习")

print(prompt) # 执行结果: 你是一个人工智能专家,请用中文介绍一下机器学习。
print(type(prompt)) # 执行结果: <class 'str'>

区别:使用from_template方法,可以在定义模版时不需要通过input_variables指定变量名称,更加的方便

2.3、两种特殊结构的使用(部分提示词模版的使用,组合提示词的使用)

部分提示词模版:在生成prompt前就已经提前通过partial_variables初始化部分变量提示词,在导入模版时只导入除初始化以外的变量即可

#方式一: 实例化过程中使用partial_variables参数
partial_prompt=PromptTemplate.from_template(
    template="你是一个{role}专家,请用{language}介绍一下{product}。",
    partial_variables={"role":"人工智能"}
)
prompt = partial_prompt.format(language = '中文', product='深度学习')
print(prompt) # 执行结果: 你是一个人工智能专家,请用中文介绍一下深度学习。

# 方式二:使用PromptTemplate.partial方法创建部分提示模版
base_prompt=PromptTemplate.from_template(
    template="你是一个{role}专家,请用{language}介绍一下{product}。",
)
partial_prompt=base_prompt.partial(role="编程")
prompt=partial_prompt.format(language="Python", product="函数式编程")
print(prompt) # 执行结果: 你是一个编程专家,请用Python介绍一下函数式编程。

组合提示词模版

from langchain_core.prompts import PromptTemplate
template = (
    PromptTemplate.from_template("Tell me a joke about {topic}")
    + ", make it funny"
    + "\n\nand in {language}"
)
prompt = template.format(topic="sports", language="spanish")
print(prompt)

2.4、给变量赋值的两种方式(fromat()、invoke())

fromat():返回值为字符串类型

invoke():传入的是字典,返回值为PromptValue类型,接着调用to_string()返回字符串

tempalte = PromptTemplate.from_template("告诉我一段关于{topic}的历史")
prompt = tempalte.invoke({"topic": "二战"}) #传入的是一个字典 
print(prompt)
print(type(prompt)) #执行结果:<class 'langchain_core.prompt_values.StringPromptValue'>

2.5、结合大模型的使用

from langchain_core.messages import SystemMessage, HumanMessage
from langchain_openai import ChatOpenAI
import os
import dotenv

# 1.加载环境配置文件
dotenv.load_dotenv()
base_url = os.getenv("OPENAI_BASE_URLS")
api_key = os.getenv("OPENAI_API_KEY1")

# 2.创建大模型对象   
chat = ChatOpenAI(
    model = "gpt-4o-mini",
    base_url= base_url,
    api_key= api_key
)

# 3.创建提示词模版并传入变量生成最终提示词
tempalte = PromptTemplate.from_template("请{name}告诉我一段关于{topic}的畅想")
prompt = tempalte.invoke({"name": "马斯克","topic": "移民火星"}) 

# 4.调用大模型的invoke方法进行问答
message = [
    SystemMessage(content="你是一个擅长历史的专家"),
    HumanMessage(content=prompt.to_string())
]   
response = chat.invoke(message)
print(response.content)

 3、ChatPromptTemplate

 3.1、使用说明

ChatPromptTemplate是创建聊天信息列表的提示模版。它比普通PromptTemplate更适合处理多角色、多轮次的对话场景

特点:

  • 支持System /Human /AI 等不同角色的消息模版
  • 对话历史维护

参数类型:列表参数格式tuple类型(role:str  content:str 组合最常用)

元组的格式为:(role: str | type, content: str | list[dict] | list[object])

  • 其中role是:字符串(如:system、Human、ai)

3.2、实例化的2种方式

3.2.1 使用构造方法

 

3.2.2  使用from_message()

 

3.3、调用提示词模版的几种方法: invoke()、format()、format_message()、format_prompt()

 

3.4、更丰富的实例化参数类型

 

3.5、结合LLM

 

3.6、插入消息列表:MessagePlaceholder

 

posted @ 2025-11-03 15:37  尘封~~  阅读(7)  评论(0)    收藏  举报