
Langchain_v1.0|核心模块-core_component_02_messages
[@文本提示 Text Prompt](#@文本提示 Text Prompt)
[@消息提示 Message Prompt](#@消息提示 Message Prompt)
[@系统消息 SystemMessage](#@系统消息 SystemMessage)
[@人类信息 HumanMessage](#@人类信息 HumanMessage)
[@模型消息 AI message](#@模型消息 AI message)
[@工具消息 Tool Message](#@工具消息 Tool Message)
- Basic usage
- Text prompts
- Message prompts
- Dictionary format
- Message types
- System message
- Human message
- Text content
- Message metadata
- AI message
- Tool calls
- Token usage
- Streaming and chunks
- Tool message
- Message content
- Standard content blocks
- Multimodal
- Content block reference
在 LangChain 中,消息是模型的基本上下文单元。它们代表模型的输入和输出,携带与 LLM 交互时表示对话状态所需的内容和元数据。
消息是包含以下内容的对象:
- 角色 - 标识消息类型(例如 system 、 user )
- 内容 ------指消息的实际内容(例如文本、图像、音频、文档等)。
- 元数据 - 可选字段,例如响应信息、消息 ID 和令牌使用情况
LangChain 提供了一种适用于所有模型提供程序的标准消息类型,确保无论调用哪个模型,行为都保持一致。
python
基本用法
使用消息的最简单方法是创建消息对象,并在调用时将它们传递给模型。
python
from langchain.messages import SystemMessage, HumanMessage
from langchain_01.models.scii_deepseekv3 import model
system_message = SystemMessage(content="you are a helpful assistant")
human_message = HumanMessage(content="what is the capital of francer")
reposne = model.invoke([system_message, human_message])
print(reposne)
https://api.siliconflow.cn/v1
content='The capital of France is Paris.' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 7, 'prompt_tokens': 25, 'total_tokens': 32, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'Qwen/Qwen3-Coder-30B-A3B-Instruct', 'system_fingerprint': '', 'id': '019bcb07594e175d89ee43e3ae597afc', 'finish_reason': 'stop', 'logprobs': None} id='lc_run--019bcb07-578b-7c80-a518-9bf93eba1bff-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 25, 'output_tokens': 7, 'total_tokens': 32, 'input_token_details': {}, 'output_token_details': {}}
文本提示 Text Prompt
文本提示是字符串------非常适合简单的生成任务,无需保留对话历史记录。
在以下情况下使用文本提示:
- 您有一个独立的请求。
- 你不需要对话记录
- 您希望代码复杂度尽可能低。
python
model.invoke("你好")
AIMessage(content='你好!很高兴见到你!有什么我可以帮助你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 12, 'prompt_tokens': 9, 'total_tokens': 21, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'Qwen/Qwen3-Coder-30B-A3B-Instruct', 'system_fingerprint': '', 'id': '019bcaffad55e8af1ece56863ef06877', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019bcaff-abe3-74c1-b175-6661ec7e7931-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 9, 'output_tokens': 12, 'total_tokens': 21, 'input_token_details': {}, 'output_token_details': {}})
消息提示 Message Prompt
或者,您可以通过提供消息对象列表,将消息列表传递给模型。
使用消息提示时:
- 管理多轮对话
- 处理多模态内容(图像、音频、文件)
- 包括系统指令
python
from langchain.messages import AIMessage, HumanMessage, SystemMessage
from urllib3 import response
messages = [
SystemMessage("You are a chinese poetry expert,use chinese poetry to answer the user's questions"),
HumanMessage("Write a haiku about spring"),
AIMessage("春天是一年中的一个时间,当太阳 shines , _flowers bloom.")
]
print(model.invoke(messages).content)
字典格式
您也可以直接在 OpenAI 聊天补全格式中指定消息。
消息类型
- 系统消息 - 告诉模型如何行为以及为交互提供上下文
- 人类消息 - 表示用户输入和与模型的交互
- AI 消息 - 模型生成的响应,包括文本内容、工具调用和元数据
- 工具消息 - 表示工具调用的输出
python
messages = [
{"role": "system", "content": "你是唐朝诗人李白"},
{"role": "user", "content": "请写一首华山的诗"},
{"role": "assistant",
"content": "《华山吟》\n\n西岳峥嵘何壮哉!黄河如丝天际来。\n千峰竞秀云海间,万仞削壁凌苍苔。\n\n长风破浪势如雷,石径蜿蜒入翠微。\n仙人掌上观天下,玉女峰前望归期。\n\n峰头独立望九州,三秦五岳尽低首。\n此山只应天上有,人间哪得几回游?\n\n醉卧云松听松涛,华山高处不胜寒。\n若问此身何所寄,青天白日共婵娟。"},
{"role": "user", "content": "继续"}
]
model.invoke(messages).content
'《华山夜泊》\n\n夜宿华山云深处,星河倒挂映松林。\n山风萧瑟吹衣袖,月影婆娑舞石心。\n\n千岩万壑皆入梦,一剑光寒三万里。\n何时仗剑游天下,不负此生好山河。\n\n晨起推窗望远山,云海茫茫似海澜。\n华山之巅何所求,只愿长啸醉人间。\n\n登高望远心如海,天地悠悠我独行。\n山高水长情不老,华山依旧在眼中。'
系统消息 SystemMessage
SystemMessage 是一组初始指令,可以预热模型的行为。您可以使用系统消息来设定基调、定义模型的角色,并为响应建立准则。
python
system_message = SystemMessage("你是一个专业的coder")
messages = [system_message,
HumanMessage("写一个python冒泡排序算法")]
print(model.invoke(messages).content)
python
from langchain.messages import SystemMessage, HumanMessage
system_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?")
]
model.invoke(messages)
AIMessage(content='I\'ll show you how to create a REST API using Python. Here are the most common approaches:\n\n## 1. Using Flask (Simple & Popular)\n\n```python\nfrom flask import Flask, jsonify, request\nfrom flask_sqlalchemy import SQLAlchemy\n\napp = Flask(__name__)\napp.config[\'SQLALCHEMY_DATABASE_URI\'] = \'sqlite:///users.db\'\ndb = SQLAlchemy(app)\n\n# Model\nclass User(db.Model):\n id = db.Column(db.Integer, primary_key=True)\n name = db.Column(db.String(80), nullable=False)\n email = db.Column(db.String(120), unique=True, nullable=False)\n\n def to_dict(self):\n return {\n \'id\': self.id,\n \'name\': self.name,\n \'email\': self.email\n }\n\n# Routes\n@app.route(\'/users\', methods=[\'GET\'])\ndef get_users():\n users = User.query.all()\n return jsonify([user.to_dict() for user in users])\n\n@app.route(\'/users/<int:user_id>\', methods=[\'GET\'])\ndef get_user(user_id):\n user = User.query.get_or_404(user_id)\n return jsonify(user.to_dict())\n\n@app.route(\'/users\', methods=[\'POST\'])\ndef create_user():\n data = request.get_json()\n user = User(name=data[\'name\'], email=data[\'email\'])\n db.session.add(user)\n db.session.commit()\n return jsonify(user.to_dict()), 201\n\n@app.route(\'/users/<int:user_id>\', methods=[\'PUT\'])\ndef update_user(user_id):\n user = User.query.get_or_404(user_id)\n data = request.get_json()\n user.name = data.get(\'name\', user.name)\n user.email = data.get(\'email\', user.email)\n db.session.commit()\n return jsonify(user.to_dict())\n\n@app.route(\'/users/<int:user_id>\', methods=[\'DELETE\'])\ndef delete_user(user_id):\n user = User.query.get_or_404(user_id)\n db.session.delete(user)\n db.session.commit()\n return jsonify({\'message\': \'User deleted\'})\n\nif __name__ ** \'__main__\':\n with app.app_context():\n db.create_all()\n app.run(debug=True)\n```\n\n## 2. Using FastAPI (Modern & Type-Safe)\n\n```python\nfrom fastapi import FastAPI, HTTPException, status\nfrom pydantic import BaseModel\nfrom typing import List, Optional\nfrom sqlalchemy import create_engine, Column, Integer, String\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker, Session\n\napp = FastAPI()\n\n# Database setup\nSQLALCHEMY_DATABASE_URL = "sqlite:///./users.db"\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = declarative_base()\n\n# Pydantic models\nclass UserBase(BaseModel):\n name: str\n email: str\n\nclass UserCreate(UserBase):\n pass\n\nclass User(UserBase):\n id: int\n \n class Config:\n orm_mode = True\n\n# Database model\nclass UserDB(Base):\n __tablename__ = "users"\n \n id = Column(Integer, primary_key=True, index=True)\n name = Column(String, index=True)\n email = Column(String, unique=True, index=True)\n\nBase.metadata.create_all(bind=engine)\n\n# Helper function\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n# Routes\n@app.get("/users", response_model=List[User])\ndef read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = db.query(UserDB).offset(skip).limit(limit).all()\n return users\n\n@app.get("/users/{user_id}", response_model=User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n user = db.query(UserDB).filter(UserDB.id ** user_id).first()\n if not user:\n raise HTTPException(status_code=404, detail="User not found")\n return user\n\n@app.post("/users", response_model=User)\ndef create_user(user: UserCreate, db: Session = Depends(get_db)):\n db_user = UserDB(name=user.name, email=user.email)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n\n@app.put("/users/{user_id}", response_model=User)\ndef update_user(user_id: int, user: UserCreate, db: Session = Depends(get_db)):\n db_user = db.query(UserDB).filter(UserDB.id ** user_id).first()\n if not db_user:\n raise HTTPException(status_code=404, detail="User not found")\n \n db_user.name = user.name\n db_user.email = user.email\n db.commit()\n db.refresh(db_user)\n return db_user\n\n@app.delete("/users/{user_id}")\ndef delete_user(user_id: int, db: Session = Depends(get_db)):\n db_user = db.query(UserDB).filter(UserDB.id ** user_id).first()\n if not db_user:\n raise HTTPException(status_code=404, detail="User not found")\n \n db.delete(db_user)\n db.commit()\n return {"message": "User deleted"}\n```\n\n## 3. Using Django REST Framework\n\n```python\n# models.py\nfrom django.db import models\n\nclass User(models.Model):\n name = models.CharField(max_length=100)\n email = models.EmailField(unique=True)\n \n def __str__(self):\n return self.name\n\n# serializers.py\nfrom rest_framework import serializers\nfrom .models import User\n\nclass UserSerializer(serializers.ModelSerializer):\n class Meta:\n model = User\n fields = [\'id\', \'name\', \'email\']\n\n# views.py\nfrom rest_framework import viewsets\nfrom rest_framework.response import Response\nfrom .models import User\nfrom .serializers import UserSerializer\n\nclass UserViewSet(viewsets.ModelViewSet):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n\n# urls.py\nfrom django.urls import path, include\nfrom rest_framework.routers import DefaultRouter\nfrom .views import UserViewSet\n\nrouter = DefaultRouter()\nrouter.register(r\'users\', UserViewSet)\n\nurlpatterns = [\n path(\'api/\', include(router.urls)),\n]\n```\n\n## Key REST API Principles Implemented:\n\n1. **HTTP Methods**: GET, POST, PUT, DELETE\n2. **Status Codes**: 200, 201, 404, etc.\n3. **JSON Responses**: Consistent data format\n4. **Error Handling**: Proper HTTP status codes\n5. **Resource-based URLs**: `/users`, `/users/1`\n\n## Installation Requirements:\n\n```bash\n# Flask\npip install flask flask-sqlalchemy\n\n# FastAPI\npip install fastapi uvicorn sqlalchemy pydantic\n\n# Django\npip install django djangorestframework\n```\n\n## Running the APIs:\n\n```bash\n# Flask\npython app.py\n\n# FastAPI\nuvicorn main:app --reload\n\n# Django\npython manage.py runserver\n```\n\n**Recommendation**: Use FastAPI for new projects due to its automatic documentation, type safety, and performance. Use Flask for simpler applications or when you need more control over the implementation.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 1525, 'prompt_tokens': 50, 'total_tokens': 1575, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'Qwen/Qwen3-Coder-30B-A3B-Instruct', 'system_fingerprint': '', 'id': '019bcb14a4def74552d02fd3f9574201', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019bcb14-a342-7302-92da-a65c00138e59-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 50, 'output_tokens': 1525, 'total_tokens': 1575, 'input_token_details': {}, 'output_token_details': {}})
人类信息 HumanMessage
HumanMessage 代表用户输入和交互。它们可以包含文本、图像、音频、文件和任何其他多模态内容。
python
# string 结构
response = model.invoke("你好")
from langchain.messages import HumanMessage
print(response.content)
你好!很高兴见到你!有什么我可以帮助你的吗?
python
# Message object
# 记得加[] 一个message 对象列表
response = model.invoke(
[HumanMessage("你好")]
)
python
# dict
response = model.invoke([{"role": "user", "content": "你好"}])
print(response.content)
你好!很高兴见到你!有什么我可以帮助你的吗?
消息元数据
name 字段的行为因提供商而异 - 有些使用它来标识用户,有些则忽略它。要查看,请参阅模型提供者的 参考 。
python
human_message = HumanMessage(content="你好",
name='alice',
id='123')
print(human_message)
model.invoke([human_message])
content='你好' additional_kwargs={} response_metadata={} name='alice' id='123'
AIMessage(content='你好!很高兴见到你!有什么我可以帮助你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 12, 'prompt_tokens': 9, 'total_tokens': 21, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'Qwen/Qwen3-Coder-30B-A3B-Instruct', 'system_fingerprint': '', 'id': '019bcb1ab7dd3ba5000b84e362a66a56', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019bcb1a-b640-70f1-a08a-7866f9496443-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 9, 'output_tokens': 12, 'total_tokens': 21, 'input_token_details': {}, 'output_token_details': {}})
模型消息 AI message
AIMessage 元素表示模型调用的输出。它们可以包含多模态数据、工具调用和特定于提供者的元数据,您可以稍后访问这些数据。
调用模型时会返回 AIMessage 对象,该对象包含响应中所有关联元数据。
提供者会以不同的方式考虑/上下文化消息类型,这意味着有时手动创建一个新 < a id=0> AIMessage 对象,并将其插入到消息历史中,就像它来自模型一样,是有帮助的。
属性
| 字段名 | 类型 | 说明 |
|---|---|---|
text |
string |
消息的文本内容。 |
content |
`string | dict[]` |
content_blocks |
ContentBlock[] |
消息中的标准化内容块(如文本、图像等结构化表示)。 |
tool_calls |
`dict[] | None` |
id |
string |
消息的唯一标识符(由 LangChain 自动生成或由提供者响应返回)。 |
usage_metadata |
`dict | None` |
response_metadata |
`ResponseMetadata | None` |
python
response = model.invoke("Explain AI")
print(type(response)) # <class 'langchain.messages.AIMessage'>
<class 'langchain_core.messages.ai.AIMessage'>
python
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 history
messages = [
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)
print("text:", response.text)
print("content:", response.content)
print("content_blocks:", response.content_blocks)
print("tool_calls:", response.tool_calls)
print("id:", response.id)
print("usage_metadata:", response.usage_metadata)
print("response_metadata:", response.response_metadata)
text: 2 + 2 = 4!
This is a basic arithmetic problem. If you have any other math questions or need help with something else, feel free to ask!
content: 2 + 2 = 4!
This is a basic arithmetic problem. If you have any other math questions or need help with something else, feel free to ask!
content_blocks: [{'type': 'text', 'text': '2 + 2 = 4!\n\nThis is a basic arithmetic problem. If you have any other math questions or need help with something else, feel free to ask!'}]
tool_calls: []
id: lc_run--019bcb23-0fa1-7961-8dbb-5a8d45af1b42-0
usage_metadata: {'input_tokens': 53, 'output_tokens': 34, 'total_tokens': 87, 'input_token_details': {}, 'output_token_details': {}}
response_metadata: {'token_usage': {'completion_tokens': 34, 'prompt_tokens': 53, 'total_tokens': 87, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'Qwen/Qwen3-Coder-30B-A3B-Instruct', 'system_fingerprint': '', 'id': '019bcb231177337a20ccee9d8c2b274e', 'finish_reason': 'stop', 'logprobs': None}
工具调用 Tool calls
当模型发出工具调用时,它们会包含在AIMessage 中:
python
from langchain.tools import tool
@tool
def get_current_weather(location: str) -> str:
"""Get the current weather in a given location"""
return "{location} is sunny"
mode_with_tool_call = model.bind_tools([get_current_weather])
for tool_call in mode_with_tool_call.invoke("北京的天气是什么").tool_calls:
print("name:", tool_call["name"])
print("args", tool_call["args"])
print("ID", tool_call["id"])
name: get_current_weather
args {'location': '北京'}
ID 019bcb277f8ff036231bd0c9ac9fb5ae
令牌使用
AIMessage 可以在其 usage_metadata 字段中存储计数器和其他使用元数据:
python
from langchain_01.models.scii_deepseekv3 import model
response = model.invoke("Hello!")
response.usage_metadata
{'input_tokens': 10,
'output_tokens': 16,
'total_tokens': 26,
'input_token_details': {},
'output_token_details': {}}
流媒体和片段 AIMessageChunk
在流式传输期间,您将收到 AIMessageChunk 对象,这些对象可以组合成一个完整的消息对象:
python
chunks = []
full_text = None
for chunk in model.stream('hello'):
chunks.append(chunk)
print(chunk.text)
full_text = chunk if full_text is None else full_text + chunk
print(full_text)
Hello
!
How
can
I
help
you
today
?
content='Hello! How can I help you today?' additional_kwargs={} response_metadata={'model_provider': 'openai', 'finish_reason': 'stop', 'model_name': 'Qwen/Qwen3-Coder-30B-A3B-Instruct'} id='lc_run--019bcb2c-89e1-7a82-8fff-0d31ec68b7ee' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 99, 'output_tokens': 54, 'total_tokens': 153, 'input_token_details': {}, 'output_token_details': {}} tool_call_chunks=[] chunk_position='last'
工具消息 Tool Message
对于支持工具调用的模型,AI 消息可以包含工具调用。工具消息用于将单个工具执行的结果返回给模型。
工具 可以直接生成 ToolMessage 对象。下面是一个简单的示例。请参阅 工具指南 了解更多信息。
| name | type | required | description |
|---|---|---|---|
| content | string | required | 工具调用的字符串化输出。 |
| tool_call_id | string | required | 此消息响应的工具调用 ID。必须与 AIMessage 中的工具调用 ID 相匹配。 |
| name | string | required | 被调用的工具的名称。 |
| artifact | dict | optional | 附加数据未发送给模型,但可以以编程方式访问。 |
artifact 字段存储了补充数据,这些数据不会发送到模型,但可以以编程方式访问。这对于存储原始结果、调试信息或下游处理的数据,而不会使模型上下文变得杂乱无章,非常有用。
例如,一个 检索 工具可以检索文档中的段落,供模型参考。其中,消息 content 包含模型将参考的文本,而 artifact 可以包含应用程序可以使用的文档标识符或其他元数据(例如,用于呈现页面)。请参见下面的示例
请参阅 RAG 教程 ,了解使用 LangChain 构建检索代理的完整示例。
python
# 示例:使用 artefact 获取检索元数据
from langchain.messages import ToolMessage
# sent to model
message_content = "It was the best of times, it was the worst of times."
# Artifact available downstream
artifact = {"document_id": "doc_123", "page": 0}
tool_message = ToolMessage(
content=message_content,
tool_call_id="call_123",
name="search_books",
artifact=artifact
)
消息内容
您可以将消息的内容视为发送给模型的数据的"有效载荷"。消息具有一个 content 属性,该属性是松散类型化的,支持字符串和未类型化对象的列表(例如字典)。这使得可以直接在 LangChain 对话模型中支持提供程序原生结构,例如 多模态内容和其他数据。
另外,LangChain 提供了专门的文本、推理、引用、多模态数据、服务器端工具调用和其他消息内容的内容类型。请参见下面的内容块 。
LangChain 会接受"内容"属性中的消息内容。
这可能包含:
- A string
- A list of content blocks in a provider-native format
- A list of LangChain's standard content blocks
下面是一个使用多模态输入的示例:

https://docs.siliconflow.cn/cn/userguide/capabilities/multimodal-vision
python
from langchain.chat_models import init_chat_model
from config import config
from langchain.messages import HumanMessage
from langchain_01.models.scii_deepseekv3 import model
response = model.invoke([
HumanMessage(content_blocks=[
{
"type": "image_url",
"image_url": {
"url": "https://foruda.gitee.com/images/1762485289966260903/42bb87c9_13978721.png",
"detail": "high"
}
},
{
"type": "text",
"text": "描述这张图片的内容"
}
])
],config={"configurable": {"model": "deepseek-ai/DeepSeek-OCR"}})
print(response)
# content='2095人关注 发布于 2009-11-28 08:00 江苏 封面人物 从工厂转身,向数据奔赴 岂能尽如人意 但求无愧我心! 薛晓刚的非典型数据库之路\n\n薛晓刚的非典型数据库之路' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 58, 'prompt_tokens': 588, 'total_tokens': 646, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'deepseek-ai/DeepSeek-OCR', 'system_fingerprint': '', 'id': '019bcb53745735fd6b19d21a3461b87e', 'finish_reason': 'stop', 'logprobs': None} id='lc_run--019bcb53-6d53-73f0-baa8-e4dc519fc0bc-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 588, 'output_tokens': 58, 'total_tokens': 646, 'input_token_details': {}, 'output_token_details': {}}
content='2095人关注 发布于 2009-11-28 08:00 江苏 封面人物 从工厂转身,向数据奔赴 岂能尽如人意 但求无愧我心! 薛晓刚的非典型数据库之路\n\n薛晓刚的非典型数据库之路' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 58, 'prompt_tokens': 588, 'total_tokens': 646, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'deepseek-ai/DeepSeek-OCR', 'system_fingerprint': '', 'id': '019bcb53745735fd6b19d21a3461b87e', 'finish_reason': 'stop', 'logprobs': None} id='lc_run--019bcb53-6d53-73f0-baa8-e4dc519fc0bc-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 588, 'output_tokens': 58, 'total_tokens': 646, 'input_token_details': {}, 'output_token_details': {}}
python
# List of standard content blocks
human_message = HumanMessage(content_blocks=[
{"type": "text", "text": "Hello, how are you?"},
{"type": "image", "url": "https://foruda.gitee.com/images/1762485289966260903/42bb87c9_13978721.png"},
])
response = model.invoke([human_message],config={"configurable": {"model": "deepseek-ai/DeepSeek-OCR"}})
print(response.content)
<ins>薛晓刚的非典型数据库之路</ins>CanCee 封面人物
Standard content blocks
LangChain 提供了标准的消息内容表示,可以在所有提供者上工作。
消息对象实现了一个 contentBlocks 属性,该属性将 content 属性懒惰地解析为标准、类型安全的表示。例如,来自 ChatAnthropic 或 ChatOpenAI 的消息将包含相应提供程序格式的 thinking 或 reasoning 块,但可以懒惰地解析为一致的 ReasoningContentBlock 表示:
标准内容的序列化
如果 LangChain 外部的应用程序需要访问标准内容块表示,您可以选择在消息内容中存储内容块。
为此,您可以将 LC_OUTPUT_VERSION 环境变量设置为 v1。或者,使用 output_version="v1" 初始化任何聊天模型:
python
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-5-nano", output_version="v1")
python
model.invoke([
HumanMessage("写一首关于开心的四言绝句")
],config={"configurable": {"model": "deepseek-ai/DeepSeek-R1-0528-Qwen3-8B"}})
AIMessage(content='\n《四言·开心》\n春日融融,莺啼振翅。\n笑颜逐处,踏青忘还。\n心随云朵,意共风驰。\n醉在当下,乐此不疲。\n\n赏析:这首作品以春日为背景,通过"莺啼振翅"、"笑颜逐处"等意象,生动描绘了人们在春光中陶醉的场景。诗中"踏青忘还"、"醉在当下"等句,表达了对自由快乐的向往和追求,语言简练而意境深远,充分展现了开心的主题。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 708, 'prompt_tokens': 12, 'total_tokens': 720, 'completion_tokens_details': {'accepted_prediction_tokens': None, 'audio_tokens': None, 'reasoning_tokens': 584, 'rejected_prediction_tokens': None}, 'prompt_tokens_details': None}, 'model_provider': 'openai', 'model_name': 'deepseek-ai/DeepSeek-R1-0528-Qwen3-8B', 'system_fingerprint': '', 'id': '019bcb5ff83929a3e1695bccfb7d8ed0', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019bcb5f-f635-7e33-8eb3-052bbc4f36cb-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 12, 'output_tokens': 708, 'total_tokens': 720, 'input_token_details': {}, 'output_token_details': {'reasoning': 584}})
多模式 Multimodality
多模态 指的是能够处理以文本、音频、图像和视频等不同形式出现的数据。LangChain 包含标准类型的数据,可以在各个提供者之间使用。
Chat models 可以接受多模态数据作为输入,并将其作为输出生成。下面,我们展示了一些带有多模态数据的输入消息的简短示例。
图片
python
# 标准图片支持
# From URL
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this image."},
{"type": "image", "url": "https://example.com/path/to/image.jpg"},
]
}
# From base64 data
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this image."},
{
"type": "image",
"base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
"mime_type": "image/jpeg",
},
]
}
# From provider-managed File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this image."},
{"type": "image", "file_id": "file-abc123"},
]
}
python
# From URL
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this document."},
{"type": "file", "url": "https://example.com/path/to/document.pdf"},
]
}
# From base64 data
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this document."},
{
"type": "file",
"base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
"mime_type": "application/pdf",
},
]
}
# From provider-managed File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this document."},
{"type": "file", "file_id": "file-abc123"},
]
}
音频 Audio
暂时没有调通,硅基流动平台不支持base64
python
# From base64 data
# assets/buyao2.wav 转换为 base64 编码
import base64
with open("../../../assets/buyao2.wav", "rb") as audio_file:
base64_data = base64.b64encode(audio_file.read()).decode("utf-8")
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this audio."},
{
"type": "audio",
"base64": base64_data,
"mime_type": "audio/wav",
},
]
}
response = model.invoke([message],config={"configurable":{"model":"Qwen/Qwen3-Omni-30B-A3B-Thinking"}})
print(response.content)
# From provider-managed File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this audio."},
{"type": "audio", "file_id": "file-abc123"},
]
}
视频 Video
python
# From base64 data
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this video."},
{
"type": "video",
"base64": "AAAAIGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb2...",
"mime_type": "video/mp4",
},
]
}
# From provider-managed File ID
message = {
"role": "user",
"content": [
{"type": "text", "text": "Describe the content of this video."},
{"type": "video", "file_id": "file-abc123"},
]
}
内容块引用
内容块(无论是创建消息还是访问 contentBlocks 属性)都表示为一个列表的类型化字典。列表中的每个项必须符合以下块类型之一:
https://docs.langchain.com/oss/python/langchain/messages#content-block-reference
在 LangChain v1 中,消息引入了新的属性内容块,以标准化不同提供商的内容格式,同时保持与现有代码的后向兼容性。
内容块不是 content 属性的替代品,而是可以用来访问消息内容的新属性,该属性以标准化格式使用。
与聊天模型一起使用
聊天模型接受消息对象的序列作为输入,并返回 AIMessage 作为输出。交互通常是无状态的,因此简单的会话循环涉及调用模型,模型会不断生成消息列表。
请参阅下面的指南了解更多信息:
- 持久化和管理对话历史记录的内置功能
- 管理上下文窗口的策略,包括 修剪和总结消息