해커톤 우승작을 실시간 콜봇으로: 하네스 엔지니어링
세션 소개
해커톤 우승작을 실시간 콜봇으로 만든 과정입니다. 파트 1(김동화)은 고객과 가게 두 통화를 오가는 음성 에이전트를 코드 가드레일로 안정화한 사례, 파트 2(김영남)는 그 콜봇을 만든 하네스를 실제 서비스에 맞게 고쳐 온 과정을 다룹니다.
핵심 내용
파트 1. 콜봇 구조와 두 통화에서 놓친 맥락
앞단 음성 모델이 통화를 응대하고, 뒷단 분류 에이전트가 고객 의도를 판단해 담당 에이전트(주문 조회, 가게 발신 툴 사용)에게 넘기는 구조입니다. 에이전트 하나가 고객·가게 두 통화를 실시간으로 오가면서 맥락을 놓쳤고, 이 문제를 다섯 가지 요인으로 세분화했습니다.
- 사례: 메뉴 누락 문의 → 업주가 재발송 약속 → 에이전트가 결과를 전하지 않고 고객에게 "가게에 연락해 볼게요"라고 처음부터 다시 응대
가드레일 다섯 가지
다섯 요인 모두 프롬프트 대신 코드로 막았습니다. 프롬프트는 확률적으로, 코드는 확정적으로 동작하기 때문입니다.
| 가드레일 | 문제 | 해결 |
|---|---|---|
| 통화 | 두 통화가 동시에 열려 꼬임 | 말하는 통화는 하나만. 고객 통화를 대기로 두고 발신, 그 사이 다른 통화 시도는 실행 전 차단 |
| 연결 | 전화 걸기·초대·재초대·전환 등 도구가 많아 성능 저하 | 에이전트는 대화 상대만 지정, 대기 통화 전환이나 신규 발신은 시스템이 판단 |
| 기록 | 통화가 바뀌면 맥락 단절 | 상담 ID 하나에 고객·업주 대화를 함께 저장하고 에이전트가 이 기록을 읽음 |
| 게이트 | 문의 유형 오분류, 잘못된 보상 처리 | 오분류는 재시도 후 반복 실패 시 상담사 이관. 보상은 정책 확인 게이트 통과 후 발급 |
| 평가 | 정답지를 본 에이전트가 정답을 말해 버림 | 답변 근거가 대화·조회 툴에서 왔는지 출처를 확인해 허용·차단하는 자동 평가 |
- 배치: 앞단 음성 계층에 통화·연결, 뒷단에 게이트·기록·평가
- 모두 에이전트 밖의 코드라 에이전트가 틀려도 상담 유지
결과와 다음 과제
첫 응답 0.8초 이내로 통화가 끊기는 느낌이 거의 없고, 기존 상담사보다 많은 상담을 처리(?)할 수 있게 됐습니다.
- 다음 과제: 소음 환경의 음성 인식 오류. 검토 중인 방안은 노이즈 캔슬링, 도메인 용어 기반 교정, 음성 인식 모델 학습
파트 2. 하네스를 직접 만든 이유
superpowers, ralph-loop, oh-my-opencode는 범용 설계라 사내 환경과 맞지 않고, 정해진 워크플로를 따라야 하며, 내부 동작을 몰라 고치기 어려웠습니다. 그래서 사내 환경과 작업 방식에 맞춘 하네스를 직접 만들었습니다.
- 해커톤 이후 실제 서비스에 쓰면서 기억, 비용, 제어, 목표, 협업 다섯 축의 문제를 만남
- 협업 축은 발표 자료에 내용 없음
기억: 잊어버리는 루프 → 루프 안의 위키
새 세션마다 에이전트가 예전 입력을 잊고 같은 질문과 실수를 반복했습니다. 공개된 LLM 위키 중 에이전틱 루프와 통합된 것이 없어, 단계마다 읽고 쓸 문서를 스킬로 정하고 루프 산출물과 위키를 분리했습니다.
- 원인: 루프와 위키가 따로 동작, 문서를 읽고 쓰는 시점이 없음, 사람의 입력이 루프 종료와 함께 휘발
- 루프 순서: 요구사항 → 계획 → 구현 → 검증 → 정리 → MR/PR
- 정리 단계에서 반복 실수, 아키텍처상 중요한 결정만 골라 위키로 distill
| 구분 | 위치 | 성격 | 내용 |
|---|---|---|---|
| 루프 산출물 | loops/ | 많고 일시적, MR 머지 후 삭제 | 실패 로그, 판정 결과, 리뷰 메모, 재시도 기록, 사용자 입력, 검증 결과 |
| LLM 위키 | docs/ | 적고 지속적, 다음 루프의 계획·구현 단계에서 읽음 | knowledge/pitfalls, knowledge/decisions, rules/(사용자 확인 후 규칙화) |
- 결과: 한 번 입력한 결정은 다시 묻지 않고, 실패 경험을 기억해 같은 실수 방지
비용: 서브에이전트 27개 → 8개
오케스트레이터는 루프 제어만 맡고 계획·구현·리뷰·테스트·문서 다섯 영역을 서브에이전트 27개에 위임했더니 토큰 사용량이 급증했습니다. 계획·구현을 메인 에이전트로 옮기고 서브에이전트는 검증·문서에만 남겨, 결과물 품질은 유지한 채 토큰 사용량을 10분의 1 정도로 줄였습니다.
- 원인: Claude Code 서브에이전트는 fire-and-forget 방식이라 결과만 반환하고 종료되어 피드백을 이어 줄 수 없음
- 새 작업마다 CLAUDE.md, PRD(제품 요구사항 문서), 설계, 위키, 코드를 처음부터 다시 읽음
- 피드백 3회차부터 MAX 주간 한도 초과, 주간 사용량을 하루 만에 소진
| 구분 | 메인 에이전트 | 서브에이전트 |
|---|---|---|
| 전 | 루프 제어만 | 27개: 계획, 구현, 검증, 문서 |
| 후 | 루프 제어, 계획, 구현(스킬로 수행) | 8개: 검증, 문서 갱신 |
제어: 꼬이는 루프 → 스킬 정리와 그래프
메인 에이전트의 일이 늘자 의도와 다른 스킬을 호출하거나 검증 단계를 건너뛰는 문제가 생겼습니다. 스킬을 라우트 구조로 묶고, 스킬 사이 이동을 그래프로 검사해 막았습니다.
스킬 정리: 흩어져 있던 구현·빠른 수정·디버그·스파이크·리뷰 대응·마무리를 work 스킬 아래 라우트(pull, push, fastrack, debug, spike, revise, close)로 통합했습니다. 전체 스킬 6개(init, plan, work, status, review, llm-wiki), 라우트 39개입니다.
skills/work/
├── SKILL.md 라우팅·검증·재진입
├── references/ 라우트별 절차 (pull.md, revise.md, close.md …)
└── shared/ 공유 절차
- 실행 순서:
SKILL.md라우팅 표로 라우트 선택 →references/<라우트>.md절차 실행 → 라우트별 체크리스트로 검증 → 재진입 판정(같은 스킬의 다른 라우트, 다른 스킬, 다음 단계 중 선택) SKILL.md부터 읽는 점진적 공개 방식
그래프 제어: 노드는 스킬:라우트, 엣지는 이동 경로와 조건입니다. hook과 로컬 MCP 서버가 엣지와 조건을 검사합니다.
{ "from": "work:push", "to": "plan:architecture", "kind": "call", "when": ["user_choice"] }
kind:call(호출 후 출발 노드로 복귀),transition(다른 스킬로 이동)when:steps_complete(절차 완료),user_choice(사용자 선택),reason(에이전트가 사유 기록)- 위 엣지: 작업 중 아키텍처를 고치고 돌아오려면 사용자 승인 필요
| 경로 | 전이 | 결과 |
|---|---|---|
| 작업 종료 → MR 리뷰 대응 | work:close → work:revise · user_choice | 통과 |
| 리뷰 반영 → 검증 → 종료 | work:revise → work:close · steps_complete | 통과 |
| MR 리뷰 대응 → 계획 세우기 | work:revise → plan:charter · 엣지 없음 | 차단 |
| 검증 생략 후 종료 | work:revise → work:close · 조건 미충족 | 차단 |
목표: 바텀업 요청 → 목표를 아는 에이전트
요구사항을 하나씩 처리하는 바텀업 방식에서는 에이전트가 최종 목적을 몰라, 새 요청마다 이전 구현이 레거시가 되고 목표에 지그재그로 다가갔습니다. 사람이 목표를 정하고 에이전트가 작업으로 분해하는 탑다운 경로를 만들고, 바텀업 경로에는 목표 검사를 넣었습니다.
- 예: 메모 저장(한 사람 기준) → 친구와 공유(복사본 전송) → 함께 편집(복사본으로 불가, 저장 구조 재설계)
| 계층 | 담당 | 내용 |
|---|---|---|
| Decision layer (목표 설정) | 사람 | charter(정의·규칙·목표·원칙), 아키텍처, 마일스톤 |
| Delivery layer (계획) | 에이전트 | 마일스톤에서 요구사항·성공 조건·갭·작업 도출 |
| 작업 루프 | 사람 요청 후 에이전트 | 역할·우선순위에 맞는 작업 할당 → 구현 → 검증 → MR |
- 작업 결과를 현재 상태에 반영하고, 작업 시작마다 현재 상태와 비교해 갭을 다시 측정
- 바텀업 경로는 모든 경우를 탑다운으로 풀 수 없어 유지하고 목표 검사 추가: 목표와 상충하면 요청자가 요구사항이나 목표를 고친 뒤 작업, 충돌이 없으면 기존 흐름대로 작업