통화 받아쓰기·요약 데이터 구조: sttAI·sttDirect·summary
KAT Cloud의 통화 받아쓰기와 요약은 통화 기록의 sttAI(AI 구간), sttDirect(직원 구간), summary(요약) 필드에 담깁니다. 필드 구조, CALL_COMPLETED 웹훅과 통화 기록 API로 받는 방법, 요금과 주의점을 정리했습니다.

KAT Cloud의 통화 받아쓰기와 요약 결과는 통화 기록의 세 필드, 즉 sttAI(AI가 응대한 구간의 대화), sttDirect(직원이 응대한 구간의 대화), summary(통화 요약)에 담깁니다. sttAI와 sttDirect는 role, text, timestamp로 이루어진 객체 배열이고 summary는 문자열입니다. 이 데이터는 통화가 끝나고 STT·요약 처리가 완료되면 CALL_COMPLETED 웹훅으로 받거나 통화 기록 API(GET /call-history)로 조회할 수 있습니다.
요금은 AI 받아쓰기 분당 10원, AI 요약 분당 10원이며 사용량 구간 없이 같은 단가입니다(부가세 별도). 이 글은 세 필드의 구조와 채워지는 조건, 받는 방법, 저장할 때 주의할 점을 차례로 설명합니다.
세 필드는 이렇게 나뉩니다

| 필드 | 타입 | 내용 |
|---|---|---|
sttAI | object[] | AI 구간 STT. 항목마다 role, text, timestamp(초 단위, 소수점 포함) |
sttDirect | object[] | 직원(Direct) 구간 STT. 구조는 sttAI와 같음 |
summary | string | 통화 요약 |
tag | string | AI, DIRECT, AI_TO_DIRECT, UNKNOWN |
isRecorded | boolean | false면 녹음, 요약, STT가 제공되지 않음 |
recordingAI, recordingDirect | object | 통화 기록 API의 구간별 녹음 파일(url, expiresAt, contentLength, contentType) |
recordingUrl | string | CALL_COMPLETED 웹훅의 녹음 파일 URL(선택) |
role 값은 agent와 customer 두 가지입니다. API 문서 예시를 보면 sttAI의 agent는 AI 에이전트의 발화이고, sttDirect의 agent는 연결받은 직원의 발화입니다. customer는 두 배열 모두 고객의 발화입니다.
{
"tag": "AI_TO_DIRECT",
"summary": "예약 변경 요청 후 담당자 연결하여 상담 완료",
"sttAI": [
{ "role": "agent", "text": "안녕하세요. KAT Cloud입니다. 무엇을 도와드릴까요?", "timestamp": 1.2 },
{ "role": "customer", "text": "내일 예약 시간을 변경하고 싶은데요.", "timestamp": 4.3 }
],
"sttDirect": [
{ "role": "agent", "text": "안녕하세요, 담당자 김민수입니다.", "timestamp": 1.2 },
{ "role": "customer", "text": "네, 내일 오후 3시로 예약 변경하고 싶어서요.", "timestamp": 4.5 }
]
}tag와 isRecorded로 채워지는 내용이 달라집니다
통화 기록의 tag는 그 통화를 누가 응대했는지 보여 주고, 어느 배열에 대화가 담길지도 이 값과 맞물립니다.
- AI: AI 에이전트가 응대한 통화로, AI 구간 대화가 sttAI에 담깁니다.
- DIRECT: 직원이 응대한 통화로, 직원 구간 대화가 sttDirect에 담깁니다.
- AI_TO_DIRECT: AI가 받다가 직원에게 연결한 통화로, 앞부분은 sttAI에, 뒷부분은 sttDirect에 나뉘어 담깁니다. 녹음 파일도 recordingAI와 recordingDirect로 나뉩니다.
- UNKNOWN: 앞의 세 값에 해당하지 않는 경우입니다. 두 배열이 모두 비어 있을 수 있다고 보고 처리합니다.
isRecorded가 false인 통화는 녹음 파일, 요약, STT 대화 내역이 모두 제공되지 않습니다. 저장 코드에서는 세 필드가 비어 있거나 없는 경우를 정상 상황으로 다뤄야 합니다.
timestamp는 초 단위 숫자입니다. 문서 예시에서는 sttAI와 sttDirect가 각각 작은 값부터 시작하기도 하므로, 두 배열의 timestamp를 하나의 시간축으로 단정하기보다 각 배열 안의 순서로 쓰고, 두 구간을 합칠 때는 AI 구간 다음 직원 구간 순서로 이어 붙이는 편이 안전합니다. 직원 연결 흐름은 AI 상담원 연결(핸드오프) 설계에서 자세히 다룹니다.
데이터를 받는 두 가지 방법

| 방법 | 받는 시점 | 특징 |
|---|---|---|
| CALL_COMPLETED 웹훅 | 통화 종료 후 STT·요약 분석이 완료되면 | 폴링이 필요 없음. 타임아웃 10초, HTTP 2xx 응답 시 성공 처리 |
GET /call-history + updatedAfter | 주기적으로 조회할 때 | 갱신된 기록만 updatedAt 오름차순으로 받음. offset과 함께 쓰지 않음, limit 최대 100 |
GET /call-history/{callHistoryId}?groupId= | 특정 통화가 필요할 때 | 단건 상세 조회 |
통화 기록의 updatedAt은 녹음 파일이 저장되는 순간이 아니라 STT·요약 처리가 끝나 통화 기록이 저장되는 시점에 갱신됩니다. 그래서 증분 조회로 잡히는 통화에는 summary와 sttAI가 함께 채워져 있습니다. 증분 조회 구현은 통화 기록 증분 동기화를, 필드 전체는 통화 기록 API 문서와 웹훅 이벤트 문서를 참고하세요. 통화 기록과 웹훅 API는 문자 발신 외 API이므로 비즈니스 요금제 그룹 또는 별도 허용된 그룹에서 쓸 수 있습니다.
받아쓰기를 대화록으로 바꾸는 예제
CALL_COMPLETED 웹훅의 data나 통화 기록 항목을 받아, 사람이 읽기 좋은 대화록 한 덩어리로 바꾸는 Python 예제입니다. 구간에 따라 agent를 "AI" 또는 "직원"으로 표시합니다.
def to_transcript(record: dict) -> str:
"""CALL_COMPLETED 웹훅 data 또는 통화 기록 항목을 대화록 텍스트로 바꾼다."""
if record.get("isRecorded") is False:
return "" # 녹음이 꺼진 통화는 STT·요약이 없다
lines = []
sections = [("AI", record.get("sttAI") or []), ("직원", record.get("sttDirect") or [])]
for agent_label, items in sections:
for item in items: # 각 배열 안의 순서를 그대로 쓴다
speaker = agent_label if item["role"] == "agent" else "고객"
lines.append(f"{speaker}: {item['text']}")
summary = record.get("summary")
header = f"[요약] {summary}\n" if summary else ""
return header + "\n".join(lines)웹훅 수신 서버를 처음 만든다면 10초 타임아웃 안에 먼저 2xx로 응답하고, 대화록 변환과 저장은 비동기로 처리하는 구조를 권장합니다.
활용 예와 비용
- CRM 메모: summary를 고객 연락처의 상담 이력에 붙입니다. 전화번호(fromNumber)로 고객을 찾아 연결할 수 있습니다.
- 팀 알림: 통화가 끝날 때마다 요약을 사내 메신저로 보냅니다. 예제는 통화 요약을 슬랙으로 보내기에 있습니다.
- 검색:
GET /call-history의 keyword 파라미터는 통화 요약 내용을 검색합니다. - 품질 점검: sttAI를 읽어 AI가 잘못 알아들은 단어, 같은 질문을 되묻는 구간, 직원 연결로 넘어가기 직전의 대화를 찾습니다.
비용은 통화 분에 단가를 곱해 계산합니다. 월 2,000분 통화에 받아쓰기와 요약을 모두 쓰면 (10원 + 10원) × 2,000분 = 40,000원(부가세 별도)입니다.
저장할 때는 몇 가지를 함께 챙깁니다. 녹음 파일 URL은 S3 Presigned URL로 1시간 후 만료되므로, 보관이 필요하면 받는 즉시 내려받아 별도 저장소에 둡니다. 웹훅과 증분 조회를 함께 쓰면 같은 통화가 두 경로로 들어올 수 있으니 callHistoryId 기준으로 덮어쓰게 만듭니다. 받아쓰기와 요약에는 고객이 말한 이름, 연락처, 주소가 그대로 담기므로 보관 기간과 접근 권한도 정해 둡니다. 설계 원칙은 AI 전화와 개인정보에 정리했습니다.
자주 묻는 질문
sttAI와 sttDirect의 차이는 무엇인가요?
sttAI는 KAT Cloud 통화 기록에서 AI 에이전트가 응대한 구간의 받아쓰기이고, sttDirect는 직원이 응대한 구간의 받아쓰기입니다. 두 필드는 role, text, timestamp로 된 같은 배열 구조이며, AI가 응대하다 직원에게 연결한 AI_TO_DIRECT 통화에는 두 구간이 나뉘어 담깁니다.
받아쓰기와 요약은 통화가 끝나면 언제 받을 수 있나요?
KAT Cloud의 CALL_COMPLETED 웹훅은 통화 종료 후 STT와 요약 분석이 완료되면 전송됩니다. 웹훅을 쓰기 어렵다면 통화 기록 API에 updatedAfter를 지정해 처리가 끝난 기록만 주기적으로 가져올 수 있습니다.
통화 받아쓰기와 요약 요금은 얼마인가요?
KAT Cloud의 AI 받아쓰기와 AI 요약은 각각 분당 10원이며, 사용량 구간 없이 같은 단가가 적용됩니다(부가세 별도). 둘 다 쓰면 통화 1,000분에 20,000원입니다.
녹음을 끈 통화도 받아쓰기가 남나요?
KAT Cloud 통화 기록에서 isRecorded가 false인 통화는 녹음 파일, 요약, STT 대화 내역이 제공되지 않습니다. 받아쓰기와 요약이 필요한 업무라면 통화 녹음이 활성화되어 있는지 먼저 확인해야 합니다.
- #통화 받아쓰기
- #통화 요약
- #STT
- #웹훅
- #통화 기록



