Skip to content

feat: add rag quality evaluation question set - #120

Merged
Yu-JeSeung merged 2 commits into
mainfrom
feat/rag-evaluation-regression
May 24, 2026
Merged

feat: add rag quality evaluation question set#120
Yu-JeSeung merged 2 commits into
mainfrom
feat/rag-evaluation-regression

Conversation

@Yu-JeSeung

@Yu-JeSeung Yu-JeSeung commented May 23, 2026

Copy link
Copy Markdown
Contributor

🎯 배경

  • 챗봇 기능의 취업 어필력을 높이기 위해 단순 구현 여부가 아니라 RAG 품질을 측정하고 회귀로 관리할 수 있는 평가 체계가 필요했습니다.
  • 질문 세트 구축, 검색 결과 평가, 답변 근거성 평가, GitHub Actions 경량 자동화를 한 흐름으로 정리했습니다.

🔍 주요 내용

  • debug/regression/questions/*.json에 학사일정, 연락처, 장학금, 수강신청, 졸업, 학과/기숙사 질문 세트 30개를 추가했습니다.
  • tests/regression/evaluate_rag_retrieval.py가 질문 디렉터리 로딩, schema 검증, top-k 검색 평가, 답변 키워드/출처/날짜/환각 proxy 리포트를 지원하도록 개선했습니다.
  • RAG Light Check 워크플로에서 질문 세트 schema와 query-index 경량 회귀를 검증하도록 연결했습니다.
  • README에 RAG 품질 평가 흐름과 실행 명령, 검색 recall 개선 전/후 기록 표를 추가했습니다.

변경 요약(1~3줄)

RAG(검색-생성) 품질 평가 파이프라인을 추가해 회귀용 질문 세트(30개)로 검색 리콜·답변 근거성·환각 여부 등을 자동으로 검증하도록 했습니다. 평가 스크립트와 경량 CI 워크플로우를 보강하고 문서와 .gitignore를 업데이트했습니다.

주요 변경점

  • 질문 세트 추가: debug/regression/questions/*.json에 학사일정, 연락처, 졸업/학과/생활, 정책 등 총 약 30개 케이스 추가
  • 평가 스크립트 개선: tests/regression/evaluate_rag_retrieval.py에 디렉터리 기반 로드, 배열/객체 형태 지원, validate-only 옵션, DEFAULT_CASES_PATH 및 validate_cases(), configure_default_artifact_env() 추가
  • 에러/지표 처리 강화: 검색·스케줄·답변 단계별 예외 기록(errors.{retrieval,schedule,answer}), top-k 리콜 및 키워드/날짜/출처/환각 프록시 리포트
  • CI 워크플로우 변경: .github/workflows/rag-light-check.yml이 전체 질문 세트의 스키마 검증(--validate-only) 및 경량 회귀 체크를 수행하도록 업데이트
  • 문서화: README에 RAG 품질 평가 흐름, 실행 명령 예시, 비교 테이블(기준선/브랜치/CI 결과) 추가
  • .gitignore: debug/ 디렉터리 예외 패턴을 정리해 regression/questions를 추적하도록 수정

주의/리스크

  • 평가 스크립트 확장으로 유지보수·테스트 부담 증가 가능
  • configure_default_artifact_env()가 환경 의존성을 숨겨 디버깅을 어렵게 할 수 있음
  • 경량 CI는 전체 통합 테스트를 대체하지 않으므로 실제 결과와 차이 발생 가능

다음 액션

  • CI 실행 결과(리포트) 모니터링 및 실패 케이스 원인 분석
  • 질문 세트·도메인 확장 및 평가 기준(예: 환각 판정) 정교화
  • 필요 시 평가 스크립트의 로깅/디버깅 출력 강화

Review Change Stack

@Yu-JeSeung Yu-JeSeung self-assigned this May 23, 2026
@Yu-JeSeung Yu-JeSeung added feat run-rag-check check rag eval labels May 23, 2026
@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7ec68b5a-cdcc-4348-90f4-2c14cd02ef6e

📥 Commits

Reviewing files that changed from the base of the PR and between 854363a and 883cd47.

📒 Files selected for processing (1)
  • tests/regression/evaluate_rag_retrieval.py

📝 Walkthrough

Walkthrough

PR #120은 RAG 회귀 검증 스크립트에 디렉터리 기반 케이스 로드와 스키마 검증을 추가하고, 평가 단계별 오류 처리를 강화하며, 회귀 질문 세트 데이터와 워크플로우·문서를 업데이트합니다.

변경 사항

RAG 회귀 검증 인프라 및 데이터

Layer / File(s) Summary
워크플로우 · 문서 · .gitignore
.github/workflows/rag-light-check.yml, .gitignore, README.md
GitHub Actions가 --validate-only 플래그로 evaluate_rag_retrieval.py를 호출하도록 변경하고, 워크플로우 단계 설명을 "질문 세트 스키마 검증"으로 갱신하며 .gitignoredebug/regression/questions/ 예외 추가 및 README의 RAG 품질 평가 섹션을 추가했습니다.
회귀 테스트 질문 세트 데이터
debug/regression/questions/academic_schedule.json, debug/regression/questions/contacts.json, debug/regression/questions/graduate_department_life.json, debug/regression/questions/policies.json
학사 일정(5개), 연락처(6개), 졸업/학부 생활(10개), 정책(8개) 등 검색·스케줄 기반 회귀 케이스 JSON 파일을 추가했습니다.
케이스 발견 및 스키마 검증
tests/regression/evaluate_rag_retrieval.py
DEFAULT_CASES_PATH 도입, 디렉터리 또는 단일 JSON 파일 로드 지원, JSON 배열 및 {category, cases} 형식 처리, validate_cases()로 필수 필드와 기대 제약 검증, configure_default_artifact_env()로 로컬 실행용 기본 환경 변수 주입을 추가했습니다.
검색 케이스 평가 오류 처리
tests/regression/evaluate_rag_retrieval.py
evaluate_search_case()에서 hybrid_search/build_answer 임포트 실패와 실행 예외를 별도 흐름으로 캡처하여 errors.retrieval/errors.answer로 기록하고, hits가 None/빈 경우 안전하게 top1 정보를 추출하며 passed 조건에 에러 부재를 포함하도록 변경했습니다.
일정 케이스 평가 오류 처리
tests/regression/evaluate_rag_retrieval.py
evaluate_schedule_case()에서 schedule_search 임포트/실행 오류를 errors.schedule에 기록하고, 반환 결과에 errors를 포함하며 passed 조건에 에러 부재를 요구하도록 변경했습니다.
CLI 통합 및 실패 이유 포맷
tests/regression/evaluate_rag_retrieval.py
main()--cases 기본값을 DEFAULT_CASES_PATH로 설정하고 --validate-only 플래그를 추가했습니다. 케이스 로드 후 validate_cases() 실패 시 즉시 종료하며, 실패 케이스 출력에 단계별 stage:error 형식의 이유를 포함합니다.

예상 코드 리뷰 노력

🎯 4 (복잡) | ⏱️ ~45분

관련 PR

  • dongsooop/AI#110: 동일한 tests/regression/evaluate_rag_retrieval.py 파일을 다루며, 본 PR이 케이스 로드/검증 및 --validate-only 모드를 추가한 변경과 코드적 연결성이 높습니다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a RAG quality evaluation question set with 30 test cases and supporting infrastructure.
Description check ✅ Passed The description includes all required template sections (배경, 주요 내용) with detailed information about changes, but the related issue section is missing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat/rag-evaluation-regression

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@debug/regression/questions/graduate_department_life.json`:
- Around line 1-2: This file's JSON uses per-case "category" fields inside the
"cases" array but lacks a top-level "category" like other files; either add a
top-level "category" key (e.g., "category": "graduate_department_life")
alongside "cases" to match the schema used by academic_schedule.json,
contacts.json, policies.json, or update the schema/validator to accept per-case
categories; locate the "cases" array in graduate_department_life.json and either
insert the top-level "category" entry or adjust the validation logic that
references "category" to accept case-level category keys.
- Around line 64-71: The test case with id "department_visual_design_intro" has
mismatched URL expectations: expected_url_contains is ["4647/subview.do"] but
answer_must_contain_any contains "4649/subview.do", which weakens the source URL
check when requires_source_url is true; fix by making the URLs consistent—either
change answer_must_contain_any to include "4647/subview.do" (or replace 4649
with 4647) or, if 4649 should also be acceptable, update expected_url_contains
and the source URL validation criteria to include both "4647/subview.do" and
"4649/subview.do" so source_url_match reflects the intended acceptance.

In `@README.md`:
- Around line 93-97: Update the README table row labeled "CI 경량 회귀": replace the
"synthetic + schema" description with a clear note that the CI job performs
schema-only validation using the --validate-only flag (no synthetic test cases
are executed), and replace the ambiguous "리포트 기준값" text with an explicit
baseline report location name (e.g., baseline_report.json or
rag_eval_report.json) so readers know where the baseline is stored; ensure the
changes specifically touch the "CI 경량 회귀" row and the columns that currently
show "synthetic + schema" and "리포트 기준값".

In `@tests/regression/evaluate_rag_retrieval.py`:
- Around line 178-204: The test currently collapses multiple failure sources
into a single "error" field (e.g., import_error, retrieval_error, answer_error)
which loses which stage failed; update the result objects created in the import
try/except and the other similar result constructions to preserve stage-specific
error fields (keep import_error, add retrieval_error and answer_error keys where
applicable) instead of merging them into one "error" string, and ensure any
later logic that sets retrieval_error or answer_error assigns into those
dedicated keys (e.g., the import block around importing
LLM.sub_model.query_index and the result dicts built after
schedule_search/hybrid_search) so both import and runtime errors are reported
independently; apply the same change to the other blocks mentioned (the result
constructions at the other ranges) so reports always expose import_error,
retrieval_error, and answer_error separately.
- Around line 65-95: validate_cases currently only checks presence of fields but
not their types; update validate_cases to validate types for
expected_url_contains and expected_title_contains (must be list[str] or
empty/absent), answer_must_contain_any and answer_must_contain_all (must be
list[str]), and boolean flags like requires_source_url (must be bool); for each
invalid type append an error like "{prefix}:invalid_type:<field>" (use the
existing prefix variable and case id logic), use isinstance checks and ensure
list items are str (reject non-list or lists with non-str items), and keep
existing presence checks (e.g., missing_expected_source) but only after type
validation to avoid treating strings as iterables.
- Line 391: The default output argument currently hardcodes a world-writable
/tmp path in the ap.add_argument("--out", ...) call which can cause collisions
and symlink attacks; change the default to a safer option (e.g., no default or a
path inside the repository such as a reports/ subdir) and when the CLI runs,
create a unique tempfile or use tempfile.NamedTemporaryFile/tmpdir or pathlib to
ensure a per-run unique and non-world-writable file; update the code that
consumes the --out value to create the directory if missing and write to that
resolved safe path instead of assuming /tmp.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d95766e2-8801-409b-adf7-0e47af8eb300

📥 Commits

Reviewing files that changed from the base of the PR and between 409523d and 854363a.

📒 Files selected for processing (8)
  • .github/workflows/rag-light-check.yml
  • .gitignore
  • README.md
  • debug/regression/questions/academic_schedule.json
  • debug/regression/questions/contacts.json
  • debug/regression/questions/graduate_department_life.json
  • debug/regression/questions/policies.json
  • tests/regression/evaluate_rag_retrieval.py

Comment on lines +1 to +2
{
"cases": [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

스키마 일관성: 최상위 category 필드가 누락되었습니다.

다른 질문 세트 파일(academic_schedule.json, contacts.json, policies.json)은 모두 최상위 레벨에 "category" 필드를 선언하지만, 이 파일은 각 케이스마다 개별 category 필드를 사용합니다. 스키마 검증 로직이 두 패턴을 모두 허용하는지 확인이 필요하며, 일관성을 위해 다른 파일과 동일한 구조를 사용하는 것을 권장합니다.

♻️ 제안된 수정 (일관성 개선)

만약 이 파일의 모든 케이스가 혼합된 카테고리를 가지므로 최상위 category가 적절하지 않다면, 현재 구조를 유지하되 스키마 검증 코드가 이를 지원하는지 확인하세요. 그렇지 않고 단일 카테고리로 그룹화 가능하다면:

 {
+  "category": "mixed",
   "cases": [
     {
       "id": "grad_professional_associate",
-      "category": "grad",
       "kind": "search",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@debug/regression/questions/graduate_department_life.json` around lines 1 - 2,
This file's JSON uses per-case "category" fields inside the "cases" array but
lacks a top-level "category" like other files; either add a top-level "category"
key (e.g., "category": "graduate_department_life") alongside "cases" to match
the schema used by academic_schedule.json, contacts.json, policies.json, or
update the schema/validator to accept per-case categories; locate the "cases"
array in graduate_department_life.json and either insert the top-level
"category" entry or adjust the validation logic that references "category" to
accept case-level category keys.

Comment on lines +64 to +71
"id": "department_visual_design_intro",
"category": "department",
"kind": "search",
"query": "시각디자인과 소개",
"expected_url_contains": ["4647/subview.do"],
"expected_title_contains": ["시각디자인과"],
"answer_must_contain_any": ["시각디자인과", "4649/subview.do"],
"requires_source_url": true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify actual visual design department URLs in the search index

rg -i "시각디자인과" --type=py -C3 -g '!debug/**'

Repository: dongsooop/AI

Length of output: 38


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== File snippet ==="
nl -ba debug/regression/questions/graduate_department_life.json | sed -n '50,90p'

echo "=== Find expected URL substrings ==="
rg -n --fixed-string "4647/subview.do" .
rg -n --fixed-string "4649/subview.do" .

echo "=== Find 시각디자인과 occurrences (limited to repo relevant dirs) ==="
rg -n -i "시각디자인과" debug . || true

Repository: dongsooop/AI

Length of output: 138


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== File snippet ==="
nl -ba debug/regression/questions/graduate_department_life.json | sed -n '50,90p'

echo "=== Find expected URL substrings ==="
rg -n --fixed-string "4647/subview.do" .
rg -n --fixed-string "4649/subview.do" .

echo "=== Find 시각디자인과 occurrences (limited to debug + rest) ==="
rg -n -i "시각디자인과" debug . || true

Repository: dongsooop/AI

Length of output: 138


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== File snippet ==="
nl -ba debug/regression/questions/graduate_department_life.json | sed -n '50,90p'

echo "=== Find expected URL substrings ==="
rg -n --fixed-string "4647/subview.do" .
rg -n --fixed-string "4649/subview.do" .

echo "=== Find 시각디자인과 occurrences (limited to debug + rest) ==="
rg -n -i "시각디자인과" debug . || true

Repository: dongsooop/AI

Length of output: 138


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="debug/regression/questions/graduate_department_life.json"

echo "=== File snippet (awk with line numbers) ==="
awk 'NR>=50 && NR<=90 {printf "%d:%s\n", NR, $0}' "$FILE"

echo "=== Find expected URL substrings ==="
rg -n --fixed-string "4647/subview.do" .
rg -n --fixed-string "4649/subview.do" .

echo "=== Find 시각디자인과 occurrences ==="
rg -n -i "시각디자인과" . || true

Repository: dongsooop/AI

Length of output: 2113


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="debug/regression/questions/graduate_department_life.json"

echo "=== File snippet (awk with line numbers) ==="
awk 'NR>=50 && NR<=90 {printf "%d:%s\n", NR, $0}' "$FILE"

echo "=== Find expected URL substrings (4647 / 4649) ==="
rg -n --fixed-strings "4647/subview.do" .
rg -n --fixed-strings "4649/subview.do" .

echo "=== Find '시각디자인과' occurrences ==="
rg -n -i "시각디자인과" . || true

Repository: dongsooop/AI

Length of output: 2716


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "expected_url_contains" . 
rg -n "answer_must_contain_any" .

Repository: dongsooop/AI

Length of output: 12396


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/regression/evaluate_rag_retrieval.py"

echo "=== evaluate_rag_retrieval.py: top relevant section ==="
sed -n '60,120p' "$FILE"

echo "=== evaluate_rag_retrieval.py: expected_urls / answer checks ==="
sed -n '200,270p' "$FILE"

Repository: dongsooop/AI

Length of output: 5687


테스트 기대 URL과 답변 키워드 URL이 불일치(의도 약화)

debug/regression/questions/graduate_department_life.json에서 expected_url_contains4647/subview.do를 기대하지만, requires_source_url: true일 때는 답변에 expected_url_contains(즉 4647/subview.do)가 포함됐는지로 source_url_match를 판단합니다. 그런데 answer_must_contain_any에 다른 URL인 4649/subview.do가 들어가 있어 답변에 4649가 없어도 "시각디자인과"만으로 통과할 수 있습니다(테스트 의도가 흐려짐). answer_must_contain_any4647/subview.do로 통일하거나, 4649를 함께 허용하려면 expected_url_contains/검증 기준도 같이 조정하는 편이 좋습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@debug/regression/questions/graduate_department_life.json` around lines 64 -
71, The test case with id "department_visual_design_intro" has mismatched URL
expectations: expected_url_contains is ["4647/subview.do"] but
answer_must_contain_any contains "4649/subview.do", which weakens the source URL
check when requires_source_url is true; fix by making the URLs consistent—either
change answer_must_contain_any to include "4647/subview.do" (or replace 4649
with 4647) or, if 4649 should also be acceptable, update expected_url_contains
and the source URL validation criteria to include both "4647/subview.do" and
"4649/subview.do" so source_url_match reflects the intended acceptance.

Comment thread README.md
Comment on lines +93 to +97
| 구분 | 질문 세트 | 검색 Recall@3 | 답변 근거성 | 비고 |
| --- | ---: | ---: | ---: | --- |
| 개선 전 기준선 | 30개 | 리포트 기준값 | 리포트 기준값 | `/tmp/rag_eval_report.json` 또는 저장된 baseline 리포트 |
| 현재 브랜치 | 30개 | `summary.top3_url_accuracy` | `summary.source_url_pass_rate` | `evaluate_rag_retrieval.py` 실행 결과로 갱신 |
| CI 경량 회귀 | synthetic + schema | 통과/실패 | 통과/실패 | 무거운 임베딩 모델 다운로드 없이 PR에서 빠르게 검증 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

표의 "CI 경량 회귀" 행 설명을 명확히 하세요.

Line 97에서 "synthetic + schema"라고 기술했으나, 실제 워크플로우(.github/workflows/rag-light-check.yml)는 --validate-only로 스키마 검증만 수행합니다. "synthetic" 테스트 케이스는 현재 워크플로우에 포함되지 않았으므로 독자에게 혼란을 줄 수 있습니다.

또한 Line 95의 "리포트 기준값"이 어디에 저장되는지(예: baseline_report.json 파일 경로) 명시하면 더 명확합니다.

📝 제안된 수정
-| 개선 전 기준선 | 30개 | 리포트 기준값 | 리포트 기준값 | `/tmp/rag_eval_report.json` 또는 저장된 baseline 리포트 |
+| 개선 전 기준선 | 30개 | 리포트 기준값 | 리포트 기준값 | 저장된 baseline 리포트 파일 (예: `baseline_report.json`) |
 | 현재 브랜치 | 30개 | `summary.top3_url_accuracy` | `summary.source_url_pass_rate` | `evaluate_rag_retrieval.py` 실행 결과로 갱신 |
-| CI 경량 회귀 | synthetic + schema | 통과/실패 | 통과/실패 | 무거운 임베딩 모델 다운로드 없이 PR에서 빠르게 검증 |
+| CI 경량 회귀 | schema | 통과/실패 | 통과/실패 | 스키마 검증 및 Python 컴파일 체크만 수행 (임베딩 모델 다운로드 없음) |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| 구분 | 질문 세트 | 검색 Recall@3 | 답변 근거성 | 비고 |
| --- | ---: | ---: | ---: | --- |
| 개선 전 기준선 | 30개 | 리포트 기준값 | 리포트 기준값 | `/tmp/rag_eval_report.json` 또는 저장된 baseline 리포트 |
| 현재 브랜치 | 30개 | `summary.top3_url_accuracy` | `summary.source_url_pass_rate` | `evaluate_rag_retrieval.py` 실행 결과로 갱신 |
| CI 경량 회귀 | synthetic + schema | 통과/실패 | 통과/실패 | 무거운 임베딩 모델 다운로드 없이 PR에서 빠르게 검증 |
| 구분 | 질문 세트 | 검색 Recall@3 | 답변 근거성 | 비고 |
| --- | ---: | ---: | ---: | --- |
| 개선 전 기준선 | 30개 | 리포트 기준값 | 리포트 기준값 | 저장된 baseline 리포트 파일 (예: `baseline_report.json`) |
| 현재 브랜치 | 30개 | `summary.top3_url_accuracy` | `summary.source_url_pass_rate` | `evaluate_rag_retrieval.py` 실행 결과로 갱신 |
| CI 경량 회귀 | schema | 통과/실패 | 통과/실패 | 스키마 검증 및 Python 컴파일 체크만 수행 (임베딩 모델 다운로드 없음) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 93 - 97, Update the README table row labeled "CI 경량
회귀": replace the "synthetic + schema" description with a clear note that the CI
job performs schema-only validation using the --validate-only flag (no synthetic
test cases are executed), and replace the ambiguous "리포트 기준값" text with an
explicit baseline report location name (e.g., baseline_report.json or
rag_eval_report.json) so readers know where the baseline is stored; ensure the
changes specifically touch the "CI 경량 회귀" row and the columns that currently
show "synthetic + schema" and "리포트 기준값".

Comment thread tests/regression/evaluate_rag_retrieval.py
Comment thread tests/regression/evaluate_rag_retrieval.py
ap.add_argument("--top-k", type=int, default=5, help="hybrid_search top_k for retrieval metrics")
ap.add_argument("--answer-top-k", type=int, default=6, help="build_answer top_k for answer metrics")
ap.add_argument("--schedule-top-k", type=int, default=5, help="schedule_search top_k for schedule cases")
ap.add_argument("--out", default="/tmp/rag_eval_report.json", help="output report path")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

기본 출력 경로를 고정 /tmp 파일로 두지 않는 편이 좋습니다.

고정된 world-writable 경로는 병렬 실행 시 충돌하기 쉽고, 로컬에서는 사전 생성된 심볼릭 링크를 따라갈 위험도 있습니다. 기본값은 저장소 내부 경로나 실행마다 고유한 tempfile로 바꾸는 쪽이 안전합니다.

제안 diff
-    ap.add_argument("--out", default="/tmp/rag_eval_report.json", help="output report path")
+    ap.add_argument(
+        "--out",
+        default=str(ROOT_DIR / "debug" / "regression" / "rag_eval_report.json"),
+        help="output report path",
+    )
🧰 Tools
🪛 Ruff (0.15.13)

[error] 391-391: Probable insecure usage of temporary file or directory: "/tmp/rag_eval_report.json"

(S108)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/regression/evaluate_rag_retrieval.py` at line 391, The default output
argument currently hardcodes a world-writable /tmp path in the
ap.add_argument("--out", ...) call which can cause collisions and symlink
attacks; change the default to a safer option (e.g., no default or a path inside
the repository such as a reports/ subdir) and when the CLI runs, create a unique
tempfile or use tempfile.NamedTemporaryFile/tmpdir or pathlib to ensure a
per-run unique and non-world-writable file; update the code that consumes the
--out value to create the directory if missing and write to that resolved safe
path instead of assuming /tmp.

@Yu-JeSeung
Yu-JeSeung merged commit 7351767 into main May 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat run-rag-check check rag eval

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant