Skip to content

[Feat] LLM 분석 설명 근거 검증 내부 API 구현 - #43

Open
boogiewooki02 wants to merge 8 commits into
SeCause:developfrom
boogiewooki02:feat/41-answer-verification
Open

boogiewooki02 wants to merge 8 commits into
SeCause:developfrom
boogiewooki02:feat/41-answer-verification

Conversation

@boogiewooki02

@boogiewooki02 boogiewooki02 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

‼️ 관련 이슈

close #41


🔎 개요

LLM이 생성한 보안 분석 설명을 코드·탐지 결과·RAG 근거와 대조하는 내부 검증 API 구현


📝 작업 내용

  • 검증 요청·결과 조회 API 추가
  • 전용 RQ 큐·Worker를 통한 비동기 처리
  • 주장별 근거 있음·모순·근거 부족 판정
  • 입력 검증, 인용 근거 확인, 타임아웃·결과 보관 기간 적용

👀 변경 사항

  • 요청·조회 시 X-Internal-Token 필수
  • 검증 전용 Worker 별도 실행 필요
  • 기존 분석 파이프라인 변경 없음

✅ 체크리스트

  • label, milestone, assignees, reviewers 등을 지정했습니다.
  • 성능 개선/최적화 관련 내용이 있는지 확인했습니다.
  • 변경 사항에 대한 테스트를 했습니다.
  • 테스트 시 사용한 로그를 삭제했습니다.

💬 고민사항 및 리뷰 요구사항

  • 단위 테스트 통과했으며, 실제 Claude·Redis·Worker를 사용하는 통합 검증은 미수행 상태입니다.

Summary by CodeRabbit

  • 새로운 기능
    • 보안 분석 답변을 제공된 증거와 대조해 항목별로 검증하는 기능을 추가했습니다.
    • 내부 인증을 거쳐 검증 작업을 제출하고 진행 상태와 결과를 조회할 수 있습니다.
    • 증거가 없으면 각 항목을 ‘증거 불충분’으로 표시합니다.

@boogiewooki02 boogiewooki02 self-assigned this Oct 12, 2026
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d5e79ac3-72dd-4a4e-a584-8073e4eac3c1
📥 Commits

Reviewing files that changed from the base of the PR and between 69dfdaa and facfb07.

📒 Files selected for processing: 22
  • .env.verification.example
  • .gitignore
  • app/api/routes/verifications.py
  • app/jobs/verification_job.py
  • app/jobs/verification_queue.py
  • app/jobs/verification_worker.py
  • app/main.py
  • app/schemas/verification.py
  • app/services/verification/__init__.py
  • app/services/verification/claude_client.py
  • app/services/verification/config.py
  • app/services/verification/prompt.py
  • app/services/verification/rules.py
  • app/services/verification/service.py
  • app/services/verification/tasks.py
  • tests/api/test_verifications.py
  • tests/jobs/test_verification_job.py
  • tests/services/verification/__init__.py
  • tests/services/verification/test_claude_client.py
  • tests/services/verification/test_rules.py
  • tests/services/verification/test_schemas.py
  • tests/services/verification/test_service.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

답변의 summary, rootCause, impact를 제공된 증거와 대조하는 검증 기능을 추가합니다. 내부 API가 검증 요청을 RQ 작업으로 등록하고, 별도 워커가 처리한 결과를 조회할 수 있습니다.

Changes: 답변 검증

Layer / File(s) Summary
검증 계약과 입력 설정
app/schemas/verification.py, app/services/verification/config.py, app/services/verification/rules.py, tests/services/verification/test_schemas.py, tests/services/verification/test_rules.py, .env.verification.example, .gitignore
요청·응답 모델과 설정 기본값을 추가했습니다. 요청 크기, 증거 ID 중복, 코드 증거의 줄 범위를 검증하며 관련 테스트와 환경 변수 예시를 추가했습니다.
판정 생성과 무결성 확인
app/services/verification/prompt.py, app/services/verification/claude_client.py, app/services/verification/service.py, app/services/verification/__init__.py, tests/services/verification/test_claude_client.py, tests/services/verification/test_service.py
증거에 기반한 판정을 요청하는 프롬프트와 Claude 클라이언트를 추가했습니다. 판정의 답변 범위와 인용을 확인하고, 증거가 없으면 모델 호출 없이 INSUFFICIENT_EVIDENCE 결과를 생성합니다.
RQ 작업 실행과 상태 조회
app/jobs/verification_queue.py, app/services/verification/tasks.py, app/jobs/verification_job.py, app/jobs/verification_worker.py, tests/jobs/test_verification_job.py
전용 RQ 큐와 워커를 추가했습니다. 작업 등록, 실행 제한 시간 확인, 상태 변환 및 결과 직렬화를 구현하고 작업 오류 로그에서 요청 세부 정보를 제외합니다.
내부 검증 API 연결
app/api/routes/verifications.py, app/main.py, tests/api/test_verifications.py
내부 토큰 인증이 적용된 검증 요청 등록·조회 경로를 추가하고 앱에 등록했습니다. 입력 오류, Redis 오류, 누락된 결과에 대한 HTTP 응답을 테스트합니다.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant VerificationRoute
  participant VerificationTasks
  participant RQQueue
  participant VerificationWorker
  participant VerifyAnswer
  participant ClaudeVerificationClient
  Client->>VerificationRoute: POST 검증 요청
  VerificationRoute->>VerificationTasks: enqueue_verification
  VerificationTasks->>RQQueue: 검증 작업 등록
  VerificationWorker->>RQQueue: 작업 가져오기
  VerificationWorker->>VerifyAnswer: run_verification_job
  VerifyAnswer->>ClaudeVerificationClient: 증거가 있을 때 판정 요청
  ClaudeVerificationClient-->>VerifyAnswer: 판정과 사용량 반환
  Client->>VerificationRoute: GET 검증 결과
  VerificationRoute->>VerificationTasks: get_verification
  VerificationTasks-->>VerificationRoute: 작업 상태 또는 결과
  VerificationRoute-->>Client: 검증 응답 반환
Loading
Merge Risk: ⚪ Minimal · up to facfb

The verification API has no identified merge-blocking issue. Live Claude, Redis, and worker integration remains untested, so run the normal deployment checks.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Linked Issues check Warning 직접 연결된 이슈 #41의 핵심 구현은 대부분 충족합니다. app/api/routes/verifications.py는 별도 요청·조회 API와 내부 토큰 검사를 추가합니다. app/services/verification/rules.py와 service.py는 입력·인용 무결성 검사와 근거 부족 판정을 구현합니다. claude_client.py… 이슈 #41의 평가 요구를 충족하도록 소규모 평가셋과 실행 가능한 평가 코드 또는 테스트를 추가하십시오. 평가 결과에 판정 정확도, 처리 시간, 토큰 사용량 또는 비용을 기록하십시오.
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 60 functions across 19 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed PR 제목은 LLM 분석 설명의 근거 검증을 위한 내부 API 구현이라는 주요 변경 사항을 명확하고 간결하게 설명합니다.
Out of Scope Changes check Passed 변경 사항은 이슈 #41의 검증 API 범위에 연결됩니다. .env.verification.example과 .gitignore는 검증 전용 설정을 지원합니다. API, 스키마, 규칙 검사, Claude 어댑터, RQ 작업·Worker, TTL 처리, 단위 테스트는 요청·결과 조회와 비동기 검증을 구현하거나 검증합니다. 기존 분석 라우터와 분석 파이프…
Full details: Linked Issues check

Explanation

직접 연결된 이슈 #41의 핵심 구현은 대부분 충족합니다. app/api/routes/verifications.py는 별도 요청·조회 API와 내부 토큰 검사를 추가합니다. app/services/verification/rules.py와 service.py는 입력·인용 무결성 검사와 근거 부족 판정을 구현합니다. claude_client.py는 LLM 판정을 구현합니다. tasks.py, 전용 RQ 큐, Worker는 비동기 처리와 TTL을 구현합니다. 그러나 이슈 #41의 소규모 평가셋을 사용한 판정 정확도·처리 시간·비용 확인에 해당하는 평가셋, 평가 코드 또는 결과가 변경 사항에 없습니다.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 60 functions across 19 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@boogiewooki02 boogiewooki02 added the ✨ FEAT New feature or request label Oct 12, 2026
@dldusgh318

Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@dldusgh318 dldusgh318 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검토 의견을 파일별 인라인 코멘트로 옮겼습니다. 해당 코드 줄의 리뷰 스레드를 확인해 주세요.

@dldusgh318 dldusgh318 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다~~ 기존 코드와 중복되는 부분도 좀 있어서 리뷰 남겨놨으니 확인부탁드려용

configured = get_verification_settings().ANALYSIS_CALLBACK_INTERNAL_TOKEN
if not configured or not configured.strip():
raise HTTPException(status.HTTP_503_SERVICE_UNAVAILABLE, "Verification authentication is not configured")
if x_internal_token is None or not hmac.compare_digest(

@dldusgh318 dldusgh318 Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존 app/api/dependencies.py의 verify_internal_token과 헤더 추출·토큰 비교 로직이 겹쳐서 공통 토큰 비교 로직으로 빼거나 토큰 미설정 시 정책을 명시적으로 구분하는 공통 의존성으로 정리하는 게 어떨까요?


@lru_cache
def get_verification_redis() -> Redis:
return Redis.from_url(get_verification_settings().REDIS_URL)

@dldusgh318 dldusgh318 Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 기존 app/jobs/queue.py의 Redis 연결 생성과 거의 같은 구현이라서 로직 공통화할 수 있을 거 같습니다~
다만 검증 설정은 .env.verification에서 별도로 덮어쓸 수 있으므로 기존 분석 연결을 그대로 재사용하면 설정 의미가 달라질 수 있어서 이 부분은 연결 팩토리를 두는 게 좋을 거 같아요!


def run_worker() -> None:
logging.basicConfig(level=logging.INFO)
worker = VerificationWorker(

@dldusgh318 dldusgh318 Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 기존 app/jobs/worker.py와 Worker 초기화 구조가 유사한 거 같은데, 따로 만드신 이유가 있을까요??
없다면 큐·serializer·Worker 클래스를 받는 실행 헬퍼는 따로 공통 로직으로 빼도 될 거 같습니다!

raise VerificationIntegrityError("Citation ID or quote does not match the evidence")

for field, text in answer.items():
if any(not covered and not char.isspace() for char, covered in zip(text, coverage[field])):

@dldusgh318 dldusgh318 Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 커버리지 검사는 sourceText가 원문을 덮는지만 확인하고, claim이 해당 원문의 모든 주장을 보존하는지는 확인하지 않는 거 같아요!
예를 들어 전체 문장을 sourceText에 넣고 claim에는 일부 주장만 적어도 이 검사를 통과할 수 있는 거 같습니다.. 인용문 검사도 근거 안에 해당 문자열이 존재하는지 확인하는 수준이라 의미적 뒷받침은 LLM에 의존하는 거 같은데, 보장 범위를 문서에 명시하고, 복합 주장·조건·부정 표현에 대한 실제 모델 평가 사례를 추가하는 것도 좋을 거 같습니당

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

Labels

✨ FEAT New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 최종 분석 설명 검증 API 구현

2 participants