C.W.K.
Stream
Lesson 01 of 07 · published

Provider port — 시점과 위치

~16 min · provider-port, abstraction, architecture

Level 0Observer
0 XP0/64 lessons0/13 achievements
0/150 XP to next level150 XP to go0% complete

Valid 패턴 둘, wrong move 하나

멀티-프로바이더 시스템엔 valid 패턴 둘 — (1) 프로바이더 port — 스트리밍 API에 대한 narrow ABC, 매 프로바이더가 구현, downstream 코드 neutral; 또는 (2) canonical-shape 베리언트 — 한 프로바이더를 canonical로 픽, 나머지는 downstream에서 specialize. 둘 다 ship; 둘 다 살아남아. Wrong move는 day one에 한 프로바이더로 prematurely generalize.

cwkPippa는 베리언트 픽

cwkPippa의 어댑터 ABC가 의도적으로 narrow — 스트리밍-턴 경계만. Routes, store, frontend가 Claude shape 가정. ChatGPT, Gemini, Ollama 브레인이 베리언트지 peer 아님. 이게 cwkPippa 아키텍처 룰 2 — cost is absorbed downstream, never pushed upstream. 결과는 더 적은 추상과 더 직접적인 코드, canonical 결정 일찍 필요한 비용.

Port 선택 시점

프로바이더가 진짜 interchangeable이면(같은 능력, 같은 비용 모양, mid-traffic swappable), strict port 보상 — A/B 프로바이더 가능, 깔끔히 fail over, downstream 안 만지고 새 거 bring up. Interchangeable 아니면(하나는 prompt caching, 다른 건 agent harness, 다른 건 local-only), 베리언트가 더 나은 service.

원칙: 구체 먼저, 추상 그다음. 두 프로바이더 갖는 날이 결정의 날. 한 프로바이더의 day one은 너무 일러.

Code

cwkPippa-스타일 narrow ABC·python
from abc import ABC, abstractmethod
from typing import AsyncIterator, Any

class Adapter(ABC):
    """시스템에서 유일한 추상.
    Routes, store, frontend가 이게 반환하는 응답 모양 가정."""

    @abstractmethod
    async def stream_turn(
        self,
        *,
        conversation_id: str,
        messages: list[dict[str, Any]],
        system: str,
    ) -> AsyncIterator[dict[str, Any]]:
        ...

# claude.py가 canonical 구현;
# codex.py / gemini.py / ollama.py가 downstream에서 SPECIALIZE — 위로 abstract X.
Strict port (대안 패턴)·python
# 프로바이더가 정말 interchangeable일 때만 옳음.
class ModelProvider(ABC):
    capabilities: dict  # prompt_caching, files, agent 등 advertise

    @abstractmethod
    async def generate(self, req: GenerateRequest) -> GenerateResult: ...
    @abstractmethod
    async def stream(self, req: GenerateRequest) -> AsyncIterator[Event]: ...
    async def count_tokens(self, req: GenerateRequest) -> int: ...  # 선택

# Caller가 capabilities로 분기, common surface로 fall through.

External links

Exercise

프로젝트에 대해 한 단락 — 어느 패턴(port 또는 canonical-shape 베리언트), 그 선택 driving한 specific 기능·제약 하나. 아직 픽 안 했지만 두 프로바이더 가지면 그게 기다리는 결정.
Hint
정당화가 'flexibility'면 정당화 X — 모든 패턴이 그 주장. 기능이나 deploy 스토리 이름.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.