Skip to content

refactor/chatbot routing metadata - #154

Merged
Yu-JeSeung merged 6 commits into
mainfrom
refactor/chatbot-routing-metadata
Aug 15, 2026
Merged

refactor/chatbot routing metadata#154
Yu-JeSeung merged 6 commits into
mainfrom
refactor/chatbot-routing-metadata

Conversation

@Yu-JeSeung

@Yu-JeSeung Yu-JeSeung commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

Closes #148

🎯 배경

  • 챗봇의 질의 분류, tool 선택, 출처 및 fallback 정보가 여러 내부 변수와 로그 인자로 분산되어 있어 처리 경로를 일관되게 관측하기 어려웠습니다.
  • 외부 응답 계약을 유지하면서 내부 routing 결정을 구조화할 metadata 경계가 필요했습니다.

🔍 주요 내용

  • RoutingMetadata를 추가해 intent, route stage, tool, confidence, decision source, source 및 fallback 정보를 정규화했습니다.
  • ToolResult에 결정 출처와 확인된 source URL 정보를 추가했습니다.
  • 모든 챗봇 응답 경로에 routing metadata를 연결했습니다.
  • 실제 source URL 대신 source_counthas_source만 운영 summary 로그에 기록합니다.
  • 기존 {engine, text, url?} 응답 형식과 deterministic tool 선택 순서를 유지했습니다.
  • 공백으로만 구성된 engine override를 정규화해 기본 질의 분류로 fallback하도록 수정했습니다.
  • routing metadata와 tool routing 회귀 테스트 및 관련 운영 문서를 추가했습니다.

변경 요약

챗봇 라우팅 정보를 RoutingMetadata로 통합했습니다. 기존 응답 형식과 결정적 도구 선택 순서는 유지했습니다.

주요 변경점

  • intent, route stage, tool, confidence, 결정 출처, source URL, fallback 정보를 표준화했습니다.
  • ToolResultdecision_sourcesource_urls를 추가했습니다.
  • 캐시, 도구, LLM, fallback 등 모든 응답 경로에 메타데이터를 전달했습니다.
  • 구조화 로그에 source_counthas_source를 기록합니다.
  • 공백만 있는 engine override는 기본 분류를 사용합니다.
  • 라우팅·도구 회귀 검사와 운영 문서를 추가했습니다.

주의/리스크

  • confidence는 단독 SLI나 배포 차단 기준으로 사용하지 않습니다.
  • latency, 오류, fallback rate, 품질은 기존 기준선과 별도 비교가 필요합니다.

다음 액션

  • 회귀 검사 스크립트를 실행합니다.
  • 운영 환경에서 latency, 오류, fallback rate, 품질을 검증합니다.

@Yu-JeSeung Yu-JeSeung self-assigned this Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8feb0860-adb4-4e27-bb4e-c1929bc52770

📥 Commits

Reviewing files that changed from the base of the PR and between 563149b and dce2a9f.

📒 Files selected for processing (1)
  • LLM/OSS/service.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • LLM/OSS/service.py

📝 Walkthrough

Walkthrough

챗봇 라우팅 정보를 불변 RoutingMetadata로 통합했습니다. 도구 결과에 결정 출처와 출처 URL을 추가했습니다. 서비스의 응답, 폴백, 캐시 경로가 라우팅 메타데이터를 구조화 로그에 전달합니다. 회귀 검사와 운영 문서를 갱신했습니다.

Changes

챗봇 라우팅 메타데이터

Layer / File(s) Summary
메타데이터 및 도구 결과 계약
LLM/OSS/routing.py, LLM/OSS/tools.py
normalize_intent_override와 불변 RoutingMetadata를 추가했습니다. ToolResult에 결정 출처와 출처 URL을 추가하고 검색 및 폴백 결과에 값을 설정했습니다.
서비스 라우팅 구성 및 로그 진입점
LLM/OSS/service.py
정규화된 intent와 ToolResultRoutingMetadata로 변환합니다. 요약 로그와 캐시 반환 경로가 메타데이터 필드를 사용합니다.
응답 및 폴백 경로 전파
LLM/OSS/service.py
가드, 정적 응답, 도구, grounded LLM, OSS LLM 및 최종 폴백 경로에 단계, 도구, 출처, 폴백 상태와 LLM 필요 여부를 연결했습니다. 빈 LLM 결과는 주제 복구 또는 대화 폴백으로 처리합니다.
회귀 검증 및 운영 문서
tests/regression/chatbot/*, docs/PLANS.md, docs/operations/OPERATIONS_LOG_SLI_COLLECTION.md
메타데이터 생성, 불변성, 입력 검증, 서비스 전파와 도구별 출처를 검증합니다. 구조화 로그 필드와 운영 해석 규칙을 문서화했습니다.

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

Mergeability Score: ⚪ Minimal · up to dce2a

This change structures chatbot routing metadata while preserving the existing response contract and routing behavior; no actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant chat_with_oss
  participant ToolResult
  participant LLM
  participant StructuredLog

  Client->>chat_with_oss: 요청 및 intent override
  chat_with_oss->>ToolResult: 도구 라우팅 또는 실행
  ToolResult-->>chat_with_oss: 결과, 결정 출처, source URLs
  chat_with_oss->>LLM: 필요한 경우 LLM 요청
  LLM-->>chat_with_oss: 응답 또는 빈 결과
  chat_with_oss->>StructuredLog: RoutingMetadata 기반 요약 기록
Loading

Possibly related PRs

  • dongsooop/AI#121: LLM/OSS/service.pyLLM/OSS/tools.py의 도구 라우팅 및 ToolResult 메타데이터 경로를 확장한 변경입니다.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 라우팅 메타데이터 타입화와 구조화 로그는 구현했지만, 이슈의 Ollama structured classifier shadow 평가 요구사항을 충족하는 변경이나 근거가 없습니다. 미분류 질의 대상 Ollama structured classifier shadow 평가와 기존 baseline 비교 결과를 추가하거나, 해당 범위를 별도 이슈로 분리하십시오.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 챗봇 라우팅 메타데이터 리팩터링이라는 주요 변경을 간결하고 명확하게 설명합니다.
Description check ✅ Passed 설명은 템플릿의 이슈, 배경, 주요 내용 섹션을 모두 포함하고 변경 사항과 호환성 조건을 구체적으로 설명합니다.
Out of Scope Changes check ✅ Passed 코드, 회귀 검사, 운영 문서 변경은 모두 챗봇 라우팅 메타데이터, 로그 관측성, 기존 계약 유지와 직접 관련됩니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/chatbot-routing-metadata

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.

@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: 3

🧹 Nitpick comments (2)
LLM/OSS/service.py (2)

313-319: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

fallback_reason 값 형식을 통일하십시오.

이 경로는 fallback_reasonToolResult.reason의 자유 문장을 넣습니다. 예: "no deterministic tool matched; rag context collected for grounded llm answer". 다른 경로(387-394행, 453-462행)는 "empty_llm_greeting" 같은 짧은 코드를 넣습니다. docs/operations/OPERATIONS_LOG_SLI_COLLECTION.md 39행은 fallback_reason별 count 집계를 규정합니다. 값 형식이 혼재하면 카디널리티가 커지고 집계가 어려워집니다.

ToolResult에 안정적인 fallback_code를 추가하거나, 자유 문장 대신 tool 이름 기반 코드를 사용하십시오. 자유 문장은 _log_tool_routereason 필드로만 남기십시오.

🤖 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 `@LLM/OSS/service.py` around lines 313 - 319, oss_grounded_fallback 경로의
_routing_metadata 호출에서 fallback_reason에 ToolResult.reason 자유 문장을 전달하지 말고 안정적인
코드값을 사용하십시오. ToolResult에 fallback_code를 추가해 이를 전달하거나 기존 tool 이름 기반 코드를 재사용하고, 상세
자유 문장은 _log_tool_route의 reason 필드에만 유지하십시오. 다른 fallback 경로의 짧은 코드 형식과 일관되게
맞추십시오.

453-462: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

사용자 노출 문자열이 중복 선언되어 서로 어긋납니다. 인사말과 근거 부족 안내 문구를 여러 위치에 리터럴로 반복 선언했습니다. 이 때문에 한 곳만 수정하면 fallback 판정이 잘못되거나 문구가 불일치합니다. 두 문구를 모듈 상수로 추출하십시오.

  • LLM/OSS/service.py#L453-L462: 447행의 인사말 리터럴과 453행의 비교 리터럴을 공용 상수 GREETING_FALLBACK_TEXT로 대체하십시오.
  • LLM/OSS/service.py#L479-L485: 482행의 "다시 입력해주세요."를 415행과 동일한 "다시 입력해 주세요."로 맞추고, 두 위치를 공용 상수로 대체하십시오.
🤖 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 `@LLM/OSS/service.py` around lines 453 - 462, LLM/OSS/service.py lines 453-462:
extract the greeting fallback text into the shared GREETING_FALLBACK_TEXT module
constant and replace both the greeting literal near line 447 and the comparison
in the routing metadata around lines 453-462. LLM/OSS/service.py lines 479-485:
standardize the retry text to “다시 입력해 주세요.”, extract it into a shared module
constant, and reuse that constant at both the existing line 415 location and the
fallback response around line 482.
🤖 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 `@docs/operations/OPERATIONS_LOG_SLI_COLLECTION.md`:
- Line 100: Update the intent definition row in OPERATIONS_LOG_SLI_COLLECTION.md
to include the guard-path value intent="guard", which is recorded before
decide_mode() by the guard branches. Clarify that this value is a guard
classification alongside decide_mode() and request overrides, while preserving
the existing explanation about its relationship to the response engine and
routing distribution.

In `@LLM/OSS/service.py`:
- Around line 519-531: In the not-fused fallback block, evaluate
looks_like_topic(user_text) before calling run_mode_tools("topic", user_text),
and only invoke the tool when the check is true. Preserve the existing
recovery.text success path and conversation_fallback behavior for non-topic
input or empty recovery results.
- Around line 479-485: Update the shared guidance message used near the OSS
response and the corresponding message around line 415 to use the correctly
spaced “다시 입력해 주세요.” wording, and extract both usages into a single shared
constant to keep the text consistent.

---

Nitpick comments:
In `@LLM/OSS/service.py`:
- Around line 313-319: oss_grounded_fallback 경로의 _routing_metadata 호출에서
fallback_reason에 ToolResult.reason 자유 문장을 전달하지 말고 안정적인 코드값을 사용하십시오. ToolResult에
fallback_code를 추가해 이를 전달하거나 기존 tool 이름 기반 코드를 재사용하고, 상세 자유 문장은 _log_tool_route의
reason 필드에만 유지하십시오. 다른 fallback 경로의 짧은 코드 형식과 일관되게 맞추십시오.
- Around line 453-462: LLM/OSS/service.py lines 453-462: extract the greeting
fallback text into the shared GREETING_FALLBACK_TEXT module constant and replace
both the greeting literal near line 447 and the comparison in the routing
metadata around lines 453-462. LLM/OSS/service.py lines 479-485: standardize the
retry text to “다시 입력해 주세요.”, extract it into a shared module constant, and reuse
that constant at both the existing line 415 location and the fallback response
around line 482.
🪄 Autofix

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 Plus

Run ID: 2d1504a8-4e88-4580-96a8-189fe582177b

📥 Commits

Reviewing files that changed from the base of the PR and between 0e06f07 and 563149b.

📒 Files selected for processing (7)
  • LLM/OSS/routing.py
  • LLM/OSS/service.py
  • LLM/OSS/tools.py
  • docs/PLANS.md
  • docs/operations/OPERATIONS_LOG_SLI_COLLECTION.md
  • tests/regression/chatbot/check_chatbot_routing_metadata.py
  • tests/regression/chatbot/check_chatbot_tool_routing.py


| 필드 | 의미 | 운영 해석 |
| --- | --- | --- |
| `intent` | `decide_mode()` 또는 요청 override로 정해진 최초 내부 분류 | 사용자 응답의 `engine`과 다를 수 있으며 routing 분포를 보는 기준 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

intent의 guard 경로 값을 문서에 추가하십시오.

이 행은 intent를 "decide_mode() 또는 요청 override로 정해진 최초 내부 분류"로 정의합니다. LLM/OSS/service.py 211행과 220행의 guard 경로는 decide_mode() 실행 이전에 intent="guard"를 기록합니다. 따라서 intent=guard는 현재 정의에 해당하지 않습니다. 운영자가 intent 분포를 집계할 때 오해할 수 있습니다. guard 경로 값을 정의에 포함하십시오.

📝 제안 수정
-| `intent` | `decide_mode()` 또는 요청 override로 정해진 최초 내부 분류 | 사용자 응답의 `engine`과 다를 수 있으며 routing 분포를 보는 기준 |
+| `intent` | `decide_mode()` 또는 요청 override로 정해진 최초 내부 분류. guard 경로는 분류 이전에 차단되므로 `guard`를 기록 | 사용자 응답의 `engine`과 다를 수 있으며 routing 분포를 보는 기준 |
📝 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
| `intent` | `decide_mode()` 또는 요청 override로 정해진 최초 내부 분류 | 사용자 응답의 `engine`과 다를 수 있으며 routing 분포를 보는 기준 |
| `intent` | `decide_mode()` 또는 요청 override로 정해진 최초 내부 분류. guard 경로는 분류 이전에 차단되므로 `guard`를 기록 | 사용자 응답의 `engine`과 다를 수 있으며 routing 분포를 보는 기준 |
🤖 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 `@docs/operations/OPERATIONS_LOG_SLI_COLLECTION.md` at line 100, Update the
intent definition row in OPERATIONS_LOG_SLI_COLLECTION.md to include the
guard-path value intent="guard", which is recorded before decide_mode() by the
guard branches. Clarify that this value is a guard classification alongside
decide_mode() and request overrides, while preserving the existing explanation
about its relationship to the response engine and routing distribution.

Comment thread LLM/OSS/service.py
Comment on lines +479 to +485
return cache_and_return(
{
"engine": "oss",
"text": "관련 근거를 충분히 확인하지 못했어요. 질문을 조금 더 구체적으로 다시 입력해주세요."
},
routing,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

동일한 안내 문구의 띄어쓰기를 통일하십시오.

482행은 "다시 입력해주세요."를 사용합니다. 415행은 같은 안내에서 "다시 입력해 주세요."를 사용합니다. 한국어 맞춤법 기준으로 보조용언은 띄어 쓰는 형태가 권장됩니다. 두 문구를 하나의 상수로 통일하십시오.

✏️ 제안 수정
-                    "text": "관련 근거를 충분히 확인하지 못했어요. 질문을 조금 더 구체적으로 다시 입력해주세요."
+                    "text": "관련 근거를 충분히 확인하지 못했어요. 질문을 조금 더 구체적으로 다시 입력해 주세요.",
📝 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
return cache_and_return(
{
"engine": "oss",
"text": "관련 근거를 충분히 확인하지 못했어요. 질문을 조금 더 구체적으로 다시 입력해주세요."
},
routing,
)
return cache_and_return(
{
"engine": "oss",
"text": "관련 근거를 충분히 확인하지 못했어요. 질문을 조금 더 구체적으로 다시 입력해 주세요.",
},
routing,
)
🤖 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 `@LLM/OSS/service.py` around lines 479 - 485, Update the shared guidance
message used near the OSS response and the corresponding message around line 415
to use the correctly spaced “다시 입력해 주세요.” wording, and extract both usages into
a single shared constant to keep the text consistent.

Comment thread LLM/OSS/service.py
@Yu-JeSeung Yu-JeSeung added the fix label Aug 13, 2026
@Yu-JeSeung
Yu-JeSeung merged commit 9dc3aa6 into main Aug 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] OCI 환경 AI 서비스 성능 및 품질 고도화

1 participant