Agent 2.0 exdev 서버 배포 스택

- server-dev start/stop/deploy 및 Gitea push 자동 배포
- local-dev 로컬 개발 환경

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Macbook
2026-07-21 22:57:30 +09:00
commit 4b86b2a660
344 changed files with 45787 additions and 0 deletions
@@ -0,0 +1,115 @@
# kakaoChatbotSkill — 카카오/웹 진입(Web) 서비스
한국도로공사 챗봇의 **진입 계층(Web)** 입니다. 카카오 오픈빌더 웹훅과 웹앱(chatbotApp)의 요청을 받아 **Agent(RAG `/agent/chat`)** 로 위임하고, 응답을 카카오/웹 UI로 조립합니다.
> **운영:** `128.200.100.61:8083` (DMZ 웹 서버, nginx 뒤)
> **운영 모드:** `agent.mode=agent` — WAS·RAG는 모드 분기 없이 Agent tool API와 `/agent/chat`를 제공합니다.
> **전체 구조:** [`../SYSTEM_ARCHITECTURE.md`](../SYSTEM_ARCHITECTURE.md) · **Agent 상세:** [`../docs/AGENT_ARCHITECTURE.md`](../docs/AGENT_ARCHITECTURE.md)
> **콜백 구현:** [`CALLBACK_구현_정리.md`](CALLBACK_구현_정리.md)
> **최종 갱신:** 2026-07-10
---
## 1. 역할
| 책임 | 설명 |
|------|------|
| 카카오 웹훅 수신 | `/kakao/skill` (폴백 블록 발화) |
| 웹앱 수신 | `/web/ask`(JSON), `/web/ask/stream`(SSE) — chatbotApp |
| 오케스트레이션 위임 | RAG `/agent/chat` 호출 |
| WEB domain tool 제공 | `/internal/tools/data-portal` (WAS 역호출 전용, `GASSTATION`·`BRAND_SHOP`·`REST_AREA_FOOD_LIST`) |
| UI 조립 | Agent 응답 → SimpleText·ListCard·BasicCard·QuickReply·fareBreakdown |
**핵심 원칙:** 정책(`fetchOwner`/`uiType`/`needsClarification`)은 WAS+YAML이 결정하고, Skill은 **진입·위임·UI 표현**만 담당합니다.
---
## 2. 요청 흐름
```mermaid
flowchart TD
K[카카오 오픈빌더] -->|/kakao/skill| SC[SkillController]
APP[chatbotApp/브라우저] -->|/web/ask, /web/ask/stream| WC[WebChatController]
SC --> RB[ResultBuilder → KakaoIntentApp]
WC --> WS[WebChatService] --> RB
RB --> RAG[RagAgentClient → RAG :28012 /agent/chat]
ITC[InternalToolController /internal/tools/data-portal] --> IDP[InternalDataPortalToolService → data.ex.co.kr]
WAS2[WAS tool execute, agent WEB tool] -->|역호출| ITC
RAG --> UI[buildLlmAgentOutputs + SkillResponseWebExtractor]
UI --> OUT([카카오 SimpleText/카드 · WebAskResponse])
```
- **Agent 모드:** Skill → RAG `/agent/chat` 1회. WEB domain 데이터는 WAS가 `/internal/tools/data-portal`로 **역호출**해 가져옵니다.
---
## 3. 진입 API
| Method | URL | 구현 | 용도 |
|--------|-----|------|------|
| `POST`/`GET` | `/kakao/skill` (`/oakak/skill` 별칭) | `SkillController` | 카카오 폴백 블록 |
| `POST` | `/web/ask` | `WebChatController` → `WebChatService` | 웹 JSON 응답 (`WebAskResponse`) |
| `POST` | `/web/ask/stream` | `WebChatController` | SSE 스트리밍 (chatbotApp) |
| `POST` | `/internal/tools/data-portal` | `InternalToolController` | WAS→Skill WEB tool (내부 전용, `X-Internal-Tool-Key`) |
---
## 4. 주요 구현 파일
| 파일 | 책임 |
|------|------|
| `controller/SkillController.java` | 카카오 웹훅 진입 |
| `response/build/ResultBuilder.java` | intent → 핸들러 라우팅 |
| `response/build/KakaoIntentApp.java` | 카카오 fallback 블록, Agent 호출, 카드 UI 조립, `buildLlmAgentOutputs` |
| `service/RagAgentClient.java` | RAG `POST /agent/chat` 클라이언트 |
| `web/WebChatController.java`·`WebChatService.java` | `/web/ask`(+stream) → Agent 호출 및 웹 응답 매핑 |
| `web/SkillResponseWebExtractor.java` | SkillResponse → 웹 DTO(ListCard·quickReplies·fareBreakdown) |
| `api/InternalToolController.java` | WAS→Skill internal API |
| `service/InternalDataPortalToolService.java`·`DataPortalService.java` | WEB tool data.ex.co.kr 조회 |
| `config/AgentProperties.java` | `agent.mode`, `fallback-legacy`, `agent.chat.url` |
| `config/InternalToolProperties.java` | `internal.tool.api-key` |
---
## 5. 설정 (jar 옆 `application.yml`)
```yaml
agent:
mode: agent
fallback-legacy: true # 장애 대응용 fallback 설정
chat:
url: http://172.16.180.130:28012/agent/chat
timeout-ms: 100000
internal:
tool:
api-key: ${INTERNAL_TOOL_API_KEY} # WAS↔Skill 내부 인증(3서비스 동일)
```
**방화벽:** `172.16.180.130 → 128.200.100.61:8083` (WAS→Skill WEB tool), `128.200.100.61 → 172.16.180.130:28012`(Skill→RAG)·`:8086`(Skill→WAS).
---
## 6. botId · 세션 정책
| 채널 | botId | 이력·pending |
|------|-------|--------------|
| 카카오 | `userRequest.user.id` (사용자별 고정) | 24h 내 동일 사용자 이력·pending 이어짐 |
| 웹(chatbotApp) | `sessionStorage` 랜덤(`web-...`) — **대화마다 새 botId(무상태)** | 새 대화는 이력·pending 없음 |
- 카카오↔웹은 세션을 **연계하지 않고**, 웹은 대화마다 새 botId로 시작해 **과거 대화를 복원하지 않습니다**. 상세: [`../SYSTEM_ARCHITECTURE.md`](../SYSTEM_ARCHITECTURE.md).
- pending(되묻기)은 Agent 모드에서 **RAG(MongoDB `agent_pending`)** 가 소유하며 Skill은 무상태입니다. Skill은 `query + botId`만 RAG로 전달합니다.
---
## 7. 관련 문서
| 문서 | 내용 |
|------|------|
| [`../SYSTEM_ARCHITECTURE.md`](../SYSTEM_ARCHITECTURE.md) | 전체 구조·API·포트·세션 정책 |
| [`../docs/AGENT_ARCHITECTURE.md`](../docs/AGENT_ARCHITECTURE.md) | Agent 모드 상세·방화벽 |
| [`CALLBACK_구현_정리.md`](CALLBACK_구현_정리.md) | 카카오 콜백(5초 초과 응답) 구현 |
| [`../chatbotApp/README.md`](../chatbotApp/README.md) | 웹앱 UI·`/web/ask` 연동 |