실무 Multi-Agent 오케스트레이션 24장 · 서비스 통합과 실행 1 / 9 ← 이전목차다음 → TechLead Cro

24장. 서비스 통합과 실행

왜 서비스로 만들어야 하는가 — 고객은 터미널을 쓰지 않는다

한 줄 요약

Supervisor와 전문 에이전트, 승인 게이트까지 구현했지만, 지금까지는 터미널에서만 시스템을 사용했습니다. 마지막 장에서는 고객용 채팅 화면과 상담원용 승인 화면을 서버에 연결해, 브라우저에서 상담과 승인 업무를 진행할 수 있도록 만듭니다. 이어서 표준 질문 12개로 전체 상담 흐름이 의도한 대로 동작하는지 확인합니다.


1. 지금 가진 것과 없는 것

가진 것 만든 곳
본인 확인과 마스킹이 들어간 도구 8장 haru_tools.py
정책 문서 검색 저장소 13장 chroma_db/
배송지 변경·교환 접수·환불 승인 요청을 하는 처리 도구 21장 haru_actions.py
전문 에이전트 셋 (주문조회, 정책안내, 요청처리) 21장 haru_agents.py
이들을 지휘하는 Supervisor 22장 haru_supervisor.py
사람의 승인을 거치는 흐름 23장 lesson23_hitl.py

없는 것은 입구입니다. 그것도 둘입니다.

없는 입구 지금은 어떻게 하고 있나
고객이 문의하는 곳 파이썬 파일을 열어 질문을 고쳐 적고 python lesson22_supervisor.py를 실행한다
상담원이 승인하는 곳 23장에서는 코드가 Command(resume="approve")를 넣어 상담원 역할을 대신했다

2. 브라우저와 우리 프로그램은 따로 돈다

웹 서비스의 기본 구조부터 정리합니다.

이름 무엇인가 우리 프로젝트에서
프론트엔드(frontend) 사용자가 보는 화면. 브라우저에서 돈다 app/frontend/index.html 채팅 화면, app/frontend/admin.html 상담원 화면 (둘 다 제공됨)
백엔드(backend) 요청을 받아 처리하는 프로그램. 서버에서 돈다 app/main.py (이번 장에서 만든다)
HTTP 둘이 주고받는 약속된 형식 "이 주소로 이 내용을 보낸다 → 응답을 받는다"
API 백엔드가 열어 둔 주소들의 목록과 사용법 /api/chat에 문의를 보내면 답이 온다. /api/approvals에서 승인 대기 목록을 받는다

브라우저와 우리 파이썬 프로그램은 서로 다른 프로그램입니다. 브라우저는 파이썬 함수를 직접 부를 수 없습니다. 그래서 파이썬 쪽에서 "이 주소로 요청이 오면 이 함수를 실행한다" 고 문을 열어 두어야 합니다. 그 문을 여는 프로그램이 서버입니다.

화면은 이 과정에서 만들지 않습니다. 화면을 만드는 것은 다른 분야의 일이라, 완성된 파일 둘을 app/frontend/ 폴더에 제공했습니다. 우리가 만드는 것은 그 두 화면이 말을 걸 상대입니다.

제공된 화면 누가 쓰나 하는 일
index.html 고객 문의를 보내고, 위임 과정과 답변을 본다
admin.html 상담원 승인 대기 요청을 승인·반려하고, 처리 내역과 넘겨받은 문의를 본다

3. 승인 게이트는 화면의 버튼이 된다

23장에서 사람의 결정은 코드 안의 "approve"라는 글자였습니다. 서비스에서는 그 자리에 상담원 화면의 승인 버튼이 들어갑니다.

23장 24장
승인 요청을 등록하는 것 그래프의 검토 노드가 request_refund를 부른다 요청처리 에이전트가 request_refund를 부른다
사람이 보는 곳 터미널에 출력한 요청서 상담원 화면의 "승인 대기" 구역
사람의 결정이 들어오는 길 Command(resume="approve") 승인 버튼 → POST /api/approvals/{처리번호}
결정을 기록하는 것 decide() 같은 decide()
기다리는 동안 상태가 있는 곳 체크포인터 + actions.json actions.json (승인대기)

요청을 등록하는 쪽과 결정을 기록하는 쪽이 같은 처리 기록 파일을 봅니다. 그래서 고객이 채팅으로 주문 취소를 요청하면 상담원 화면에 곧 한 줄이 뜨고, 상담원이 승인하면 고객이 다시 물었을 때 "승인이 끝났다"는 답이 나갑니다.


4. 서버로 만들면 새로 생기는 문제

터미널에서는 없던 문제가 세 가지 생깁니다. 이번 장의 개념 절 셋이 각각 하나씩 다룹니다.

문제 터미널에서는 서버에서는 다루는 곳
입력이 밖에서 온다 우리가 코드에 적은 질문 누가 무엇을 보낼지 모른다 FastAPI와 입력 검증
여러 사람이 동시에 쓴다 대화 하나 브라우저마다 대화가 따로 있어야 한다 세션과 대화 이력
답이 늦게 온다 [위임 →] 줄이 찍히니 기다릴 만하다 빈 화면 10초는 멈춘 서비스로 보인다 SSE 스트리밍

세 번째를 조금 더 봅니다. 22장에서 복합 문의 하나는 전문 에이전트를 여러 번 거치느라 10초 가까이 걸렸습니다. 터미널에서는 [위임 → 주문조회] 줄이 하나씩 찍혀 "일하고 있구나"를 알 수 있었습니다. 화면에서도 지금 무엇을 하고 있는지를 보여 줘야 합니다.


5. 이걸 모르면 무엇을 판단하지 못하는가

  • 화면에 답이 안 나올 때 화면 문제인지, 서버 문제인지, 에이전트 문제인지 가려내지 못합니다.
  • 서버를 껐다 켜면 대화가 사라지는 이유, 새로고침하면 "그거"를 못 알아듣는 이유를 설명하지 못합니다.
  • 고객 화면과 상담원 화면이 무엇을 함께 보고 있기에 서로의 일이 이어지는지 설명하지 못합니다.
  • "완성했다"는 말의 기준이 없습니다. 몇 번 써 보고 잘 되는 것 같다는 것은 기준이 아닙니다.

마지막 항목이 이 장의 끝입니다. 1장에서 정한 표준 질문 12개가 완성의 기준입니다. 서버를 띄운 뒤 열두 개를 전부 넣어 보고, 기대한 동작과 실제 동작을 표로 맞춰 봅니다.


6. 이번 장에서 만드는 것

파일 위치 내용
main.py app 폴더 안 두 화면을 내려 주고, 문의를 받아 Supervisor를 실행하고, 상담원의 승인·반려를 받는 서버

만드는 파일은 이것 하나입니다. 화면 둘(index.html, admin.html)은 제공된 것을 그대로 씁니다.

지금까지 만든 파일은 모두 haru-market 폴더 맨 위에 있습니다. main.py만 app 폴더 안에 만듭니다. 이 과정에서 유일한 예외입니다.


핵심 정리

  • 시스템은 완성됐지만 고객이 문의할 입구와 상담원이 승인할 입구가 없습니다.
  • 브라우저(프론트엔드)와 우리 프로그램(백엔드)은 따로 돌고, HTTP로 대화합니다.
  • 23장의 승인 게이트는 웹에서 상담원 화면의 승인 버튼이 되고, 버튼은 같은 decide()를 부릅니다.
  • 서버로 만들면 밖에서 오는 입력, 여러 사람의 대화, 늦게 오는 답 세 가지를 다뤄야 합니다.
  • 완성의 기준은 느낌이 아니라 표준 질문 12개입니다.
  • 이번 장의 산출물은 app/main.py 하나이고, app 폴더 안에 만듭니다. 화면 둘은 제공됩니다.
← 23장실습문제와 해답다음 절 →FastAPI — 파이썬 함수를 주소로 만든다
오명운 · macro@prag-ai.com