# Milestone: Tool Call Runtime 검증 재시도 MVP ## 위치 - Roadmap: `agent-roadmap/ROADMAP.md` - Phase: `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md` ## 목표 명시적 `tools[]`와 `tool_choice` 계약이 있는 OpenAI-compatible 요청에서 IOP가 provider 응답의 마지막 tool call을 반환 직전에 검증한다. tool name 또는 `function.arguments`가 요청 schema와 맞지 않으면 caller agent에 실패를 노출하기 전에 IOP 내부에서 같은 요청을 bounded exact replay로 재시도한다. 이 Milestone은 validator 모델 없이 runtime이 결정적으로 판단할 수 있는 케이스만 다룬다. ## 상태 [완료] ## 승격 조건 - 없음 ## 구현 잠금 - 상태: 해제 - SDD: 불필요 - SDD 문서: 없음 - SDD 사유: 기존 OpenAI-compatible 요청/응답 계약 안에서 명시적 `tools[]` schema를 검증하고 같은 요청을 내부 재제출하는 bounded MVP로 제한하며, 새 proto/config/API field나 외부 계약 확장은 만들지 않는다. - 잠금 해제 조건: 없음 - 결정 필요: 없음 ## 범위 - OpenAI-compatible Chat Completions 요청의 `tools[]`, `tool_choice` 기반 runtime validation contract 판정 - native OpenAI `tool_calls`와 IOP text tool-call fallback 결과를 공통 `ToolCallCandidate` 형태로 해석 - 요청 `tools[].function.parameters`를 기준으로 tool name, arguments JSON, required/type/object/array/enum/additionalProperties 중심의 JSON Schema subset 검증 - 검증 실패 시 caller에게 응답을 내보내기 전 같은 `SubmitRunRequest`를 bounded exact replay로 재제출 - non-stream 또는 buffered stream처럼 아직 caller에게 malformed 응답을 흘리지 않은 경로 우선 적용 - retry attempt와 validation failure reason을 run metadata 또는 로그로 구분 가능하게 남기는 최소 추적 ## 기능 ### Epic: [runtime-validate] Runtime Tool Call Validation 명시적 schema가 있는 요청에서 모델 응답의 tool call shape를 runtime이 결정적으로 검증하고 재시도하는 capability를 묶는다. - [x] [contract-detect] `tools[]`가 있는 OpenAI-compatible 요청을 runtime validation 대상으로 판정하고 `tool_choice: none` 등 검증 제외 조건을 정리한다. - [x] [candidate-normalize] native `tool_calls`와 IOP text fallback 결과를 tool name, arguments, origin, raw payload를 가진 공통 후보로 정규화한다. - [x] [schema-validate] 요청 tool schema를 기준으로 tool name, arguments JSON parse, required/type/object/array/enum/additionalProperties subset을 검증한다. - [x] [exact-retry] validation 실패가 응답 방출 전 발견되면 같은 요청을 bounded exact replay로 재제출하고, 새 attempt run과 원 요청의 상관관계를 남긴다. - [x] [failure-surface] retry 한도 초과 또는 재시도 불가 경로에서는 malformed tool call을 그대로 성공 응답으로 내보내지 않고 OpenAI-compatible 실패로 구분한다. - [x] [validation-tests] runtime validation, retry 성공, retry 한도 초과, stream 제외 또는 buffer 경로를 테스트한다. 검증: `go test ./apps/edge/internal/openai` ## 완료 리뷰 - 상태: 통과 - 요청일: 2026-07-03 - 완료 근거: `agent-task/archive/2026/07/m-tool-call-runtime-validation-retry/complete.log`의 Roadmap Completion에서 `contract-detect`, `candidate-normalize`, `schema-validate`, `exact-retry`, `failure-surface`, `validation-tests`가 모두 PASS로 기록되었다. - 검토 항목: 2026-07-03 현재 `go test -count=1 ./apps/edge/internal/openai`, `go test -count=1 ./apps/edge/...` 재실행 PASS. 구현 잠금은 해제이며 남은 결정 필요와 SDD gate는 없다. - agent-ui 상태 반영: 해당 없음 - 리뷰 코멘트: 코드 레벨 종료 검토 통과로 완료 archive 처리했다. ## 범위 제외 - `tools[]`가 없는 요청에서 tool 사용 필요 여부를 추론하는 validator 모델 - agent-specific 자연어 또는 임의 텍스트를 tool call로 추정하는 휴리스틱 확장 - caller agent까지 실패를 되돌려 repair instruction을 넣는 외부 loop - live SSE로 이미 content를 방출한 뒤의 투명 재시도 - 새 public API/config/proto field와 장기 ledger schema 확정 ## 작업 컨텍스트 - 관련 경로: `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/adapters/openai_compat`, `apps/node/internal/adapters/vllm`, `agent-contract/outer/openai-compatible-api.md` - 표준선(선택): 명시적 `tools[]`가 있는 요청은 별도 validator 모델 없이 요청 schema를 source of truth로 삼는다. - 표준선(선택): 재시도는 작업 전체 재실행이 아니라 IOP 내부 provider 응답 sampling의 bounded exact replay로 제한한다. - 선행 작업: OpenAI-compatible tool call passthrough와 text fallback - 후속 작업: Tool Call 판정 모델 Gate 리뷰, 요청 실행 로그와 Usage Ledger 기반 - 확인 필요: 없음