Files
hyungi_document_server/contract/AI-ROUTING.md
T
Hyungi 17f8830d37 feat(ds-app): freeze S1 contract + S2 AIProvider interface baseline
S1 = contract/CONTRACT.md + 14 fixtures + README + AI-ROUTING.
S2 = Sources/AI/{AIProvider,AIRouter,MockAIProvider} + Providers skeletons.
Baseline before S3 (device app) scaffold work begins.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 15:27:24 +09:00

4.0 KiB

DS App AI 라우팅 계약 (S2 인터페이스 동결) — v0.1

S1(데이터 fixture)이 앱의 데이터 모양을 동결했듯, 이 문서 + Sources/AI/는 앱의 AI 호출 모양을 동결한다. S3 는 AIProvider 프로토콜 + MockAIProvider 로 AI 흐름을 끝까지 그리고, S2 가 실 provider 를 뒤에서 채운다.

  • Frozen: 2026-06-04 · typecheck PASS (swift 6 strict concurrency) · router 스모크 PASS
  • 위치: Sources/AI/{AIProvider,AIRouter,MockAIProvider}.swift + Sources/AI/Providers/*.swift
  • 파일 경계: 이 AI/ 디렉토리 = S2 소유(앱 나머지 = S3). 같은 Xcode repo 디렉토리 단위 분담 → 충돌 0.

1. Provider 티어 (= 디바이스 역할 표와 1:1)

AIProviderID 노드 용도 구현 경로
.onDevice 맥북·아이폰 즉답·오프라인·프라이버시 Apple FoundationModels (SystemLanguageModel/LanguageModelSession)
.localMLX 맥미니 허브 무거운 로컬 생성 Gemma 4 26B — llm-router :8890 / MLX :8801 (OpenAI 호환)
.remoteDS GPU(원격) 코퍼스 RAG GET /search/ask?backend= (CONTRACT.md §4)
.specialized GPU rerank·embed·vision·OCR 특화 모델 통로(온디맨드)

2. 태스크 → 티어 정책 (AIRoutingPolicy.default)

AITask 선호 체인 근거
quickSummarize onDevice → localMLX 빠르고 사적
memoAssist onDevice → localMLX 짧은 보조
askSelection onDevice → localMLX → remoteDS 로컬 컨텍스트, 부족 시 승급
corpusAsk remoteDS only 코퍼스 필요 — 온디바이스로 폴백 불가
classify localMLX → remoteDS → onDevice 분류 품질 우선
vision specialized → onDevice GPU VLM 우선

3. 3단 fallback 규칙 (feedback_task_routing_hybrid + no_silent_fallback)

  1. explicit > rule > error.
  2. 명시 opt-in(request.explicitProvider) → 그 provider 만. 불가 시 에러(explicitProviderUnavailable) — 자동 다른 티어 호출 금지.
  3. 미지정 → 태스크 선호 체인 순회. 불가/실패는 다음으로 넘기되 routingNote로 가시화(silent skip 금지) + log 훅.
  4. 전부 불가 → noProviderAvailable.

스모크 검증:

quickSummarize → onDevice         corpusAsk → remoteDS (citations=1)
vision → specialized              classify → localMLX
explicit onDevice 불가 → 에러(자동 fallback X)
rule fallback: onDevice 불가 → localMLX  note="fallback from onDevice → localMLX"

4. S1 계약과의 다리 (RemoteDSProvider)

corpusAsk.remoteDS 책임. 매핑(고정):

GET /search/ask?q=<prompt>&backend=<map(explicitProvider)>   → AskResponse (CONTRACT.md §4)
AskResponse.ai_answer            → AICompletionResponse.text
AskResponse.citations[]          → AICitation[]  (n, doc_id, title, section_title, span_text)
AskResponse.synthesis_status     → AIFinishReason  (completed/timeout/no_evidence/backend_unavailable/…)
AskResponse.confidence           → AIConfidence
AskResponse.backend_used         → routingNote (어느 LLM 이 응답했는지)

backend 매핑: nilmac-mini-default · .localMLXgemma-macmini · (M5 Max Qwen 경로)→qwen-macbook · cloud→claude-cloud(503, 별 PR).

5. S2 가 다음에 채울 것 (인터페이스는 고정)

  • OnDeviceProvider: import FoundationModels 가용성 프로브 + LanguageModelSession 호출.
  • LocalMLXProvider: 맥미니 OpenAI 호환 호출(messages system/user 분리 call-shape 고정).
  • RemoteDSProvider: S3 의 DS API client 주입 → 위 §4 매핑 결선.
  • SpecializedProvider: GPU 비전/특화 통로(필요 태스크만).

동시 출발선 (S1 + S2 둘 다 동결 완료)

  • S3 = MockAIProvider 주입 + S1 fixtures/ 디코딩 → 실 백엔드·실 LLM 대기 0 으로 앱 전체 빌드.
  • S1 = [S1-ADD] 구현 + 응답 shape 유지.
  • S2 = 위 §5 provider 결선. 인터페이스(AIProvider/AIRouter) 변경 시만 합의.