ChatMessage
ChatMessage
LLM과 주고받는 메시지를 표현하는 가장 중심적인 데이터 클래스가 바로 ChatMessage예요. 메시지에는 역할(role)과 메타데이터가 담기고, 본문은 텍스트·이미지·파일·툴 호출·툴 호출 결과·추론 내용 등 여러 종류의 콘텐츠를 수용할 수 있어요.
ChatMessage 인스턴스를 만들 때는 from_user, from_system, from_assistant, from_tool 이렇게 네 가지 클래스 메서드를 사용해요.
그리고 본문 콘텐츠는 text, texts, image, images, file, files, tool_call, tool_calls, tool_call_result, tool_call_results, reasoning, reasonings 같은 프로퍼티로 꺼내 볼 수 있어요.
이 데이터 클래스의 메서드와 파라미터 상세가 궁금하다면 API 문서를 확인해 보세요.
출처: 공식문서
콘텐츠 종류 (Types of Content)
ChatMessage는 현재 TextContent, ImageContent, FileContent, ToolCall, ToolCallResult, ReasoningContent 이렇게 여섯 종류의 콘텐츠를 지원해요.
@dataclass
class TextContent:
"""
The textual content of a chat message.
:param text: The text content of the message.
"""
text: str
@dataclass
class ToolCall:
"""
Represents a Tool call prepared by the model, usually contained in an assistant message.
:param tool_name: The name of the Tool to call.
:param arguments: The arguments to call the Tool with.
:param id: The ID of the Tool call.
:param extra: Dictionary of extra information about the Tool call. Use to store provider-specific
information. To avoid serialization issues, values should be JSON serializable.
"""
tool_name: str
arguments: Dict[str, Any]
id: Optional[str] = None # noqa: A003
extra: Optional[Dict[str, Any]] = None
@dataclass
class ToolCallResult:
"""
Represents the result of a Tool invocation.
:param result: The result of the Tool invocation.
:param origin: The Tool call that produced this result.
:param error: Whether the Tool invocation resulted in an error.
"""
result: str | Sequence[TextContent | ImageContent]
origin: ToolCall
error: bool
@dataclass
class ImageContent:
"""
The image content of a chat message.
:param base64_image: A base64 string representing the image.
:param mime_type: The MIME type of the image (e.g. "image/png", "image/jpeg").
Providing this value is recommended, as most LLM providers require it.
If not provided, the MIME type is guessed from the base64 string, which can be slow and not always reliable.
:param detail: Optional detail level of the image (only supported by OpenAI). One of "auto", "high", or "low".
:param meta: Optional metadata for the image.
:param validation: If True (default), a validation process is performed:
- Check whether the base64 string is valid;
- Guess the MIME type if not provided;
- Check if the MIME type is a valid image MIME type.
Set to False to skip validation and speed up initialization.
"""
base64_image: str
mime_type: Optional[str] = None
detail: Optional[Literal["auto", "high", "low"]] = None
meta: Dict[str, Any] = field(default_factory=dict)
validation: bool = True
@dataclass
class FileContent:
"""
The file content of a chat message.
:param base64_data: A base64 string representing the file.
:param mime_type: The MIME type of the file (e.g. "application/pdf").
Providing this value is recommended, as most LLM providers require it.
If not provided, the MIME type is guessed from the base64 string, which can be slow and not always reliable.
:param filename: Optional filename of the file. Some LLM providers use this information.
:param extra: Dictionary of extra information about the file. Can be used to store provider-specific information.
To avoid serialization issues, values should be JSON serializable.
:param validation: If True (default), a validation process is performed:
- Check whether the base64 string is valid;
- Guess the MIME type if not provided.
Set to False to skip validation and speed up initialization.
"""
base64_data: str
mime_type: str | None = None
filename: str | None = None
extra: dict[str, Any] = field(default_factory=dict)
validation: bool = True
@dataclass
class ReasoningContent:
"""
Represents the optional reasoning content prepared by the model, usually contained in an assistant message.
:param reasoning_text: The reasoning text produced by the model.
:param extra: Dictionary of extra information about the reasoning content. Use to store provider-specific
information. To avoid serialization issues, values should be JSON serializable.
"""
reasoning_text: str
extra: Dict[str, Any] = field(default_factory=dict)
ImageContent와 FileContent는 편의용 클래스 메서드인 from_file_path와 from_url도 제공해요. 더 자세한 내용은 API 문서를 참고하세요.
ChatMessage 다루기
아래 예시들은 ChatMessage를 만들고 그 프로퍼티를 확인하는 흐름을 보여줘요.
from_user + TextContent
from haystack.dataclasses import ChatMessage
user_message = ChatMessage.from_user("What is the capital of Australia?")
print(user_message)
# >> ChatMessage(
# >> _role=<ChatRole.USER: 'user'>,
# >> _content=[TextContent(text='What is the capital of Australia?')],
# >> _name=None,
# >> _meta={}
# >> )
print(user_message.text)
# >> What is the capital of Australia?
print(user_message.texts)
# >> ['What is the capital of Australia?']
from_user + TextContent와 ImageContent
from haystack.dataclasses import ChatMessage, ImageContent
lion_image_url = (
"https://images.unsplash.com/photo-1546182990-dffeafbe841d?"
"ixlib=rb-4.0&q=80&w=1080&fit=max"
)
image_content = ImageContent.from_url(lion_image_url, detail="low")
user_message = ChatMessage.from_user(
content_parts=["What does the image show?", image_content]
)
print(user_message)
# >> ChatMessage(
# >> _role=<ChatRole.USER: 'user'>,
# >> _content=[
# >> TextContent(text='What does the image show?'),
# >> ImageContent(
# >> base64_image='/9j/4...',
# >> mime_type='image/jpeg',
# >> detail='low',
# >> meta={
# >> 'content_type': 'image/jpeg',
# >> 'url': '...'
# >> }
# >> )
# >> ],
# >> _name=None,
# >> _meta={}
# >> )
print(user_message.text)
# >> What does the image show?
print(user_message.texts)
# >> ['What does the image show?']
print(user_message.image)
# >> ImageContent(
# >> base64_image='/9j/4...',
# >> mime_type='image/jpeg',
# >> detail='low',
# >> meta={
# >> 'content_type': 'image/jpeg',
# >> 'url': '...'
# >> }
# >> )
from_user + TextContent와 FileContent
from haystack.dataclasses import ChatMessage, FileContent
paper_url = "https://arxiv.org/pdf/2309.08632"
file_content = FileContent.from_url(paper_url)
user_message = ChatMessage.from_user(
content_parts=[file_content, "Summarize this paper in 100 words."]
)
print(user_message)
# >> ChatMessage(
# >> _role=<ChatRole.USER: 'user'>,
# >> _content=[
# >> FileContent(
# >> base64_data='JVBERi0...',
# >> mime_type='application/pdf',
# >> filename='2309.08632',
# >> extra={}
# >> ),
# >> TextContent(text='Summarize this paper in 100 words.')
# >> ],
# >> _name=None,
# >> _meta={}
# >> )
print(user_message.text)
# >> Summarize this paper in 100 words.
print(user_message.texts)
# >> ['Summarize this paper in 100 words.']
print(user_message.file)
# >> FileContent(
# >> base64_data='JVBERi0...',
# >> mime_type='application/pdf',
# >> filename='2309.08632',
# >> extra={}
# >> )
from_assistant + TextContent
from haystack.dataclasses import ChatMessage
assistant_message = ChatMessage.from_assistant("How can I assist you today?")
print(assistant_message)
# >> ChatMessage(
# >> _role=<ChatRole.ASSISTANT: 'assistant'>,
# >> _content=[TextContent(text='How can I assist you today?')],
# >> _name=None,
# >> _meta={}
# >> )
print(assistant_message.text)
# >> How can I assist you today?
print(assistant_message.texts)
# >> ['How can I assist you today?']
from_assistant + ToolCall
from haystack.dataclasses import ChatMessage, ToolCall
tool_call = ToolCall(tool_name="weather_tool", arguments={"location": "Rome"})
assistant_message_w_tool_call = ChatMessage.from_assistant(tool_calls=[tool_call])
print(assistant_message_w_tool_call)
# >> ChatMessage(
# >> _role=<ChatRole.ASSISTANT: 'assistant'>,
# >> _content=[ToolCall(tool_name='weather_tool', arguments={'location': 'Rome'}, id=None)],
# >> _name=None,
# >> _meta={}
# >> )
print(assistant_message_w_tool_call.text)
# >> None
print(assistant_message_w_tool_call.texts)
# >> []
print(assistant_message_w_tool_call.tool_call)
# >> ToolCall(tool_name='weather_tool', arguments={'location': 'Rome'}, id=None)
print(assistant_message_w_tool_call.tool_calls)
# >> [ToolCall(tool_name='weather_tool', arguments={'location': 'Rome'}, id=None)]
print(assistant_message_w_tool_call.tool_call_result)
# >> None
print(assistant_message_w_tool_call.tool_call_results)
# >> []
from_tool
from haystack.dataclasses import ChatMessage
tool_message = ChatMessage.from_tool(
tool_result="temperature: 25°C", origin=tool_call, error=False
)
print(tool_message)
# >> ChatMessage(
# >> _role=<ChatRole.TOOL: 'tool'>,
# >> _content=[ToolCallResult(
# >> result='temperature: 25°C',
# >> origin=ToolCall(tool_name='weather_tool', arguments={'location': 'Rome'}, id=None),
# >> error=False
# >> )],
# >> _name=None,
# >> _meta={}
# >> )
print(tool_message.text)
# >> None
print(tool_message.texts)
# >> []
print(tool_message.tool_call)
# >> None
print(tool_message.tool_calls)
# >> []
print(tool_message.tool_call_result)
# >> ToolCallResult(
# >> result='temperature: 25°C',
# >> origin=ToolCall(tool_name='weather_tool', arguments={'location': 'Rome'}, id=None),
# >> error=False
# >> )
print(tool_message.tool_call_results)
# >> [
# >> ToolCallResult(
# >> result='temperature: 25°C',
# >> origin=ToolCall(tool_name='weather_tool', arguments={'location': 'Rome'}, id=None),
# >> error=False
# >> )
# >> ]
레거시 ChatMessage에서 마이그레이션하기 (v2.9 이전)
Haystack 2.9에서 ChatMessage 데이터 클래스가 더 유연해졌고 텍스트·툴 호출·툴 호출 결과 등 여러 콘텐츠 타입을 지원하게 되면서 바뀐 부분이 있어요. 몇 가지 breaking change(호환되지 않는 변경)가 포함돼 있으니, 이 가이드를 따라 부드럽게 옮겨 오시길 권해요.
ChatMessage 만들기
이제 role, content, meta로 ChatMessage를 직접 초기화할 수 없어요.
- 대신
from_assistant,from_user,from_system,from_tool클래스 메서드를 사용하세요. content파라미터는text로 바꿔서 쓰세요.
from haystack.dataclasses import ChatMessage
# LEGACY - DOES NOT WORK IN 2.9.0
message = ChatMessage(role=ChatRole.USER, content="Hello!")
# Use the class method instead
message = ChatMessage.from_user("Hello!")
ChatMessage 속성 접근하기
- 레거시
content속성은 이제 내부 속성(_content)이 됐어요. ChatMessage속성은 아래 프로퍼티로 확인하세요:rolemetanametext와textsimage와imagestool_call와tool_callstool_call_result와tool_call_resultsreasoning와reasonings
from haystack.dataclasses import ChatMessage
message = ChatMessage.from_user("Hello!")
# LEGACY - DOES NOT WORK IN 2.9.0
print(message.content)
# Use the appropriate property instead
print(message.text)