Skip to content

component chat assistant

JJong-03 edited this page Jun 17, 2026 · 4 revisions

컴포넌트 - AI 채팅 어시스턴트

본사 관제자가 자연어로 공장 상태·원인·보고서·증빙 이미지를 물어보는 Dashboard의 챗봇 QA 기능이다. 질문은 Dashboard Backend가 해석하고, Backend가 직접 read model을 조회해 근거(Evidence)를 만든 뒤 답변을 생성한다. LLM은 질문 해석과 최종 설명에만 쓰며, 데이터 조회 자체는 항상 Backend 코드가 수행한다.


책임과 경계

Dashboard Web (/chat)
  -> POST /chat/query  (Cognito JWT)
      -> 질문 해석 (intent + 시간 + 공장)            services.chat / services.bedrock
      -> RBAC: 공장/시스템 범위 강제 (데이터 조회 이전)  deps.rbac
      -> 데이터 도구 실행 (Backend가 데이터를 찾음)      services.ddb / services.s3
      -> Evidence 구성 (확인 / 추정 / 데이터 한계)
      -> 답변 생성 (Bedrock 또는 규칙 템플릿)           services.bedrock / services.chat
  -> 답변 + Evidence 패널 + 증빙 이미지 렌더링

핵심 원칙:

  • RBAC가 단일 경계다. 공장/시스템 범위 검사를 어떤 데이터 도구보다 먼저 수행한다. 사용자가 접근할 수 없는 공장에 대해서는 DynamoDB/S3 호출 자체를 하지 않는다. LLM이 고른 대상도 같은 검사로 재검증해, 채팅이 RBAC 우회 통로가 되지 않게 한다.
  • 답변은 Backend가 찾은 근거에만 기반한다. LLM은 자유롭게 사실을 만들어내는 주체가 아니라, Backend가 만든 Evidence를 사람이 읽기 좋게 정리하는 역할이다.
  • LLM 장애에 우아하게 degrade한다. Bedrock 해석/설명이 실패하면 결정론적 규칙 파서·템플릿으로 fallback하며, 그 사이 데이터 파이프라인은 동일하다.

처리 흐름 (POST /chat/query)

routers/chat.py가 다음 순서로 처리한다.

  1. 질문 해석_resolve_parsed. 라우팅이 켜져 있고 Bedrock이 활성이면 LLM이 intent·시간·공장을 추출(router="llm")하고, 아니면/실패 시 결정론적 규칙 파서로 해석(router="rule")한다. 해석 입력은 질문 텍스트뿐이라 RBAC 이전에 실행해도 공장 데이터가 새지 않는다.
  2. 선행 종료 — intent가 unknown이거나, 공장이 필요한데 식별되지 않으면 데이터 조회 없이 안내 답변을 돌려준다.
  3. RBAC 강제 — 대상이 cloud-infrarequire_system_access, 일반 공장이면 require_factory_access. 통과해야만 데이터 도구가 실행된다.
  4. Evidence 수집_fetch_evidence가 intent/시간에 맞는 도구를 고른다(아래 표).
  5. 증빙 이미지(선택) — 질문에 이미지 키워드가 있으면 _maybe_fetch_image_refrequire_system_access 후 S3 이미지 스냅샷을 조회해 image_ref로 동봉한다.
  6. 답변 생성_explain. Bedrock 활성 시 LLM이 Evidence 위에서 설명을 쓰고(generator="bedrock"), 아니면/실패 시 규칙 템플릿(generator="rule").

Intent와 데이터 도구

Intent 의미 주 데이터 소스
current_status 지금 상태 DynamoDB LATEST
cause_analysis 점수 급락/이상 원인 DynamoDB HISTORY 또는 S3 processed 상세(risk_score drill-down)
history_trend 구간 추이 DynamoDB HISTORY/GRAPH#5M, 필요 시 S3 state_snapshot 보강
spike_check 특정 지표 임계 초과/급등 여부 S3 processed_agg/metrics_5m + state_snapshot 상세
report 일간 보고서 근거 요약 S3 reports/daily/ Markdown
unknown 해석 불가 없음(안내만)
  • 과거 시점·구간 질문은 TTL이 있는 DynamoDB 대신 S3 processed 를 우선 읽어 오래된 데이터도 조회한다.
  • spike_check는 지표(risk_score/ai_detection/temperature)와 임계·비교(이상/이하)를 파싱해 결정론적으로 판정한다.

Evidence 모델

답변과 별개로, 화면에는 근거가 출처와 함께 노출된다. Evidence는 세 묶음으로 나뉜다.

구분 의미
confirmed read model에서 직접 확인한 값 안전점수, 평균/최저~최고, 점수 변화, 온도, AI 탐지 최대, 표본 수, 이미지 개수·시각 범위
inferred 확인값으로부터의 추정·해석 "AI 탐지 상승과 이미지 스냅샷이 같은 시간대에 확인됨"
missing 조회했으나 없거나 실패한 데이터 한계 "요청 시각 범위에서 S3 image_snapshot 객체를 찾지 못함"

이 구분은 답변 신뢰성의 핵심이다. 확인된 사실과 추정을 섞지 않고, 데이터 한계를 숨기지 않는다.


응답 envelope

POST /chat/query 응답:

{
  "answer": "<Markdown 답변>",
  "intent": "cause_analysis",
  "factory_id": "factory-a",
  "time_scope": { "...": "해석된 시간 범위/시점" },
  "evidence": { "confirmed": { }, "inferred": [], "missing": [] },
  "image_ref": {
    "kind": "image_snapshots",
    "factory_id": "factory-a",
    "time_range_kst": "2026-06-09 09:25~09:45 KST",
    "count": 3,
    "items": [ { "s3_key": "...", "filename": "...", "url": "<presigned GET>", "detection_type": "FIRE" } ]
  },
  "generator": "bedrock",
  "model_tier": "precise",
  "router": "llm"
}
  • generator: bedrock | rule — 답변을 LLM이 썼는지 규칙 템플릿이 썼는지.
  • model_tier: fast | precise | null — 응답 모드. 실제 model id는 노출하지 않는다(관리자 전용).
  • router: llm | rule — intent/시간을 LLM이 해석했는지 규칙이 해석했는지.
  • image_ref: 증빙 이미지가 있을 때만. presigned GET URL은 Image Snapshot Pipeline의 대시보드 조회 경로와 동일하다.

Chat 화면 (/chat)

apps/dashboard-webChatPage가 대화형 UI를 그린다.

  • 추천 질문과 자유 입력(최대 500자)을 제공한다. 공장 selector("질문에서 식별" 포함)와 응답 모드 selector(자동/빠른 답변/정밀 분석)를 함께 보낸다.
  • 응답 대기 동안 진행 단계(질문 해석 → 접근 범위 확인 → DynamoDB 조회 → S3 상세 확인 → 답변 정리)를 표시한다. 실제 단계 진행을 그대로 반영하는 것이 아니라 사용자 체감용 progress이다.
  • 답변은 Markdown으로 렌더링하고, 그 아래 Evidence 패널에 증빙 이미지 / 확인된 값 / 추정 / 데이터 한계를 구분해 보여준다. 증빙 이미지는 presigned URL <img>이며 클릭 시 원본을 새 탭으로 연다.

권한과 보안

  • 모든 요청은 Cognito JWT가 필요하다(get_current_principal).
  • 공장/시스템 범위는 데이터 조회 이전에 강제되며, LLM이 선택한 대상도 재검증한다.
  • 증빙 이미지 경로는 별도로 require_system_access를 통과해야 한다. presigned URL은 짧은 만료와 대상 object key로 제한되고, S3 객체에 public ACL을 부여하지 않는다.
  • 응답에 raw model id, 토큰, 전체 endpoint 주소 같은 민감 정보를 싣지 않는다.
  • 쓰기 기능이 아니다. 채팅은 read model 조회만 하며 관제 데이터를 수정하지 않는다.

동작 모드와 fallback

설정 질문 해석 답변 생성
Bedrock 활성 + 라우팅 on LLM(router="llm") LLM(generator="bedrock")
Bedrock 활성 + 라우팅 off 규칙 파서(router="rule") LLM(generator="bedrock")
Bedrock 비활성 규칙 파서 규칙 템플릿(generator="rule")
LLM 호출 실패 규칙 파서로 fallback 규칙 템플릿으로 fallback

어느 모드에서도 RBAC 강제와 Evidence 구성 단계는 동일하다. LLM은 해석과 표현만 담당하고, 데이터 출처는 항상 Backend가 통제한다.


Bedrock 모델

채팅은 두 가지 LLM 사용 지점을 가진다.

  • Resolve: 질문에서 intent, 공장, 시간 범위를 구조화한다. ADR 0034 기준으로 Bedrock Converse tool-use를 사용하며, 실패하거나 비활성화되면 규칙 파서로 fallback한다.
  • Explain: Backend가 만든 Evidence만 받아 사람이 읽기 좋은 답변을 만든다. ADR 0033 기준으로 fast/precise tier를 분리한다.

현재 docs 기준 모델 정책:

단계 기준
Resolve Claude Haiku 4.5
Explain fast Claude Haiku 4.5
Explain precise Claude Sonnet 4.6

/chat/query 응답은 tier label만 노출하고 raw model id는 노출하지 않는다.


관련 문서

Aegis-Pi Wiki

· 대표 문서 목록은 홈의 문서 탐색 표 참조

시작하기

요구사항

핵심 개념

아키텍처

컴포넌트 (Edge → Cloud → Dashboard)

Dashboard & 운영

시나리오 · 사례 · 참조

Clone this wiki locally