iop/agent-roadmap/sdd/operational-observability-provider-management/provider-catalog-device-status/SDD.md

17 KiB

SDD: Model Alias Provider Pool과 Provider Catalog

위치

  • Milestone: agent-roadmap/phase/operational-observability-provider-management/milestones/provider-catalog-device-status.md
  • Phase: agent-roadmap/phase/operational-observability-provider-management/PHASE.md

상태

[승인됨]

SDD 잠금

  • 상태: 해제
  • 사용자 리뷰: 없음
  • 잠금 항목:
    • [D01] Edge config는 models[]를 model catalog이자 외부 model key 목록으로 두고, 각 model의 providers에 provider id와 실제 served model name을 매핑한다. provider 정의는 nodes[].providers[] 아래에 두며, 각 provider는 제공 가능한 models[] list를 가진다.
    • [D02] MVP provider 선택은 available provider 중 in_flight / capacity load ratio가 가장 낮은 후보를 우선한다. priority/weight/fallback 정책은 후속 확장으로 둔다.
    • [D03] provider별 실제 served target rewrite와 routing/control 책임은 Edge가 가진다. Node/provider adapter는 Edge가 전달한 concrete target을 실행한다.
    • [D04] MVP provider category는 api, cli, local_inference로 시작하고, 상태 추적은 health, capacity, in_flight, derived load_ratio, models, queued까지 포함한다. runtime process와 resource telemetry는 후속으로 둔다.
    • [D05] MVP catalog에는 provider별 lifecycle capability를 coarse flags로만 표시하고, 상세 lifecycle 동작, compatibility, benchmark, quality, model별 qualification 결과는 후속 Qualification Report Milestone으로 둔다.
    • [D06] MVP는 읽기 전용 관찰과 Edge config 기반 routing 계약까지만 포함한다. enable/disable, drain, fallback 우선순위 변경, capacity override 같은 runtime 제어는 후속 Milestone으로 둔다.

문제 / 비목표

  • 문제: 현재 OpenAI-compatible model route는 단일 adapter + target으로 해석되고, Edge queue도 같은 resolved target 기준으로 후보를 필터링한다. qwen3.6:35b 같은 논리 model alias 아래에 vLLM, Lemonade, Ollama, SGLang 같은 여러 provider candidate를 묶으려면 alias를 canonical routing key로 유지하는 계약, candidate schema, selection/queue 정책, served target rewrite 책임, catalog 표시 기준을 먼저 고정해야 한다.
  • 비목표:
    • vLLM, vLLM-MLX, Lemonade, SGLang provider adapter 구현 자체
    • provider pool scheduler 코드 구현과 config migration 실행
    • provider/device/model qualification report 저장/조회/비교
    • 자동 benchmark, 품질 평가, provider marketplace, cross-Edge provider balancing
    • cloud fallback과 품질 평가 feedback 구현

Source of Truth

영역 기준 메모
Roadmap agent-roadmap/phase/operational-observability-provider-management/milestones/provider-catalog-device-status.md Milestone 목표, 범위, 기능 Task, 잠금 해제 기준
Code packages/go/config/config.go 현재 openai.model_routes[], adapter instance config, capacity/queue config 구조
Code apps/edge/internal/openai/routes.go /v1/modelsmodel_routes를 catalog처럼 노출하는 현재 외부 model 표면
Code apps/edge/internal/service/run_dispatch.go ModelGroupKey 기반 queue, candidate filtering, capacity policy의 현재 dispatch 기준
Code proto/iop/runtime.proto ProviderSnapshot의 provider 상태, capacity, in-flight, queued 기준
External Provider 없음 이번 Milestone은 외부 provider 상태를 변경하지 않고 IOP 내부 계약과 catalog 기준을 고정한다.
User Decision user_review_0.log D01-D06 resolved

State Machine

상태 진입 조건 다음 상태 근거
Model Accepted OpenAI-compatible model 또는 내부 실행 요청이 models[].id에 정의된 model id를 포함한다. Candidate Resolving agent-contract/provided/openai-compatible-api.md, SubmitRunRequest.ModelGroupKey
Candidate Resolving Edge가 models[].providers에서 provider id와 실제 served model name 매핑을 읽는다. Candidate Ready 또는 No Candidate packages/go/config/config.go, apps/edge/internal/service/run_dispatch.go
Provider Matched models[].providers의 provider id가 nodes[].providers[].id와 매칭되고, served model name이 해당 provider의 models[]에 존재한다. Candidate Ready 또는 No Candidate Edge config validation
Candidate Ready candidate가 enabled이고 health/capacity/in-flight 기준을 만족한다. Load Ranked provider snapshot, adapter instance capacity, queue policy
Load Ranked Edge가 available candidate의 in_flight / capacity load ratio를 계산한다. Target Rewritten 또는 Queued 낮은 load ratio 우선, 동률 시 deterministic tie-break
Target Rewritten Edge가 선택된 provider id의 served model name을 models[].providers[provider_id]에서 읽는다. Dispatched Edge-owned routing/control 책임
Queued 즉시 사용 가능한 slot이 없고 queue policy가 대기를 허용한다. Dispatched 또는 Timed Out ModelGroupKey queue, max_queue, queue_timeout_ms
Dispatched Edge가 선택한 node/provider와 concrete served target을 Node에 전달한다. Completed 또는 Failed Edge-Node run request, run event
Catalog Observed Node/Edge가 provider snapshot 또는 catalog 상태를 갱신한다. Available, Degraded, Unavailable health, capacity, in_flight, load_ratio, models, queued

Interface Contract

  • 계약 원문: agent-contract/provided/openai-compatible-api.md
  • 입력:
    • models[].id: OpenAI-compatible API의 model로 호출 가능한 model id이며, qwen3.6:35b 같은 형식을 유지한다.
    • models[].display_name: 운영 화면에서 보여줄 model 이름이다.
    • models[].providers: provider id를 key로, 해당 provider에서 실제 호출할 served model name을 value로 둔 map이다.
    • models[].providers.<provider_id>: nodes[].providers[].id와 매칭되는 provider id다.
    • models[].providers[<provider_id>]: provider가 실제로 제공하는 model id 또는 target profile이며, 해당 provider의 models[] list 안에 있어야 한다.
    • nodes[].id: provider를 소유하는 Node identity다.
    • nodes[].providers[]: provider 정의는 Node 아래에 둔다. 같은 Node 아래에 여러 provider가 있을 수 있다.
    • nodes[].providers[].id: models[].providers의 key로 참조되는 provider id다.
    • nodes[].providers[].type: provider runtime type이다. 예: ollama, vllm, lemonade, sglang, openai_api, cli.
    • nodes[].providers[].category: MVP provider category다. 값은 api, cli, local_inference로 시작한다.
    • nodes[].providers[].models: 해당 provider가 실제로 제공 가능한 served model name list다.
    • provider.health: available, unavailable, unknown 중 하나의 최소 provider health 상태다.
    • provider.capacity: provider가 동시에 처리할 수 있는 실행 slot 수다.
    • provider.in_flight: provider에서 현재 실행 중인 요청 수다.
    • provider.load_ratio: in_flight / capacity로 계산하는 선택 기준이다. capacity가 0이거나 알 수 없으면 선택 대상에서 제외하거나 unavailable로 본다.
    • provider.queued: Edge queue에서 관측 가능한 provider 또는 model group 대기 요청 수다.
    • provider.lifecycle_capabilities: provider별 model lifecycle capability를 coarse flags로 표시한다. 예: list_models, load_model, unload_model, pull_model, delete_model.
    • catalog.status: MVP에서는 health, capacity, in-flight, derived load ratio, model list, queued, coarse lifecycle capability를 표시한다. runtime process/container detail과 CPU/GPU/RAM/VRAM resource telemetry는 후속으로 둔다.
    • catalog.control: MVP에서는 읽기 전용 관찰과 Edge config 기반 routing 계약만 포함한다. runtime control은 후속 Milestone 책임이다.
  • 출력:
    • resolution.adapter: Node에 전달할 adapter type 또는 adapter instance key다.
    • resolution.target: Node adapter가 실행할 concrete served target이다.
    • resolution.node_id: 선택된 Node identity다.
    • resolution.provider_id: Edge가 선택한 provider identity다.
    • resolution.model_group_key: queue와 관측에 남길 models[].id다.
    • catalog.providers[]: 운영자가 provider pool과 provider 상태를 비교할 수 있는 표시 record다.
  • 금지:
    • OpenAI-compatible 외부 경계에서 model을 제거하거나 caller에게 adapter + target을 직접 요구하지 않는다.
    • models[]에 정의되지 않은 model id를 새 provider-pool 경로에서 암묵적으로 실행하지 않는다.
    • 단일 provider model이라도 별도 축약 구조를 만들지 않고 models[].providers에 provider 한 개만 둔다.
    • models[].providers에서 참조한 provider id가 nodes[].providers[].id에 없거나, served model name이 해당 provider의 models[]에 없으면 유효한 route로 보지 않는다.
    • capacity가 남았다는 이유만으로 더 높은 load ratio의 provider를 우선 선택하지 않는다.
    • MVP selection policy에 priority, weight, fallback policy를 필수 필드로 넣지 않는다.
    • Node/provider adapter가 catalog model id나 alias를 자체적으로 provider별 served model name으로 rewrite하지 않는다.
    • MVP catalog/status에 runtime process/container detail이나 CPU/GPU/RAM/VRAM resource telemetry를 필수 필드로 넣지 않는다.
    • MVP catalog에 lifecycle API 상세 동작, compatibility, benchmark, quality score, model별 qualification 결과를 직접 넣지 않는다.
    • MVP catalog/control 표면에 provider enable/disable, drain, fallback 우선순위 변경, capacity override 같은 runtime 제어를 넣지 않는다.
    • Control Plane을 Edge-owned provider 상태의 canonical store로 만들지 않는다.
    • SDD 본문에 agent-contract 원문을 복제하지 않는다.
    • qualification report, benchmark, 품질 비교를 이번 Milestone의 필수 구현으로 끌어오지 않는다.

Acceptance Scenarios

ID Milestone Task Given When Then
S01 alias-contract 운영자가 models[]qwen3.6:35b 같은 model id를 정의한다. OpenAI-compatible 요청 또는 내부 실행 요청이 해당 model id를 사용한다. model id는 queue와 catalog의 canonical key로 유지되고, dispatch 직전에만 provider별 served model name으로 해석된다.
S02 candidate-schema 하나의 models[] 항목에 여러 provider id와 served model name 매핑이 있다. provider pool schema를 검토한다. models[].providers가 provider id -> 실제 served model name map으로 정리되어 있고, provider 정의는 Node 아래 provider list로 분리되며, provider별 models[] list가 제공 가능 모델의 기준이 된다.
S03 target-rewrite provider마다 실제 served model id가 다르다. Edge가 candidate를 선택한다. Edge가 models[].providers[provider_id] 값을 concrete target으로 rewrite해 Node에 전달하고, Node/provider adapter는 전달받은 target만 실행한다.
S04 selection-policy 여러 candidate가 서로 다른 health, capacity, in-flight 값을 가진다. Edge가 실행 후보를 고른다. unavailable 후보를 제외하고 in_flight / capacity load ratio가 가장 낮은 provider를 우선 선택한다. 예: 1/3 provider가 2/3 provider보다 우선한다.
S05 pool-compat 기존 openai.model_routes, adapter + target, Node provider instance 설정이 존재한다. 새 pool 계약을 도입하거나 compat layer를 설계한다. 기존 route와 provider instance 설정의 호환/마이그레이션 방향이 정리되어 있다.
S06 category-map API, CLI, local inference provider가 같은 catalog에 노출된다. catalog 표시 필드를 검토한다. MVP category는 api, cli, local_inference로 정의되어 있다.
S07 device-status local inference provider가 health, capacity, in-flight, model list, queue 상태 일부를 제공한다. 운영자가 상태를 조회한다. MVP 상태 필드는 health, capacity, in_flight, derived load_ratio, models, queued이며 runtime/resource telemetry는 후속으로 분리되어 있다.
S08 lifecycle-cap Ollama/Lemonade와 vLLM/SGLang의 model lifecycle 동작이 다르다. catalog 또는 후속 report 입력을 설계한다. MVP catalog에는 coarse lifecycle capability flags만 표시하고 상세 lifecycle/compatibility/benchmark/quality/qualification 결과는 후속 Milestone으로 분리되어 있다.
S09 boundary adapter 구현, pool routing, 운영 catalog가 서로 다른 책임을 가진다. 구현 계획을 작성한다. provider adapter 구현, provider pool routing, read-only operations catalog, 후속 runtime control의 책임 경계가 분리되어 있다.
S10 ops-review SDD와 사용자 결정 항목이 준비되어 있다. 사용자가 MVP 범위와 2차 후보를 검토한다. D01-D06 결정이 user_review_0.log와 SDD에 반영되고 SDD 잠금이 해제되어 있다.

Evidence Map

Scenario Required Evidence agent-task 연결 Spec Completion 기대
S01 pool 계약 문서 또는 config/proto/API diff, OpenAI-compatible model id test agent-task/m-provider-catalog-device-status/... alias-contractmodels[].id canonical key와 dispatch resolution 기준을 충족했다는 근거
S02 candidate schema diff 또는 SDD/plan 확정 표, config validation test agent-task/m-provider-catalog-device-status/... candidate-schemamodels[].providers map, Node 하위 provider 정의, provider별 models[] list 검증 기준을 충족했다는 근거
S03 target rewrite 책임 문서, Edge/Node request mapping test agent-task/m-provider-catalog-device-status/... target-rewrite가 Edge-owned routing/control 원칙을 따르고 concrete target 전달을 검증했다는 근거
S04 queue/selection policy test 또는 smoke, timeout/overflow case evidence agent-task/m-provider-catalog-device-status/... selection-policy가 available provider 중 낮은 in_flight / capacity load ratio를 우선하고, 동률 tie-break와 queue timeout을 검증했다는 근거
S05 migration/compat note, 기존 model_routes regression test agent-task/m-provider-catalog-device-status/... pool-compat가 기존 OpenAI route와 Node provider instance 설정을 깨지 않는다는 근거
S06 catalog DTO/API/UI/CLI 표시 evidence agent-task/m-provider-catalog-device-status/... category-mapapi, cli, local_inference category를 확인했다는 근거
S07 provider snapshot/status test, unknown/unavailable case evidence agent-task/m-provider-catalog-device-status/... device-status가 health/capacity/in-flight/load-ratio/models/queued 범위를 검증하고 runtime/resource telemetry를 후속으로 분리했다는 근거
S08 lifecycle capability 표 또는 follow-up handoff evidence agent-task/m-provider-catalog-device-status/... lifecycle-cap이 coarse flags로 catalog에 표시되고 상세 qualification 항목은 후속 Milestone으로 분리되었다는 근거
S09 architecture boundary note, package/API ownership evidence agent-task/m-provider-catalog-device-status/... boundary가 adapter, routing, read-only catalog, 후속 runtime control 책임을 분리했다는 근거
S10 user_review_0.log 해결 log 또는 사용자 승인 기록 agent-task/m-provider-catalog-device-status/... ops-review가 완료되어 SDD 잠금 해제 상태를 확인했다는 근거

Cross-repo Dependencies

  • 없음

Drift Check

  • Milestone 기능 Task와 Acceptance Scenario가 일치한다.
  • Evidence Map이 plan/code-review/complete.log에서 검증 가능하다.
  • agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
  • 열린 사용자 리뷰가 없고 해결된 리뷰는 user_review_0.log에 남겼다.

사용자 리뷰 이력

  • user_review_0.log: D01-D06 결정 반영, SDD 잠금 해제

작업 컨텍스트

  • 표준선: 외부 OpenAI-compatible 경계는 model을 유지하고, 내부 실행은 adapter + target으로 resolve한다. Edge는 queue와 dispatch를 담당하며, Edge-owned 상태의 canonical store는 Control Plane이 아니라 Edge/Node 쪽에 둔다.
  • 후속 SDD: 없음. Provider-Device-Model Qualification 리포트 Milestone에서 lifecycle capability, benchmark, 품질 비교 저장/조회가 구현 범위가 되면 별도 SDD 필요 여부를 다시 판정한다.