Mistral은 2026년 4월 29일 Medium 3.5를 출시했습니다. API 모델 ID는 mistral-medium-3.5, 엔드포인트는 https://api.mistral.ai/v1/chat/completions입니다. 요청 형식은 OpenAI Chat Completions와 매우 유사하므로, 기존 OpenAI 호환 코드에서는 기본 URL과 모델 ID만 바꾸면 테스트를 시작할 수 있습니다. 핵심 사양은 256K 컨텍스트 창, 네이티브 비전, 함수 호출, 24개 언어 지원, SWE-Bench Verified 77.6%입니다.
이 글에서는 Mistral Medium 3.5 API를 실제로 호출하는 데 필요한 인증, 요청 매개변수, Python 및 Node 예제, 비전 입력, 도구 호출, JSON 모드, 스트리밍, 오류 처리, 비용 제어 패턴을 다룹니다. 프롬프트 반복 작업 중 요청과 비용을 시각적으로 비교하려면 Apidog를 사용할 수 있습니다. 유사한 모델 가이드는 DeepSeek V4 API 사용 방법 및 GPT-5.5 API 사용 방법을 참고하십시오.
요약
- 엔드포인트:
POST https://api.mistral.ai/v1/chat/completions - 인증:
Authorization: Bearer <MISTRAL_API_KEY> - 모델 ID:
mistral-medium-3.5 - 컨텍스트 창: 256K 토큰
- 가격: 입력 토큰 100만 개당 $1.5, 출력 토큰 100만 개당 $7.5
- 기능: 추론, 비전, 네이티브 함수 호출, 구조화된 JSON 출력, 24개 언어 지원
- 공개 가중치:
mistralai/Mistral-Medium-3.5-128B - 라이선스: 고수익 기업 예외 조항이 포함된 수정 MIT 라이선스
- 벤치마크: SWE-Bench Verified 77.6%, τ³-Telecom 91.4
- 현재 모델과 Medium 3.5를 A/B 테스트하고 호출당 비용을 비교하려면 Apidog를 다운로드하십시오.
Medium 3.5에서 무엇이 바뀌었나요?
Medium 3은 128K 컨텍스트를 가진 텍스트 전용 모델이었습니다. Medium 3.5는 Mistral의 첫 플래그십 병합 모델입니다. 명령어 이해, 추론, 코딩 능력이 단일 가중치 세트에 통합되어 있어 채팅 모델과 추론 모델을 별도로 선택할 필요가 줄어듭니다.
주요 변경점은 다음과 같습니다.
- 컨텍스트 창이 128K에서 256K로 증가
- 텍스트 전용에서 네이티브 비전 지원으로 확장
- 함수 호출이 별도 API 계층이 아니라 모델 수준에서 통합
- 코드 패치 작업에서 SWE-Bench Verified 77.6% 달성
- 다중 턴 에이전트 대화에서 τ³-Telecom 91.4 기록
비용도 달라졌습니다. Medium 3은 입력 100만 토큰당 $0.40, 출력 100만 토큰당 $2.00이었습니다. Medium 3.5는 입력 $1.5, 출력 $7.5입니다. 따라서 모든 요청을 Medium 3.5로 보내기보다, 정확도나 긴 컨텍스트가 필요한 요청에 선택적으로 사용하는 방식이 적합합니다.
사전 요구 사항
첫 호출 전에 다음을 준비하십시오.
- console.mistral.ai 계정
- 결제 수단 또는 사용 가능한 크레딧
- 프로젝트 범위의 API 키
- Python 또는 Node 런타임
- 요청을 저장하고 반복 실행할 API 클라이언트
프로덕션에서는 계정 전체 키보다 프로젝트 키를 사용하는 것이 안전합니다. 키는 코드에 직접 넣지 말고 환경 변수나 비밀 변수로 관리하십시오.
터미널에서는 다음처럼 설정합니다.
export MISTRAL_API_KEY="..."
Apidog를 사용하는 경우에는 {{MISTRAL_API_KEY}}를 환경 비밀 변수로 저장하면 요청 공유나 내보내기 시 키가 노출되는 것을 줄일 수 있습니다.
엔드포인트 및 인증
Mistral Chat Completions 엔드포인트는 다음입니다.
POST https://api.mistral.ai/v1/chat/completions
최소 요청은 다음과 같습니다.
curl https://api.mistral.ai/v1/chat/completions \
-H "Authorization: Bearer $MISTRAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-medium-3.5",
"messages": [
{
"role": "user",
"content": "Explain dense merged checkpoints in two sentences."
}
]
}'
성공 응답에는 일반적으로 다음 필드가 포함됩니다.
-
id: 요청 추적용 ID -
choices: 모델 응답 배열 -
usage.prompt_tokens: 입력 토큰 수 -
usage.completion_tokens: 출력 토큰 수 -
usage.total_tokens: 총 토큰 수
비용 계산에는 usage 블록을 사용합니다.
cost = prompt_tokens * 1.5 / 1_000_000
+ completion_tokens * 7.5 / 1_000_000
요청 매개변수
mistral-medium-3.5 호출에서 자주 쓰는 매개변수는 다음과 같습니다.
| 매개변수 | 유형 | 값 | 설명 |
|---|---|---|---|
model |
string | mistral-medium-3.5 |
필수 |
messages |
array | role/content 쌍 | 필수, OpenAI와 유사한 스키마 |
temperature |
float |
0 ~ 1.5
|
일반 용도는 0.7, 코드는 0.3 권장 |
top_p |
float |
0 ~ 1
|
기본값 1.0
|
max_tokens |
int |
1 ~ 컨텍스트 제한 |
출력 길이 제한 |
stream |
bool |
true 또는 false
|
SSE 스트리밍 |
tools |
array | OpenAI 도구 사양 | 네이티브 함수 호출 |
tool_choice |
string/object |
auto, any, none, 특정 도구 |
도구 사용 제어 |
response_format |
object | JSON object 또는 JSON schema | 구조화된 출력 |
random_seed |
int | 임의의 정수 | 재현성 제어 |
safe_prompt |
bool |
true 또는 false
|
Mistral 안전 서문 추가 |
presence_penalty |
float |
-2 ~ 2
|
반복 주제 억제 |
frequency_penalty |
float |
-2 ~ 2
|
반복 토큰 억제 |
OpenAI에서 마이그레이션할 때 주의할 차이는 두 가지입니다.
OpenAI: tool_choice="required"
Mistral: tool_choice="any"
OpenAI: seed
Mistral: random_seed
Python 클라이언트로 호출하기
공식 SDK를 사용하는 예제입니다.
import os
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
response = client.chat.complete(
model="mistral-medium-3.5",
messages=[
{"role": "system", "content": "Reply in code only."},
{"role": "user", "content": "Write a Rust function that debounces events."},
],
temperature=0.3,
max_tokens=2048,
)
print("Content:", response.choices[0].message.content)
print("Prompt tokens:", response.usage.prompt_tokens)
print("Completion tokens:", response.usage.completion_tokens)
print("Total tokens:", response.usage.total_tokens)
cost = (
response.usage.prompt_tokens * 1.5 / 1_000_000
+ response.usage.completion_tokens * 7.5 / 1_000_000
)
print("Estimated cost USD:", cost)
OpenAI SDK를 이미 사용 중이라면 기본 URL만 바꿔도 됩니다.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["MISTRAL_API_KEY"],
base_url="https://api.mistral.ai/v1",
)
response = client.chat.completions.create(
model="mistral-medium-3.5",
messages=[
{"role": "user", "content": "Hello, Mistral."}
],
)
print(response.choices[0].message.content)
공급업체 독립적인 코드를 유지하려면 OpenAI SDK 경로가 편합니다. Mistral 고유 기능을 더 직접적으로 다루려면 mistralai SDK를 사용하십시오.
Node 클라이언트로 호출하기
공식 Mistral SDK 예제입니다.
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({
apiKey: process.env.MISTRAL_API_KEY,
});
const response = await client.chat.complete({
model: "mistral-medium-3.5",
messages: [
{
role: "user",
content: "Explain dense merged checkpoints in plain English.",
},
],
temperature: 0.7,
});
console.log(response.choices[0].message.content);
console.log("Usage:", response.usage);
OpenAI SDK를 사용하는 경우입니다.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.MISTRAL_API_KEY,
baseURL: "https://api.mistral.ai/v1",
});
const response = await client.chat.completions.create({
model: "mistral-medium-3.5",
messages: [
{
role: "user",
content: "Hello, Mistral.",
},
],
});
console.log(response.choices[0].message.content);
스트리밍 응답 처리하기
긴 응답을 UI에 점진적으로 표시하려면 stream: true를 사용합니다.
stream = client.chat.stream(
model="mistral-medium-3.5",
messages=[
{
"role": "user",
"content": "Stream a 300-word essay on merged checkpoints.",
}
],
)
for chunk in stream:
delta = chunk.data.choices[0].delta.content or ""
print(delta, end="", flush=True)
스트리밍 응답은 SSE(Server-Sent Events) 형태로 도착합니다. 토큰을 받을 때마다 UI에 append하면 채팅 인터페이스에서 체감 지연을 줄일 수 있습니다.
터미널 테스트 이후에는 Apidog 응답 뷰어에서 동일한 프롬프트를 반복 실행하고, 각 실행의 usage 값을 비교하는 방식이 더 관리하기 쉽습니다.
도구 호출 구현하기
Medium 3.5는 네이티브 함수 호출을 지원합니다. 먼저 tools 배열에 호출 가능한 함수를 정의합니다.
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Return the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
"unit": {"type": "string", "enum": ["c", "f"]},
},
"required": ["city"],
},
},
}
]
response = client.chat.complete(
model="mistral-medium-3.5",
messages=[
{
"role": "user",
"content": "Weather in Lagos in Celsius?",
}
],
tools=tools,
tool_choice="auto",
)
tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name)
print(tool_call.function.arguments)
일반적인 도구 호출 루프는 다음 순서입니다.
- 사용자 메시지를 모델에 전달
- 모델이
tool_calls를 반환 - 애플리케이션에서 해당 함수를 로컬 실행
- 실행 결과를
role: "tool"메시지로 추가 - 다시 모델을 호출해 최종 답변 생성
예시 흐름입니다.
messages = [
{"role": "user", "content": "Weather in Lagos in Celsius?"}
]
first = client.chat.complete(
model="mistral-medium-3.5",
messages=messages,
tools=tools,
tool_choice="auto",
)
tool_call = first.choices[0].message.tool_calls[0]
# 실제 구현에서는 arguments를 JSON으로 파싱하고 함수를 실행합니다.
weather_result = {
"city": "Lagos",
"temperature": 31,
"unit": "c",
"condition": "humid",
}
messages.append(first.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(weather_result),
})
final = client.chat.complete(
model="mistral-medium-3.5",
messages=messages,
)
print(final.choices[0].message.content)
JSON 모드 및 구조화된 출력
정해진 스키마에 맞는 응답이 필요하면 response_format을 사용합니다.
schema = {
"type": "json_schema",
"json_schema": {
"name": "release_note",
"schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string"},
"bullets": {
"type": "array",
"items": {"type": "string"},
},
},
"required": ["title", "date", "bullets"],
"additionalProperties": False,
},
"strict": True,
},
}
response = client.chat.complete(
model="mistral-medium-3.5",
messages=[
{
"role": "system",
"content": "Reply with a single JSON object matching the schema.",
},
{
"role": "user",
"content": "Summarize today's Mistral Medium 3.5 release.",
},
],
response_format=schema,
)
print(response.choices[0].message.content)
스키마까지 강제할 필요가 없고 “유효한 JSON 객체”만 필요하다면 다음처럼 단순화할 수 있습니다.
response = client.chat.complete(
model="mistral-medium-3.5",
messages=[
{
"role": "user",
"content": "Return three API testing tips as JSON.",
}
],
response_format={"type": "json_object"},
)
프로덕션에서는 JSON 모드만 믿기보다, 응답을 Pydantic 또는 Zod로 한 번 더 검증하는 방식을 권장합니다.
비전 입력 사용하기
Medium 3.5는 텍스트와 이미지를 같은 messages 배열에 넣어 처리할 수 있습니다.
response = client.chat.complete(
model="mistral-medium-3.5",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "What is in this image and what is it doing wrong?",
},
{
"type": "image_url",
"image_url": "https://example.com/diagram.png",
},
],
}
],
)
print(response.choices[0].message.content)
print(response.usage.prompt_tokens)
이미지 입력은 입력 토큰으로 과금됩니다. 정확한 토큰 수는 해상도와 이미지 내용에 따라 달라지며, 응답의 usage.prompt_tokens에서 확인할 수 있습니다.
대량 이미지 워크로드에서는 다음을 적용하십시오.
- 질문에 필요한 영역만 crop
- 불필요하게 큰 해상도는 축소
- 비디오 프레임은 전부 보내지 말고 샘플링
- 이미지당 평균
prompt_tokens를 기록해 비용 추정
Apidog에서 Mistral 컬렉션 만들기
터미널에서 curl만 반복하면 요청 버전, 응답, 비용을 비교하기 어렵습니다. Apidog에서는 다음 흐름으로 컬렉션을 구성할 수 있습니다.
- Apidog를 다운로드하고 프로젝트를 생성합니다.
- 환경 변수를 추가합니다.
BASE_URL=https://api.mistral.ai/v1MISTRAL_API_KEY=<secret>
-
POST {{BASE_URL}}/chat/completions요청을 만듭니다. - 헤더를 추가합니다.
Authorization: Bearer {{MISTRAL_API_KEY}}
Content-Type: application/json
- 기본 요청 본문을 저장합니다.
{
"model": "mistral-medium-3.5",
"messages": [
{
"role": "user",
"content": "Explain the tradeoffs of long context windows."
}
],
"temperature": 0.7,
"max_tokens": 1000
}
-
model,temperature,max_tokens,tool_choice를 변수화해 A/B 테스트합니다. - 응답의
usage값을 확인하고 호출당 비용을 계산합니다.
비용 계산식은 다음과 같습니다.
const usage = responseBody.usage;
const cost =
usage.prompt_tokens * 1.5 / 1_000_000 +
usage.completion_tokens * 7.5 / 1_000_000;
console.log(`Estimated cost: $${cost}`);
이미 DeepSeek V4 API 컬렉션을 사용 중이라면 컬렉션을 복제한 뒤 다음만 바꾸면 됩니다.
BASE_URL=https://api.mistral.ai/v1
model=mistral-medium-3.5
GPT-5.5와 비교할 때도 같은 방식으로 기본 URL과 모델 ID를 분리해두면 공급자별 결과를 쉽게 비교할 수 있습니다.
오류 처리
Mistral 오류 응답은 OpenAI 형식과 유사한 error 엔벨롭을 반환합니다. 먼저 처리해야 할 코드는 다음과 같습니다.
| 코드 | 의미 | 해결 방법 |
|---|---|---|
400 |
잘못된 요청 |
messages, tools, JSON 스키마 검증 |
401 |
유효하지 않은 키 | console.mistral.ai에서 키 재생성 |
402 |
결제 필요 | 계정 충전 또는 카드 추가 |
403 |
모델 허용 안 됨 | 프로젝트 범위와 모델 ID 확인 |
422 |
매개변수 범위 초과 |
max_tokens, tool_choice, 스키마 형식 확인 |
429 |
요청 제한 | 지수 백오프 후 재시도 |
500 |
서버 오류 | 한 번 재시도, 반복되면 상태 확인 |
503 |
과부하 | 대기 후 재시도 또는 다른 모델로 대체 |
재시도 로직은 429와 5xx에만 적용하십시오. 400, 401, 403, 422는 대부분 요청 버그이므로 자동 재시도해도 해결되지 않습니다.
간단한 Python 재시도 예시입니다.
import time
from mistralai import Mistral
def call_with_retry(client: Mistral, payload: dict, retries: int = 3):
for attempt in range(retries):
try:
return client.chat.complete(**payload)
except Exception as e:
message = str(e)
retryable = (
"429" in message
or "500" in message
or "503" in message
)
if not retryable or attempt == retries - 1:
raise
sleep_seconds = 2 ** attempt
time.sleep(sleep_seconds)
비용 제어 패턴
Medium 3.5는 Medium 3보다 비싸므로 라우팅 전략이 중요합니다.
1. 기본은 저렴한 모델, 필요할 때만 Medium 3.5
대량 분류, 단순 요약, 짧은 채팅은 Medium 3 또는 더 작은 모델로 처리하고, 다음 경우에만 Medium 3.5로 에스컬레이션하십시오.
- 검증 실패
- 낮은 신뢰도
- 긴 컨텍스트 필요
- 비전 입력 필요
- 도구 호출이 많은 에이전트 작업
2. max_tokens를 항상 설정
출력 토큰은 100만 개당 $7.5입니다. 출력이 길어질 수 있는 요청에는 반드시 제한을 둡니다.
{
"model": "mistral-medium-3.5",
"messages": [
{
"role": "user",
"content": "Summarize this document."
}
],
"max_tokens": 1200
}
3. 시스템 프롬프트를 짧게 유지
시스템 프롬프트는 모든 요청에 반복 포함됩니다. 2,000 토큰짜리 정책 프롬프트를 500 토큰으로 줄이면 대량 호출에서 입력 비용을 크게 낮출 수 있습니다.
4. 모든 호출에서 usage 저장
관측성 스택에 다음 필드를 기록하십시오.
- 요청 ID
- 모델 ID
prompt_tokenscompletion_tokens- 예상 비용
- 지연 시간
- 오류 코드
출력 토큰이 갑자기 증가하면 프롬프트가 과도한 설명이나 반복을 유도하고 있을 수 있습니다.
5. 비전 입력은 선택적으로 사용
이미지는 입력 토큰 비용을 빠르게 증가시킬 수 있습니다. OCR이나 단순 이미지 분류에 무조건 Medium 3.5를 쓰기보다, 필요한 경우에만 비전 입력을 전달하십시오.
Medium 3.5와 다른 Mistral 티어 비교
2026년 4월 말 기준 비교입니다.
| 모델 | 컨텍스트 | 입력 $/백만 | 출력 $/백만 | 비전 | 최적 용도 |
|---|---|---|---|---|---|
mistral-small |
32K | $0.10 | $0.30 | 아니요 | 대량 분류, 가벼운 채팅 |
mistral-medium-3 |
128K | $0.40 | $2.00 | 아니요 | 대량 처리, 긴 채팅 |
mistral-medium-3.5 |
256K | $1.5 | $7.5 | 예 | 추론, 코드, 비전, 에이전트 |
mistral-large |
128K | $2.00 | $6.00 | 제한적 | 고급 텍스트 추론 |
Medium 3.5는 긴 컨텍스트, 비전, 병합된 추론 기능을 함께 제공하는 티어입니다. 단, 모든 작업에 가장 경제적인 선택은 아닙니다. 모델 이름보다 워크로드 특성에 따라 선택하십시오.
다른 공급자에서 마이그레이션하기
대부분의 경우 기본 URL과 모델 ID만 바꾸면 됩니다.
OpenAI에서 이동하는 경우:
- base_url="https://api.openai.com/v1"
- model="gpt-5.5"
+ base_url="https://api.mistral.ai/v1"
+ model="mistral-medium-3.5"
DeepSeek에서 이동하는 경우:
- base_url="https://api.deepseek.com/v1"
- model="deepseek-v4-pro"
+ base_url="https://api.mistral.ai/v1"
+ model="mistral-medium-3.5"
마이그레이션 체크리스트입니다.
-
base_url변경 -
model변경 -
tool_choice="required"를tool_choice="any"로 변경 -
seed를random_seed로 변경 - 기존 테스트 스위트 실행
- 하루 정도 섀도우 트래픽으로 응답 비교
- 비용과 지연 시간 확인 후 프로덕션 전환
실제 사용 사례
Medium 3.5가 적합한 패턴은 다음과 같습니다.
코드 검토 도우미
256K 컨텍스트를 사용하면 PR diff와 주변 파일을 함께 넣어 코드 리뷰를 요청할 수 있습니다. SWE-Bench Verified 77.6% 점수는 코드 패치 작업에 강점이 있음을 보여줍니다.
긴 문서 QA
계약서, RFP, 정책 문서처럼 긴 입력을 청크 분할 없이 처리해야 할 때 유용합니다. 다만 200K 토큰 입력은 생성 전부터 입력 비용이 발생하므로, 먼저 문서 길이와 비용을 계산하십시오.
멀티모달 데이터 추출
영수증, 스크린샷, 다이어그램에서 구조화된 필드를 추출할 수 있습니다. JSON 스키마와 함께 사용하면 후처리 비용을 줄일 수 있습니다.
도구 호출 기반 에이전트
네이티브 함수 호출과 τ³-Telecom 91.4 점수는 다중 턴 워크플로우에서 유리합니다. 특히 “도구를 호출할지, 사용자에게 질문할지, 직접 답할지”를 모델이 결정해야 하는 경우에 적합합니다.
자주 묻는 질문
API에서 Mistral Medium 3.5의 모델 ID는 무엇인가요?
호스팅 API에서는 mistral-medium-3.5를 사용합니다. Hugging Face 체크포인트는 mistralai/Mistral-Medium-3.5-128B입니다.
Medium 3.5는 OpenAI와 호환되나요?
유사하지만 완전히 동일하지는 않습니다. 엔드포인트 형식, 헤더, 대부분의 매개변수는 OpenAI와 비슷하므로 OpenAI Python 및 Node SDK에서 기본 URL을 바꿔 사용할 수 있습니다.
주의할 차이는 다음 두 가지입니다.
-
tool_choice="required"대신tool_choice="any" -
seed대신random_seed
Medium 3.5를 로컬에서 실행할 수 있나요?
예. 가중치는 수정 MIT 라이선스와 고수익 기업 예외 조항 하에 공개됩니다. 단, 128B 매개변수 모델이므로 상당한 GPU 메모리가 필요합니다. 양자화된 GGUF 빌드는 unsloth/Mistral-Medium-3.5-128B-GGUF에서 사용할 수 있습니다. 관련 패턴은 DeepSeek V4를 로컬에서 실행하는 방법을 참고하십시오.
도구 호출과 스트리밍을 함께 사용할 수 있나요?
예. 스트리밍 중 도구 호출 인자가 delta.tool_calls 형태로 조각 단위로 반환됩니다. 스트림이 끝나면 조각을 누적해 완전한 JSON 객체로 처리합니다.
전송 전에 입력 토큰을 어떻게 계산하나요?
정확한 계산이 필요하면 mistral-common Python 패키지의 토크나이저를 사용하십시오. API와 동일한 토크나이저를 사용하므로 응답의 usage.prompt_tokens와 맞춰볼 수 있습니다.
프로덕션에서 어느 정도의 컨텍스트 길이를 계획해야 하나요?
256K는 상한선입니다. 비용은 토큰 수에 비례합니다. 예를 들어 200K 입력 토큰 호출은 모델이 출력을 시작하기 전부터 입력 비용이 발생합니다. 대부분의 프로덕션 워크로드는 32K 이하로 설계하고, 정말 필요한 경우에만 긴 컨텍스트를 사용하십시오.
무료 티어가 있나요?
Mistral은 영구 무료 티어를 광고하지 않지만, 새 계정에는 일반적으로 소량의 시험 크레딧이 제공됩니다. 유사한 티어 모델을 무료로 실험하는 방법은 DeepSeek V4 API를 무료로 사용하는 방법을 참고하십시오.


Top comments (0)