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 SystemMessage, HumanMessage, AIMessagemessages = [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 usersid="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 modelHumanMessage("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 calltool_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"}
夜雨聆风