From 601ec79a53cbac6c109930f3af68664781b722ac Mon Sep 17 00:00:00 2001 From: leedongmyun Date: Thu, 9 Jul 2026 15:22:59 +0900 Subject: [PATCH] docs: add milestone for OpenAI-compatible output validation filters --- .../PHASE.md | 4 + ...ai-compatible-output-validation-filters.md | 84 +++++++++++++ .../SDD.md | 118 ++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md create mode 100644 agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md diff --git a/agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md b/agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md index 3d92348..16a9a93 100644 --- a/agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md +++ b/agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md @@ -27,6 +27,10 @@ Ollama serving 경로와 운영 기반이 안정화된 뒤, 단계 호출, tool/ - 경로: [openai-compatible-tool-call-boundary-hardening](../../archive/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-tool-call-boundary-hardening.md) - 요약: provider-pool/OpenAI-compatible 응답에서 raw text tool-call block, unknown tool name, chat-template sentinel token이 클라이언트 화면으로 새지 않도록 Edge tool-call 경계를 검증/정규화한다. +- [계획] OpenAI-compatible 출력 검증 필터 + - 경로: [openai-compatible-output-validation-filters](milestones/openai-compatible-output-validation-filters.md) + - 요약: OpenAI-compatible Chat Completions provider stream에서 반복 출력 루프를 감지해 upstream만 중단하고 같은 downstream SSE에 continuation repair를 이어 붙이며, `metadata.scheme` JSON 출력 계약은 buffered `contract_schema` 경로로 검증/재시도한다. + - [스케치] 단계 호출과 검증 최적화 MVP - 경로: [knowledge-tool-validation-optimization](milestones/knowledge-tool-validation-optimization.md) - 요약: 요청 의도 분석, 실제 작업, 검증/schema 강제, 오류 시 회귀를 단계 호출 실행 모드의 MVP 후보로 스케치한다. diff --git a/agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md b/agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md new file mode 100644 index 0000000..6dfddf5 --- /dev/null +++ b/agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md @@ -0,0 +1,84 @@ +# Milestone: OpenAI-compatible 출력 검증 필터 + +## 위치 + +- Roadmap: [ROADMAP.md](../../../ROADMAP.md) +- Phase: [PHASE.md](../PHASE.md) + +## 목표 + +OpenAI-compatible Chat Completions provider 경로에서 모델 출력 이상을 요청 단위 필터로 감지하고, 사용자 경험을 해치지 않는 방식으로 중단/재시도/검증한다. +반복 출력 루프는 streaming passthrough를 유지한 채 upstream만 교체해 continuation repair로 이어 쓰고, `metadata.scheme` JSON 출력 계약은 검증 전 downstream content streaming을 막는 `contract_schema` 경로로 처리한다. + +## 상태 + +[계획] + +## 승격 조건 + +- 없음 + +## 구현 잠금 + +- 상태: 해제 +- SDD: 필요 +- SDD 문서: [SDD.md](../../../sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md) +- SDD 사유: OpenAI-compatible metadata schema, streaming retry/abort 상태 전이, provider 응답 검증 계약이 바뀌는 Milestone이다. +- 잠금 해제 조건: + - [x] SDD 잠금이 해제되어 있다 + - [x] SDD 사용자 리뷰가 없거나 승인/해결되었다 + - [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다 + - [x] Evidence Map이 완료 시 `Roadmap Completion`과 최종 검증 evidence로 검증 가능하게 연결되어 있다 +- 결정 필요: 없음 + +## 범위 + +- OpenAI-compatible `/v1/chat/completions` provider route의 출력 검증 필터 모듈과 response path 선택 +- 반복 출력 루프 감지용 rolling stream inspector, upstream abort, continuation repair, 1회 repair 제한 +- `metadata.scheme` JSON schema 계약 수신, 마지막 user message prompt append, buffered validation, schema 위반 시 bounded retry +- `passthrough`, `passthrough_guarded`, `contract_schema` 내부 response path 구분과 실행 로그/side observation. 이 이름들은 caller가 임의로 넣는 `metadata.iop_response_mode` 값이 아니라 IOP 내부 경로/로그 기준이다. +- normalized 실행 경로와 CLI adapter 경로를 OpenAI-compatible provider 출력 검증 경로와 분리하는 책임 경계 + +## 기능 + +### Epic: [output-filter] Output Validation Filters + +OpenAI-compatible provider 응답을 사용자에게 노출하기 전에 필터별 정책으로 감시, 중단, 재시도, 검증하는 capability를 묶는다. + +- [ ] [contract-doc] OpenAI-compatible 계약 문서와 구현 타입이 `metadata.scheme`, 내부 `contract_schema`/`passthrough_guarded` path, normalized CLI-only 경계를 설명한다. 검증: [openai-compatible-api.md](../../../../agent-contract/outer/openai-compatible-api.md)와 관련 Go 타입/handler 테스트가 새 계약과 일치한다. +- [ ] [filter-pipeline] Edge Chat Completions provider route에 여러 출력 검증 filter를 붙일 수 있는 모듈 파이프라인이 생기고, 요청별로 pure passthrough, guarded stream, schema contract 경로를 결정한다. 검증: `go test ./apps/edge/internal/openai -count=1`에서 path selection과 unknown/unsupported 조합 테스트가 통과한다. +- [ ] [repeat-guard] streaming 응답에서 반복 루프를 rolling window로 감지하면 downstream SSE를 닫지 않고 upstream provider request만 abort한 뒤 emitted safe prefix와 bad tail summary로 continuation repair 요청을 이어 붙인다. 검증: 반복 chunk fixture 기반 stream test가 1회 repair, safe prefix 보존, `[DONE]` 단일 종료, tool side-effect 구간 차단을 확인한다. +- [ ] [schema-contract] `metadata.scheme`이 있으면 `stream=true` 요청이어도 downstream content streaming을 보류하고, 마지막 user message에 scheme 계약 block을 append한 뒤 JSON parse/schema validation, 실패 시 1회 재요청, 성공 시 validated JSON만 반환한다. 검증: valid JSON, invalid-then-repair, retry-exhausted, multimodal user content append fixture가 통과한다. +- [ ] [ops-evidence] 출력 필터 결과가 요청 실행 로그와 smoke에서 원인 축을 구분할 수 있게 남는다. 검증: dev-corp Pi TUI smoke에서 반복루프 중단/재요청 또는 schema validation 결과가 model/provider/IOP/CLI 축과 함께 관찰된다. + +## 완료 리뷰 + +- 상태: 없음 +- 요청일: 없음 +- 완료 근거: 기능 Task가 아직 충족되지 않았다. +- 검토 항목: + - [ ] `complete.log`의 `Roadmap Completion`이 각 기능 Task id를 기록한다. + - [ ] 최종 검증 출력이 SDD Evidence Map과 일치한다. + - [ ] dev-corp Pi TUI 기준 반복루프와 `metadata.scheme` 케이스가 모두 확인된다. +- agent-ui 상태 반영: 해당 없음 +- 리뷰 코멘트: 없음 + +## 범위 제외 + +- normalized 실행 경로를 provider 출력 검증 필터와 섞는 작업 +- CLI adapter 전용 normalized protocol 변경 +- 반복루프 감지를 위해 전체 응답을 buffer한 뒤 사용자에게 늦게 보내는 방식 +- schema 계약이 있는 요청에서 검증 전 content delta를 사용자에게 먼저 노출하는 방식 +- validator 모델을 이용한 자연어/tool-call 판정 gate +- 장기 RAG, advisor, context compression, cloud routing score 정책 + +## 작업 컨텍스트 + +- 관련 경로: `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/openai_compat`, `apps/node/internal/runtime`, `packages/go/config`, [openai-compatible-api.md](../../../../agent-contract/outer/openai-compatible-api.md) +- 표준선(선택): 반복루프 필터는 streaming passthrough UX를 유지하는 `passthrough_guarded` 경로이며, 이미 흘린 정상 prefix를 버리지 않고 continuation repair로 이어 쓴다. +- 표준선(선택): schema 출력 계약은 `metadata.scheme` 하나로 표현하고 wrapper/options를 추가하지 않는다. 계약이 있으면 streaming 요청보다 contract validation을 우선하며, 검증 전 content delta를 흘리지 않는다. +- 표준선(선택): `metadata.scheme`은 JSON schema로 간주하며 IOP가 마지막 user message에 출력 계약 블록을 append해 provider로 전달한다. +- 표준선(선택): OpenAI-compatible provider 출력 검증은 normalized 경로로 전환하지 않는다. normalized는 CLI 전용으로 유지한다. +- 선행 작업: [OpenAI-compatible Tool Call Boundary Hardening](../../../archive/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-tool-call-boundary-hardening.md), [OpenAI-compatible Raw Tunnel과 Sideband Passthrough](../../../archive/phase/routing-policy-model-orchestration/milestones/openai-compatible-raw-tunnel-sideband-passthrough.md) +- 후속 작업: 단계 호출과 검증 최적화 MVP, Tool Call 판정 모델 Gate 리뷰 +- 확인 필요: 없음 diff --git a/agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md b/agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md new file mode 100644 index 0000000..28b6af1 --- /dev/null +++ b/agent-roadmap/sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md @@ -0,0 +1,118 @@ +# SDD: OpenAI-compatible 출력 검증 필터 + +## 위치 + +- Milestone: [Milestone 문서](../../../phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md) +- Phase: [PHASE.md](../../../phase/knowledge-tool-optimization-extension/PHASE.md) + +## 상태 + +[승인됨] + +## SDD 잠금 + +- 상태: 해제 +- 사용자 리뷰: 없음 +- 잠금 항목: + - 없음 + +## 문제 / 비목표 + +- 문제: provider stream에서 반복 출력 루프가 발생하면 Pi TUI 같은 client는 이미 열린 SSE를 계속 받으므로, IOP가 모델/provider 축의 이상을 감지해 upstream만 중단하고 같은 downstream stream에 안전하게 repair 출력을 이어 붙여야 한다. 동시에 `metadata.scheme` JSON 출력 계약은 전체 결과 검증 없이는 성공 여부를 알 수 없어 streaming passthrough와 다른 gated 경로가 필요하다. +- 비목표: + - normalized 실행 경로를 OpenAI-compatible provider 출력 검증 경로와 합친다. + - CLI adapter protocol을 이 Milestone에서 변경한다. + - 전체 streaming 응답을 기본적으로 buffer해 사용자 경험을 늦춘다. + - schema 계약이 있는 요청에서 검증 전 partial content를 성공 출력으로 노출한다. + - validator 모델로 애매한 자연어/tool-call 후보를 판정한다. + +## Source of Truth + +| 영역 | 기준 | 메모 | +|------|------|------| +| Roadmap | [Milestone 문서](../../../phase/knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md) | 범위, Task, 완료 evidence 기준 | +| Code | `apps/edge/internal/openai`, `apps/node/internal/adapters/openai_compat` | OpenAI-compatible Chat Completions provider route와 stream bridge 구현 기준 | +| Contract | [openai-compatible-api.md](../../../../agent-contract/outer/openai-compatible-api.md) | `metadata.scheme`, 내부 response path, streaming/gated 정책 원문 | +| External Provider | OpenAI-compatible provider pool | provider 원본 요청/응답은 IOP 필터 정책에 따라 upstream abort/retry 대상이 된다. | +| User Decision | 없음 | 사용자가 `metadata.scheme` 단일 계약, normalized CLI-only 경계, streaming guard 방향을 확정했다. | + +## State Machine + +| 상태 | 진입 조건 | 다음 상태 | 근거 | +|------|-----------|-----------|------| +| `ingress` | `/v1/chat/completions` 요청 수신 | `passthrough`, `guarded_stream`, `contract_schema` | request metadata, internal filter path policy | +| `passthrough` | `metadata.scheme` 없음, guarded filter 비활성 또는 적용 대상 아님 | `done`, `provider_error` | provider SSE/non-stream 응답 | +| `guarded_stream` | streaming 응답에 반복루프 등 online filter 적용 | `repairing`, `done`, `guard_error` | rolling inspector event | +| `repairing` | 반복루프 감지 후 upstream provider request abort 성공 | `guarded_stream`, `guard_error` | continuation repair provider 응답 | +| `contract_schema` | `metadata.scheme` 있음 | `schema_retry`, `done`, `schema_error` | JSON parse/schema validation | +| `schema_retry` | schema validation 실패이며 retry budget 남음 | `contract_schema`, `schema_error` | retry counter | +| `guard_error` | repair 불가, retry exhausted, tool side-effect 구간 진입 | `done` | OpenAI-compatible error or terminal SSE error | +| `schema_error` | retry 후에도 JSON/schema 불일치 | `done` | OpenAI-compatible validation error | +| `done` | 성공 응답 또는 terminal error 전송 | 없음 | final chunk/body | + +## Interface Contract + +- 계약 원문: [openai-compatible-api.md](../../../../agent-contract/outer/openai-compatible-api.md) +- 입력: + - `metadata.scheme`: optional JSON schema object. 있으면 IOP는 요청 출력 계약으로 간주한다. + - `stream`: caller 요청값. `metadata.scheme`이 있으면 downstream content streaming보다 schema validation이 우선한다. + - `messages`: 마지막 user message에 IOP output scheme instruction을 append할 대상이다. + - `tools`: tool call side effect 안전성 판단에 사용한다. +- 출력: + - `passthrough`: 기존 provider-compatible 응답을 유지한다. + - `passthrough_guarded`: downstream SSE 연결을 유지하되 IOP가 upstream stream을 감시하고 필요 시 upstream만 abort/retry한다. 내부 실행/로그 path이며 provider-original byte-identical로 표시하지 않는다. + - `contract_schema`: 전체 응답을 수집/검증한 뒤 valid JSON만 반환한다. `stream=true` 요청에서도 검증 전 `delta.content`를 흘리지 않는다. + - `tool_validation_error`, `schema_validation_error`, `guard_error`: 복구 불가 또는 retry exhausted terminal error. +- 내부 path 주의: + - `passthrough_guarded`와 `contract_schema`는 caller가 임의로 지정하는 `metadata.iop_response_mode` 값이 아니라 IOP 내부 실행/로그 path 이름이다. + - caller가 지정할 수 있는 공개 response mode 값은 [계약 원문](../../../../agent-contract/outer/openai-compatible-api.md)에서 별도로 명시한 값만 허용한다. +- 금지: + - `metadata.scheme`을 `iop_output_contract` 같은 wrapper로 감싸지 않는다. + - schema 계약 요청을 normalized path로 보내지 않는다. + - normalized path를 CLI 외 OpenAI-compatible provider 출력 검증에 사용하지 않는다. + - 반복루프 repair 안내 문구를 assistant content chunk로 주입하지 않는다. + - 이미 downstream으로 tool call을 보내 실행 side effect 가능성이 생긴 뒤 자동 continuation repair를 수행하지 않는다. + +## Acceptance Scenarios + +| ID | Milestone Task | Given | When | Then | +|----|----------------|-------|------|------| +| S01 | `contract-doc` | OpenAI-compatible Chat Completions 계약 문서와 구현 타입 | `metadata.scheme` 및 내부 response path 경계가 추가된다 | 계약 문서, request 타입, handler 정책이 wrapper 없는 `metadata.scheme`과 normalized CLI-only 경계를 동일하게 설명한다 | +| S02 | `filter-pipeline` | provider route 요청이 들어온다 | request metadata와 filter 정책을 평가한다 | pure passthrough, guarded stream, contract schema 중 하나의 내부 path로 결정되고 unsupported 조합은 400으로 거부된다 | +| S03 | `repeat-guard` | provider SSE가 같은 문장/단락을 반복 출력한다 | rolling inspector가 threshold를 넘긴다 | downstream SSE는 유지되고 upstream만 abort되며 safe prefix 보존과 bad tail summary 기반 continuation repair가 1회 이어진다 | +| S04 | `repeat-guard` | tool call delta가 이미 downstream으로 흘렀거나 tool side effect 가능 구간이다 | 반복루프가 감지된다 | 자동 repair를 수행하지 않고 guard terminal error 또는 안전한 중단으로 끝낸다 | +| S05 | `schema-contract` | request `metadata.scheme`에 JSON schema가 있다 | provider가 schema-valid JSON을 반환한다 | IOP가 JSON parse/schema validation 후 valid JSON만 반환한다 | +| S06 | `schema-contract` | request `metadata.scheme`에 JSON schema가 있다 | provider가 invalid JSON 또는 schema 위반 JSON을 반환한다 | IOP가 schema와 validation error summary로 1회 재요청하고, 실패가 반복되면 schema validation error를 반환한다 | +| S07 | `ops-evidence` | dev-corp Pi TUI에서 반복루프 또는 schema 계약 smoke를 실행한다 | 로그와 TUI 출력을 확인한다 | 문제 축이 model/provider, IOP guard, CLI/normalized 경계로 구분되고 최종 stream/body가 오염되지 않는다 | + +## Evidence Map + +| Scenario | Required Evidence | `agent-task` 연결 | 완료 Evidence 기대 | +|----------|-------------------|------------------|---------------------------| +| S01 | 계약 문서 diff, Go request/metadata type tests | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion`에 `contract-doc`, `go test ./apps/edge/internal/openai -count=1` 결과 | +| S02 | mode selection unit tests, unsupported 조합 tests | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion`에 `filter-pipeline`, handler test 결과 | +| S03 | 반복 chunk fixture stream test | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion`에 `repeat-guard`, upstream abort/repair/single `[DONE]` assertion | +| S04 | tool side-effect guard fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion`에 `repeat-guard`, automatic repair block assertion | +| S05 | valid JSON schema fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion`에 `schema-contract`, validated JSON body/SSE assertion | +| S06 | invalid-then-repair, retry-exhausted fixtures | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion`에 `schema-contract`, retry count/error assertion | +| S07 | dev-corp Pi TUI smoke log, Edge provider log | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion`에 `ops-evidence`, dev-corp smoke evidence path 또는 로그 요약 | + +## Cross-repo Dependencies + +- 없음 + +## Drift Check + +- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다. +- [x] Evidence Map이 code-review/complete.log에서 검증 가능하다. +- [x] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다. +- [x] 사용자 리뷰가 필요한 항목은 `USER_REVIEW.md`에만 남겼다. + +## 사용자 리뷰 이력 + +- 없음 + +## 작업 컨텍스트 + +- 표준선: OpenAI-compatible provider 출력 검증은 Edge OpenAI handler/stream bridge에 두고, normalized는 CLI 전용으로 유지한다. 반복루프는 streaming repair filter, `metadata.scheme`은 buffered contract validation으로 분리한다. +- 후속 SDD: 없음