173 lines
6.1 KiB
Markdown
173 lines
6.1 KiB
Markdown
# Edge Local Quickstart
|
|
|
|
이 문서는 Edge를 로컬에서 빌드하고 실행해 Node를 연결하고, OpenAI-compatible smoke까지 확인하는 최소 절차다.
|
|
|
|
설정 기준은 `edge.yaml`이다. 주소는 환경 변수로 흩뿌리지 않는다.
|
|
|
|
## 1. Package
|
|
|
|
```bash
|
|
make build
|
|
```
|
|
|
|
## 2. Edge 설정
|
|
|
|
```bash
|
|
rm -rf "$HOME/iop-edge-test"
|
|
mkdir -p "$HOME/iop-edge-test"
|
|
tar -xzf build/packages/iop-edge-<platform>.tar.gz -C "$HOME/iop-edge-test"
|
|
cd "$HOME/iop-edge-test/iop-edge-<platform>"
|
|
./iop-edge config init
|
|
```
|
|
|
|
`edge.yaml`에서 아래 값만 맞춘다. 모델만 필요하면 바꾼다.
|
|
|
|
### Provider-first 구성 (권장)
|
|
|
|
Provider-first는 `models[]`로 라우팅 키를 정의하고 `nodes[].providers[]`로 provider 후보를 선언한다. 두 구조를 `models[].providers[provider_id]` 키로 연결한다.
|
|
|
|
```yaml
|
|
models:
|
|
# Top-level catalog: canonical routing key → provider-pool mapping.
|
|
# models[].id is the external model id; providers maps provider id → served model.
|
|
- id: "gemma4:26b"
|
|
providers:
|
|
ollama-gemma: "gemma4:26b"
|
|
|
|
edge:
|
|
id: "edge-1"
|
|
name: "Edge 1"
|
|
|
|
server:
|
|
listen: "0.0.0.0:19090"
|
|
|
|
bootstrap:
|
|
listen: "0.0.0.0:18080"
|
|
artifact_dir: "artifacts"
|
|
|
|
refresh:
|
|
enabled: true
|
|
listen: "127.0.0.1:19093"
|
|
|
|
# Legacy adapter/target fallback (backward compat only).
|
|
# New deploys should use models[] + nodes[].providers[].
|
|
openai:
|
|
enabled: true
|
|
listen: "0.0.0.0:18081"
|
|
adapter: "ollama"
|
|
target: "gemma4:26b"
|
|
|
|
nodes:
|
|
- id: "node-ollama-1"
|
|
agent_kind: "generic-node"
|
|
providers:
|
|
- id: "ollama-gemma"
|
|
type: "ollama"
|
|
category: "local_inference"
|
|
base_url: "http://127.0.0.1:11434"
|
|
models:
|
|
- "gemma4:26b"
|
|
capacity: 2
|
|
```
|
|
|
|
`models[]`를 사용할 경우 `openai.adapter`/`openai.target`은 하향 호환 fallback이다. 실제 routing은 `nodes[].providers[].id`를 기준으로 provider-pool에서 선택된다.
|
|
|
|
확인:
|
|
|
|
```bash
|
|
./iop-edge --config edge.yaml env
|
|
./iop-edge --config edge.yaml config check
|
|
```
|
|
|
|
## 3. Node 등록
|
|
|
|
```bash
|
|
./iop-edge --config edge.yaml node register node-ollama-1 \
|
|
--adapter ollama \
|
|
--ollama-base-url http://127.0.0.1:11434
|
|
```
|
|
|
|
출력된 OS별 bootstrap 명령 원문을 보관한다. 명령 원문에는 실제 token이 포함되므로 tracked 문서에는 기록하지 않는다.
|
|
|
|
## 4. Edge 실행
|
|
|
|
```bash
|
|
mkdir -p logs run
|
|
nohup ./iop-edge --config edge.yaml serve > logs/edge.stdout.log 2>&1 &
|
|
echo $! > run/iop-edge.pid
|
|
```
|
|
|
|
확인:
|
|
|
|
```bash
|
|
# Control Plane에 연결된 Edge 상태 조회
|
|
curl -fsS http://<control-plane-host>:18000/edges
|
|
```
|
|
|
|
## 5. Node 실행
|
|
|
|
3단계에서 출력된 bootstrap 명령을 Node host에서 그대로 실행한다. Linux/macOS는 generated `curl | bash` 명령을 사용하고, Windows native PowerShell은 generated `.ps1` bootstrap과 `Start-IopNode` 함수를 사용한다.
|
|
|
|
Node 연결 확인:
|
|
|
|
```bash
|
|
curl -fsS http://<control-plane-host>:18000/edges/<edge-id>/status
|
|
```
|
|
|
|
## 6. 기본 Smoke
|
|
|
|
```bash
|
|
curl -fsS http://<edge-host>:18081/v1/models
|
|
|
|
./iop-edge --config edge.yaml smoke openai \
|
|
--model gemma4:26b \
|
|
--base-url http://<edge-host>:18081 \
|
|
--timeout 60s
|
|
```
|
|
|
|
외부 OpenAI-compatible client base URL:
|
|
|
|
```text
|
|
http://<edge-host>:18081/v1
|
|
```
|
|
|
|
## 7. Thinking/Reasoning 제어 smoke
|
|
|
|
`/v1/chat/completions` 요청은 `think`, `reasoning_effort`, `thinking_token_budget`, `include_reasoning`으로 thinking/reasoning 동작과 응답 노출을 제어할 수 있다. 단, provider-pool pure `passthrough`는 provider body 보존이 우선이므로 `include_reasoning=false`만으로 IOP-side reasoning 제거를 보장하지 않는다.
|
|
|
|
- dev-corp `gemma4:26b` provider-pool 안정 smoke: `think`, `reasoning_effort`, `thinking_token_budget`을 생략하고 현재 provider/vLLM 기본값을 유지한다.
|
|
- 일반 표준 caller의 `stream=false` 측정은 `/v1/chat/completions`에서 요청 파라미터만으로 확인한다.
|
|
- `include_reasoning=false`는 non-provider normalized route의 hide 동작 기준이다. dev-corp `gemma4:26b` provider-pool pure `passthrough`에서는 client가 reasoning field를 선택적으로 무시/제거한다.
|
|
- `think=false` 또는 `reasoning_effort=none`은 hide-only 옵션이 아니라 thinking disable 요청이다. dev-corp `gemma4:26b` 기본 안정 smoke에서는 쓰지 않는다.
|
|
- 세부 표와 금지/허용 범위는 `agent-contract/outer/openai-compatible-api.md`의 dev-corp `gemma4:26b` provider-pool passthrough 파라미터 범위를 기준으로 한다.
|
|
|
|
예시 (dev-corp `gemma4:26b` provider-pool non-stream 측정, think 생략):
|
|
|
|
```bash
|
|
curl -fsS http://<edge-host>:18081/v1/chat/completions \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Bearer <token>' \
|
|
-d '{"model":"gemma4:26b","messages":[{"role":"user","content":"hello"}],"stream":false}'
|
|
```
|
|
|
|
예시 (non-provider normalized route에서 response reasoning_content 숨김):
|
|
|
|
```bash
|
|
curl -fsS http://<edge-host>:18081/v1/chat/completions \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"model":"<model-alias>","messages":[{"role":"user","content":"hello"}],"include_reasoning":false}'
|
|
```
|
|
|
|
## 8. Raw text tool-call boundary smoke
|
|
|
|
Pi/Cline형 긴 agent prompt와 `tools[]` 요청은 provider가 native `tool_calls` 대신 assistant content에 raw 블록을 담아 응답할 수 있다. 계약 기준은 `agent-contract/outer/openai-compatible-api.md`의 Chat Completions raw text tool-call 정규화 정책이다.
|
|
|
|
요청 payload는 tracked 문서에 secret 없이 남기고, token은 원격 환경 변수에서 주입한다. 실제 token 원문을 명령/로그/보고에 남기지 않는다.
|
|
|
|
판정 기준:
|
|
|
|
- 응답 body와 SSE delta 어디에도 raw tool block 원문이 성공 content로 남지 않는다.
|
|
- 요청 `tools[]`에 있는 valid tool-call은 `message.tool_calls` 또는 stream `delta.tool_calls`와 `finish_reason: "tool_calls"`로 정규화된다.
|
|
- 요청 `tools[]`에 없는 unknown tool hallucination이나 malformed 블록은 success content가 아니라 `tool_validation_error`로 끝난다.
|
|
|
|
evidence는 tracked 문서가 아니라 ignored run 위치(`agent-test/runs/**`) 또는 code-review output path에 저장한다.
|