180 lines
18 KiB
Markdown
180 lines
18 KiB
Markdown
---
|
|
test_env: dev-corp
|
|
test_profile: edge-smoke
|
|
domain: edge
|
|
verification_type: smoke
|
|
last_rule_updated_at: 2026-07-11
|
|
---
|
|
|
|
# edge-smoke dev-corp 테스트
|
|
|
|
## 읽기 조건
|
|
|
|
- `apps/edge/**` 변경 또는 dev-corp Edge registry, transport, service, OpenAI-compatible/A2A 입력 표면 검증 판단이 필요한 경우
|
|
|
|
## 적용 범위
|
|
|
|
- `apps/edge/cmd/edge/**`
|
|
- `apps/edge/internal/bootstrap/**`
|
|
- `apps/edge/internal/transport/**`
|
|
- `apps/edge/internal/service/**`
|
|
- `apps/edge/internal/events/**`
|
|
- `apps/edge/internal/input/**`
|
|
- `apps/edge/internal/openai/**`
|
|
- `apps/edge/internal/opsconsole/**`
|
|
- `apps/edge/internal/node/**`
|
|
- dev-corp Edge host, provider pool config, OpenAI-compatible model alias routing
|
|
|
|
## 분류
|
|
|
|
- domain: edge
|
|
- verification_type: smoke
|
|
- scope: dev-corp Edge 실행 그룹, provider pool, input surface baseline
|
|
|
|
## 환경
|
|
|
|
- host: local checkout. provider pool과 source/build evidence가 필요하면 mac-mini `ssh fe@172.24.63.178`의 `/Users/fe/agent-work/iop-dev-corp` checkout을 사용한다.
|
|
- Edge runtime evidence: public `iop.ai.kr` host를 기준으로 한다.
|
|
- port: compose Edge-Node TCP transport `19006`; native provider-pool Edge-Node TCP 후보 `18087`; artifact/bootstrap HTTP 후보 `18085`; Edge OpenAI-compatible HTTP 후보 `18086`; Edge metrics 후보 `19102`; admin 후보 `19094`.
|
|
- runtime: Go `1.24`
|
|
- package manager: Go modules / Makefile
|
|
- docker: unit/smoke quick check는 Docker를 요구하지 않는다. compose dev-corp 검증은 mac-mini에서 `.env.dev-corp.example` 기준으로 수행한다.
|
|
- external service: dev-corp artifact/base URL 기본 후보 `http://iop.ai.kr:18085`, dev-corp Edge runtime 기본 후보 `iop.ai.kr:18087`; mac-mini local endpoint는 dev-corp Edge 경로로 사용하지 않는다.
|
|
- model endpoint: dev-corp OpenAI-compatible base URL 기본 후보 `http://digitalplatform.iop.ai.kr:18086/v1`
|
|
- credential: token/secret/API key 원문은 문서에 기록하지 않는다.
|
|
|
|
## dev-corp provider pool 인벤토리
|
|
|
|
dev-corp provider pool과 3-node 연결 상태를 점검할 때는 `agent-test/dev-corp/inventory.yaml`의 machine-readable 값을 우선한다. Edge runtime은 public `iop.ai.kr`이며, mac-mini checkout은 source/build/provider SSH runner로만 사용한다.
|
|
|
|
- Edge host: `iop.ai.kr` / `115.21.224.82`
|
|
- Edge config: public host runtime config at `/Users/toki/agent-work/iop-dev-corp/build/dev-corp-runtime/edge.yaml`.
|
|
- Edge id: `dev-corp-edge`
|
|
- Control Plane HTTP/status 후보: `http://iop.ai.kr:18002`, `http://iop.ai.kr:18002/edges/dev-corp-edge/status` when the public port is enabled
|
|
- Control Plane-Edge wire 후보: `iop.ai.kr:19005` when the public port is enabled
|
|
- bootstrap HTTP 기본 후보: `http://iop.ai.kr:18085`
|
|
- Edge OpenAI-compatible base URL 기본 후보: `http://digitalplatform.iop.ai.kr:18086/v1`
|
|
- Edge-Node TCP transport 기본 후보: `iop.ai.kr:18087`
|
|
- mac-mini/internal 후보는 dev-corp Edge 경로가 아니다. Node `edge_addr`는 `iop.ai.kr:18087`이어야 한다.
|
|
- model alias 후보: `gemma4:26b`
|
|
- host Pi dev-corp profile: `agent-test/dev-corp/inventory.yaml`의 `model.pi_agent_profile` 기준. 2026-07-10 현재 Pi 기본 provider/model/thinking level은 `dev-corp` / `gemma4:26b` / `high`이며, base URL은 public Edge route `http://digitalplatform.iop.ai.kr:18086/v1`이고 sampling parameter는 Pi extension으로 `temperature=0.2`, `top_p=0.95`를 주입한다. dev `qwen3.6:35b` Pi profile은 `agent-test/dev/inventory.yaml`에서 별도로 관리한다.
|
|
|
|
노드 후보:
|
|
|
|
- DGX Spark 01 vLLM node: `corp-dgx-spark-01-vllm-node` / `corp-dgx-spark-01-vllm`
|
|
- SSH/user: mac-mini에서 `ssh digitalcommerce_dgx_spark_01@192.168.2.2`
|
|
- provider endpoint: `http://192.168.2.2:8002/v1`
|
|
- Edge adapter endpoint: node-local `http://127.0.0.1:8002/v1`
|
|
- Edge connectivity: direct public Edge `iop.ai.kr:18087`.
|
|
- served model: `gemma-4-26B-A4B-it-NVFP4`
|
|
- capacity baseline 후보: `4`
|
|
- runtime: tmux `vllm_server_8002`, start script `/home/digitalcommerce_dgx_spark_01/start_vllm_8002.sh`, `vllm=0.24.0`, `PATH=/home/digitalcommerce_dgx_spark_01/vllm_env_0_24_0/bin:$PATH`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /home/digitalcommerce_dgx_spark_01/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`, 2026-07-08 startup log GPU KV cache `1,453,705` tokens / full-context concurrency `5.55x`, `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304`
|
|
- DGX Spark 02 vLLM node: `corp-dgx-spark-02-vllm-node` / `corp-dgx-spark-02-vllm`
|
|
- SSH/user: mac-mini에서 `ssh dplab@192.168.2.4`
|
|
- provider endpoint: `http://192.168.2.4:8004/v1`
|
|
- Edge adapter endpoint: node-local `http://127.0.0.1:8004/v1`
|
|
- Edge connectivity: direct public Edge `iop.ai.kr:18087`.
|
|
- served model: `gemma-4-26B-A4B-it-NVFP4`
|
|
- capacity baseline 후보: `4`
|
|
- runtime: Docker container `vllm-gemma4`, start script `/home/dplab/start_vllm_gemma4_8004.sh`, host `8004` -> container `8004`, image `vllm/vllm-openai:v0.24.0`, `vllm=0.24.0`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--chat-template /vllm-workspace/examples/tool_chat_template_gemma4.jinja`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`, 2026-07-08 startup log GPU KV cache `1,452,633` tokens / full-context concurrency `5.54x`, `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304`
|
|
- Mac Studio vLLM-MLX node: `corp-mac-studio-mlx-vllm-node` / `corp-mac-studio-mlx-vllm`
|
|
- SSH/user: mac-mini에서 `ssh dc_dev@192.168.2.3`
|
|
- provider endpoint: `http://192.168.2.3:8004/v1`
|
|
- Edge adapter endpoint: node-local `http://127.0.0.1:8004/v1`
|
|
- Edge provider catalog type: `openai_compat`; provider runtime type remains `vllm-mlx`.
|
|
- served model: `mlx-community/gemma-4-26b-a4b-it-nvfp4`
|
|
- capacity baseline 후보: `5` (provider catalog capacity; current runtime headroom `--max-num-seqs 6`)
|
|
- runtime: `vllm-mlx=0.4.0`, start script `/Users/dc_dev/iop-dev-corp-field/start_vllm_mlx_8004.sh`, python `/Users/dc_dev/vllm-env-0.4.0/bin/python`, `--continuous-batching`, `--max-num-seqs 6`, `--prefill-batch-size 6`, `--completion-batch-size 6`, `--chunked-prefill-tokens 1024`, `--disable-prefix-cache`, `--max-kv-size 786432`, `--max-request-tokens 262144`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`
|
|
- process manager: 2026-06-25 기준 detached `screen` session `vllm_mlx_8004`; `DYLD_LIBRARY_PATH=/opt/homebrew/opt/expat/lib` 필요
|
|
|
|
Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는 확인된 secondary provider 후보지만, 기본 provider pool에는 넣지 않는다. 별도 alias와 capacity policy가 결정된 뒤 추가한다.
|
|
|
|
## provider runtime 설정/검증 상태
|
|
|
|
- DGX Spark 01 provider runtime은 capacity `4`, context window `262144`, requested KV `262144x2` 이상의 기준으로 재설정했다. dev-corp DGX01 vLLM 기준으로는 `vllm=0.24.0`, `--max-num-seqs 4`, `--max-model-len 262144`, `--gpu-memory-utilization 0.40`, `--enforce-eager`, text-only multimodal limits, `--default-chat-template-kwargs '{"enable_thinking":true}'`, `VLLM_MAX_TOKENS_PER_EXPERT_FP4_MOE=4194304` 조합이며, 2026-07-08 startup log에서 GPU KV cache `1,453,705` tokens와 `262144` tokens/request concurrency `5.55x`를 확인했다.
|
|
- DGX Spark 02 provider runtime은 capacity `4`, context window `262144`, requested KV `262144x2` 이상의 기준으로 설정됐다. Docker `vllm-gemma4`는 host/container `8004`, image `vllm/vllm-openai:v0.24.0`, text-only/eager, `--default-chat-template-kwargs '{"enable_thinking":true}'` 기준으로 동작하며 2026-07-08 startup log에서 GPU KV cache `1,452,633` tokens와 `262144` tokens/request concurrency `5.54x`를 확인했다.
|
|
- DGX Spark 01은 0.24.0 venv의 toolchain을 사용하므로 start script에 `PATH=/home/digitalcommerce_dgx_spark_01/vllm_env_0_24_0/bin:$PATH`를 둔다.
|
|
- Gemma4 agent/tool-call compatibility profile은 DGX Spark 01/02 vLLM에서 `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, Gemma4 tool chat template, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`, `--enforce-eager`, `--skip-mm-profiling`, `--limit-mm-per-prompt '{"image": 0, "video": 0}'`, `--mm-processor-cache-gb 0`을 함께 둔다. Mac Studio vLLM-MLX는 별도 chat template override 없이 `--continuous-batching`, `--disable-prefix-cache`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`를 둔다. Qwen provider는 dev-runtime 문서의 Qwen 전용 parser/template 값을 따른다.
|
|
- Mac Studio provider runtime은 `vllm-mlx=0.4.0`, provider catalog capacity `5`, context window `262144`, requested KV `262144x3` 기준으로 `--continuous-batching`, runtime headroom `--max-num-seqs 6`, `--prefill-batch-size 6`, `--completion-batch-size 6`, `--chunked-prefill-tokens 1024`, `--disable-prefix-cache`, `--max-request-tokens 262144`, `--max-kv-size 786432`, `--enable-auto-tool-choice`, `--tool-call-parser gemma4`, `--reasoning-parser gemma4`, `--default-chat-template-kwargs '{"enable_thinking":true}'`를 적용했고 `/health`, `/v1/models`, 직접 API non-stream/stream auto tool-call, streaming multi-turn tool-result final answer, Pi `-p` tool-call, Pi TUI 초기 프롬프트 tool-call 로그 종료를 확인했다.
|
|
- Mac Studio vLLM-MLX의 위 값은 2026-07-08 기준 구동 가능한 최종 체크포인트다. 잔여 이슈로 Gemma4 thought channel delimiter가 최종 content에 누수될 수 있으며, 이 경우 runtime option 미세 조정보다 vLLM-MLX Gemma provider 전용 Pi extension/provider adapter sanitizer를 우선 검토한다. 추가 튜닝은 Spark vLLM 설정과 분리된 별도 실험으로만 수행한다.
|
|
- 2026-07-08 재확인 기준 DGX Spark 01은 mac-mini 내부 endpoint `http://192.168.2.2:8002`에서 `/health` 200과 `/v1/models`, 직접 API forced/auto/streaming tool-call smoke, 로컬 Pi TUI bash/git-push tool-call 흐름을 통과했다. DGX Spark 02는 mac-mini 내부 endpoint `http://192.168.2.4:8004`에서 `/health` 200과 `/v1/models`, 직접 API auto/streaming tool-call smoke를 통과했다. 이때의 `/v1/responses` capacity 결과는 mac-mini provider-pool runtime 기준 legacy evidence이며, 2026-07-09 public Edge 표준 smoke는 `/v1/chat/completions` 15개 동시 요청이다.
|
|
- Gemma provider-pool `gemma4:26b`는 `default_thinking_token_budget: 1024` 기준으로 thinking을 기본 활성화한다. Edge strict output이 켜져 있어도 provider-pool catalog의 thinking policy가 우선하며, vLLM/vLLM-MLX adapter에는 `chat_template_kwargs.enable_thinking=true`로 전달되는지 확인한다.
|
|
- Gemma provider를 Pi/Cline형 agent/tool-call 용도로 검증할 때는 일반 chat smoke와 별도로 forced tool call, auto tool call, streaming `delta.tool_calls`, multi-turn tool result 후 최종 답변을 확인한다. raw `<|tool_call>`/`<|"|>` marker나 thought channel text가 assistant content로 새면 provider parser/template profile 또는 Edge relay 경계 문제로 판정한다.
|
|
- Gemma provider-pool의 IOP queue timeout은 두지 않는다. config 값은 `queue_timeout_ms=0`이며, caller context cancellation 또는 연결 종료로만 queued request를 중단한다. OpenAI run timeout과 backend request timeout은 long reasoning/long-context 요청을 위해 각각 `openai.timeout_sec=1800`, `request_timeout_ms=1800000`으로 둔다.
|
|
|
|
## 2026-07-09 dev-corp public Edge runtime 상태
|
|
|
|
- Active Edge runtime is `iop.ai.kr` (`115.21.224.82`) with public `18085` bootstrap, `18086` OpenAI-compatible, and `18087` Edge-Node TCP.
|
|
- mac-mini checkout/runtime is a runner and must not be used as Edge source of truth unless explicitly doing a local-runner comparison.
|
|
- On 2026-07-09 the three provider nodes were moved from mac-mini/reverse-tunnel Edge addresses to `iop.ai.kr:18087`, and public `/v1/chat/completions` 15-concurrency smoke passed 15/15.
|
|
- On 2026-07-09 after rebuilding the public Edge from the current passthrough source, default streaming `/v1/chat/completions` preserved provider reasoning deltas for 15/15 concurrent requests; transformed `chatcmpl-manual` IDs were 0/15. Evidence: `build/dev-corp-runtime/logs/public_passthrough_chat_15_20260709_180115.json`.
|
|
- On 2026-07-09 after deploying latest node binaries to DGX Spark 01/02 and Mac Studio, public streaming `/v1/chat/completions` again passed 15/15 with provider reasoning deltas preserved and transformed `chatcmpl-manual` IDs 0/15. Evidence: `build/dev-corp-runtime/logs/public_latest_edge_node_chat_15_20260709_181222.json`.
|
|
- Mac Studio provider catalog `type`은 최신 config validator 기준으로 `openai_compat`를 사용한다. 실제 provider runtime은 vLLM-MLX이고 `runtime_type: vllm-mlx`로 추적한다.
|
|
- `/v1/chat/completions` capacity smoke 표준: 15개 동시 요청을 public `http://digitalplatform.iop.ai.kr:18086/v1`로 보낸다. 2026-07-09 public Edge 재연결 검증에서는 15/15 성공했다.
|
|
- `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 provider-pool capacity 성공 기준에서 제외한다.
|
|
|
|
## 명령
|
|
|
|
- setup:
|
|
- lint:
|
|
- unit: `go test ./apps/edge/...`
|
|
- smoke: `./scripts/e2e-smoke.sh`는 기본 포트 임시 설정을 쓰는 보조 smoke이므로 dev-corp 포트 override 필요 여부를 먼저 확인한다.
|
|
- e2e: `make test-e2e`는 보조 smoke이며 full-cycle 실제 구동을 대체하지 않는다.
|
|
- model: dev-corp OpenAI-compatible profile을 띄운 경우 `OPENAI_API_KEY=$(cat build/dev-corp-runtime/.secrets/openai_api_key) iop-edge smoke openai --model gemma4:26b --base-url http://digitalplatform.iop.ai.kr:18086`
|
|
- direct-provider: mac-mini에서 `curl -fsS http://192.168.2.2:8002/v1/models`, `curl -fsS http://192.168.2.4:8004/v1/models`, `curl -fsS http://192.168.2.3:8004/v1/models`
|
|
- full-cycle: repo 내부 edge-node 진단, `iop-edge smoke openai`, OpenAI-compatible 입력 표면 수동 검증
|
|
|
|
## 필수 검증
|
|
|
|
- 변경한 edge 패키지 또는 `go test ./apps/edge/...`를 실행한다.
|
|
- registry, service, transport, console, HTTP/A2A 입력 표면을 바꾼 경우 edge-node 메시지 2회 왕복과 command 응답을 확인한다.
|
|
- OpenAI-compatible 경계를 바꾼 경우 dev-corp `18086` 기준 `iop-edge smoke openai` 또는 동등한 `/healthz`, `/v1/models`, `/v1/chat/completions` 확인으로 edge service와 node adapter 경로 수렴을 확인한다. provider-pool `/v1/responses` 미지원은 실패로 보지 않는다.
|
|
- provider pool config 변경 전 mac-mini에서 세 기본 provider endpoint의 `/health`와 `/v1/models`가 성공하는지 확인한다.
|
|
- DGX Spark 02가 provider port down과 SSH banner exchange timeout을 동시에 보이면 provider runtime 추가 조작을 보류하고, SSH 회복 후 process/log, `/health`, `/v1/models`, Edge OpenAI-compatible smoke를 순서대로 재검증한다.
|
|
- bootstrap/artifact 경계를 바꾼 경우 dev-corp artifact/base URL 후보 `18085`가 local/test/dev field baseline을 덮어쓰지 않는지 확인한다.
|
|
|
|
## 보조 검증
|
|
|
|
- `./scripts/e2e-smoke.sh`는 edge-node 최소 생존 확인에 사용한다.
|
|
- `./scripts/e2e-openai-ollama.sh`는 OpenAI-compatible 입력 표면 보조 확인에 사용할 수 있으나 provider pool capacity 검증을 대체하지 않는다.
|
|
|
|
## 판정 기준
|
|
|
|
- node 등록, `/nodes`, console 메시지 전송, 기대 payload를 포함한 `[node-*-message]` 출력, 같은 run의 complete event가 확인된다.
|
|
- node 로컬 `[node-message]` payload 라인 목록과 edge `[node-*-message]` payload 라인 목록이 run별로 내용/순서까지 동일해야 한다.
|
|
- edge complete는 같은 run의 마지막 `[node-*-message]` 이후에만 정상이다.
|
|
- OpenAI-compatible smoke에서 `/healthz`, `/v1/models`, `/v1/chat/completions`가 기대 상태로 응답한다. provider-pool `/v1/responses`는 현재 미지원이다.
|
|
- dev-corp provider-pool capacity smoke는 현재 `/v1/chat/completions`에 15개 동시 요청을 보낸다. `/v1/responses`는 OpenAI-compatible provider model group raw passthrough parity 전까지 미지원이므로 capacity 성공 기준에서 제외한다.
|
|
- capacity smoke 완료 후 대상 provider의 `in_flight=0`, `queued=0` 회복을 확인한다.
|
|
- Gemma 계열 provider-pool smoke는 thinking enabled 기준이며 reasoning/tool-parser 관련 텍스트가 포함될 수 있다. exact-output match를 기본 판정으로 쓰지 않는다.
|
|
|
|
## 기준 출력 예시
|
|
|
|
```text
|
|
curl -fsS http://192.168.2.2:8002/v1/models
|
|
curl -fsS http://192.168.2.4:8004/v1/models
|
|
curl -fsS http://192.168.2.3:8004/v1/models
|
|
```
|
|
|
|
## 차단 기준
|
|
|
|
- mac-mini host 또는 Edge-Node TCP 후보 port 접근이 불가능하다.
|
|
- mac-mini에 `/Users/fe/agent-work/iop-dev-corp` checkout이 없어 dev-corp runtime artifact를 만들 수 없다.
|
|
- provider endpoint `192.168.2.2:8002`, `192.168.2.4:8004`, `192.168.2.3:8004` 중 필수 endpoint가 닫혀 있다.
|
|
- 외부 CLI profile 검증에 필요한 CLI 설치, 계정, provider 상태가 없다.
|
|
- dev-corp 포트가 local/test/dev baseline과 충돌한다.
|
|
|
|
## 보고 항목
|
|
|
|
- 실행한 명령:
|
|
- 성공한 검증:
|
|
- 실패/차단된 검증:
|
|
- 생략 사유:
|
|
- 남은 위험:
|
|
|
|
## 금지 사항
|
|
|
|
- secret, token, API key 원문은 tracked 파일에 기록하지 않는다.
|
|
- mac-mini에서 다시 도달 가능한 provider endpoint를 확인하지 않고 Edge provider config 성공을 선언하지 않는다.
|
|
- 사용자가 명시적으로 요청하지 않았는데 mac-mini local endpoint를 Edge runtime, Node `edge_addr`, bootstrap 기본 URL, OpenAI-compatible base URL로 사용하지 않는다.
|
|
- field baseline 포트(`18080`, `18081`, `19090`, `19092`)나 dev 포트(`18082`, `18083`, `19003`, `19101`)를 dev-corp 전용 포트로 재사용하지 않는다.
|