メッセージは LangChain におけるモデルのコンテキストの基本ユニットです。メッセージはモデルの入出力を表し、LLM とやり取りする際、会話の状態を表すのに必要なコンテンツとメタデータの両方をキャリーします。
LangChain 1.0 alpha : コアコンポーネント – メッセージ
作成 : クラスキャット・セールスインフォメーション
作成日時 : 09/23/2025
バージョン : 1.0.0a6
* 本記事は docs.langchain.com の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています。スニペットはできる限り日本語を使用しています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
◆ お問合せ : 下記までお願いします。
- クラスキャット セールス・インフォメーション
- sales-info@classcat.com
- ClassCatJP

LangChain 1.0 alpha : コアコンポーネント – メッセージ
メッセージは LangChain におけるモデルのコンテキストの基本ユニットです。メッセージはモデルの入出力を表し、LLM とやり取りする際、会話の状態を表すのに必要なコンテンツとメタデータの両方をキャリーします。
メッセージは以下を含むオブジェクトです :
- ロール – メッセージ・タイプ (e.g., system、user) を識別します。
- コンテンツ – テキスト、画像、音声、ドキュメント 等のような、メッセージの実際の内容を表します。
- メタデータ – レスポンス情報、メッセージ ID、トークン使用量のようなオプションフィールド
LangChain は、すべてのモデルプロバイダーに渡り動作する標準的なメッセージタイプを提供し、呼び出されるモデルに関係なく一貫した動作を保証します。
基本的な使用方法
メッセージを使用する最も簡単な方法は、メッセージ・オブジェクトを作成して、モデルを呼び出すときにそれらを渡すことです。
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
model = init_chat_model("openai:gpt-5-nano")
system_msg = SystemMessage("You are a helpful assistant.")
human_msg = HumanMessage("Hello, how are you?")
# Use with chat models
messages = [system_msg, human_msg]
response = model.invoke(messages) # Returns AIMessage
出力例
Hi there! I’m here and ready to help with whatever you need. I don’t have feelings, but I’m ready to assist. What would you like help with today?
テキスト・プロンプト
テキストプロンプトは文字列です – 会話履歴を保持する必要のない、単純な生成タスクに最適です。
response = model.invoke("春について俳句を書いてください。")
出力例
もちろん。春をテーマにした俳句を3つ挙げます。 1) 春風や 桜の下で 鳥の声 2) 春雨や 蛙が跳ねる 春の風 3) 桜並木 風に散る花 春日かな
以下のような場合に、テキストプロンプトを使用します :
- 単一の、スタンドアローンなリクエストがある
- 会話履歴を必要としない
- 最小限のコードの複雑を望む
メッセージ・プロンプト
あるいは、メッセージ・オブジェクトのリストを提供することで、メッセージのリストをモデルに渡すこともできます。
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
messages = [
SystemMessage("あなたは詩の専門家です。"),
HumanMessage("春について俳句を作成してください。W"),
AIMessage("桜🌸の花が咲きました ...")
]
response = model.invoke(messages)
出力例
以下、春をテーマにした俳句を3つご提案します。 1) 春風や 桜の花びらが 川を染める 2) 春の朝 霧の中に光る 蝶ひらり 3) 雪解けて 庭の小さな芽が 風に揺れる ご希望の雰囲気や季節感があれば、別のスタイルでさらに作成します。
以下の場合、メッセージ・プロンプトを使用します :
- マルチターンの会話を管理
- マルチモーダル・コンテンツ (画像、音声、ファイル) を扱う
- システム指示を含む
辞書形式
OpenAI チャット completions 形式でメッセージを直接指定することもできます。
messages = [
{"role": "system", "content": "あなたは詩の専門家です。"},
{"role": "user", "content": "春について俳句を作成してください。"},
{"role": "assistant", "content": "桜🌸の花が咲きました .."}
]
response = model.invoke(messages)
出力例
春を題材にした俳句をいくつかご用意しました。5-7-5の定型を意識しています。 - 春風や 桜咲く頃 川の音 - 春ひらく 花びらゆらぐ 朝露や - 水辺へと 鶯の声 春来る日 どれも季語として「春」と自然の情景を取り入れています。お気に入りがあれば教えてください。別の雰囲気でも作成します。
メッセージ・タイプ
- System メッセージ – モデルに動作する方法を伝えて、インタラクションのコンテキストを提供します。
- Human メッセージ – ユーザ入力とモデルとのインタラクションを表します。
- AI メッセージ – テキストコンテンツ、ツール呼び出し、メタデータを含む、モデルにより生成されたレスポンス。
- Tool メッセージ – ツール呼び出しの出力を表します。
System メッセージ
SystemMessage は、モデルの動作を準備する指示の初期セットを表します。雰囲気 (tone) を決め、モデルの役割りを定義し、レスポンスのガイドラインを確立するために system メッセージを使用できます。
Basic instructions
system_msg = SystemMessage("あなたは役立つコーディング・アシスタントです。")
messages = [
system_msg,
HumanMessage("REST API をどのように作成しますか?")
]
response = model.invoke(messages)
Detailed persona
from langchain_core.messages import SystemMessage, HumanMessage
system_msg = SystemMessage("""
あなたは Web フレームワークの専門知識を持つ上級 Python 開発者です。
必ずコード例を提示し、その理由を説明してください。
説明は簡潔でありながら完全に行ってください。
""")
messages = [
system_msg,
HumanMessage("REST API をどのように作成しますか?")
]
response = model.invoke(messages)
出力例
REST API を作成する基本的な道筋と、実装例を FastAPI を用いて示します。最新の Python で高性能・型安全・自動ドキュメントが得られる点が魅力です。
1) 要件定義と設計
- 何をリソースとして公開するかを決める(例: items, users, orders など)
- 各リソースに対して CRUD 操作を HTTP メソッドで設計する
- Create: POST /items
- Read: GET /items, GET /items/{id}
- Update: PUT /items/{id}
- Delete: DELETE /items/{id}
- バージョン管理(例: /api/v1/...)と適切なステータスコードを採用
- 入力検証・エラーハンドリング・認証・認可・データ検証を整備
- ドキュメント化(OpenAPI/Swaggerは自動生成が望ましい)
2) 技術選択と理由
- FastAPI を推奨:型ヒントを活用した検証・自動生成ドキュメント、非同期処理、パフォーマンス、初心者にも扱いやすい。
- ORM は SQLAlchemy 或いは Tortoise ORM など、データベースと連携してモデルを定義。
- テストには httpx(あるいは requests)と pytest。
3) プロジェクト構成の例
- app/
- main.py : FastAPI アプリの起動・ルーティング
- api/
- v1/
- items.py : アイテム関連のエンドポイント
- models/
- item.py : SQLAlchemy の ORM モデル
- schemas/
- item.py : Pydantic モデル(リクエスト/レスポンス用)
- core/
- config.py : 設定(例: データベースURL)
- db.py : DB セッション管理
- tests/ : テスト
4) 最小実装サンプル(FastAPI + in-memory store)
- ファイル名: main.py
```python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
app = FastAPI(title="Sample API", version="1.0.0")
class Item(BaseModel):
id: int
name: str
description: Optional[str] = None
price: float
# インメモリストア(サンプル用)
_items: dict[int, Item] = {}
@app.post("/api/v1/items/", response_model=Item, status_code=201)
async def create_item(item: Item):
if item.id in _items:
raise HTTPException(status_code=400, detail="Item already exists")
_items[item.id] = item
return item
@app.get("/api/v1/items/", response_model=List[Item])
async def list_items():
return list(_items.values())
@app.get("/api/v1/items/{item_id}", response_model=Item)
async def get_item(item_id: int):
item = _items.get(item_id)
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
return item
@app.put("/api/v1/items/{item_id}", response_model=Item)
async def update_item(item_id: int, item: Item):
if item_id != item.id:
raise HTTPException(status_code=400, detail="ID mismatch")
if item_id not in _items:
raise HTTPException(status_code=404, detail="Item not found")
_items[item_id] = item
return item
@app.delete("/api/v1/items/{item_id}", status_code=204)
async def delete_item(item_id: int):
if item_id not in _items:
raise HTTPException(status_code=404, detail="Item not found")
del _items[item_id]
return
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
```
実行方法:
- 環境構築
- pip install fastapi uvicorn pydantic
- 起動
- uvicorn main:app --reload
- ドキュメント
- http://localhost:8000/api/v1/items/ で自動生成された Swagger UI/ ReDoc が利用可能
5) データベース連携の基本(SQLAlchemy 例)
- 追加ファイルを用意して ORM で永続化する基本例
ファイル: db.py
```python
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
DATABASE_URL = "sqlite:///./test.db" # 環境に合わせて変更
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
```
ファイル: models/item.py
```python
from sqlalchemy import Column, Integer, String, Float
from .base import Base # ここでは Base が db.py の Base を指す想定
class ItemModel(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
description = Column(String, nullable=True)
price = Column(Float, nullable=False)
```
ファイル: schemas/item.py
```python
from pydantic import BaseModel
from typing import Optional
class ItemCreate(BaseModel):
id: int
name: str
description: Optional[str] = None
price: float
```
ファイル: main.py の簡易統合例(要調整)
```python
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from db import SessionLocal, Base
from models.item import ItemModel
from schemas.item import ItemCreate
Base.metadata.create_all(bind=engine)
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/api/v1/items/", response_model=ItemCreate)
def create_item(item: ItemCreate, db: Session = Depends(get_db)):
db_item = ItemModel(id=item.id, name=item.name, description=item.description, price=item.price)
db.add(db_item)
db.commit()
db.refresh(db_item)
return item
```
補足:
- 実運用では、インメモリストアは避け、必ずデータベースへ永続化します。上の例は最小構成のイメージです。
- Pydantic のスキーマと SQLAlchemy のモデルを分けると、入力検証と永続化をきれいに分離できます。
6) 認証とエラーハンドリングの基本
- 認証: OAuth2 Password Flow や JWT を導入
- 実装例(簡易): JWT トークンを発行するエンドポイントと、保護されたエンドポイントの例
```python
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def create_access_token(data: dict):
return jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM)
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload
except JWTError:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
@app.post("/api/v1/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
# 実際にはユーザー確認を行う
access_token = create_access_token({"sub": form_data.username})
return {"access_token": access_token, "token_type": "bearer"}
@app.get("/api/v1/protected")
async def protected_route(user: dict = Depends(get_current_user)):
return {"hello": user.get("sub")}
```
7) ドキュメントとテスト
- FastAPI は OpenAPI に基づく自動ドキュメントを提供
- http://localhost:8000/docs(Swagger UI)
- http://localhost:8000/redoc(ReDoc)
- テスト例(httpx + pytest)
```python
# tests/test_items.py
import httpx
import pytest
BASE = "http://localhost:8000/api/v1"
@pytest.mark.asyncio
async def test_create_and_get_item():
async with httpx.AsyncClient() as client:
r = await client.post(f"{BASE}/items/", json={"id":1,"name":"Sample","price":9.99})
assert r.status_code == 201
r = await client.get(f"{BASE}/items/1")
assert r.status_code == 200
```
8) デプロイと運用のヒント
- ASGI サーバーで運用
- uvicornや gunicorn + uvicorn workers の組み合わせ
- 例: gunicorn -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8000
- Docker 化の基本
- Dockerfile:
- FROM python:3.11-slim
- WORKDIR /app
- COPY requirements.txt .
- RUN pip install -r requirements.txt
- COPY . .
- CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
- docker-compose で DB 連携と API を同時に起動する構成がよく用いられます。
- 監視・運用
- ログ、エラーレスポンス、レイテンシの監視を組み込み
- API バージョンを使った後方互換性の維持
- セキュリティ対策として TLS、入力検証、 rate limit、認証・権限の適切な設定
要点
- FastAPI は最速で実用的な REST API を作成でき、型安全・自動ドキュメント・非同期処理を同時に得られます。
- まずは小さなエンドポイントから始め、徐々にデータベース連携・認証・エラーハンドリングを拡張するのが現実的です。
- 本番運用ではデータベース・認証・デプロイ手順を明確に分離・自動化し、テストとドキュメントを常に最新に保つことが重要です。
必要であれば、あなたの用途(データベース種別、認証要件、公開 API の規模)に合わせた具体的なコード構成とファイルテンプレを作成します。どのフレームワークがよいか(FastAPI/DRF/Flask など)も目的に合わせて提案します。
Human メッセージ
HumanMessage はユーザの入力とインタラクションを表します。テキスト、画像、音声、ファイルと、その他のマルチモーダルなコンテンツを含むことができます。
テキストコンテンツ
Message オブジェクト
human_msg = HumanMessage("What is machine learning?")
response = model.invoke([human_msg])
文字列ショートカット
# Using a string is a shortcut for a single HumanMessage
response = model.invoke("What is machine learning?")
メッセージ・メタデータ
メタデータの追加
human_msg = HumanMessage(
content="Hello!",
name="alice", # Optional: identify different users
id="msg_123", # Optional: unique identifier for tracing
)
AI メッセージ
AIMessage はモデル呼び出しの出力を表します。マルチモーダルデータ、ツール呼び出し、そして (後でアクセス可能な) プロバイダー固有のメタデータを含むことができます。
response = model.invoke("Explain AI")
print(type(response)) # <class 'langchain_core.messages.AIMessage'>
AIMessage オブジェクトはモデルを呼び出した際にモデルにより返され、これはレスポンス内の関連メタデータのすべてを含みます。けれども、これが AIMessage オブジェクトの作成/変更が可能な唯一の場所ではありません。
プロバイダーはメッセージのタイプにより異なって重み付けし、コンテキストを理解するので、新しい AIMessage オブジェクトの作成や (モデルから取得したかのように) メッセージ履歴への挿入は役立つ場合があります。
from langchain_core.messages import AIMessage, SystemMessage, HumanMessage
# Create an AI message manually (e.g., for conversation history)
ai_msg = AIMessage("その問題について喜んでお手伝いさせていただきます!")
# Add to conversation history
messages = [
SystemMessage("あなたは役に立つアシスタントです"),
HumanMessage("手伝ってもらえますか?"),
ai_msg, # Insert as if it came from the model
HumanMessage("素晴らしい!2+2 はいくつですか?")
]
response = model.invoke(messages)
出力例
4です。ほかにも計算の問題があれば教えてください。
ツール呼び出しレスポンス
モデルがツールを呼び出すとき、ツール呼び出しレスポンスは AI メッセージに (tool_calls として) 含まれます :
Tool calling
model_with_tools = model.bind_tools([GetWeather])
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']}")
ストリーミングとチャンク
ストリーミング中、完全なメッセージに組み合わせることができる AIMessageChunk オブジェクトを受け取ります :
chunks = []
full_message = None
for chunk in model.stream("Hi"):
chunks.append(chunk)
print(chunk.text)
full_message = chunk if full_message is None else full_message + chunk
ツールメッセージ
ツール呼び出しをサポートするモデルについては、AI メッセージはツール呼び出しを含めることができます。ツールメッセージは、単一のツール実行の結果をモデルに返すために使用されます。
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"{city} では常に晴れています!"
model = init_chat_model("openai:gpt-5-nano")
# モデルがツール呼び出しを行った後
ai_message = AIMessage(
content=[],
tool_calls=[{
"name": "get_weather",
"args": {"location": "東京"},
"id": "call_123"
}]
)
# ツールを実行して結果メッセージを作成
weather_result = "晴れ, 22度"
tool_message = ToolMessage(
content=weather_result,
tool_call_id="call_123" # Must match the call ID
)
# 会話の続行
messages = [
HumanMessage("東京の天気はどうですか?"),
ai_message, # Model's tool call
tool_message, # Tool execution result
]
response = model.invoke(messages) # Model processes the result
出力例
東京は晴れで、気温は22度です。日中は過ごしやすいですが日差しが強いので、外出時は帽子や日焼け止めをお忘れなく。 夜になると涼しくなる可能性があります。何か計画があれば、時間帯に合わせたアドバイスもします。
以上
