# 에이전트 아키텍처 ## 개요 프로젝트는 세 개의 UI 진입점과 하나의 공용 채팅 런타임으로 구성됩니다. 1. `app.py` 2. `app_gradio.py` 3. `app_gradio_messenger.py` 4. `megumin_agent/` 각 UI 계층은 같은 채팅 서비스 헬퍼를 호출하고, 채팅 서비스는 검색, 에이전트 실행, 스트리밍, 세션 상태 관리를 담당합니다. ## 런타임 흐름 1. `megumin_agent/bootstrap.py`가 환경 변수를 불러오고 로컬 또는 원격 데이터 파일을 준비합니다. 2. `megumin_agent/retrieval.py`가 페르소나/사실 검색에 필요한 FAISS 인덱스와 메타데이터를 로드합니다. 3. `megumin_agent/agent.py`가 ADK 에이전트를 구성하고 검색 기반 도구를 연결합니다. 4. `megumin_agent/chat.py`가 채팅 서비스를 만들고 부분 응답 스트리밍과 세션 메모리를 관리합니다. 5. UI 모듈이 화면을 렌더링하고 사용자 메시지를 `stream_chat()`으로 전달합니다. ## 모듈별 설명 ### `megumin_agent/bootstrap.py` - `.env`를 로드합니다. - 필요 시 로컬 `adk-python/src` 경로를 준비합니다. - 가능하면 Hugging Face에서 데이터셋 자산을 내려받습니다. - 원격 자산을 사용할 수 없으면 로컬 처리 데이터로 폴백합니다. ### `megumin_agent/retrieval.py` - QA JSON 소스와 FAISS 인덱스를 로드합니다. - 페르소나형 데이터와 사실형 데이터에 대해 검색을 수행합니다. - 프롬프트 구성에 사용할 간결한 검색 결과를 반환합니다. ### `megumin_agent/agent.py` - 메구밍 페르소나 프롬프트와 검색 도구를 정의합니다. - 페르소나 검색과 사실 검색을 하나의 에이전트 흐름으로 합칩니다. - 멀티턴 대화에 필요한 요약 상태를 관리합니다. ### `megumin_agent/chat.py` - 공용 러너와 메모리 기반 세션 서비스를 생성합니다. - `stream_chat()`으로 SSE 스타일의 부분 응답을 제공합니다. - 최근 턴 상태와 요약 정보를 유지해 후속 대화를 지원합니다. ### `app_gradio.py` - 기존 다중 패널 구성의 메인 채팅 UI입니다. - 첫 요청 시점에 채팅 서비스를 지연 초기화합니다. - 어시스턴트의 부분 응답을 화면의 채팅 영역에 스트리밍합니다. ### `app_gradio_messenger.py` - 동일한 공용 채팅 서비스 계층 위에 메신저형 UI를 올린 파일입니다. - 좌측과 우측 섹터는 Gradio `Column(scale=3)`과 `Column(scale=7)`으로 `3:7` 비율을 유지합니다. - 데스크톱 메신저 레이아웃은 의도적으로 고정 높이를 사용합니다. - 우측 섹터는 `상단 헤더`, `메시지 표시 영역`, `입력 영역`의 세 파트로 나뉘며, 고정 3행 grid로 배치됩니다. - `상단 헤더`와 `입력 영역`은 명시적인 픽셀 높이를 사용합니다. - 메시지 뷰포트는 `calc(...)`로 남는 높이만 사용합니다. - 아바타 이미지는 외부 저장소 대신 프로젝트 내부 `source_file` 폴더의 로컬 이미지 파일을 Gradio 파일 라우트로 서빙합니다. - 우선적으로 `megumin_profile` 이름의 `png`, `jpg`, `jpeg`, `webp` 파일을 찾고, 없으면 같은 폴더의 첫 번째 이미지 파일을 사용합니다. - fallback SVG는 로컬 이미지 로드 실패 시에만 표시되며, `source_file` 폴더는 메신저 단독 실행과 `app.py` 경유 실행 모두에서 `allowed_paths`로 명시적으로 노출합니다. - Gradio 자동 stretch 래퍼가 세로 확장을 다시 유발할 수 있으므로 이 파일에서는 `gr.Blocks(fill_height=True)`를 사용하지 않습니다. ### `app.py` - Hugging Face Spaces 진입점입니다. - `MEGUMIN_UI` 값에 따라 기본 UI와 메신저 UI 중 하나를 선택합니다. ## 세션 모델 - 현재 세션 저장소는 메모리 기반입니다. - 앱 프로세스가 살아 있는 동안 대화 연속성이 유지됩니다. - 최근 메시지는 직접 보존하고, 오래된 맥락은 요약 상태로 축약합니다. ## 메신저 레이아웃 유지보수 규칙 - `app_gradio_messenger.py`는 뷰포트를 꽉 채우는 flex 실험이 아니라 고정 높이 레이아웃으로 다룹니다. - 메신저 패널 높이가 바뀌면 CSS 변수와 이 문서를 함께 수정합니다. - 좌우 비율이 바뀌면 Gradio `scale` 값과 README 메모를 함께 수정합니다. - 특별한 이유와 브라우저 검증 없이 내부 래퍼에 중첩된 고정 `min-height` 체인을 다시 도입하지 않습니다.