anthropic 모델의 도구 호출용 메시지 정화
anthropic 모델의 도구 호출용 메시지 정화 (Message Sanitization)
modify_params=True 와 함께 도구 호출을 사용할 때 흔한 메시지 형식 문제를 자동으로 고쳐요.
LiteLLM은 도구 호출 워크플로 중에 발생하는 흔한 문제, 특히 엄격한 메시지 형식 요구사항이 있는 프로바이더(Anthropic Claude 같은)에 OpenAI 호환 클라이언트를 사용할 때 메시지를 자동으로 정화할 수 있습니다.
개요
litellm.modify_params = True 가 활성화되면, LiteLLM은 세 가지 흔한 문제를 고치도록 메시지를 자동으로 정화합니다:
- 고아 도구 호출 (Orphaned Tool Calls) - tool_calls가 있지만 tool 결과가 없는 assistant 메시지
- 고아 도구 결과 (Orphaned Tool Results) - 존재하지 않는
tool_call_id를 참조하는 tool 메시지 - 빈 메시지 콘텐츠 (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 메시지 변환 파이프라인에서만 적용됩니다. 추가 프로바이더 지원은 향후 릴리스에서 추가될 수 있어요.
구현 세부 사항
동작 방식
메시지 정화 프로세스는 메시지가 프로바이더별 형식으로 변환되기 전에 실행됩니다:
- 입력: 잠재적 문제가 있는 OpenAI 형식 메시지
- 정화: 세 가지 헬퍼 함수가 메시지 처리:
_sanitize_empty_text_content()- 빈 콘텐츠 수정_add_missing_tool_results()- 더미 도구 결과 추가_is_orphaned_tool_result()- 고아 결과 식별
- 출력: 깨끗하고 프로바이더 호환되는 메시지
코드 참조
정화 로직은 다음에 구현됩니다:
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
관련 기능
- Drop Params - 특정 프로바이더의 지원되지 않는 파라미터 버리기
- Message Trimming - 토큰 한도에 맞게 메시지 자르기
- Function Calling - 도구/함수 호출 완전 가이드
- Reasoning Content - 도구 호출과 함께하는 확장 사고
문제 해결
정화가 작동하지 않음
문제: modify_params=True 임에도 메시지가 여전히 오류를 일으킴
해결책:
# 1. Verify modify_params is enabled
import litellm
print(litellm.modify_params) # Should be True
- 문제가 프로바이더별인지 확인:
litellm.set_verbose = True(디버그 로깅 활성화) - 최신 LiteLLM 버전 사용:
uv add --upgrade-package litellm litellm
예상치 못한 더미 도구 결과
문제: 실제 결과를 기대할 때 더미 도구 결과가 나타남
원인: 도구 결과 메시지가 누락되었거나 tool_call_id 가 잘못됨
해결책:
- 도구 결과 메시지의
tool_call_id가 올바른지 확인:{"role": "tool", "tool_call_id": "call_123", "content": "result"}— 잘못되면wrong_id는 고아로 취급됨 - 도구 결과가
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 파라미터 제거
둘 다 동시에 활성화할 수 있습니다.