Skip to content

fix(llm): reject nonconforming structured output - #1552

Closed
seonghobae wants to merge 1 commit into
developfrom
codex/goal21-json-schema
Closed

fix(llm): reject nonconforming structured output#1552
seonghobae wants to merge 1 commit into
developfrom
codex/goal21-json-schema

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

목적

Naruon의 구조화 의미 처리 세 경로가 OpenAI 호환 json_schema 요청을 보내고, contextual-orchestrator 또는 선택된 테넌트 provider가 스키마 밖 값을 반환하면 성공으로 받아들이지 않도록 닫습니다.

감사 결과와 수정

  • protected develop의 요약·project graph·근거 기반 검색 경로는 이미 AsyncOpenAI.beta.chat.completions.parse(...)와 Pydantic response_format을 사용했습니다.
  • OpenAI SDK 2.45.0은 이를 strict json_schema wire envelope로 바꾸지만, Naruon payload 모델은 Pydantic 기본 extra=ignore여서 비준수 응답의 미지 필드를 조용히 버릴 수 있었습니다.
  • 세 최상위 payload와 project-graph 중첩 payload를 extra="forbid", strict=True로 바꿔 malformed 응답을 fail closed 처리합니다.
  • 새 transport 계약 테스트는 실제 OpenAI SDK request builder를 실행하고 네트워크 전송만 가로채 세 경로의 /chat/completions body에 response_format.type=json_schema, strict schema, 선택된 model이 들어가는지 확인합니다.
  • API·provider 선택 코드는 바꾸지 않아 signed-session 인증, organization_id 기반 provider 선택, allowlisted/pinned outbound 연결을 그대로 보존합니다. 사용자 응답에는 내부 검증 상세를 노출하지 않습니다.

기존 PR 승계

PR #1529의 유효한 wire/fail-closed 요구를 최신 protected base에서 승계합니다. #1529 branch는 현재 develop과 공통 조상이 없어 force push나 unrelated-history merge를 하지 않았습니다. 이 PR이 보호 병합되기 전에는 #1529를 닫지 않습니다.

정확한 식별자

  • base: develop@6cb9cc93a398e72c1c0daa564da7acbca65376fb
  • head: f7401c1f44f0fef977438fe51894133f2de81084

검증

  • 집중 경로: 188 passed, 경고 없음
  • Ruff: 통과
  • git diff --check: 통과
  • 전체 backend: 1714 passed, 33 skipped; 기존 protected-main에서도 발생하는 경고 10건이 있어 무경고 통과 증거로 사용하지 않음

범위

자유 형식 번역·답장에는 구조화 schema를 억지로 적용하지 않았습니다. 목표 #21의 기계 판독 consumer 결과인 요약/action item, project graph, 근거 기반 검색 응답만 다룹니다.

Summary by CodeRabbit

  • Bug Fixes

    • Improved validation of AI-generated structured responses by rejecting unexpected fields and enforcing strict data types.
    • Added fail-closed handling when responses do not match the expected format.
  • Tests

    • Added coverage for strict schema generation, schema transmission, and invalid-response handling across summary, project graph, and grounded-answer workflows.

Signed-off-by: Seongho Bae <me@seonghobae.me>
@seonghobae
seonghobae enabled auto-merge (squash) September 4, 2026 09:16
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 3c3c02c7-24c8-4e79-a24a-7ad2fe7245d8

📥 Commits

Reviewing files that changed from the base of the PR and between 042b0c7 and f7401c1.

📒 Files selected for processing (4)
  • backend/services/llm_service.py
  • backend/services/project_graph/llm_extractor.py
  • backend/services/rag_service.py
  • backend/tests/test_llm_structured_output_contract.py

📝 Walkthrough

Walkthrough

The change applies strict Pydantic validation to LLM response models. It rejects extra fields, enforces strict types, and adds contract tests for schema transmission and invalid response handling across three integrations.

Changes

Strict LLM contracts

Layer / File(s) Summary
Strict payload model contracts
backend/services/llm_service.py, backend/services/project_graph/llm_extractor.py, backend/services/rag_service.py
ExtractionResult, project-graph payloads, and GroundedAnswerPayload now forbid extra fields and enforce strict validation.
Structured-output contract validation
backend/tests/test_llm_structured_output_contract.py
Tests validate strict JSON schemas, schema transmission across three orchestrator-backed integrations, and LLMServiceError handling for unexpected fields.

Estimated code review effort: 3 (Moderate) | ~20 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/goal21-json-schema

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae

Copy link
Copy Markdown
Contributor Author

현재 protected develop이 history 교체로 042b0c70531b229af3acbd0421a2f23098d848b3에 이동해 이 PR은 공통 조상이 없는 이전 base에서 생성됐습니다. force push나 unrelated-history merge를 쓰지 않고 동일 delta를 현재 base에 적용한 successor #1553 (head c059482)로 완전 승계했습니다. #1552에는 독자 delta가 남지 않아 종료하며 branch는 삭제하지 않습니다.

@seonghobae seonghobae closed this Sep 4, 2026
auto-merge was automatically disabled September 4, 2026 09:19

Pull request was closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant