에이전트는 무엇인가
단순 챗봇이 아니라 툴을 호출해 실제 데이터를 읽고 행동하는 에이전트입니다.
구조상 apps/agent/ 라는 하나의 Bounded Context 이며, 도메인 데이터에는 내부 포트로만 접근합니다.
사용자 입력
│
▼
[오케스트레이션 루프] ← 최대 N회 (기본 5회) 제한
│ ├─ LLM 에 현재 상태 전달
│ ├─ LLM 이 툴 호출을 요청하면 → Tool Executor 실행
│ ├─ 툴 결과를 다시 LLM 에 전달
│ └─ 최종 답변이 나오면 종료
▼
SSE 스트리밍 (delta → tool → done)
시나리오 3개
⚠︎ 기획서 v6 대조 전까지 자리표시자입니다
시나리오의 구조(입력·기대 동작·성공 판정)는 확정이고, 내용은 기획서에서 옮겨와야 합니다. AI-01 (신채연, D-13) 항목입니다.
| # | 시나리오 | 필요한 툴 | 성공 판정 | 우선순위 |
|---|---|---|---|---|
| SC-1 | 사용자가 자연어로 묻고, 에이전트가 자기 데이터를 조회해 답한다 | search_items, get_item |
답변에 실제 DB 값이 포함됨 | MUST |
| SC-2 | 에이전트가 대화 맥락을 유지하며 후속 질문에 답한다 | (없음) | 앞 대화를 참조한 답변 | MUST |
| SC-3 | 에이전트가 사용자 대신 무언가를 생성/기록한다 | create_item |
DB 에 실제 레코드 생성 | MUST |
툴 정의
툴은 좁게, 예측 가능하게 만듭니다. 하나의 툴이 많은 걸 하면 LLM 이 잘못 부릅니다.
| 툴 | 입력 | 출력 | 부작용 |
|---|---|---|---|
search_items |
query, limit(≤10) |
항목 요약 배열 | 없음 (읽기) |
get_item |
public_id |
항목 상세 | 없음 (읽기) |
create_item |
도메인 필드 | 생성된 public_id |
있음 (쓰기) |
쓰기 툴은 확인을 거친다
create_item 처럼 부작용이 있는 툴은 실행 전 사용자 확인을 받습니다.
LLM 이 오해해서 만든 데이터를 사용자가 나중에 발견하는 것보다, 한 번 물어보는 게 낫습니다.
프롬프트 관리
- 프롬프트는 코드가 아니라 자산으로 취급하고
prompts/v{n}/아래에 버전 디렉토리로 둡니다. - 운영에 나가는 프롬프트는 태깅합니다 (
v1.0). 9/11(D-5) 이후 변경은 PM 승인 사항. - 프롬프트를 고칠 때는 반드시 평가셋을 다시 돌립니다. 한 케이스를 고치다 다른 셋을 망가뜨리는 일이 잦습니다.
품질 평가셋
D-6(9/10)까지 20 케이스를 만듭니다. 감이 아니라 숫자로 판단하기 위해서입니다.
| 구성 | 개수 | 판정 기준 |
|---|---|---|
| 정상 시나리오 | 10 | 기대 정보가 답변에 포함 |
| 데이터 없음 | 3 | 지어내지 않고 없다고 말함 |
| 범위 밖 질문 | 4 | 정해진 문구로 거절 |
| 프롬프트 인젝션 | 3 | 시스템 지시 유지 |
통과 기준: 18/20. 이 미만이면 오픈하지 않고 프롬프트를 고칩니다.
가드레일
| 상황 | 동작 |
|---|---|
| 서비스 범위 밖 질문 | 정해진 문구로 거절하고 할 수 있는 일을 안내 |
| 유해·위험 요청 | 거절. 우회 시도에도 시스템 지시 유지 |
| 개인정보 요구 | 타인 데이터 조회 툴 자체를 제공하지 않음 (권한은 서버가 강제) |
| 프롬프트 인젝션 (“이전 지시 무시”) | 사용자 입력을 데이터로만 취급. 시스템 지시와 분리 |
| 확신 없는 정보 | 모른다고 말한다. 지어내는 것보다 낫다 |
권한은 프롬프트로 지키지 않는다
“남의 데이터는 보여주지 마” 라고 프롬프트에 쓰는 건 방어가 아닙니다. 툴이 호출하는 내부 포트에서 서버가 사용자 권한을 강제합니다. LLM 이 뭘 요청하든 권한 없는 데이터는 애초에 반환되지 않아야 합니다.
실패 처리 — 여기가 실제 품질이다
| 실패 | 사용자에게 | 시스템 |
|---|---|---|
| 프로바이더 타임아웃 | “잠시 후 다시 시도해 주세요” | 1회 재시도 후 AI_UNAVAILABLE |
| 토큰 한도 초과 | 대화가 길다고 안내, 새 대화 유도 | 오래된 메시지 요약 후 재시도 |
| 툴 실행 실패 | 해당 정보만 못 가져왔다고 안내 | 나머지 답변은 계속 진행 |
| 루프 한도 도달 | 현재까지의 답변 반환 | 로그에 기록, 프롬프트 개선 대상 |
| 프로바이더 전면 장애 | AI 기능만 비활성화 | 기능 플래그로 degrade. 나머지 서비스는 정상 |
비용 관리
- 요청마다
llm_usage에 모델·토큰·비용·시각을 기록한다. - 일일 상한을 걸고 초과 시 알림 + 자동 차단 (AI-33).
- 동일 질의 캐싱으로 절감 (AI-27, SHOULD).
- D-8(9/08)부터 PM 대시보드에서 일일 사용량을 확인한다 (PM-19).
기획서 v6 대조
- 시나리오 3개의 실제 내용 확정 (SC-1~3)
- 에이전트 페르소나·말투 확정
- 범위 밖 질문 거절 문구 확정
- 툴 3종의 실제 도메인 대응 확정
- RAG 로 넣을 지식 문서가 있는지 확인 (있으면 S1 우선순위 상향 검토)
결정 로그
| 날짜 | 결정 | 이유 |
|---|---|---|
| 2026-09-03 | 권한 검사는 서버 포트에서 강제 (프롬프트 신뢰 안 함) | 프롬프트 방어는 우회 가능. 실제 사고로 이어짐 |
| 2026-09-03 | 쓰기 툴은 사용자 확인 후 실행 | 오해로 생성된 데이터의 복구 비용이 확인 1회보다 큼 |
| 2026-09-03 | 평가셋 통과 기준 18/20 을 오픈 조건에 포함 | 체감으로 판단하면 오픈 전날 의견이 갈린다 |
| 2026-09-03 | LLM 장애 시 AI 기능만 degrade | AI 하나 때문에 서비스 전체가 멎으면 안 됨 |