1、 关于对话模型的Message

聊天模型除了将字符串作为输入之外,还可以将聊天消息作为输入,并返回聊天消息作为输出。

LangChain的常用内置消息类型:

  • SystemMessage:设定AI行为规则或者背景信息,例如设定AI的初始状态、行为模式或对话的目标。这通常是输入消息序列中的第一个传递;
  • HumanMessage:来自用户的输入,例如“实现某某功能”;
  • AIMessage:存储AI回复的内容,这可以是文本也可以是调用工具的请求。

示例1:

from langchain_core.messages import SystemMessage,HumanMessage

system_message = SystemMessage(content = "你是一个数学专家")
human_message = HumanMessage(content = "制定一个高中数学学习计划")

message = [system_message, human_message]

print(message)

使用大模型调用上述的Message列表:

response = chat_model.invoke(message)
print(response.content)

2、 多轮对话与上下文记忆

大模型自身不具备上下文的能力!!!

示例1:

from langchain_core.messages import SystemMessage, HumanMessage

sys_message = SystemMessage(
    content="我是一个人工智能的助手,我的名字叫小智",
)
human_message = HumanMessage(content="猫王是一只猫吗?")
human_message1 = HumanMessage(content="你叫什么名字?")

messages = [sys_message, human_message,human_message1] # 只有最后一个用户消息被作为问答,前面的作为过程消息

#调用大模型,传入messages
response = chat_model.invoke(messages)
print(response.content)

输出:我叫小智。你有什么问题可以问我!

说明:模型只对最后的 huamn_message1做出了回复,第一个问答的human_message 只是过程消息。

示例2:

from langchain_core.messages import SystemMessage, HumanMessage

sys_message = SystemMessage(
    content="我是一个人工智能的助手,我的名字叫小智",
)
human_message = HumanMessage(content="猫王是一只猫吗?")

sys_message1 = SystemMessage(
    content="我可以做很多事情,有需要就找我吧",
)
human_message1 = HumanMessage(content="你叫什么名字?")

messages = [sys_message, human_message,sys_message1,human_message1]
#调用大模型,传入messages
response = chat_model.invoke(messages)
print(response.content)

输出:我叫小智,是你的人工智能助手。这有什么我可以帮助你的吗?

说明:对于两个消息列表设置,只是采用第一个系统消息回答了最后一个用户问题,说明不具备上下文以及记忆的能力。

3 、模型调用的方式

很多LangChain组件实现了Runnable协议,包括聊天模型、提示词模版、输出解析器、检索器、智能体等。

Runnable 定义的公共调用方法:

  • invoke:处理单条输入,等待LLM完全推理结束后再返回结果;
  • stream:流式响应,逐字输出LLM的响应结果;
  • batch:用于处理批量输入

以此也有对应的异步方式:(关于异步的说明下文会进行)

  • ainvoke:异步处理单条输入;
  • astream:异步流式响应;
  • abatch:异步处理批量输入。

(1)流式输出与非流式输出

这两种输出模式是LangChain中语言模型的主要模式,下面详细介绍:

①非流式输出:是LangChain与LLM交互的默认形式,也是最简单、最稳定的语言模型调用方式,在用户发送请求后,系统在后台等待模型生成完整的响应,然后一次性将结果返回

  • 举例:用户提问:写一首诗,系统在加载数秒后弹出完整的诗歌;
  • 在大多数问答、摘要、信息抽取类任务中,非流式输出提供了结构清晰、逻辑完整的结果,适用于快速集成与部署

②流式输出:一种更具交互感的模型输出方式,用户不用等待完整的答案,而是能够看到模型逐个token的实时回答。

  • 举例:用户提问:写一首诗,问题发送之后系统就开始一字一句的进行回复;
  • 更接近人类交互的习惯、更像实时对话、更具吸引;
  • 适合构建强调“实时反馈”的应用,例如聊天机器人、写作助手。

示例1:invoke()阻塞式调用

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

dotenv.load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
#初始化大模型
chat_model = ChatOpenAI(
    model="gpt-4o-mini"
)
# 创建消息
messages = [HumanMessage(content="你好,请介绍一下自己")]
# 非流式调用LLM获取响应
response = chat_model.invoke(messages)
# 打印响应内容
print(response.content)

输出:思考几秒后直接完整显示所有生成内容。

示例2:流式输出 LangChain中设置 streaming = True 并配合回调机制启用流式输出

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

dotenv.load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
# 初始化大模型
chat_model = ChatOpenAI(model="gpt-4o-mini",
                        streaming=True # 启用流式输出
)
# 创建消息
messages = [HumanMessage(content="你好,请介绍一下自己")]
# 流式调用LLM获取响应
print("开始流式输出:")

for chunk in chat_model.stream(messages):
    # 逐个打印内容块
    print(chunk.content, end="", flush=True)
# 刷新缓冲区 (无换行符,缓冲区未刷新,内容可能不会立即显示)
print("\n流式输出结束")

输出:逐个token进行输出回答的内容

(2)批量调用

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

dotenv.load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
# 初始化大模型
chat_model = ChatOpenAI(
    model="gpt-4o-mini"
)
messages1 = [SystemMessage(content="你是一位乐于助人的智能小助手"),
             HumanMessage(content="请帮我介绍一下什么是机器学习"), ]
messages2 = [SystemMessage(content="你是一位乐于助人的智能小助手"),
             HumanMessage(content="请帮我介绍一下什么是AIGC"), ]
messages3 = [SystemMessage(content="你是一位乐于助人的智能小助手"),
             HumanMessage(content="请帮我介绍一下什么是大模型技术"), ]
messages = [messages1, messages2, messages3]
# 调用batch
response = chat_model.batch(messages)
print(response)

输出:三个问题都会按照响应顺序做出回答。

(3)同步调用与异步调用

示例1:同步调用

import time
def call_model():
    # 模拟同步API调用
    print("开始调用模型...")
    time.sleep(5)# 模拟调用等待,单位:秒
    print("模型调用完成。")
def perform_other_tasks():
    # 模拟执行其他任务
    for i in range(5):
        print(f"执行其他任务 {i + 1}")
        time.sleep(1)# 单位:秒
def main():
    start_time = time.time()
    call_model()
    perform_other_tasks()
    end_time = time.time()
    total_time = end_time - start_time
    return f"总共耗时:{total_time}秒"
# 运行同步任务并打印完成时间
main_time = main()
print(main_time)

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

示例2:异步调用

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

我对于同步调用和异步调用的理解就是同步调用类似于串行执行,异步调用类似并行执行。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐