멀티모달 입력과 출력

멀티모달 입력과 출력 (Multimodal inputs and outputs)

Deep Agents는 모델이 멀티모달 입력과 도구 결과를 받아들이거나 멀티모달 출력을 반환할 때 멀티모달 워크플로우를 지원해요. 사용자 메시지에 이미지와 기타 미디어를 붙이고, 내장 read_file 도구로 비텍스트 파일을 읽고, 커스텀 도구에서 멀티모달 콘텐츠를 반환할 수 있어요. 다만 내장 컨텍스트 컴프레션은 주로 텍스트 중심이라, 큰 미디어는 백엔드에 저장하고 가능하면 참조를 넘기는 방식으로 멀티모달 워크로드를 계획하는 게 좋아요.

출처: 공식문서

멀티모달 사용자 입력 (Multimodal user input)

에이전트에 보내는 messages에 LangChain 채팅 모델과 동일한 표준 콘텐츠 블록을 사용해 멀티모달 콘텐츠를 전달해요.

result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": [
            {"type": "text", "text": "What is in this screenshot?"},
            {"type": "image", "url": "https://example.com/screenshot.png"},
        ],
    }],
})

블록 타입, 프로바이더별 요구사항, 추가 예제(PDF, 오디오, 비디오)는 Multimodal messages 문서를 참고해요.

내장 read_file 도구

하네스 read_file 도구는 지원되는 멀티모달 파일에 대해 일반 텍스트 대신 표준 콘텐츠 블록을 반환해요. 선택한 모델이 해당 모달리티를 지원하면 에이전트가 자체 파일시스템에 저장된 이미지, 문서, 미디어를 검사할 수 있어요. 모델이 지원하는 MIME 타입은 프로바이더 문서를 확인해요.

지원되는 멀티모달 파일 확장자

타입 확장자
이미지 .png, .jpg, .jpeg, .gif, .webp, .heic, .heif
비디오 .mp4, .mpeg, .mov, .avi, .flv, .mpg, .webm, .wmv, .3gpp
오디오 .wav, .mp3, .aiff, .aac, .ogg, .flac
파일 .pdf, .ppt, .pptx

커스텀 도구 출력 (Custom tool outputs)

커스텀 도구는 이미지 같은 멀티모달 파일을 포함할 수 있어요.

from langchain.tools import tool

@tool
def capture_screenshot() -> list[dict]:
    """Capture a screenshot of the current page."""
    return [
        {"type": "text", "text": "Screenshot of the current page:"},
        {"type": "image", "url": "https://example.com/page.png"},
    ]

반환 값은 다음 턴에 모델이 읽는 ToolMessage로 변환돼요. 결과 메시지의 content_blocks로 정규화된 표현에 접근할 수 있어요. 반환 타입 옵션, 직렬화 동작, MCP 예제는 Multimodal content 문서를 참고해요.

도구가 이미지나 다른 큰 바이너리 데이터를 만들면 아티팩트를 백엔드에 저장하고 간결한 텍스트 설명 + 경로나 URL을 반환하는 걸 권장해요. 그러면 메시지 기록이 작게 유지되고 컨텍스트 컴프레션과도 잘 어울려요.

컨텍스트 컴프레션과 멀티모달 콘텐츠

내장 오프로딩과 요약은 텍스트와 메시지 기록에 최적화돼 있어요.

  • **오프로딩(Offloading)**은 텍스트 토큰만 측정해요. 비텍스트 블록(이미지 포함)은 컴프레스되는 대신 교체 메시지에서 보존돼요. 이미지만 있는 메시지는 이미지 크기만으로는 오프로딩되지 않아요.
  • **요약(Summarization)**은 오래된 메시지를 텍스트 전용 요약으로 컴팩트해요. 그 범위의 이미지·오디오·비디오·파일 블록은 앞으로 전달되지 않아요 — 모델은 요약기가 그에 대해 쓴 내용만 볼 수 있어요. keep 기준 아래 최근 메시지는 변경 없이 남아요.

요약이 실행되면 오래된 턴의 미디어 블록이 활성 컨텍스트에서 빠져나와요.

# 이전 — 모델이 오래된 턴의 이미지 블록을 받음
[
    HumanMessage(
        content=[
            {"type": "text", "text": "What trends do you see in this chart?"},
            {"type": "image", "base64": IMG, "mime_type": "image/png"},
        ]
    ),
    ToolMessage(
        content=[
            {"type": "text", "text": "Updated chart:"},
            {"type": "image", "base64": IMG, "mime_type": "image/png"},
        ],
        tool_call_id="call_chart_1",
    ),
    AIMessage(content="Revenue rose in Q3 based on the chart trend."),
    HumanMessage(content="Reply with one sentence summarizing our analysis."),
]

# 이후 — 해당 턴이 텍스트로 접히고 이미지 블록은 사라짐
{"content": (
    "User asked about trends in a chart screenshot. "
    "Tool returned an updated chart. Agent identified Q3 revenue growth."
)}

원래 대화는 여전히 파일시스템에 텍스트로 기록돼요. 트리거, keep 기준, 전체 흐름은 Summarization 문서를 참고해요.

멀티모달이 많은 워크로드를 위한 조언:

  • 이미지, 스크린샷, 차트는 파일시스템 백엔드나 외부 객체 스토리지에 저장하고 메시지로 경로나 URL을 전달해요.
  • 오래 지속되는 대화에서는 base64 인코딩 이미지 블록보다 참조를 선호해요.
  • 이미지가 많은 검사는 subagents를 사용해 메인 에이전트는 간결한 텍스트 결과만 받도록 해요.
  • 프로바이더가 이미지에 많은 토큰을 청구한다면 요약 기준을 조정하거나 커스텀 토큰 카운터를 제공해요.

오프로딩 기준, 요약 트리거, 커스터마이징 옵션은 Context compression 문서를 참고해요.

더 알아보기 (Learn more)