乐于分享
好东西不私藏

LangChain 源码剖析-消息类详解(Messages)

LangChain 源码剖析-消息类详解(Messages)

消息是包含以下内容的对象:

– 角色(Role)-标识消息类型(例如系统、用户)

– 内容(Content)-表示消息的实际内容(如文本、图像、音频、文档等)

– 元数据(Metadata)-可选字段,如响应信息、消息ID和令牌使用情况

– LangChain提供了一种标准消息类型,适用于所有模型提供者,确保无论调用何种模型,行为都是一致的。

基本用途

from langchain.chat_models import init_chat_modelfrom langchain.messages import HumanMessage, AIMessage, SystemMessagemodel = init_chat_model("gpt-5-nano")system_msg = SystemMessage("You are a helpful assistant.")human_msg = HumanMessage("Hello, how are you?")# Use with chat modelsmessages = [system_msg, human_msg]response = model.invoke(messages)  # Returns AIMessage

文本提示

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

response = model.invoke("Write a haiku about spring")

在以下情况下使用文本提示

– 你有一个单独的请求

– 你不需要对话历史记录

– 你想要最小的代码复杂性

消息提示

– 您可以通过提供消息对象列表将消息列表传递给模型。

from langchain.messages import SystemMessageHumanMessageAIMessagemessages = [    SystemMessage("You are a poetry expert"),    HumanMessage("Write a haiku about spring"),    AIMessage("Cherry blossoms bloom...")]response = model.invoke(messages)

字典格式

– 您还可以直接以OpenAI聊天完成格式指定消息

messages = [    {"role""system""content""You are a poetry expert"},    {"role""user""content""Write a haiku about spring"},    {"role""assistant""content""Cherry blossoms bloom..."}]response = model.invoke(messages)

消息类型

– 系统消息(System message) – 告诉模型如何行为并为互动提供上下文

– 人类信息(Human message) – 代表用户输入及与模型的交互

– AI消息(AI message) – 由模型生成的回复,包括文本内容、工具调用和元数据

– 工具消息(Tool message) – 代表工具调用的输出结果

系统消息(System message)

– SystemMessage表示启动模型行为的初始指令集。您可以使用系统消息来设定基调,定义模型的角色,并为响应制定指导方针。

– 基本指令

system_msg = SystemMessage("You are a helpful coding assistant.")messages = [    system_msg,    HumanMessage("How do I create a REST API?")]response = model.invoke(messages)

– 详细信息

from langchain.messages import SystemMessage, HumanMessagesystem_msg = SystemMessage("""You are a senior Python developer with expertise in web frameworks.Always provide code examples and explain your reasoning.Be concise but thorough in your explanations.""")messages = [    system_msg,    HumanMessage("How do I create a REST API?")]response = model.invoke(messages)

人类信息(Human message)

– HumanMessage表示用户输入和交互。它们可以包含文本、图像、音频、文件和任何其他数量的多模式内容。

– 文本内容

response = model.invoke([  HumanMessage("What is machine learning?")])

– 消息元数据

human_msg = HumanMessage(    content="Hello!",    name="alice",  # Optional: identify different users    id="msg_123",  # Optional: unique identifier for tracing)

AI消息(AI message)

– AIMessage表示模型调用的输出。它们可以包括多模式数据、工具调用和稍后可以访问的特定于提供商的元数据。

response = model.invoke("Explain AI")print(type(response))  # <class 'langchain.messages.AIMessage'>

– AIMessage对象在调用模型时由模型返回,其中包含响应中的所有相关元数据。

– 提供者对消息类型进行不同的权衡/上下文化,这意味着有时手动创建一个新的AIMessage对象并将其插入消息历史记录中是有帮助的,就像它来自模型一样。

from langchain.messages import AIMessage, SystemMessage, HumanMessage# Create an AI message manually (e.g., for conversation history)ai_msg = AIMessage("I'd be happy to help you with that question!")# Add to conversation historymessages = [    SystemMessage("You are a helpful assistant"),    HumanMessage("Can you help me?"),    ai_msg,  # Insert as if it came from the model    HumanMessage("Great! What's 2+2?")]response = model.invoke(messages)

AIMessage 工具调用

– 当模型调用工具时,它们会包含在AIMessage中

from langchain.chat_models import init_chat_modelmodel = init_chat_model("gpt-5-nano")def get_weather(location: str) -> str:    """Get the weather at a location."""    ...model_with_tools = model.bind_tools([get_weather])response = model_with_tools.invoke("What's the weather in Paris?")for tool_call in response.tool_calls:    print(f"Tool: {tool_call['name']}")    print(f"Args: {tool_call['args']}")    print(f"ID: {tool_call['id']}")

– 其他结构化数据,如推理或引用,也可以出现在消息内容中。

令牌使用情况

– AIMessage可以在其usage_metadata字段中保存令牌计数和其他使用元数据:

from langchain.chat_models import init_chat_modelmodel = init_chat_model("gpt-5-nano")response = model.invoke("Hello!")response.usage_metadata
{    'input_tokens'8,     'output_tokens'304,     'total_tokens'312,     'input_token_details': {'audio'0'cache_read'0},     'output_token_details': {'audio'0'reasoning'256}}

流媒体和块

– 在流式传输过程中,您将收到AIMessageChunk对象,这些对象可以组合成一个完整的消息对象:

chunks = []full_message = Nonefor chunk in model.stream("Hi"):    chunks.append(chunk)    print(chunk.text)    full_message = chunk if full_message is None else full_message + chunk

工具消息(Tool message)

– 对于支持工具调用的模型,AI消息可以包含工具调用。工具消息用于将单个工具执行的结果传递回模型。

– 工具可以直接生成ToolMessage对象。下面,我们展示一个简单的例子。阅读工具指南中的更多内容。

from langchain.messages import AIMessagefrom langchain.messages import ToolMessage# After a model makes a tool call# (Here, we demonstrate manually creating the messages for brevity)ai_message = AIMessage(    content=[],    tool_calls=[{        "name""get_weather",        "args": {"location""San Francisco"},        "id""call_123"    }])# Execute tool and create result messageweather_result = "Sunny, 72°F"tool_message = ToolMessage(    content=weather_result,    tool_call_id="call_123"  # Must match the call ID)# Continue conversationmessages = [    HumanMessage("What's the weather in San Francisco?"),    ai_message,  # Model's tool call    tool_message,  # Tool execution result]response = model.invoke(messages)  # Model processes the result

消息内容(Message content)

– 您可以将消息的内容视为发送到模型的数据的有效载荷。消息具有松散类型的内容属性,支持字符串和非类型化对象列表(例如字典)。这允许在LangChain聊天模型中直接支持提供者本机结构,如多模式内容和其他数据。

– 另外,LangChain为文本、推理、引用、多模态数据、服务器端工具调用和其他消息内容提供了专用的内容类型。请参阅下面的内容块。

– LangChain聊天模型在content属性中接受消息内容。

这可能包含以下任一内容:

– 字符串

– 提供程序原生格式的内容块列表

– LangChain标准内容块列表

使用多模式输入的示例见下文:

from langchain.messages import HumanMessage# String contenthuman_message = HumanMessage("Hello, how are you?")# Provider-native format (e.g., OpenAI)human_message = HumanMessage(content=[    {"type""text""text""Hello, how are you?"},    {"type""image_url""image_url": {"url""https://example.com/image.jpg"}}])# List of standard content blockshuman_message = HumanMessage(content_blocks=[    {"type""text""text""Hello, how are you?"},    {"type""image""url""https://example.com/image.jpg"},])

标准内容块

– LangChain为跨提供商工作的消息内容提供了一种标准表示。

– 消息对象实现了一个content_blocks属性,该属性将延迟地将内容属性解析为标准的类型安全表示。

– 例如,从ChatAnthropic或ChatOpenAI生成的消息将包括相应提供者格式的思考或推理块,但可以延迟解析为一致的ReasoningContentBlock表示:

– Anthropic

from langchain.messages import AIMessagemessage = AIMessage(    content=[        {"type""thinking""thinking""...""signature""WaUjzkyp..."},        {"type""text""text""..."},    ],    response_metadata={"model_provider""anthropic"})message.content_blocks

– OpenAI

from langchain.messages import AIMessagemessage = AIMessage(    content=[        {"type""thinking""thinking""...""signature""WaUjzkyp..."},        {"type""text""text""..."},    ],    response_metadata={"model_provider""anthropic"})message.content_blocks

– 响应

[	{		'type''reasoning''reasoning''...',  		'extras': {'signature''WaUjzkyp...'}  	}, 	{'type''text''text''...'}]

多模态

– 多模态是指处理不同形式的数据的能力,如文本、音频、图像和视频。LangChain为这些数据提供了标准类型,可供跨提供商使用。

– 聊天模型(Chat models)可以接受多模式数据作为输入,并将其作为输出生成。下面我们展示了以多模态数据为特征的输入消息的简短示例。

图片输入

# From URLmessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this image."},        {"type""image""url""https://example.com/path/to/image.jpg"},    ]}# From base64 datamessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this image."},        {            "type""image",            "base64""AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",            "mime_type""image/jpeg",        },    ]}# From provider-managed File IDmessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this image."},        {"type""image""file_id""file-abc123"},    ]}

PDF文档输入

# From URLmessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this document."},        {"type""file""url""https://example.com/path/to/document.pdf"},    ]}# From base64 datamessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this document."},        {            "type""file",            "base64""AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",            "mime_type""application/pdf",        },    ]}# From provider-managed File IDmessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this document."},        {"type""file""file_id""file-abc123"},    ]}

音频输入

# From base64 datamessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this audio."},        {            "type""audio",            "base64""AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",            "mime_type""audio/wav",        },    ]}# From provider-managed File IDmessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this audio."},        {"type""audio""file_id""file-abc123"},    ]}

视频输入

# From base64 datamessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this video."},        {            "type""video",            "base64""AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",            "mime_type""video/mp4",        },    ]}# From provider-managed File IDmessage = {    "role""user",    "content": [        {"type""text""text""Describe the content of this video."},        {"type""video""file_id""file-abc123"},    ]}

内容块引用

– 内容块(在创建消息或访问Content_blocks属性时)表示为类型化字典的列表。列表中的每个项目都必须符合以下块类型之一

Core

– TextContentBlock

{    "type": "text",    "text": "Hello world",    "annotations": []}

– ReasoningContentBlock

{    "type": "reasoning",    "reasoning": "The user is asking about...",    "extras": {"signature": "abc123"},}

Multimodal

– ImageContentBlock

{    "type": "image",    "base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",    "mime_type": "image/jpeg",    "url": "location img"}

– AudioContentBlock

{    "type": "audio",    "base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",    "mime_type": "audio/wav",    "url": "location audio"}

– VideoContentBlock

{    "type": "video",    "base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",    "mime_type": "video/mp4",    "url": "location video"}

– FileContentBlock

{    "type": "file",     "base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",    "mime_type": "application/pdf",    "url": "https://example.com/path/to/document.pdf"}

– PlainTextContentBlock

{    "type": "text-plain",     "text": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",    "mime_type": "text/plain或text/markdown",}

Tool Calling

– ToolCall

{    "type": "tool_call",    "name": "search",    "args": {"query": "weather"},    "id": "call_123"}

– ToolCallChunk

{    "type": "tool_call_chunk",    "name": "search",    "args": {"query": "weather"},    "id": "call_123"}

– InvalidToolCall

{    "type": "invalid_tool_call",    "name": "search",    "args": {"query": "weather"},    "id": "call_123"}

提供商特定块(Provider-Specific Blocks)

– NonStandardContentBlock

{    "type": "non_standard",    "value": "xxx"}