← Files vox.aiARCHIVED FILE
references/workflow-examples.md
12.7 KB · Nov 7, 2026 · 06:13 UTC
# 합성 고객 여정: 만들기, 다듬기, 직접 시험, 운영, 재개
이 예시는 합성 자료와 도구 호출 형식을 보여준다. 실제 요청 전에 연결된 호스트의 실제 도구와 schema를 확인한다. 번들의 도구 schema 후보는 실제 사용 가능 여부를 연결된 서버에서 확인한다.
## 합성 요청과 완료 기준
고객이 “샘플 홈케어 문의를 받는 음성 에이전트를 만들고 싶어요”라고 요청한다. 제공된 합성 자료에는 세 가지 업무가 있다.
- 어떤 서비스를 원하는지와 가능한 날짜 범위를 접수한다.
- 위치와 주소는 업무 범위를 파악한 뒤 한 번만 확인한다.
- 가격표나 예약 API는 연결되어 있지 않으므로 가격·방문 시간·예약 확정을 약속하지 않는다. 접수 내용 요약과 담당자 확인이 다음 단계다.
성공은 Manual에 접수 흐름과 제한이 저장되고 재조회되는 것이다. 이는 예약 기능 연결이나 고객 음성 시험 통과를 뜻하지 않는다.
## 1. Authoring: 첫 Manual 저장
조직이 의도한 곳인지 확인한 뒤, 반환된 ID만 후속 호출에 사용한다.
```mcp-call
{"tool":"get_organization","arguments":{}}
```
새 agent 모델을 고를 때는 먼저 `list_models(kind=llm)`을 호출한다. 이 예시는 사용자가 모델·계열을 지정하지 않은 경우의 흐름만 보인다. 정확한 모델·계열·공급사 지정과 구 API fallback 우선 규칙은 [모델 선택 규칙](../skills/build-first-voice-agent/SKILL.md#모델-고르기)을 따른다. `featured=true`이고 `deprecated=false`인 결과 중 `display_order`가 가장 작은 항목의 `model`을 사용한다. 아래 모델 값은 placeholder이며 실제 호출에서는 조회 결과의 `model` 값으로 바꾼다. 결과에 `featured` 필드가 없는 구 API에서는 `data.llm`을 생략하고, 서버 기본값을 사용한다고 알린다.
```mcp-call
{"tool":"list_models","arguments":{"kind":"llm"}}
```
```mcp-call
{"tool":"save_agent","arguments":{"mode":"create","payload":{"name":"샘플 홈케어 문의","data":{"llm":{"model":"<selected list_models item model>"}}}}}
```
`save_agent` 응답의 실제 `agent_id`를 받아 현재 상태와 revision을 읽는다. 아래 UUID는 모양을 보이는 합성값이며 실제 호출에서는 반환된 ID를 쓴다.
```mcp-call
{"tool":"get_agent","arguments":{"agent_id":"11111111-1111-4111-8111-111111111111"}}
```
아래 `expected_head_revision`은 형식을 보이는 예시값이다. 실제 호출에서는 방금 읽은 revision으로 바꾼다. Manual은 현재 agent에 귀속된다.
```mcp-call
{"tool":"save_manual","arguments":{"mode":"create","agent_id":"11111111-1111-4111-8111-111111111111","payload":{"expected_head_revision":7,"name":"샘플 홈케어 문의 접수","trigger":"고객이 홈케어 서비스나 방문 가능 여부를 문의할 때, 서비스 종류나 지역을 먼저 말할 때, 또는 앞서 말한 접수 정보를 정정할 때. 이미 잡힌 방문의 변경·취소는 제외한다.","content":"## 규칙\n- 범위: 홈케어 서비스 문의 접수만 한다. 가격 확정, 방문 시각 약속, 예약 완료 안내는 하지 않는다.\n- 연결된 가격표와 예약 확인 기능이 없다. 확인이 필요한 질문은 추측하지 않고 \"담당자 확인이 필요합니다.\"라고 말한다.\n- 이미 들은 정보는 다시 묻지 않는다. 정정되면 그 값만 고친다.\n- 완료 조건: 서비스 종류, 날짜 범위, 위치를 확인하고 요약에 동의받은 뒤 \"말씀하신 내용을 확인했습니다.\"라고 안내한다. 예약 확정이나 외부 접수 성공을 말하지 않는다.\n## 진행 절차\n### 시작\n1. 고객이 이미 말한 서비스 종류, 날짜 범위, 위치를 기억하고 아직 듣지 못한 항목의 단계로 이동한다.\n### 서비스 종류\n1. 원하는 서비스 종류를 묻는다.\n### 날짜 범위\n1. 가능한 날짜 범위를 묻는다. 모른다고 하면 \"모름\"으로 기억하고 넘어간다.\n### 위치\n1. 서비스 범위를 좁힌 뒤 위치와 주소를 한 번만 확인한다.\n### 요약 확인\n1. 접수 내용을 요약하고 빠진 점이나 정정이 있는지 묻는다.\n2. 정정하면 그 항목만 고치고 요약을 다시 확인한다.\n3. 맞다고 하면 말씀하신 내용을 확인하고 끝낸다. 예약 확정이나 외부 접수 성공을 말하지 않는다."}}}
```
저장 결과의 `manual_id`를 보존하고 실제 리소스를 재조회한다.
```mcp-call
{"tool":"get_manual","arguments":{"agent_id":"11111111-1111-4111-8111-111111111111","manual_id":"22222222-2222-4222-8222-222222222222"}}
```
본문과 `head_revision`이 의도한 값인지 확인한다. Manual만 저장됐다면 새 agent를 만들지 않고 같은 `agent_id`로 이어간다. 저장 성공과 readback 성공은 별도 결과로 보고한다.
## 2. Refine: 정책을 좁게 바꾸고 확인
고객이 “주소를 먼저 묻지 말고, 어떤 서비스를 원하는지 파악한 다음 한 번만 물어봐 주세요”라고 한다. 먼저 같은 agent의 전체 Manual을 읽고 변경 지점과 보존할 제한을 확인한다.
```mcp-call
{"tool":"get_manual","arguments":{"agent_id":"11111111-1111-4111-8111-111111111111","manual_id":"22222222-2222-4222-8222-222222222222"}}
```
Manual 본문 저장은 전체 본문 교체다. 아래 `content`에는 변경 문장뿐 아니라 가격·예약 확정 제한, 요약과 정정 흐름을 포함한 **전체 새 본문**을 보낸다. `expected_head_revision`은 방금 조회한 Manual의 현재 revision으로 교체한다.
```mcp-call
{"tool":"save_manual","arguments":{"mode":"update","agent_id":"11111111-1111-4111-8111-111111111111","manual_id":"22222222-2222-4222-8222-222222222222","payload":{"expected_head_revision":8,"content":"## 규칙\n- 범위: 홈케어 서비스 문의 접수만 한다. 가격 확정, 방문 시각 약속, 예약 완료 안내는 하지 않는다.\n- 연결된 가격표와 예약 확인 기능이 없다. 확인이 필요한 질문은 추측하지 않고 \"담당자 확인이 필요합니다.\"라고 말한다.\n- 이미 들은 정보는 다시 묻지 않는다. 정정되면 그 값만 고친다.\n- 완료 조건: 서비스 종류, 날짜 범위, 위치를 확인하고 요약에 동의받은 뒤 \"말씀하신 내용을 확인했습니다.\"라고 안내한다. 예약 확정이나 외부 접수 성공을 말하지 않는다.\n## 진행 절차\n### 시작\n1. 고객이 이미 말한 서비스 종류, 날짜 범위, 위치를 기억하고 아직 듣지 못한 항목의 단계로 이동한다.\n### 서비스 종류\n1. 원하는 서비스 종류를 묻는다.\n### 날짜 범위\n1. 가능한 날짜 범위를 묻는다. 모른다고 하면 \"모름\"으로 기억하고 넘어간다.\n### 위치\n1. 고객이 원하는 업무 범위를 파악한 다음 위치와 주소를 한 번만 확인한다. 이미 주소를 들었다면 반복 질문하지 않는다.\n### 요약 확인\n1. 접수 내용을 요약하고 빠진 점이나 정정이 있는지 묻는다.\n2. 정정하면 그 항목만 고치고 요약을 다시 확인한다.\n3. 맞다고 하면 말씀하신 내용을 확인하고 끝낸다. 예약 확정이나 외부 접수 성공을 말하지 않는다."}}}
```
`get_manual(agent_id, manual_id)`로 다시 읽어 주소 규칙이 한 번만 반영되고 다른 제한이 남았는지 확인한다. `409`이면 최신 본문을 다시 읽고 의도를 재적용한다. 쓰기 응답이 불명이면 중복 update를 보내지 말고 알려진 ID를 재조회한다.
## 3. Customer direct test: 고객이 직접 말해 보고 피드백
Assistant는 고객이 확인할 사례와 기대 동작을 준비한다. 예를 들어 고객은 “이번 주 금요일에 에어컨 청소 가능해요? 가격도 알려주세요”라고 말해 본다. 기대 동작은 서비스 종류와 날짜 범위를 접수하고, 연결되지 않은 가격·예약 확정을 약속하지 않는 것이다. 두 번째 사례에서는 고객이 먼저 주소를 말하고 서비스 종류를 바꾼다. 기대 동작은 주소를 되묻지 않고 새 서비스 범위를 반영하는 것이다.
음성 시험을 시작하는 도구는 없어 고객이 제품 UI에서 직접 시험한다. 고객이 “두 번째 사례에서 주소를 다시 물었어요”라고 보고하면 이후 작업에 영향을 줄 피드백으로 보고 기록한다. 고객이 callId를 주거나 `list_calls`로 해당 통화를 찾아 `get_call`로 읽기 전에는 independent call evidence라고 부르지 않는다. 조회한 뒤에는 상태·당시 버전·추출 결과를 근거로 쓰고 원문은 필요할 때만 `include_transcript`로 읽는다. call reference는 locator로만 남기고 전체 transcript를 수집하지 않는다.
피드백이 Manual 분기 수정으로 이어지면 위 refine 흐름으로 좁게 바꾸고 저장값을 재조회한다. 고객의 보고는 feedback_reported 또는 customer_voice_report로 요약 기록하고 계속 reported 상태로 둔다. 전달에는 고객이 다시 말할 문장과 기대 결과를 적는다. 실제 재시험 전에는 “저장 확인·고객 재시험 대기”로 상태를 표현한다.
## 4. Operate: 게시, 번호 연결, 발신, 결과 확인
고객이 “오늘부터 실제 문의를 받아도 될까요?”라고 묻는다. 순서는 다음과 같다. 각 단계 뒤에 응답과 재조회로 확인한다.
1. 현재 설정을 `create_agent_version`으로 버전에 남기고 `list_agent_versions`로 확인한다.
2. 어느 버전을 production으로 지정할지 대화에서 요약해 확인받고 `publish_agent_version`을 호출한 뒤 `get_agent`로 production 설정을 읽는다.
3. 이미 가진 번호를 `list_numbers`/`get_number`로 찾아 연결 변경(현재 → 변경, 해제 여부)을 요약해 확인받고 `set_number_agents`를 호출한 뒤 `get_number`로 확인한다. 번호 획득은 웹에서만 한다.
4. 통제된 인바운드 전화나, 대상·발신 번호·agent 버전을 요약해 확인받은 `place_call`(새 `execution_key`)로 첫 통화를 만든다. 대량은 `create_sheet` → `launch_campaign`(새 `execution_key`)이며 `pause_campaign`/`resume_campaign`/`cancel_campaign`으로 제어한다.
5. `list_calls`/`get_call`로 접수·연결·종료·추출 결과를 읽는다. 응답이 불명(`EXECUTION_RESULT_UNKNOWN`·`EXECUTION_IN_PROGRESS`)이면 다시 실행하지 않고 `list_calls`·`get_campaign`으로 확인한다.
이후 고객이 “오늘 접수는 괜찮았지만 주소를 중복 질문했다”고 알려주면 고객 보고로 분류하고, 해당 통화가 조회되면 `get_call` 근거로 수정 가설·확인 사례를 제안한다. 조회되지 않은 운영 결과는 관측된 call 통계로 표현하지 않는다. 저장된 설정만 보고 운영 가능하다고 판정하거나 실제 전화가 나갔다고 말하지 않는다.
## 5. Resume: 부분 성공을 보존하고 다른 세션에서도 안전하게 이어가기
### Manual 생성 응답이 불명인 경우
agent 생성은 성공해 실제 `agent_id`를 받았지만 Manual 생성 응답이 사라졌다고 하자. 새 Manual을 즉시 만들지 않는다. 같은 `agent_id`에서 목록을 확인한다.
```mcp-call
{"tool":"list_manuals","arguments":{"agent_id":"11111111-1111-4111-8111-111111111111"}}
```
Manual 이름이 맞는 항목이 하나여도 기존 리소스와 이번 create 요청을 구분할 수는 없다. 후보의 실제 `manual_id`로 전체 본문과 revision을 읽어 의도한 내용인지 대조한다. 일치하면 그 리소스를 현재 대상으로 이어갈 수 있지만, exact receipt나 별도 증거가 없으면 불명 쓰기의 성공이라고 보고하지 않는다. 없거나 여러 후보가 있거나 내용이 다르면 상태 불명으로 남기고 create를 반복하지 않는다.
### 다른 Thread나 호스트에서 다시 시작하는 경우
새 Thread나 다른 호스트에서는 실제 tool list와 schema를 먼저 확인하고, 현재 대화나 아래 사용자 제공 handoff로 이어가며 다른 Thread를 검색했다고 말하지 않는다.
```text
목표: 샘플 홈케어 문의 접수 Manual 완성
agent_id: <실제 ID>
manual_id: <실제 ID>
마지막으로 확인한 agent/manual revision: <실제 값>
직접 표현한 결정: 업무 범위 파악 후 주소를 한 번만 묻기
시험 피드백: 고객 보고 — 주소를 다시 물었음; call 증거는 미확인
다음 행동: 최신 Manual을 다시 읽고 규칙을 좁게 수정한 뒤 고객에게 재시험 사례 전달
```
이 fallback 요약은 사용자 제공 handoff이며 서버 기록이 아니다. 재개할 때는 [resume-agent-work](../skills/resume-agent-work/SKILL.md)의 동일 ID·최신 상태 확인 원칙을 적용한다.
SHA-256: dd19e8d1476e357613ac82b23377281d416a01afb5b222b472fd8c2678270e4d