anthropic 모델의 도구 호출용 메시지 정화

anthropic 모델의 도구 호출용 메시지 정화 (Message Sanitization)

modify_params=True 와 함께 도구 호출을 사용할 때 흔한 메시지 형식 문제를 자동으로 고쳐요.

LiteLLM은 도구 호출 워크플로 중에 발생하는 흔한 문제, 특히 엄격한 메시지 형식 요구사항이 있는 프로바이더(Anthropic Claude 같은)에 OpenAI 호환 클라이언트를 사용할 때 메시지를 자동으로 정화할 수 있습니다.

개요

litellm.modify_params = True 가 활성화되면, LiteLLM은 세 가지 흔한 문제를 고치도록 메시지를 자동으로 정화합니다:

  1. 고아 도구 호출 (Orphaned Tool Calls) - tool_calls가 있지만 tool 결과가 없는 assistant 메시지
  2. 고아 도구 결과 (Orphaned Tool Results) - 존재하지 않는 tool_call_id 를 참조하는 tool 메시지
  3. 빈 메시지 콘텐츠 (Empty Message Content) - 빈 또는 공백만 있는 텍스트 콘텐츠가 있는 메시지

그러면 도구 호출 워크플로가 수동 메시지 검증 없이 여러 LLM 프로바이더에서 동작합니다.

왜 메시지 정화인가?

여러 LLM 프로바이더는 메시지 형식에 대해 다른 요구사항을 가집니다. 특히 도구 호출 중에:

  • Anthropic Claude는 모든 tool_call에 대응하는 tool 결과를 요구합니다
  • 일부 프로바이더는 빈 콘텐츠가 있는 메시지를 거부합니다
  • OpenAI 호환 클라이언트는 항상 완벽한 메시지 일관성을 유지하지 못할 수 있어요

정화가 없으면 이 문제들이 워크플로를 중단시키는 API 오류를 일으킵니다. modify_params=True 로 LiteLLM이 이런 엣지 케이스를 자동으로 처리합니다.

빠른 시작

  • SDK
  • PROXY
import litellm

# Enable automatic message sanitization
litellm.modify_params = True

# This will work even if messages have formatting issues
response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=[
        {"role": "user", "content": "What's the weather in Boston?"},
        {
            "role": "assistant",
            "tool_calls": [
                {
                    "id": "call_123",
                    "type": "function",
                    "function": {"name": "get_weather", "arguments": '{"city": "Boston"}'}
                }
            ]
            # Missing tool result - LiteLLM will add a dummy result automatically
        },
        {"role": "user", "content": "Thanks!"}
    ],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"]
            }
        }
    }]
)
litellm_settings:
  modify_params: true  # Enable automatic message sanitization

model_list:
  - model_name: claude-sonnet-5
    litellm_params:
      model: anthropic/claude-sonnet-5

출처: 문서

본문

정화 사례

사례 A: 고아 도구 호출 (도구 결과 누락)

문제: assistant 메시지에 tool_calls 가 있지만, 뒤따르는 대응 도구 결과 메시지가 없습니다.

해결책: LiteLLM이 누락된 도구 결과에 대해 더미 도구 결과 메시지를 자동으로 추가합니다.

예시:

import litellm
litellm.modify_params = True

# Messages with orphaned tool calls
messages = [
    {"role": "user", "content": "Search for Python tutorials"},
    {
        "role": "assistant",
        "tool_calls": [
            {
                "id": "call_abc123",
                "type": "function",
                "function": {"name": "web_search", "arguments": '{"query": "Python tutorials"}'}
            }
        ]
    },
    # Missing tool result here!
    {"role": "user", "content": "What about JavaScript?"}
]

# LiteLLM automatically adds:
# {
#     "role": "tool",
#     "tool_call_id": "call_abc123",
#     "content": "[System: Tool execution skipped/interrupted by user. No result provided for tool 'web_search'.]"
# }

response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages,
    tools=[...]
)

이런 경우가 발생할 때:

  • 사용자가 도구 실행을 중단
  • 네트워크 문제로 클라이언트가 도구 결과를 잃음
  • 도구가 완료되기 전에 대화 흐름이 바뀜
  • 도구가 선택적인 멀티턴 대화

사례 B: 고아 도구 결과 (잘못된 tool_call_id)

문제: tool 메시지가 이전 assistant 메시지에 없는 tool_call_id 를 참조합니다.

해결책: LiteLLM이 이런 고아 도구 결과 메시지를 자동으로 제거합니다.

예시:

import litellm
litellm.modify_params = True

# Messages with orphaned tool result
messages = [
    {"role": "user", "content": "Hello"},
    {"role": "assistant", "content": "Hi! How can I help?"},
    {
        "role": "tool",
        "tool_call_id": "call_nonexistent",  # This tool_call_id doesn't exist!
        "content": "Some result"
    }
]

# LiteLLM automatically removes the orphaned tool message

response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages
)

이런 경우가 발생할 때:

  • 메시지 히스토리가 수동으로 편집됨
  • 도구 결과가 중복되거나 매칭이 잘못됨
  • 대화 상태가 잘못 복원됨
  • 서로 다른 대화의 메시지가 병합됨

사례 C: 빈 메시지 콘텐츠

문제: user 또는 assistant 메시지에 빈 또는 공백만 있는 콘텐츠가 있습니다.

해결책: LiteLLM이 빈 콘텐츠를 시스템 플레이스홀더 메시지로 교체합니다.

예시:

import litellm
litellm.modify_params = True

# Messages with empty content
messages = [
    {"role": "user", "content": ""},  # Empty content
    {"role": "assistant", "content": "   "},  # Whitespace only
]

# LiteLLM automatically replaces with:
# {"role": "user", "content": "[System: Empty message content sanitised to satisfy protocol]"}
# {"role": "assistant", "content": "[System: Empty message content sanitised to satisfy protocol]"}

response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages
)

이런 경우가 발생할 때:

  • UI가 빈 메시지를 보냄
  • 전처리 중 콘텐츠가 제거됨
  • 대화 히스토리의 플레이스홀더 메시지
  • 메시지 구성의 엣지 케이스

구성

전역 활성화

  • SDK
  • PROXY
  • 환경 변수
import litellm

# Enable for all completion calls
litellm.modify_params = True
litellm_settings:
  modify_params: true
export LITELLM_MODIFY_PARAMS=True

요청별 활성화

import litellm

# Enable only for specific requests
response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages,
    modify_params=True  # Override global setting
)

지원 프로바이더

메시지 정화는 현재 다음과 동작합니다:

  • ✅ Anthropic (Claude)

참고: 정화 로직은 프로바이더에 독립적이지만, 현재는 Anthropic 메시지 변환 파이프라인에서만 적용됩니다. 추가 프로바이더 지원은 향후 릴리스에서 추가될 수 있어요.

구현 세부 사항

동작 방식

메시지 정화 프로세스는 메시지가 프로바이더별 형식으로 변환되기 전에 실행됩니다:

  1. 입력: 잠재적 문제가 있는 OpenAI 형식 메시지
  2. 정화: 세 가지 헬퍼 함수가 메시지 처리:
    • _sanitize_empty_text_content() - 빈 콘텐츠 수정
    • _add_missing_tool_results() - 더미 도구 결과 추가
    • _is_orphaned_tool_result() - 고아 결과 식별
  3. 출력: 깨끗하고 프로바이더 호환되는 메시지

코드 참조

정화 로직은 다음에 구현됩니다:

  • litellm/litellm_core_utils/prompt_templates/factory.py
  • 함수: sanitize_messages_for_tool_calling()

로깅

정화가 발생하면 LiteLLM이 디버그 메시지를 로그합니다:

import litellm
litellm.set_verbose = True  # Enable debug logging

# You'll see logs like:
# "_add_missing_tool_results: Found 1 orphaned tool calls. Adding dummy tool results."
# "_is_orphaned_tool_result: Found orphaned tool result with tool_call_id=call_123"
# "_sanitize_empty_text_content: Replaced empty text content in user message"

모범 사례

1. 프로덕션 워크플로에서 활성화

# Recommended for production
litellm.modify_params = True

# Ensures robust handling of edge cases
response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages,
    tools=tools
)

2. 가능하면 도구 결과 보존

정화가 누락된 도구 결과를 처리하지만, 실제 결과를 제공하는 것이 더 좋아요:

# Good: Provide actual tool results
messages = [
    {"role": "user", "content": "Search for Python"},
    {"role": "assistant", "tool_calls": [...]},
    {"role": "tool", "tool_call_id": "call_123", "content": "Actual search results"}
]

# Fallback: Sanitization adds dummy result if missing
messages = [
    {"role": "user", "content": "Search for Python"},
    {"role": "assistant", "tool_calls": [...]},
    # Missing tool result - sanitization adds dummy
]

3. 정화 이벤트 모니터링

로깅을 사용해 정화가 발생하는 시점을 추적하세요:

import litellm
import logging

# Enable debug logging
litellm.set_verbose = True
logging.basicConfig(level=logging.DEBUG)

# Track sanitization events in your application
response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=messages
)

4. 엣지 케이스 테스트

애플리케이션이 정화된 메시지를 올바르게 처리하는지 확인하세요:

import litellm
litellm.modify_params = True

# Test orphaned tool calls
test_messages = [
    {"role": "user", "content": "Test"},
    {"role": "assistant", "tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "test", "arguments": "{}"}}]},
    {"role": "user", "content": "Continue"}  # No tool result
]

response = litellm.completion(
    model="anthropic/claude-sonnet-5",
    messages=test_messages,
    tools=[...]
)

# Verify the response handles the dummy tool result appropriately

관련 기능

문제 해결

정화가 작동하지 않음

문제: modify_params=True 임에도 메시지가 여전히 오류를 일으킴

해결책:

# 1. Verify modify_params is enabled
import litellm
print(litellm.modify_params)  # Should be True
  1. 문제가 프로바이더별인지 확인: litellm.set_verbose = True (디버그 로깅 활성화)
  2. 최신 LiteLLM 버전 사용: uv add --upgrade-package litellm litellm

예상치 못한 더미 도구 결과

문제: 실제 결과를 기대할 때 더미 도구 결과가 나타남

원인: 도구 결과 메시지가 누락되었거나 tool_call_id 가 잘못됨

해결책:

  1. 도구 결과 메시지의 tool_call_id 가 올바른지 확인: {"role": "tool", "tool_call_id": "call_123", "content": "result"} — 잘못되면 wrong_id 는 고아로 취급됨
  2. 도구 결과가 tool_calls 가 있는 assistant 메시지 바로 뒤에 오는지 확인

성능 영향

문제: 성능 오버헤드 우려

상세: 메시지 정화는 성능 영향이 최소입니다:

  • O(n) 시간 (n = 메시지 수)
  • modify_params=True 일 때만 메시지 처리
  • 보통 요청 처리 시간에 < 1ms 추가

FAQ

Q: 정화가 원래 메시지를 수정하나요? A: 아니요, 정화는 새 메시지 목록을 만듭니다. 원래 메시지는 변경되지 않습니다.

Q: 특정 정화 사례를 비활성화할 수 있나요? A: 현재 modify_params=True 일 때 세 가지 사례가 모두 함께 처리됩니다. 정화를 완전히 비활성화하려면 modify_params=False 로 설정하세요.

Q: 더미 도구 결과는 어떻게 되나요? A: 더미 도구 결과는 다른 메시지들과 함께 LLM 프로바이더로 보내집니다. 모델은 이를 정보성 오류 메시지가 있는 일반 도구 결과로 봅니다.

Q: 스트리밍과 함께 동작하나요? A: 예, 메시지 정화는 스트리밍 및 비스트리밍 요청 모두와 동작합니다.

Q: drop_params 와 관련이 있나요? A: 아니요, 별개의 기능입니다:

  • modify_params - 메시지 콘텐츠와 구조를 수정/수정
  • drop_params - 지원되지 않는 API 파라미터 제거

둘 다 동시에 활성화할 수 있습니다.

더 알아보기 (Learn more)