초보자를 위한 TypeSafe AI: 심층 튜토리얼
요약
본 문서는 기존 LLM의 텍스트 생성 및 파싱 과정에서 발생하는 불안정성과 복잡성 문제를 지적하며, 이를 해결할 새로운 접근 방식인 TypeSafe를 소개합니다. TypeSafe는 텍스트 대신 타입이 지정된 답변, 확률 분포, 신뢰도 점수를 직접 반환하는 'System One' 모델입니다. 개발자는 더 이상 JSON 파싱이나 프롬프트 엔지니어링에 의존할 필요가 없습니다.
핵심 포인트
- TypeSafe는 텍스트 생성 없이 구조화된 결정을 직접 출력합니다.
- 기존 LLM은 느리고 비용이 많이 드는 'System Two' 기계입니다.
- 개발자는 더 이상 JSON 파싱이나 복잡한 프롬프트 엔지니어링을 할 필요가 없습니다.
Jev 학습하기, 첫 번째 "System One" 모델 — 생성된 텍스트 대신 타입이 지정되고 구조화된 결정을 반환하는 AI입니다.
이미 LLM API (OpenAI, Anthropic 등)를 이미 알고 있는 개발자를 위한 내용이며, 전체에 걸쳐 Python 예제가 포함되어 있습니다.
만약 try/except 구문 안에 json.loads()를 작성하고 간절히 기도해 본 적이 있다면, 이 튜토리얼은 당신을 위한 것입니다.
우리는 텍스트를 생성하지 않는 새로운 종류의 AI인 TypeSafe를 배울 것입니다. 이는 **타입이 지정된 답변, 확률 분포(probability distributions), 그리고 신뢰도 점수(confidence scores)**를 반환합니다. 파싱(parsing) 과정이나 프롬프트 엔지니어링(prompt engineering)이 필요 없습니다. 환각성 카테고리(hallucinated categories)도 없습니다.
한 문장 요약: Jev는 TypeSafe의 플래그십 모델이자 첫 번째 System One 모델입니다 — 여기에 콘텐츠(상태, state)와 타입이 지정된 질문을 보내면, 타입이 지정된 답변, 확률 분포, 그리고 신뢰도를 반환합니다. 텍스트 생성이나 파싱 과정이 없습니다.
이 튜토리얼 읽는 방법
이 글은 이미 채팅 완료(chat-completions) 호출을 연결하고 JSON 응답을 파싱해 본 엔지니어를 위해 작성되었습니다. 시스템 프롬프트(system prompt)가 무엇인지 알고 있을 것입니다.
Part 0 — TypeSafe란 무엇인가? (System One과 여러분이 아는 LLM 비교)
모든 LLM 개발자가 아는 문제점
대규모 언어 모델(LLM)은 사람이 읽을 수 있는 텍스트를 생성하도록 구축되었습니다. 사용자가 사람일 때는 이것이 기능이지만, 출력의 소비자가 코드가 될 경우에는 버그가 됩니다.
애플리케이션 내부에서 결정을 내리기 위해 LLM을 사용했던 마지막 순간을 생각해 보세요. 지원 티켓 분류, 유해성 탐지, 의도 라우팅 등이 있습니다. 여러분은 다음과 같은 작업을 수행했을 것입니다:
- _"이 메시지를 분류하세요. 유효한 JSON만 응답하세요:
{"category": "billing|technical|sales"}"_라는 프롬프트를 작성했습니다. - 모델이 JSON 앞에 친절한 문장을 추가하지 않기를 기도했습니다.
- 마크다운 펜스(markdown fences)를 제거했습니다.
try/except블록에서json.loads()를 호출했습니다.- 모델이 여러분이 목록에 올리지 않은 카테고리를 발명한 경우를 처리했습니다.
- 파싱 실패 시 재시도하고, 어쩌면 더 엄격한 시스템 프롬프트를 사용했습니다.
2단계부터 6단계까지의 과정은 텍스트 생성 시스템을 구조화된 결정(structured decisions)을 출력하도록 강제하고, 그 결과를 다시 코드가 의존할 수 있는 무언가로 파싱하는 과정 때문에 존재합니다.
바로 이것이 TypeSafe가 제거하기 위해 구축된 정확한 불일치(mismatch)입니다.
System One 대 System Two
이 이름은 Daniel Kahneman의 저서 『생각에 관한 생각 (Thinking, Fast and Slow)』에서 유래했습니다.
- 시스템 1(System 1) 사고는 빠르고 직관적이다 (직감적 판단).
- **시스템 2(System 2)**는 느리고 신중하다 (단계별 추론).
현재의 최첨단 LLM(대규모 언어 모델)들 — o-시리즈 및 추론 모델을 포함하여 — 은 시스템 2 기계이다. 강력하지만, 긴 텍스트 체인을 생성하기 때문에 느리고 비용이 많이 든다.
Jev는 시스템 1 기계이다. 이 모델은 적절한 컨텍스트가 주어졌을 때 지식이 풍부한 사람이 몇 초 만에 내릴 수 있는 빠르고 집중적인 판단을 하도록 훈련되었다:
- "이 메시지가 긴급성을 전달하는가?" → 예, 0.98
- "어떤 팀이 이 티켓을 처리해야 하는가?" → 기술팀, 0.85
- "이 고객은 얼마나 좌절했는가? (0–2)" → 1.4
LLM처럼 Jev도 자연어 입력을 이해한다. 하지만 LLM과 달리, 생성된 텍스트 대신 타입화된 결정과 확률을 반환한다. 답변을 작성하거나, 코드를 생성하거나, 추론 과정을 설명하지 않는다.
사용자가 가능한 답변의 범위를 정의하면, 모델이 그 안에서 선택한다.
학습 방식의 차이점 (1분 만에)
문서의 AI 입문서는 사전 훈련된 언어 모델을 위한 세 가지 사후 훈련 경로를 제시합니다:
| 접근 방식 | 무엇을 위해 훈련하는가 | 결과물 |
|---|---|---|
| RLHF — 인간 피드백 기반 강화학습 (reinforcement learning from human feedback) | 사람들이 선호하는 응답 | 챗봇(GPT급 비서). 아첨이나 자신감 넘치는 환각을 보상할 수 있다. |
| ... |
보정(Calibration)이 핵심 단어이다. 보정이 된 모델에서는 확률이 실제 결과에 맞춰 최적화된다: 많은 예측에 걸쳐, 0.2로 할당된 결과는 약 20%의 시간 동안 발생하고, 0.8로 할당된 결과는 약 80%의 시간 동안 발생한다.
이는 불확실성을 소프트웨어에서 사용 가능하게 만든다 — 이를 임계값 설정(threshold)하거나, 라우팅하거나, 에스컬레이션할 수 있게 된다.
보정은 예측 그룹 전반에 걸쳐 측정되는 것이며, 단일 답변이 정확하다는 보장은 아니다.
RLHF는 또한 **모드 드롭핑(mode dropping)**을 유발한다: 모델이 훈련 중에 인간이 선호했던 출력 쪽으로 범위를 좁힌다. 채팅에는 적합하지만, 정직한 확률 분포가 필요할 때는 좋지 않다.
재미있는 사실: RLHF는 TypeSafe의 공동 창업자인 Diogo Almeida가 공동 발명했습니다. 그들의 베팅은 Machine Native Intelligence라고 불리며, 이는 구조(structure), 신뢰성(reliability), 관찰 가능성(observability), 테스트 용이성(testability), 속도(speed), 일관성(consistency), 그리고 낮은 비용을 갖춘 소프트웨어와 같은 AI를 의미합니다.
비교: 아는 것 vs. 얻게 되는 것
| 측면 | LLM 채팅 API (OpenAI/Anthropic) | TypeSafe System One API |
|---|---|---|
| 출력 | 자유 형식 텍스트 | 옵션에 제한된 타입 값 |
| ... |
한 단락 요약: 언어 생성에는 LLM을 사용하고, 코드가 판단이 필요한 경우 TypeSafe를 사용하세요. 이 둘은 아름답게 결합됩니다 — Part 6에서는 LLM과 Jev가 동일한 파이프라인에서 작동하는 것을 보여줍니다.
Part 1 — 정신 모델: 상태(State), 질문(Questions), 답변(Answers)
모든 TypeSafe 요청은 같은 형태를 가집니다. 내재화해야 할 세 단어는 다음과 같습니다:
요청 하나 → 응답 하나: 상태 + 질문 → 타입화된 답변 + 확률 + 신뢰도
state + questions ──▶ TypeSafe AI 모델 ──▶ 타입화된 답변
(각 질문을 + 확률
제공된 상태와 + 신뢰도
비교하여 평가)
...
1.1 상태 (State) — 판단의 대상
**상태(State)**는 평가를 원하는 콘텐츠입니다: 지원 메시지, 이력서, 텍스트 구절, 애플리케이션의 현재 상태 등이 될 수 있습니다. 다음과 같은 형식일 수 있습니다:
| 형식 | 유용성 | 예시 |
|---|---|---|
| 문자열 (String) | 메시지, 기사 또는 구절 | ` |
- ID: 선택하는 키입니다 (예:
refund_requested). 응답에서 답변에 레이블을 지정합니다. (ID는 코드 전용이며 모델로 전송되지 않습니다.) - type:
choice,score, 또는noul중 하나입니다 (세 가지 기본 요소; 파트 3). - instructions: 실제로 판단할 질문이나 진술입니다. 여기에 평가 로직이 존재합니다. ID가 자명해 보이더라도 완전하고 독립적인 질문 형태로 작성해야 합니다.
- criteria: 가능한 답변들입니다: Choice의 옵션, Score의 순서가 지정된 레벨, 또는 Noul에 대한 선택적 참/거짓 정의.
일반적인 초보자 오류:
instructions: "환불"이라고 작성하고 의미를 전달하는 데 ID인refund_requested에 의존하는 것입니다. 모델은 절대 ID를 볼 수 없습니다. 전체 질문을instructions에 작성해야 합니다.
1.3 답변 - 산문이 아닌 타입화된 값 (Typed Values)
각 질문은 사용자가 선택한 ID 아래에 하나의 **타입화된 답변(typed answer)**을 반환합니다. 이 답변들은 LLM 출력과는 다른 방식으로 조합 가능하게 만드는 두 가지 속성을 가집니다:
- 제약적(Constrained): 모든 답변은 사용자가 정의한 옵션이나 레벨에 대한 확률 분포입니다. 모델은 그 범위를 벗어난 값을 반환할 수 없습니다. 파싱해야 할 것도, 정의된 공간 밖에서 환각을 일으킬 것도 없습니다.
- 독립적(Independent): 모든 질문은 상태(state)에 대해 격리되어 평가됩니다. 한 질문의 답변이 다른 질문의 숨겨진 컨텍스트가 되는 경우가 없으므로, 질문을 추가하거나 제거해도 다른 질문들의 결과는 변하지 않습니다. 이것이 바로 "컨텍스트 손실 없음(no context-rot)" 보장입니다.
1.4 전문가 패널(Panel-of-Experts)의 그림
문서는 암기할 가치가 있는 사고 모델을 제공합니다: 당신은 전문가 패널에게 브리핑하고 있습니다.
- **상태(state)**는 테이블 위에 놓는 사건 파일입니다.
- 각 **질문(question)**은 한 명의 전문가이며, 다른 전문가들과 독립적으로 답변하는 하나의 좁은 질문을 받습니다.
- 당신의 **코드(code)**는 패널의 의장입니다: 타입화된 답변들을 수집하고 무슨 일이 일어날지 결정합니다.
이 그림은 좋은 TypeSafe 시스템과 나쁜 시스템을 구분하는 설계 규칙을 즉시 시사합니다:
각 질문을 직관적인 판단(gut-check judgment)으로 만들고, 복잡한 추론은 코드로 답변을 구성하세요.
이 규칙에 대한 자세한 내용은 파트 4에서 다룹니다.
파트 2 — 시작하기: 플레이그라운드, API, 그리고 첫 번째 Python 호출
세 가지 방법으로 직접 체험해 볼 수 있습니다. 가장 빠른 순서로 이 세 가지 방법을 모두 다루겠습니다.
2.1 사용해 보기: 플레이그라운드 (코드 없음)
"타입된 답변(typed answers)"이 무엇을 의미하는지 가장 빠르게 느껴볼 수 있는 곳은 console.typesafe.ai/playground의 플레이그라운드입니다.
- 플레이그라운드를 열고 로그인합니다.
- 상태로 임의의 텍스트를 붙여넣습니다. 예를 들어:
Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP.
- Noul 질문(예/아니오 확률)을 추가합니다:
{
"urgency": {
"type": "noul",
...
- 더 많은 질문을 추가합니다. Noul, Choice, Score를 한 번의 호출에 섞어 넣고 모든 타입된 답변이 한 번에 나타나는 것을 지켜보세요.
답변이 도착하는 방식을 주목하세요: Noul에는 숫자, Choice에는 옵션과 확률, Score에는 스케일 상의 위치가 표시됩니다. 파싱할 산문(prose)은 전혀 없습니다.
2.2 호출하기: 원시 HTTP API
대시보드에서 API 키를 받은 다음, 단일 엔드포인트로 POST 요청을 보냅니다:
POST https://api.typesafe.ai/v1/systemone
Authorization: Bearer <API_KEY>
Content-Type: application/json
완벽한 cURL 요청 예시 — 하나의 상태, 세 가지 혼합 질문:
curl -X POST https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
...
실제 응답은 다음과 같습니다:
{
"model": "jev-1.13.0",
"answers": {
...
이것을 채팅 API에서 알고 있는 내용과 비교해 보세요: model 필드, 메시지 유사체 (state), 도구 유사체 (questions), 그리고 토큰 수를 계산하는 usage 블록이 있습니다. answers 객체는 사용자가 선택한 질문 ID별로 키가 지정됩니다.
빠진 것을 주목하세요: choices[0].message.content 없음, 마크다운 없음, "As an AI..." 같은 서문도 없습니다.
2.3 코드로 구현하기: Python SDK
Python ≥ 3.10이 필요합니다.
pip install typesafe-sdk # 또는: uv add typesafe-sdk
export TYPESAFE_API_KEY="sk-..." # 클라이언트가 자동으로 읽습니다
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient()
...
주목할 세 가지 사항:
- 프롬프트 없음. 질문 자체가 프롬프트입니다.
instructions는 평가 로직이며,criteria는 출력 공간입니다. - 파싱 없음.
.choice,.score,.noul은 타입이 지정된 객체에 있는 필드입니다. - 한 번의 호출로 세 가지 질문 유형. 이들은 모두 동일한 상태를 대상으로 병렬로 평가됩니다.
2.4 요청/응답 구조 분석 (Annotated)
머릿속 모델을 위해, 작성하게 될 모든 요청은 다음 형태를 가집니다:
client.system_one(
state=<string | dict | list>, # 평가 대상이 되는 것
model="jev-latest", # 선택 사항이며, 이것이 기본값입니다.
...
성급한 분들을 위한 팁: 문서에는 또한
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기