Mistral AI의 Python 라이브러리에서 발견된 세 가지 사일런트 버그
요약
본 기사는 Mistral AI 스택의 핵심 라이브러리 두 가지에서 발견된 세 가지 사일런트 버그를 분석합니다. 이 버그들은 코드상으로는 오류가 없지만, 실제 에이전트 동작에 치명적인 잘못된 결과를 초래할 수 있습니다. 특히 도구 호출 시 기본값 손실과 `dict` 필드 처리의 엄격성 문제 등 중요한 개선 사항을 다룹니다.
핵심 포인트
- Mistral AI 스택 핵심 라이브러리 2개에서 버그 발견
- 도구 정의 시 Pydantic 기본값이 누락되는 문제 해결 필요
- Pydantic `dict` 필드 처리 시 스키마 엄격성 조정 필요
코드상으로는 올바르게 보이는 도구 스키마(tool schema). '유효함(valid)'이라고 말하는 검증기(validator). 파싱되는 구조화된 출력(structured output). 이 모든 경우에 코드는 오류 없이 실행되지만, 결과는 여전히 틀립니다.
저는 Mistral AI 스택의 핵심인 두 가지 Python 라이브러리를 감사했고, 이와 같은 종류의 버그 세 가지를 발견했습니다. 모두 재현되었으며, 회귀 테스트(regression tests)로 수정되어 업스트림에 제출되었습니다.
배경: 두 개의 라이브러리
- mistral-common: 채팅 요청을 검증하고 이를 토큰으로 변환합니다. vLLM과 Hugging Face Transformers는 Mistral 모델을 서비스하는 데 이 라이브러리에 의존합니다.
- client-python: 공식
mistralaiSDK입니다. 이의extra패키지는 Python 함수를 도구(tool)로, Pydantic 모델을 구조화된 출력으로 변환합니다.
Mistral 기반 에이전트들은 호출할 때마다 이 두 라이브러리를 모두 거칩니다. 여기서 사일런트 버그가 발생하면 그 위에 구축되는 모든 에이전트에 퍼지게 됩니다.
버그 1: 선택적 도구 매개변수가 필수 항목으로 변경됨
create_tool_call은 Python 함수를 모델이 호출할 수 있는 도구로 변환합니다. 관용적인 Pydantic 스타일을 사용하면 기본값(default value)이 손실됩니다:
def get_weather(
city: Annotated[str, Field(description="City name")],
unit: Annotated[str, Field(description="celsius or fahrenheit")] = "celsius",
...
기본값은 함수 시그니처에 존재하며 Annotated에서 가져온 Field에는 존재하지 않으므로 스키마에 전달되지 않습니다. 도구는 strict=True와 함께 전송되므로, 모델은 매번 unit을 채우도록 강제되며 개발자가 설정한 기본값은 사용되지 않습니다.
issue #632에 보고되었으며, 수정 사항과 두 개의 테스트가 제 포크(fork)에서 준비되었습니다.
버그 2: 키를 가질 수 없는 dict 필드
chat.parse는 Pydantic 모델과 일치하는 답변을 요청할 수 있게 해줍니다. 전송하기 전에 SDK는 모든 객체에 additionalProperties: false를 설정하여 스키마를 엄격하게 만듭니다.
문제는 다음과 같습니다: dict[str, int] 필드의 경우, Pydantic은 이미 값(value)을 설명하기 위해 additionalProperties를 사용합니다. 그런데 SDK가 이를 덮어씁니다.
stock: dict[str, int] | 스키마 (Schema) |
|---|---|
| Pydantic | {"additionalProperties": {"type": "integer"}} |
| API로 전송 시 | {"additionalProperties": false} |
두 번째 스키마의 경우, {"apples": 3}은 유효하지 않습니다. 이 필드는 비어 있어야만 합니다. 수정 사항은 키가 누락되었을 때만 추가하며, 이는 OpenAI SDK가 이미 수행하는 동작입니다.
issue #633에서 보고되었으며, 수정된 내용과 테스트를 함께 제공합니다. 저는 클라이언트 측만 확인할 수 있었고, API 엔드투엔드를 테스트하지는 않았습니다.
버그 3: 개행 문자(newline)가 검증기(validator)를 통과함
mistral-common은 함수 이름이 ^[a-zA-Z0-9_-]{1,64}$와 일치하는지, 그리고 도구 호출 ID가 9개의 영숫자 문자를 가지고 있는지 확인합니다. 이 검사는 re.match를 사용하는데, Python에서 $는 최종 바로 앞에서도 일치할 수 있습니다.
따라서 `
팀원들이 이런 에이전트를 구축하도록 하시겠습니까? 저는 실습 기반의 Copilot Studio 교육(프랑스어 진행, Spar-x 및 Qualiopi 인증, 프랑스 OPCO 자금 지원 가능): https://zakariakhchiche.github.io/formation-copilot-studio/와 무료 AI Act 제4조 키트: https://zakariakhchiche.github.io/kit-ai-act/를 진행합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기