Message는 LangChain에서 모델의 컨텍스트를 구성하는 기본 단위입니다. 이들은 모델의 입력과 출력을 나타내며, LLM과 상호작용할 때 대화의 상태를 표현하는 데 필요한 콘텐츠와 메타데이터를 모두 담고 있습니다. Message는 다음을 포함하는 객체입니다:
  • Role - 메시지 타입을 식별합니다 (예: system, user)
  • Content - 메시지의 실제 콘텐츠를 나타냅니다 (텍스트, 이미지, 오디오, 문서 등)
  • Metadata - 응답 정보, 메시지 ID, 토큰 사용량과 같은 선택적 필드
LangChain은 모든 모델 제공자에서 작동하는 표준 메시지 타입을 제공하여, 호출되는 모델에 관계없이 일관된 동작을 보장합니다.

기본 사용법

메시지를 사용하는 가장 간단한 방법은 메시지 객체를 생성하고 호출할 때 모델에 전달하는 것입니다.
from langchain.chat_models import init_chat_model
from langchain.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

텍스트 프롬프트

텍스트 프롬프트는 문자열입니다 - 대화 기록을 유지할 필요가 없는 간단한 생성 작업에 이상적입니다.
response = model.invoke("Write a haiku about spring")
텍스트 프롬프트를 사용하는 경우:
  • 단일의 독립적인 요청이 있을 때
  • 대화 기록이 필요하지 않을 때
  • 최소한의 코드 복잡성을 원할 때

메시지 프롬프트

또는 메시지 객체 목록을 제공하여 모델에 메시지 목록을 전달할 수 있습니다.
from langchain.messages import SystemMessage, HumanMessage, AIMessage

messages = [
    SystemMessage("You are a poetry expert"),
    HumanMessage("Write a haiku about spring"),
    AIMessage("Cherry blossoms bloom...")
]
response = model.invoke(messages)
메시지 프롬프트를 사용하는 경우:
  • 다중 턴 대화를 관리할 때
  • 멀티모달 콘텐츠(이미지, 오디오, 파일)를 다룰 때
  • 시스템 지침을 포함할 때

Dictionary 형식

OpenAI chat completions 형식으로 직접 메시지를 지정할 수도 있습니다.
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 message - 텍스트 콘텐츠, tool call, 메타데이터를 포함한 모델이 생성한 응답입니다
  • Tool message - tool call의 출력을 나타냅니다

System Message

SystemMessage는 모델의 동작을 준비시키는 초기 지침 세트를 나타냅니다. system message를 사용하여 톤을 설정하고, 모델의 역할을 정의하며, 응답에 대한 가이드라인을 설정할 수 있습니다.
Basic instructions
system_msg = SystemMessage("You are a helpful coding assistant.")

messages = [
    system_msg,
    HumanMessage("How do I create a REST API?")
]
response = model.invoke(messages)
Detailed persona
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?")
]
response = model.invoke(messages)

Human Message

HumanMessage는 사용자 입력과 상호작용을 나타냅니다. 텍스트, 이미지, 오디오, 파일 및 기타 멀티모달 콘텐츠를 포함할 수 있습니다.

텍스트 콘텐츠

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

메시지 메타데이터

Add metadata
human_msg = HumanMessage(
    content="Hello!",
    name="alice",  # Optional: identify different users
    id="msg_123",  # Optional: unique identifier for tracing
)
name 필드 동작은 제공자에 따라 다릅니다 - 일부는 사용자 식별에 사용하고, 다른 일부는 무시합니다. 확인하려면 모델 제공자의 reference를 참조하세요.

AI Message

AIMessage는 모델 호출의 출력을 나타냅니다. 멀티모달 데이터, tool call, 나중에 액세스할 수 있는 제공자별 메타데이터를 포함할 수 있습니다.
response = model.invoke("Explain AI")
print(type(response))  # <class 'langchain_core.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 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)
text
string
메시지의 텍스트 콘텐츠입니다.
content
string | dict[]
메시지의 원시 콘텐츠입니다.
content_blocks
ContentBlock[]
메시지의 표준화된 content block입니다.
tool_calls
dict[] | None
모델이 수행한 tool call입니다. tool이 호출되지 않으면 비어 있습니다.
id
string
메시지의 고유 식별자입니다 (LangChain에서 자동으로 생성되거나 제공자 응답에서 반환됨)
usage_metadata
dict | None
사용 가능한 경우 토큰 수를 포함할 수 있는 메시지의 사용 메타데이터입니다.
response_metadata
ResponseMetadata | None
메시지의 응답 메타데이터입니다.

Tool call

모델이 tool call을 수행하면 AIMessage에 포함됩니다:
from langchain.chat_models import init_chat_model

model = init_chat_model("openai: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']}")
추론이나 인용과 같은 다른 구조화된 데이터도 메시지 content에 나타날 수 있습니다.

토큰 사용량

AIMessageusage_metadata 필드에 토큰 수 및 기타 사용 메타데이터를 보유할 수 있습니다:
from langchain.chat_models import init_chat_model

model = init_chat_model("openai: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}}
자세한 내용은 UsageMetadata를 참조하세요.

Streaming과 chunk

스트리밍 중에는 전체 메시지 객체로 결합할 수 있는 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

Tool Message

tool calling을 지원하는 모델의 경우, AI message에 tool call이 포함될 수 있습니다. Tool message는 단일 tool 실행 결과를 모델에 다시 전달하는 데 사용됩니다. ToolToolMessage 객체를 직접 생성할 수 있습니다. 아래에 간단한 예제를 보여줍니다. tools 가이드에서 자세히 알아보세요.
# After a model makes a tool call
ai_message = AIMessage(
    content=[],
    tool_calls=[{
        "name": "get_weather",
        "args": {"location": "San Francisco"},
        "id": "call_123"
    }]
)

# Execute tool and create result message
weather_result = "Sunny, 72°F"
tool_message = ToolMessage(
    content=weather_result,
    tool_call_id="call_123"  # Must match the call ID
)

# Continue conversation
messages = [
    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
content
string
required
tool call의 문자열화된 출력입니다.
tool_call_id
string
required
이 메시지가 응답하는 tool call의 ID입니다. (AIMessage의 tool call ID와 일치해야 함)
name
string
required
호출된 tool의 이름입니다.
artifact
dict
모델에 전송되지 않지만 프로그래밍 방식으로 액세스할 수 있는 추가 데이터입니다.
artifact 필드는 모델에 전송되지 않지만 프로그래밍 방식으로 액세스할 수 있는 보조 데이터를 저장합니다. 이는 모델의 컨텍스트를 복잡하게 만들지 않으면서 원시 결과, 디버깅 정보 또는 다운스트림 처리를 위한 데이터를 저장하는 데 유용합니다.
예를 들어, retrieval tool은 모델이 참조할 문서에서 구절을 검색할 수 있습니다. 메시지 content에는 모델이 참조할 텍스트가 포함되고, artifact에는 애플리케이션이 사용할 수 있는 문서 식별자 또는 기타 메타데이터(예: 페이지 렌더링)가 포함될 수 있습니다. 아래 예제를 참조하세요:
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,
)
LangChain으로 검색 agent를 구축하는 엔드투엔드 예제는 RAG 튜토리얼을 참조하세요.

메시지 콘텐츠

메시지의 콘텐츠는 모델에 전송되는 데이터의 페이로드로 생각할 수 있습니다. 메시지에는 문자열과 타입이 지정되지 않은 객체(예: dictionary) 목록을 지원하는 느슨하게 타입이 지정된 content 속성이 있습니다. 이를 통해 multimodal 콘텐츠 및 기타 데이터와 같은 제공자 네이티브 구조를 LangChain chat model에서 직접 지원할 수 있습니다. 별도로, LangChain은 텍스트, 추론, 인용, 멀티모달 데이터, 서버 측 tool call 및 기타 메시지 콘텐츠에 대한 전용 콘텐츠 타입을 제공합니다. 아래 content block을 참조하세요. LangChain chat model은 content 속성에서 메시지 콘텐츠를 허용하며, 다음을 포함할 수 있습니다:
  1. 문자열
  2. 제공자 네이티브 형식의 content block 목록
  3. LangChain의 표준 content block 목록
multimodal 입력을 사용하는 예제는 아래를 참조하세요:
from langchain.messages import HumanMessage

# String content
human_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 blocks
human_message = HumanMessage(content_blocks=[
    {"type": "text", "text": "Hello, how are you?"},
    {"type": "image", "url": "https://example.com/image.jpg"},
])
메시지를 초기화할 때 content_blocks를 지정하면 여전히 메시지 content가 채워지지만, 이를 수행하기 위한 타입 안전 인터페이스를 제공합니다.

표준 content block

LangChain은 제공자 간에 작동하는 메시지 콘텐츠에 대한 표준 표현을 제공합니다. Message 객체는 content 속성을 표준적이고 타입 안전한 표현으로 지연 파싱하는 content_blocks 속성을 구현합니다. 예를 들어, ChatAnthropic 또는 ChatOpenAI에서 생성된 메시지는 각 제공자의 형식으로 thinking 또는 reasoning block을 포함하지만, 일관된 ReasoningContentBlock 표현으로 지연 파싱될 수 있습니다:
  • Anthropic
  • OpenAI
from langchain.messages import AIMessage

message = 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 외부의 애플리케이션이 표준 content block 표현에 액세스해야 하는 경우, 메시지 콘텐츠에 content block을 저장하도록 선택할 수 있습니다.이를 위해 LC_OUTPUT_VERSION 환경 변수를 v1로 설정할 수 있습니다. 또는 output_version="v1"로 chat model을 초기화할 수 있습니다:
from langchain.chat_models import init_chat_model

model = init_chat_model("openai:gpt-5-nano", output_version="v1")

Multimodal

Multimodality는 텍스트, 오디오, 이미지, 비디오와 같은 다양한 형태의 데이터를 다루는 능력을 의미합니다. LangChain은 제공자 간에 사용할 수 있는 이러한 데이터에 대한 표준 타입을 포함합니다. Chat model은 멀티모달 데이터를 입력으로 받아들이고 출력으로 생성할 수 있습니다. 아래에서 멀티모달 데이터가 포함된 입력 메시지의 짧은 예제를 보여줍니다.
추가 키는 content block의 최상위 레벨에 포함되거나 "extras": {"key": value}에 중첩될 수 있습니다.예를 들어, OpenAIAWS Bedrock Converse는 PDF에 대한 파일 이름이 필요합니다. 자세한 내용은 선택한 모델의 제공자 페이지를 참조하세요.
# 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"},
    ]
}
모든 모델이 모든 파일 타입을 지원하는 것은 아닙니다. 지원되는 형식과 크기 제한은 모델 제공자의 reference를 확인하세요.

Content block 참조

Content block은 (메시지를 생성하거나 content_blocks 속성에 액세스할 때) 타입이 지정된 dictionary 목록으로 표현됩니다. 목록의 각 항목은 다음 block 타입 중 하나를 준수해야 합니다:
목적: 표준 텍스트 출력
type
string
required
항상 "text"
text
string
required
텍스트 콘텐츠
annotations
object[]
텍스트에 대한 주석 목록
extras
object
추가 제공자별 데이터
예제:
{
    "type": "text",
    "text": "Hello world",
    "annotations": []
}
목적: 모델 추론 단계
type
string
required
항상 "reasoning"
reasoning
string
추론 콘텐츠
extras
object
추가 제공자별 데이터
예제:
{
    "type": "reasoning",
    "reasoning": "The user is asking about...",
    "extras": {"signature": "abc123"},
}
목적: 이미지 데이터
type
string
required
항상 "image"
url
string
이미지 위치를 가리키는 URL입니다.
base64
string
Base64로 인코딩된 이미지 데이터입니다.
id
string
외부에 저장된 이미지에 대한 참조 ID입니다 (예: 제공자의 파일 시스템 또는 버킷).
mime_type
string
이미지 MIME type (예: image/jpeg, image/png)
목적: 오디오 데이터
type
string
required
항상 "audio"
url
string
오디오 위치를 가리키는 URL입니다.
base64
string
Base64로 인코딩된 오디오 데이터입니다.
id
string
외부에 저장된 오디오 파일에 대한 참조 ID입니다 (예: 제공자의 파일 시스템 또는 버킷).
mime_type
string
오디오 MIME type (예: audio/mpeg, audio/wav)
목적: 비디오 데이터
type
string
required
항상 "video"
url
string
비디오 위치를 가리키는 URL입니다.
base64
string
Base64로 인코딩된 비디오 데이터입니다.
id
string
외부에 저장된 비디오 파일에 대한 참조 ID입니다 (예: 제공자의 파일 시스템 또는 버킷).
mime_type
string
비디오 MIME type (예: video/mp4, video/webm)
목적: 일반 파일 (PDF 등)
type
string
required
항상 "file"
url
string
파일 위치를 가리키는 URL입니다.
base64
string
Base64로 인코딩된 파일 데이터입니다.
id
string
외부에 저장된 파일에 대한 참조 ID입니다 (예: 제공자의 파일 시스템 또는 버킷).
mime_type
string
파일 MIME type (예: application/pdf)
목적: 문서 텍스트 (.txt, .md)
type
string
required
항상 "text-plain"
text
string
텍스트 콘텐츠
mime_type
string
텍스트의 MIME type (예: text/plain, text/markdown)
목적: Function call
type
string
required
항상 "tool_call"
name
string
required
호출할 tool의 이름
args
object
required
tool에 전달할 인수
id
string
required
이 tool call의 고유 식별자
예제:
{
    "type": "tool_call",
    "name": "search",
    "args": {"query": "weather"},
    "id": "call_123"
}
목적: 스트리밍 tool call 조각
type
string
required
항상 "tool_call_chunk"
name
string
호출되는 tool의 이름
args
string
부분 tool 인수 (불완전한 JSON일 수 있음)
id
string
Tool call 식별자
index
number | string
스트림에서 이 chunk의 위치
목적: 잘못된 형식의 call, JSON 파싱 오류를 포착하기 위한 것입니다.
type
string
required
항상 "invalid_tool_call"
name
string
호출에 실패한 tool의 이름
args
object
tool에 전달할 인수
error
string
무엇이 잘못되었는지에 대한 설명
목적: 서버 측에서 실행되는 tool call입니다.
type
string
required
항상 "server_tool_call"
id
string
required
tool call과 연결된 식별자입니다.
name
string
required
호출할 tool의 이름입니다.
args
string
required
부분 tool 인수 (불완전한 JSON일 수 있음)
목적: 스트리밍 서버 측 tool call 조각
type
string
required
항상 "server_tool_call_chunk"
id
string
tool call과 연결된 식별자입니다.
name
string
호출되는 tool의 이름
args
string
부분 tool 인수 (불완전한 JSON일 수 있음)
index
number | string
스트림에서 이 chunk의 위치
목적: 검색 결과
type
string
required
항상 "server_tool_result"
tool_call_id
string
required
해당 server tool call의 식별자입니다.
id
string
server tool result와 연결된 식별자입니다.
status
string
required
서버 측 tool의 실행 상태입니다. "success" 또는 "error".
output
실행된 tool의 출력입니다.
목적: 제공자별 탈출구
type
string
required
항상 "non_standard"
value
object
required
제공자별 데이터 구조
사용: 실험적이거나 제공자 고유 기능용
추가 제공자별 콘텐츠 타입은 각 모델 제공자의 참조 문서에서 찾을 수 있습니다.
API reference에서 정식 타입 정의를 확인하세요.
Content block은 제공자 간 콘텐츠 형식을 표준화하면서 기존 코드와의 하위 호환성을 유지하기 위해 LangChain v1에서 메시지의 새로운 속성으로 도입되었습니다. Content block은 content 속성을 대체하는 것이 아니라, 표준화된 형식으로 메시지의 콘텐츠에 액세스하는 데 사용할 수 있는 새로운 속성입니다.

Chat model과 함께 사용

Chat model은 메시지 객체의 시퀀스를 입력으로 받아들이고 AIMessage를 출력으로 반환합니다. 상호작용은 종종 상태가 없으므로, 간단한 대화 루프는 증가하는 메시지 목록으로 모델을 호출하는 것을 포함합니다. 자세한 내용은 아래 가이드를 참조하세요:
Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I