146 lines
7.3 KiB
Markdown
146 lines
7.3 KiB
Markdown
# dev-corp OpenAI-Compatible Direct Call Guide
|
|
|
|
이 문서는 dev-corp public Edge를 OpenAI-compatible HTTP client에서 직접 호출할 때의 사람용 가이드다. 계약 원문은 `agent-contract/outer/openai-compatible-api.md`이며, 여기서는 `digitalplatform-iop.cloud` 외부 호출에 필요한 값과 dev-corp `gemma4:26b` provider-pool 한계만 정리한다. Pi coding agent 설정은 `docs/dev-corp-pi-settings-guide.md`를 따른다.
|
|
|
|
## 대상 범위
|
|
|
|
- 환경: dev-corp public Edge
|
|
- Base URL: `http://digitalplatform-iop.cloud:18086/v1`
|
|
- 기본 endpoint: `POST /v1/chat/completions`
|
|
- 모델 alias: `gemma4:26b`
|
|
- 인증: `Authorization: Bearer <token>`
|
|
- 기준 호출 방식: OpenAI-compatible Chat Completions 표준 HTTP 요청
|
|
|
|
`/v1/responses`는 dev-corp `gemma4:26b` provider-pool에서 raw passthrough parity 전까지 지원하지 않는다. 외부 표준 호출은 `/v1/chat/completions`를 기준으로 한다.
|
|
|
|
## 기본 설정
|
|
|
|
| 항목 | 값 |
|
|
| --- | --- |
|
|
| Base URL | `http://digitalplatform-iop.cloud:18086/v1` |
|
|
| Models endpoint | `GET /v1/models` |
|
|
| Chat endpoint | `POST /v1/chat/completions` |
|
|
| Model | `gemma4:26b` |
|
|
| Content-Type | `application/json` |
|
|
| Authorization | `Bearer <token>` |
|
|
| Response mode | `metadata.iop_response_mode` 생략, 기본 `passthrough` |
|
|
| Streaming | client가 SSE를 처리할 수 있으면 `stream:true`, 아니면 `stream:false` |
|
|
|
|
토큰 원문은 tracked 문서, 예시 파일, 로그에 남기지 않는다.
|
|
|
|
## 권장 요청
|
|
|
|
가장 안정적인 기본 요청은 `think`, `reasoning_effort`, `thinking_token_budget`을 직접 지정하지 않는 형태다. 이렇게 호출하면 dev-corp `gemma4:26b` provider-pool의 현재 catalog/runtime 기본값을 유지한다.
|
|
|
|
```bash
|
|
curl -fsS http://digitalplatform-iop.cloud:18086/v1/chat/completions \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Bearer <token>' \
|
|
-d '{
|
|
"model": "gemma4:26b",
|
|
"messages": [
|
|
{
|
|
"role": "user",
|
|
"content": "간단히 현재 호출이 정상인지 확인해줘."
|
|
}
|
|
],
|
|
"stream": false
|
|
}'
|
|
```
|
|
|
|
Streaming이 필요한 client는 `stream:true`를 명시하고 SSE `data:` chunk를 처리한다.
|
|
|
|
```bash
|
|
curl -N http://digitalplatform-iop.cloud:18086/v1/chat/completions \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Bearer <token>' \
|
|
-d '{
|
|
"model": "gemma4:26b",
|
|
"messages": [
|
|
{
|
|
"role": "user",
|
|
"content": "한 문장으로 응답해줘."
|
|
}
|
|
],
|
|
"stream": true
|
|
}'
|
|
```
|
|
|
|
## 파라미터 기준
|
|
|
|
| 파라미터 | 권장값 | 이유 |
|
|
| --- | --- | --- |
|
|
| `model` | `gemma4:26b` | dev-corp provider-pool의 외부 alias다. |
|
|
| `stream` | client 처리 방식에 맞게 `false` 또는 `true` | `false`는 JSON body, `true`는 SSE stream을 반환한다. |
|
|
| `think` | 생략 | 현재 Gemma4 runtime은 thinking enabled 기준으로 튜닝되어 있다. |
|
|
| `reasoning_effort` | 생략 | `none`은 thinking disable 의도라 기본 안정 호출에 맞지 않는다. |
|
|
| `thinking_token_budget` | 생략 | 생략하면 IOP catalog의 dev-corp `gemma4:26b` 기본 thinking budget을 사용한다. 명시하면 최적화된 기본값을 바꾸는 측정이 된다. |
|
|
| `include_reasoning` | hide 보장용으로 사용하지 않음 | provider-pool pure `passthrough`는 provider body 보존이 우선이라 IOP-side reasoning 제거를 보장하지 않는다. |
|
|
| `metadata.iop_response_mode` | 생략 또는 `passthrough` | provider-original 응답을 relay한다. |
|
|
| `metadata.iop_response_mode="passthrough+sideband"` | 관측이 필요할 때만 사용 | provider body에 IOP sideband가 추가되며 hide 동작은 아니다. |
|
|
| `metadata.iop_response_mode="transformed"` | 사용하지 않음 | provider model group route에서는 `400 invalid_request_error`로 거부된다. |
|
|
|
|
Provider 전용 field인 `chat_template_kwargs`, `format`, `keep_alive`, `options`는 Chat Completions 외부 요청 body에 넣지 않는다. 이 값들은 dev-corp provider runtime 쪽 최적화 영역이며, OpenAI-compatible public Edge 호출자가 직접 조작하는 계약이 아니다.
|
|
|
|
## Reasoning 처리
|
|
|
|
dev-corp `gemma4:26b` provider-pool은 pure `passthrough`를 기본으로 한다. 따라서 provider가 reasoning field를 반환하면 Edge는 그 field를 보존할 수 있다.
|
|
|
|
Non-stream 응답에서 client가 숨길 수 있는 대표 field:
|
|
|
|
- `choices[].message.reasoning_content`
|
|
- `choices[].message.reasoning`
|
|
- `choices[].message.reasoning_text`
|
|
|
|
Streaming 응답에서 client가 숨길 수 있는 대표 delta field:
|
|
|
|
- `choices[].delta.reasoning_content`
|
|
- `choices[].delta.reasoning`
|
|
- `choices[].delta.reasoning_text`
|
|
|
|
사용자에게 reasoning을 보여주지 않아야 하는 client는 위 field를 표시/저장/후속 prompt에 주입하지 않도록 client 쪽에서 필터링한다. `include_reasoning=false`만으로 dev-corp `gemma4:26b` provider-pool에서 reasoning이 제거된다고 가정하지 않는다.
|
|
|
|
## Gemma4 설정으로 인한 한계
|
|
|
|
dev-corp `gemma4:26b` provider-pool은 Gemma4 agent/tool-call 호환성을 위해 vLLM/vLLM-MLX runtime을 thinking enabled, Gemma4 parser/template, long-context 기준으로 맞춰 둔 상태다. 이 설정은 현재 동작 가능한 최적값에 가깝기 때문에 외부 caller가 요청 파라미터로 thinking 동작을 끄거나 budget을 바꾸면 backend별로 무시, 오류, 품질 저하, tool-call drift가 날 수 있다.
|
|
|
|
현재 한계:
|
|
|
|
- `think=false`는 “응답에서 reasoning만 숨김”이 아니라 thinking disable 요청이다.
|
|
- `reasoning_effort="none"`도 thinking disable 의도로 해석된다.
|
|
- 명시적 `thinking_token_budget`은 dev-corp 기본 budget을 바꾸는 요청이다.
|
|
- `include_reasoning=false`는 provider-pool pure `passthrough`에서 hide-only 스위치가 아니다.
|
|
- streaming 응답에는 reasoning delta가 먼저 오고 최종 content가 뒤따를 수 있다.
|
|
- provider-pool은 여러 runtime 후보를 사용하므로 token 단위 출력, reasoning field 이름, chunk 경계가 완전히 동일하다고 가정하지 않는다.
|
|
- exact-output match보다 HTTP 성공, 정상 JSON/SSE 구조, 최종 assistant content 존재 여부를 우선 판정한다.
|
|
|
|
Reasoning을 provider에서 생성하게 두되 외부 사용자에게 보이지 않게 하려면, 현재 안정 기준은 `think` 관련 파라미터를 생략하고 client에서 reasoning field를 무시하는 것이다.
|
|
|
|
## 검증 순서
|
|
|
|
1. Model 목록 확인:
|
|
|
|
```bash
|
|
curl -fsS http://digitalplatform-iop.cloud:18086/v1/models \
|
|
-H 'Authorization: Bearer <token>'
|
|
```
|
|
|
|
2. Non-stream Chat Completions 확인:
|
|
|
|
```bash
|
|
curl -fsS http://digitalplatform-iop.cloud:18086/v1/chat/completions \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Bearer <token>' \
|
|
-d '{"model":"gemma4:26b","messages":[{"role":"user","content":"ok만 응답해줘."}],"stream":false}'
|
|
```
|
|
|
|
3. Streaming Chat Completions 확인:
|
|
|
|
```bash
|
|
curl -N http://digitalplatform-iop.cloud:18086/v1/chat/completions \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Bearer <token>' \
|
|
-d '{"model":"gemma4:26b","messages":[{"role":"user","content":"ok만 응답해줘."}],"stream":true}'
|
|
```
|
|
|
|
성공 판정은 HTTP 200, OpenAI-compatible `choices[]` 구조, 최종 assistant 응답 수신 기준으로 한다. Reasoning field가 포함되는 것만으로 실패로 보지 않는다.
|