Merge branch 'feature/openai-compatible-output-validation-filters' into dev
This commit is contained in:
commit
d97342f30b
1 changed files with 2 additions and 2 deletions
|
|
@ -74,8 +74,8 @@ OpenAI-compatible 출력 필터의 계약, 공통 pipeline, endpoint codec, Stre
|
|||
|
||||
반복·provider 오류·schema 위반의 감지·복구 안전 경계와 운영 관측·회귀 evidence를 묶는다.
|
||||
|
||||
- [ ] [resume-notice-builder] D01 continuation repair가 선택되고 all-complete Arbiter가 plan 하나를 고른 뒤 current attempt ownership이 끝나면 endpoint별 Rebuilder가 복구 요청을 직접 조립한다. 반복 구간을 제외한 모델의 content와 think/reasoning 원문을 channel별로 구분하고 고정 영어 지시문 `The previous model output was stopped after a repetition loop was detected. Continue from the provided content and reasoning output without repeating already generated text.`를 더한다. 사용자 요청·message는 넣지 않고, 모델 출력은 의미 요약·임의 절단·재작성하지 않는다. 두 channel 원문 전체가 문맥 한도를 넘으면 자동 복구하지 않는다. 언어 판별·번역·로컬 모델 호출·`RecoveryPlanPreparer`·번역용 설정은 구현하지 않으며, recovery budget은 실제 outbound recovery dispatch에서만 소비한다. 검증: 정확한 고정 문구, content/think channel provenance, 사용자 요청·message 부재, no-summary/no-truncation/no-rewrite, 문맥 한도 초과 no-dispatch, translator/local-model/preparer 미호출, Chat Completions와 Responses의 endpoint별 shape 보존 fixture가 통과한다.
|
||||
- [ ] [repeat-guard] content 반복은 단일 provider stream의 rolling window로 감지한다. assistant history anchor는 현재 incoming `messages`의 `role=user|assistant`, `content`, `reasoning_content`, `reasoning`, `reasoning_text`를 raw Chat Completions payload에서 role/channel별로 분리해 user 입력에는 없고 assistant history에 N회 누적된 plain-text fingerprint를 provider dispatch 전에 감지한다. 이 request-history 판정은 Pi session이나 특정 caller SDK에 의존하지 않는다. 명시적 conversation identity 계약이 없는 요청에는 stable lineage를 추정하거나 caller 간 TTL state를 공유하지 않으며, caller가 reasoning history를 재전송하지 않으면 current request/stream에서 관찰 가능한 범위로 낮춘다. history sanitation과 live reasoning dedupe는 [D01](../../../sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md)의 승인 범위에서만 수행하고, assistant final `content`, tool call, signed/encrypted/unknown reasoning field는 조용히 변경하지 않는다. progress는 current response가 아니라 incoming history에서 완료된 이전 tool call/result/error만으로 판정하며 서로 다른 action 자체를 progress로 단정하지 않는다. current provider content는 `rolling_window` pending에 기본 500 Unicode rune의 증거가 쌓이거나 terminal event가 올 때까지 보류한 뒤 safe prefix만 release한다. Core는 committed look-behind와 release cursor를 유지해 stream-open 뒤 반복도 감지하며, continuation recovery에서는 이미 보낸 prefix를 보존하고 새 attempt의 response-start/role/prefix 중복을 억제한다. 시간 경과만으로 release하지 않고 evidence 미충족 idle은 terminal error다. 현재 provider tool call delta는 `fragment_gate`로 완성 전 최소 fragment만 hold하며 이미 downstream으로 tool call이 나갔거나 side effect 가능성이 있으면 자동 repair하지 않는다. 검증: generic raw HTTP/OpenAI SDK fixture가 single-stream 반복, assistant-history anchor, reasoning alias, reasoning-history 미전송, conversation identity 부재, 200/500-rune rolling/look-behind, idle no-release, progress/no-progress, D01 원문 보존·반복 구간 제외·`[0.2, 0.4, 0.6]` 온도 후보, stream-open continuation, duplicate opening/prefix 금지, `[DONE]` 단일 종료와 tool side-effect 경계를 확인한다. fixture에는 UTF-8 multi-byte 경계에서 쪼개진 긴 한국어 문단 6개가 다시 반복되는 stream을 포함한다. dev에서는 `ornith:35b`에 `stream=true` 긴 한국어 최종 출력 요청을 model group 총 capacity+1 동시 요청으로 최소 3회 실행하고 raw SSE/한국어 출력을 ignored `agent-test/runs/**`에만 저장한다. 실제 반복이 관측되면 upstream abort, safe prefix continuation 또는 안전 중단을 확인하고 미재현이면 `not_reproduced`로 남기되 결정론적 fixture를 대체하지 않는다. 재개 안내문은 [D05](../../../sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md)의 고정 영어 지시문만 사용하며 2026-07-16 Pi/Ornith evidence는 generic fixture 입력 사례로만 쓴다.
|
||||
- [x] [resume-notice-builder] D01 continuation repair가 선택되고 all-complete Arbiter가 plan 하나를 고른 뒤 current attempt ownership이 끝나면 endpoint별 Rebuilder가 복구 요청을 직접 조립한다. 반복 구간을 제외한 모델의 content와 think/reasoning 원문을 channel별로 구분하고 고정 영어 지시문 `The previous model output was stopped after a repetition loop was detected. Continue from the provided content and reasoning output without repeating already generated text.`를 더한다. 사용자 요청·message는 넣지 않고, 모델 출력은 의미 요약·임의 절단·재작성하지 않는다. 두 channel 원문 전체가 문맥 한도를 넘으면 자동 복구하지 않는다. 언어 판별·번역·로컬 모델 호출·`RecoveryPlanPreparer`·번역용 설정은 구현하지 않으며, recovery budget은 실제 outbound recovery dispatch에서만 소비한다. 검증: 정확한 고정 문구, content/think channel provenance, 사용자 요청·message 부재, no-summary/no-truncation/no-rewrite, 문맥 한도 초과 no-dispatch, translator/local-model/preparer 미호출, Chat Completions와 Responses의 endpoint별 shape 보존 fixture가 통과한다.
|
||||
- [x] [repeat-guard] content 반복은 단일 provider stream의 rolling window로 감지한다. assistant history anchor는 현재 incoming `messages`의 `role=user|assistant`, `content`, `reasoning_content`, `reasoning`, `reasoning_text`를 raw Chat Completions payload에서 role/channel별로 분리해 user 입력에는 없고 assistant history에 N회 누적된 plain-text fingerprint를 provider dispatch 전에 감지한다. 이 request-history 판정은 Pi session이나 특정 caller SDK에 의존하지 않는다. 명시적 conversation identity 계약이 없는 요청에는 stable lineage를 추정하거나 caller 간 TTL state를 공유하지 않으며, caller가 reasoning history를 재전송하지 않으면 current request/stream에서 관찰 가능한 범위로 낮춘다. history sanitation과 live reasoning dedupe는 [D01](../../../sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md)의 승인 범위에서만 수행하고, assistant final `content`, tool call, signed/encrypted/unknown reasoning field는 조용히 변경하지 않는다. progress는 current response가 아니라 incoming history에서 완료된 이전 tool call/result/error만으로 판정하며 서로 다른 action 자체를 progress로 단정하지 않는다. current provider content는 `rolling_window` pending에 기본 500 Unicode rune의 증거가 쌓이거나 terminal event가 올 때까지 보류한 뒤 safe prefix만 release한다. Core는 committed look-behind와 release cursor를 유지해 stream-open 뒤 반복도 감지하며, continuation recovery에서는 이미 보낸 prefix를 보존하고 새 attempt의 response-start/role/prefix 중복을 억제한다. 시간 경과만으로 release하지 않고 evidence 미충족 idle은 terminal error다. 현재 provider tool call delta는 `fragment_gate`로 완성 전 최소 fragment만 hold하며 이미 downstream으로 tool call이 나갔거나 side effect 가능성이 있으면 자동 repair하지 않는다. 검증: generic raw HTTP/OpenAI SDK fixture가 single-stream 반복, assistant-history anchor, reasoning alias, reasoning-history 미전송, conversation identity 부재, 200/500-rune rolling/look-behind, idle no-release, progress/no-progress, D01 원문 보존·반복 구간 제외·`[0.2, 0.4, 0.6]` 온도 후보, stream-open continuation, duplicate opening/prefix 금지, `[DONE]` 단일 종료와 tool side-effect 경계를 확인한다. fixture에는 UTF-8 multi-byte 경계에서 쪼개진 긴 한국어 문단 6개가 다시 반복되는 stream을 포함한다. dev에서는 `ornith:35b`에 `stream=true` 긴 한국어 최종 출력 요청을 model group 총 capacity+1 동시 요청으로 최소 3회 실행하고 raw SSE/한국어 출력을 ignored `agent-test/runs/**`에만 저장한다. 실제 반복이 관측되면 upstream abort, safe prefix continuation 또는 안전 중단을 확인하고 미재현이면 `not_reproduced`로 남기되 결정론적 fixture를 대체하지 않는다. 재개 안내문은 [D05](../../../sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md)의 고정 영어 지시문만 사용하며 2026-07-16 Pi/Ornith evidence는 generic fixture 입력 사례로만 쓴다.
|
||||
- [ ] [provider-error-retry] provider tunnel 오류는 `filters[]`의 각 원소가 가진 `code`와 `message` 두 필드만으로 판정한다. `code` exact-match와 `message` 포함-match를 모두 만족하면 `provider_error_filter`가 `exact_replay` RecoveryIntent와 sanitized reason을 반환한다. 초기 원소는 `{ code: 500, message: "Failed to parse input at pos" }`이며 유사 오류는 같은 두 필드를 가진 원소를 배열에 추가한다. filter는 snapshot, counter, body, provider selection, submit을 소유하지 않는다. Core는 response-start/status/header/body를 staged evidence로 평가하고 `transport_uncommitted`에서만 D04의 최초 실행 제외 공통 최대 3회 exact replace-attempt를 허용하되, exact/continuation/schema를 합산한 최초 실행 제외 기본값/절대 상한 3회의 request 전체 `max_recovery_attempts_total`을 우선 적용한다. current attempt abort 뒤 bounded lossless Rebuilder/dispatcher로 cycle당 새 admission 하나를 실행하며 provider 선택은 기존 pool 정책에 맡긴다. 검증: response-start 뒤 알려진 parser error/두 번째 원소, commit 전 buffered chunk, tool-validation 동시/연속 violation, original status/header 미노출, final response-start 단일 노출, 0/1/3회 policy와 4회 이상 config rejection, shared exact/전체 cap 교차 소진·stream-open/cancel/filter mismatch 안전 종료가 통과한다.
|
||||
- [ ] [schema-contract] `metadata.scheme`이 있으면 `stream=true` 요청이어도 content channel을 explicit `terminal_gate`로 보류하고 JSON parse/schema validation을 수행한다. request별 `max_buffer_runes` hard bound를 필수로 두며 overflow는 partial release 없이 terminal error다. 실패 filter는 schema와 validation summary의 typed `schema_repair` intent만 반환하고 Core가 `transport_uncommitted`에서 bounded lossless Rebuilder로 새 attempt를 만든다. schema strategy budget이 남아도 request 전체 recovery cap 또는 ingress snapshot limit이 소진되면 새 attempt를 만들지 않는다. 검증: valid JSON, invalid-then-common-recovery, retry exhausted, request 전체 cap 소진, hard-limit/snapshot overflow, multimodal/unknown user field rebuild, eager header/content 없음이 통과한다.
|
||||
- [ ] [ops-evidence] 출력 필터 결과가 [Stream Evidence Gate Core](stream-evidence-gate-core.md)의 `FilterObservation` timeline과 요청 실행 로그/smoke에서 같은 correlation으로 원인 축을 구분할 수 있게 남고, 실제 incident는 raw prompt/tool args/result를 제외한 별도 sanitized evidence log로 generic 회귀 fixture에 연결된다. 이 consumer는 `repeat_guard`, `assistant_history_anchor`, `provider_error_filter` 등 stable filter/rule id와 fingerprint·count·offset만 Core observation에 제공한다. assembled output/reasoning 원문 기록은 설정 기본값 `on`으로 시작하되, `off` 전환 뒤의 요청에서는 원문을 쓰지 않고 비원문 운영 정보만 남긴다. 검증: generic raw HTTP/OpenAI SDK smoke를 필수 기준으로 실행하고, Pi TUI는 선택적 caller field smoke로 추가한다. role/channel provenance, reasoning history 미전송, provider 전환, 반복 fragment 관찰/보정/중단, pending tail의 configured evidence-rune threshold·evidence/terminal/idle-error release-or-close reason, provider-error-retry의 filter index/공통 exact-replay 사유·1~3회 shared attempt·commit 상태·기존 pool이 다시 선택한 provider/재사용 snapshot 여부 또는 schema validation 결과가 model/provider/IOP/protocol 축과 함께 관찰되며, 한국어 장문 dev smoke는 model/provider, attempt 수, repeat fingerprint/offset, guard 결정, `not_reproduced` 여부를 sanitized evidence로 남긴다. 사용자 요청 원문·tool args/result·인증 정보는 `on` 상태에서도 Core observation 또는 일반 로그에 기록하지 않고, 요청별 raw SSE와 출력은 단기 ignored `agent-test/runs/**`에만 두며 tracked 문서에는 복제하지 않는다.
|
||||
|
|
|
|||
Loading…
Reference in a new issue