Header
MMSP - Model Message Stream Protocol
GitHub Repo stars
GitHub last commit
GitHub contributors
CI
PyPI
NPM
모든 모델을 동일한 방식으로 통합하고, 제공업체별로 하나씩 API를 외우지 않아도 됩니다.
MMSP(Model Message Stream Protocol)는 개발자의 머릿속에서 제공업체별 차이점을 제거합니다. Python과 TypeScript 환경에서 모든 모델 제공업체에 대해 단일 메시지 형식과 단일 스트리밍 문법을 사용합니다.
📖 문서: mmsp.penguin.ooo
코딩 에이전트를 사용하는가요? skills/에서 MMSP SKILL 파일을 설치하여 생성된 코드에서 MMSP를 올바르게 사용할 수 있도록 하세요.
MMSP를 사용해야 하는 이유?
-
🔗 통합성 (Unified): 다양한 LLM에 걸쳐 **에이전트(agents)**를 개발하기 위한 일관되고 직관적인 인터페이스를 제공합니다.
-
🎯 정확성 (Precise): 다단계 도구 호출 중 발생하는 **상호 혼합 사고(interleaved thinking)**를 자동으로 처리하여 성능 저하를 방지합니다.
-
🧭 추적 가능성 (Traceable): 디버깅 및 LLM 실행 감사(auditing)를 위한 가볍지만 세밀한 추적(tracing) 기능을 제공합니다.
기능
AutoLLMClient (Python & TypeScript)
코드 변경 없이, 성능 손실 없이 다양한 LLM을 전환할 수 있습니다.
MMSP
내장 관측 가능성 (Built-in Observability)
데이터베이스가 필요하지 않은, 단일 trace_id 매개변수를 추가하는 것만으로 LLM 실행을 감사(audit)할 수 있습니다.
Tracer
지원되는 모델
| 모델 이름(Model Name) | 공급업체(Vendor) | 예시 모델 ID(Example Model ID) | 입력 모달리티(Input Modalities) | 출력 모달리티(Output Modalities) |
|---|
| Gemini 4 Argon | Official/Google Vertex AI | gemini-4-argon | Text, Image | Text |
| ... | | | | |
클라이언트(Clients)
AutoLLMClient는 모델 ID와 client_type을 받습니다. **공식 클라이언트(official client)**는 공급업체 자체의 API를 사용하며, 해당 공급업체의 모델을 알고 있고, 환경 변수에서 공급업체의 키를 읽어옵니다. 반면, **호환 클라이언트(compatible client)**는 자신에게 서비스를 제공하는 모든 엔드포인트에 대해 단일 와이어 프로토콜을 사용합니다.
client_type | 사용하는 프로토콜 | 키 및 엔드포인트 |
|---|
openai-official | OpenAI 응답; OpenAI 임베딩을 통한 text-embedding-* 모델 | OPENAI_API_KEY, OPENAI_BASE_URL |
| ... | | |
전체 기계가 읽을 수 있는 목록—모델, 기본 URL(base URL), 클라이언트, 입력/출력 모달리티(modalities), 컨텍스트 윈도우(context window), 그리고 백만 토큰당 가격 정보(USD 또는 CNY):
from mmsp import list_supported_models
models = list_supported_models(currency="CNY")
import { listSupportedModels } from "@prismshadow/mmsp";
const models = listSupportedModels("CNY");
설치(Installation)
Python 패키지
PyPI에서 설치:
uv add mmsp
pip install mmsp
소스 코드에서 빌드:
상세한 사용 예시와 API 문서는 src_py/README.md를 참조하십시오.
TypeScript 패키지
npm에서 설치:
npm install @prismshadow/mmsp
소스 코드에서 빌드:
cd src_ts && make install && make build
상세한 사용 예시와 API 문서는 src_ts/README.md를 참조하십시오.
에이전트 스킬(Agent Skills)
MMSP는 사용자에게 SDK 패키지를 사용하는 방법을 돕는 어시스턴트를 위해 Codex/Claude Code 스킬 파일을 제공합니다:
API
AutoLLMClient는 MMSP SDK와 상호 작용하는 주요 클래스입니다. 이 클래스는 model과 client_type(아래 Clients 참조; 알려진 계열의 모델 ID는 자체 공식 클라이언트를 지정함), 그리고 선택적(optional)으로 api_key, base_url, default_headers로 구성됩니다—이 헤더들은 해당 엔드포인트가 요구하는 모든 요청에 함께 전송되는 헤더입니다. 이 클래스는 다음 메서드를 제공합니다:
키(key)는 제공된 곳에만 사용됩니다. 전달된 키가 있으면, 전달된 base_url을 사용하고, 그렇지 않으면 클라이언트의 <P>_BASE_URL (참고: Clients)을 사용하며, 이것이 없으면 기본 엔드포인트를 사용합니다. 키 없이도 클라이언트는 base_url이 제공되지 않았거나 자체 기본 엔드포인트일 때만 <P>_API_KEY를 읽습니다: deepseek-official은 base_url이 없거나 https://api.deepseek.com을 사용할 경우 DEEPSEEK_API_KEY를 사용합니다. 키 없이 다른 base_url을 사용하는 경우, 구성 시 ApiKeyRequiredError가 발생합니다: 이 오류를 피하려면 키와 함께 전달하거나, 아니면 키를 제거하고 기본 엔드포인트가 아닌 곳에 대해 <P>_API_KEY 및 <P>_BASE_URL을 설정해야 합니다. mmsp 클라이언트는 예외입니다: 이는 키 없이도 base_url을 호출하여 개방형 MMSP 서버로 작동합니다. @prismshadow/mmsp/credentials와 mmsp.credentials는 호스트를 위한 데이터로 이 규칙을 내보냅니다.
(async) streaming_response(messages, config): 상태 비저장 방식(stateless manner)으로 LLM의 응답을 스트리밍합니다.
(async) streaming_response_stateful(message, config): 상태 저장 방식(stateful manner)으로 LLM의 응답을 스트리밍합니다.
(async) list_models(): 구성된 엔드포인트가 제공하는 모델 ID 목록을 나열합니다. 프로토콜 클라이언트(openai-chat, openai-chat-vllm-adapter, openai-responses, ant-messages, openai-embedding, google-genai, mmsp)는 명시적으로 이름이 지정되어 엔드포인트가 제공하는 모든 것을 나열하며, 모델 ID에서 추론된 클라이언트는 자신에게 역추론되는 ID만 나열합니다.
clear_history(): 상태 저장 LLM 클라이언트의 기록을 지웁니다.
get_history(): 상태 저장 LLM 클라이언트의 기록을 반환합니다.
set_history(history): 제공된 목록 사본으로 상태 저장 LLM 클라이언트의 기록을 대체합니다.
두 스트리밍 메서드 모두 delta 이벤트를 생성하며, 각 이벤트는 하나의 콘텐츠 항목을 담고 그 뒤에 사용량과 완료 이유를 담은 정확히 하나의 stop 이벤트가 이어집니다 (참고: UniEvent).
스트리밍 클라이언트는 인식하지 못하는 출력은 건너뛰므로, 게이트웨이 자체의 프레임으로는 생성을 종료할 수 없습니다. MMSP_DEBUG를 0, false, no, 또는 off가 아닌 다른 값으로 설정하면 오류를 발생시키도록 합니다.
기본 사용법
[!NOTE]
MMSP SDK를 호출할 때는 **상태 유지 인터페이스(stateful interface)**를 사용하는 것을 권장합니다.
OpenAI GPT-5.6
Python 예제:
import asyncio
import os
from mmsp import AutoLLMClient
...
TypeScript 예제:
import { AutoLLMClient } from "@prismshadow/mmsp";
process.env.OPENAI_API_KEY = "your-openai-api-key";
...
Anthropic Claude Opus 5
<details><summary><strong>Python 예제</strong></summary>
import asyncio
import os
from mmsp import AutoLLMClient
...
</details>
<details><summary><strong>TypeScript 예제</strong></summary>
import { AutoLLMClient } from "@prismshadow/mmsp";
process.env.ANTHROPIC_API_KEY = "your-anthropic-api-key";
...
</details>
OpenRouter GLM-5.3
<details><summary><strong>Python 예제</strong></summary>
import asyncio
import os
from mmsp import AutoLLMClient
...
</details>
<details><summary><strong>TypeScript 예제</strong></summary>
import { AutoLLMClient } from "@prismshadow/mmsp";
process.env.ZAI_API_KEY = "your-openrouter-api-key";
...
</details>
SiliconFlow Qwen3.8 27B (OpenAI 호환 API를 통한 사용)
<details><summary><strong>Python 예제</strong></summary>
import asyncio
import os
from mmsp import AutoLLMClient
...
</details>
<details><summary><strong>TypeScript 예제</strong></summary>
import { AutoLLMClient } from "@prismshadow/mmsp";
process.env.OPENAI_API_KEY = "your-siliconflow-api-key";
...
</details>
SiliconFlow Qwen3 Embedding 0.6B (OpenAI 호환 API를 통한 사용)
<details><summary><strong>Python 예제</strong></summary>
import asyncio
import os
from mmsp import AutoLLMClient
...
</details>
<details><summary><strong>TypeScript 예제</strong></summary>
import { AutoLLMClient } from "@prismshadow/mmsp";
process.env.OPENAI_API_KEY = "your-siliconflow-api-key";
...
</details>
DeepSeek을 OpenAI Responses 프로토콜로 사용하기
호환 가능한 모든 엔드포인트는 일반적인 프로토콜 클라이언트를 통해 클라이언트 유형(openai-chat / openai-responses / ant-messages)과 해당 프로토콜에 대한 제공업체의 기본 URL을 지정하여 호출할 수 있습니다:
<details><summary><strong id="python-example">Python 예시</strong></summary>
import asyncio
import os
from mmsp import AutoLLMClient
...
</details>
<details><summary><strong id="typescript-example">TypeScript 예시</strong></summary>
import { AutoLLMClient } from "@prismshadow/mmsp";
async function main() {
...
</details>
DeepSeek을 Anthropic Messages 프로토콜로 사용하기
<details><summary><strong id="python-example">Python 예시</strong></summary>
import asyncio
import os
from mmsp import AutoLLMClient
...
</details>
<details><summary><strong id="typescript-example">TypeScript 예시</strong></summary>
import { AutoLLMClient } from "@prismshadow/mmsp";
async function main() {
...
</details>
동일한 모델은 client_type="openai-chat" (기본 URL https://api.deepseek.com)을 통해 작동합니다. OpenRouter, Z.AI, MiniMax는 세 가지 프로토콜 모두 동일한 방식으로 노출합니다.
개념: UniConfig, UniMessage 및 UniEvent
UniConfig
UniConfig는 LLM의 구성을 포함하는 객체입니다.
UniConfig 예시:
{
"max_tokens": 1024,
"temperature": 1.0,
...
UniMessage
UniMessage는 LLM의 입력을 포함하는 객체입니다. 그 콘텐츠 항목들은 .done 접미사로 유형화된 완전한 항목들입니다.
UniMessage 예시:
{
"role": "user | assistant",
"content_items": [
...
0.5.0 이전에 저장된 메시지들은 .done 접미사가 없는 항목 유형을 사용합니다. 이들은 0.6.0까지 여전히 허용되며, 사용 중단 경고와 함께 변환됩니다. normalize_legacy_messages / normalizeLegacyMessages가 저장된 데이터를 변환합니다.
UniEvent
UniEvent는 LLM의 스트리밍 출력을 담고 있는 객체입니다. 스트림은 각각 하나의 콘텐츠 항목을 담고 있으며, 오직 사용량(usage)과 종료 이유(finish reason)만을 담고 아무 항목도 없는 stop 이벤트로 닫히는 일련의 delta 이벤트들입니다. 각 항목은 하나 이상의 .delta 조각으로 스트리밍된 후, 완전한 .done 항목이 뒤따르며, 항목들은 절대 서로 섞이지 않습니다.
도구 호출(tool call)을 위한 UniEvents 예시: