Communitygithub.com

CounterCall

📞 CALL-E가 인도네시아 관공서에 전화를 걸어 가져가야 할 서류 목록을 확인하고, 담당 공무원이 모르는 항목은 빈 칸으로 남겨둡니다.

CounterCall란 무엇인가요?

CounterCall은 CALL-E 플랫폼에서 실행되는 기술로, 인도네시아 관청(예: Samsat)에 직접 전화를 걸어 특정 민원 처리에 필요한 서류와 요구사항을 확인해줍니다. 이 기술의 핵심은 공식 웹사이트나 게시판에 공개된 정보가 불완전하거나 구식인 경우에도 전화로 실시간 확인하여 신뢰할 수 있는 체크리스트를 제공한다는 점입니다. 사용자는 사전에 전화를 걸어 확인하지 않고 직접 관청을 방문해 필요한 서류가 누락되어 돌아서는 일을 방지할 수 있습니다. 이 기술은 E.164 형식의 전화번호만 허용하고, 고유 ID를 사용해 중복 전화를 방지하며, 결과는 엄격한 스키마 검증을 거쳐 깔끔한 체크리스트로 제공됩니다. 인도네시아 공공 서비스 환경에 특화되어 있으며, useRef나 LangChain과 같은 개발 도구와 유사하게 복잡한 호출 워크플로를 안전하고 효율적으로 자동화합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add edycutjong/countercall

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

CounterCall은(는) 무엇을 하나요?

Pak Yanto는 오전에 반차를 내고 사십 분을 달려 삼삿(Samsat) 창구에 갔지만, 복사본이 A4가 아닌 폴리오(Folio) 용지라서 거절당했습니다. 그는 하루 수입을 잃었고, 다음 날 또 무엇을 빠뜨릴지 여전히 알지 못했습니다.

공공 서비스 창구는 게시된 요구사항 목록이 불완전하거나 구식이거나, 실제 창구에서는 조용히 반박되곤 합니다. 신뢰할 수 있는 유일한 출처는 사무실의 전화 회선이지만, 그 전화는 바쁘고 IVR(자동응답) 시스템을 거쳐야 하며, 네 번째 시도에야 연결됩니다. 그래서 사람들은 전화를 걸지 않습니다. 그들은 직접 가고, 줄을 서고, 서류 한 장 때문에 돌아섭니다.

이 기술이 대신 전화를 걸어, 사용자가 스크린샷을 찍어 가지고 갈 수 있는 체크리스트를 반환합니다.

CALL-E의 설계 목적에 잘 맞습니다: 낮은 빈도, 개인적이고, 높은 중요도를 가진 전화 작업으로, 사람이 아니었다면 아침 내내 재다이얼해야 했을 번호에 대해 수행됩니다.

시작하기 전에

이 기술은 실제 공공 사무소에 실제 전화를 겁니다. 사용자와 다음 사항을 확인하십시오:

  • 어떤 절차에 대해 문의하는지, 사무소 자체의 표현으로
  • 어떤 사무소이며, 사무소의 공식 게시 페이지에서 가져온 E.164 형식의 전화번호
  • 지금 전화를 걸기를 원하는지

전화번호를 추론하지 마십시오. 디렉토리에서 찾은 번호, 유사한 사무소의 번호, 국가 코드를 추측해서도 안 됩니다. 사람이 사무소의 공식 게시 페이지에서 번호를 직접 읽어온 경우에만 플로우에 진입할 수 있습니다. 잘못된 번호로 전화를 거는 것은 자동 발신자가 낯선 사람에게 연결되는 것을 의미하며, 이 기술이 할 수 있는 최악의 일입니다.

안전 경계

이 기술은 창구 요구사항만 수집합니다.

  • 신청서를 제출하거나, 약속을 예약하거나, 수수료를 지불하거나, 사용자를 어떤 행위에 구속하지 않습니다. 질문하고 보고할 뿐입니다.
  • 법률 또는 이민 조언을 제공하지 않습니다. 직원이 대체 경로를 제안하면, 그 내용을 직원이 말한 그대로 전달하며, 절대 추천으로 제시하지 않습니다.
  • 직원의 구두 답변은 정보 제공 목적이며 법적 구속력이 없으며, 모든 결과물에 이를 명시합니다. 요구사항은 변경될 수 있고, 개별 창구는 재량을 적용할 수 있습니다.
  • 전화 시작 시 자동 응답 시스템임을 명확히 밝히고, 왜 전화하는지 설명합니다. 상대방이 응답을 거부하면 감사 인사를 하고 전화를 종료합니다. 같은 날 재시도, 재질문, 재전화하지 않습니다.
  • 사무소당 절차당 하루 한 통. 이 전화선은 공공 서비스 회선이며, 대기열에 있는 사람들이 담당하는 직원이 운영합니다. 멱등성 키(idempotency key)가 이를 강제하므로 제거하지 마십시오.
  • 직원이 확신하지 못할 경우, 결과에는 '확실하지 않음'이라고 표시합니다. 일반적인 사항으로 빈칸을 채우거나, 애매한 표현을 사실로 제시하지 않습니다. 사람은 이 답변을 믿고 도시를 가로질러 이동할 수 있습니다.
  • 공개된 업무 시간에만 전화를 겁니다. 오후 10시에 공공 회선이 울리는 것은 데이터 포인트가 아니라 민폐입니다.

이 기술을 새로운 기관에 적용하기 전에 참고자료/safety.md를 읽으십시오. 일부 수신처는 자동 발신기의 대상으로 적절하지 않습니다.

이것이 단순한 대화 기록과 다른 점

대부분의 호출 기술은 텍스트를 반환하고 독자가 해석하도록 둡니다. 하지만 이 기술은 고정되고 검증된 객체를 반환하며, 다른 것은 반환하지 않습니다.

Goal의 result_schema는 additionalProperties: false를 설정하고 네 개의 필드를 열거형으로 제한합니다 — payment_method, appointment_required, originals_or_copies 및 clerk_certainty, 각각에는 "직원이 알지 못함"에 대한 값이 포함됩니다. 호출 결과가 다르게 구성되면, 결과는 검역(견리)되어 렌더링되지 않습니다. 반쯤 파싱된 체크리스트는 체크리스트가 없는 것보다 더 나쁩니다. 사용자가 그 체크리스트를 믿고 행동하기 때문입니다.

전체 계약은 참고자료/result-contract.md에 있습니다.

워크플로우

1. 요청 수집

필수: 절차 이름, 사무소 이름, 사무소의 E.164 형식 전화번호, 번호를 가져온 게시된 출처 URL.

다른 모든 일보다 먼저 번호를 검증하십시오. E.164는 플러스 기호, 0이 아닌 국가 코드 숫자, 그리고 7~14개의 추가 숫자입니다: ^\+[1-9]\d{7,14}$. 이외의 것은 거부하고 사용자에게 물어보십시오. 국가 코드를 추측하지 마십시오. 지역 형식 번호가 다이얼러에 도달하면 잘못된 사람에게 전화가 걸리는 것입니다.

scripts/preflight.mjs를 실행하여 전화를 걸지 않고 번호와 계약을 확인하십시오.

2. 게시된 계약이 변경되지 않았는지 확인

매 실행 전에, 라이브 Goal 인터페이스를 읽고 이 기술이 작성된 계약과 비교하십시오.

import { diffContract, publishedRunSpec } from './scripts/_lib.mjs';

const goal = await client.goals.get(GOAL_ID);
const drift = diffContract(PINNED_CONTRACT, publishedRunSpec(goal));
if (drift.length) throw new ContractDrift(drift);   // 전화 거절

publishedRunSpec(goal) 헬퍼를 사용하십시오. goal.published_run_spec을 직접 사용하지 마십시오. 와이어 포맷과 문서에는 published_run_spec.result_schema로 표기되며, TypeScript SDK는 카멜 케이스로 publishedRunSpec.resultSchema로 변환합니다. 문서화된 이름만을 TypeScript 클라이언트에 대해 읽으면 undefined를 반환하고(오류를 던지지 않음), 가드는 "게시된 명세 없음"이라고 결론을 내려 정상 작동하는 것처럼 보이면서 모든 다이얼을 거부합니다. 헬퍼는 두 표기법을 모두 읽습니다. 이 문제로 하루를 허비했으며, 저장소 루트의 FEEDBACK.md에 기록되어 있습니다.

CALL-E 문서에서는 변수 변경을 배포하기 전에 이 비교를 권장합니다. 매 실행마다 수행하면 API 호출 한 번으로 조용한 실패를 큰 소리로 거부로 전환합니다. 스키마가 구식인 상태로 실제 사람에게 전화를 걸면 결과는 정상으로 보이지만 조용히 잘못된 것입니다.

3. 한 통 전화 걸기

goals.run에 사무소, 절차, 날짜로 범위가 지정된 Idempotency-Key를 사용하십시오. 재시도가 공공 회선에 이중 전화를 걸지 않도록 합니다:

countercall:{office}:{procedure}:{yyyy-mm-dd}:v1

4. 결과 또는 오류가 나올 때까지 폴링

goals.waitForResult는 하나의 완료 규칙을 가집니다: result 또는 error가 null이 아닐 때 중단합니다. 완료된 호출은 CALL-E가 구조화된 결과를 파싱하는 동안 두 값이 모두 null인 상태가 잠시 발생할 수 있으므로, 그 윈도우를 실패로 처리하지 마십시오.

5. 렌더링하거나 정직하게 실패 처리

모든 8개의 게시된 GoalRunError 코드는 각각 다른 결과로 이어집니다. 아래 집합은 scripts/render.mjs가 구현한 것입니다. CALL-E가 코드를 추가하면 동기화하십시오.

결과사용자에게 표시되는 내용
유효한 결과체크리스트, 직원의 말 그대로의 문장과 출처 URL 포함
no_answer"회선이 응답하지 않았습니다". 체크리스트 없음
declined"사무소가 자동 발신자에 대한 응답을 거부했습니다". 체크리스트 없음
result_invalid호출은 완료되었지만 응답이 계약과 일치하지 않습니다. 검역됨
result_unavailable호출은 완료되었지만 구조화된 응답을 생성하지 않았습니다. 체크리스트 없음
result_failed응답을 체크리스트로 처리할 수 없습니다. 체크리스트 없음
timed_out마감 시간까지 "사용 가능한 응답 없음". 체크리스트 없음
call_failed호출을 완료할 수 없습니다. 체크리스트 없음
canceled응답을 생성하기 전에 취소됨. 체크리스트 없음

어떤 분기도 부분 체크리스트를 렌더링하지 않습니다. 각각의 작업 예제는 참고자료/examples.md에 있습니다.

실행

scripts/call.mjs는 기본적으로 드라이 런(dry-run)입니다. 보낼 정확한 요청을 출력하고 전화를 걸지 않습니다. 다이얼링에는 명시적인 --live가 필요합니다:

# 드라이 런 — 보낼 요청을 출력하고, 전화를 걸지 않으며, 자격 증명이 필요 없음
node scripts/call.mjs --office <id> --procedure "<procedure>"

# 실제로 전화를 겁니다
node scripts/call.mjs --office <id> --procedure "<procedure>" --live

기본적으로 전화를 거는 기술은 실수로 전화를 거는 기술입니다.

data/offices.json은 전화번호가 가려진 상태로 제공됩니다(+62XXXXXXXXXX). 따라서 시드된 항목으로는 전화를 걸 수 없으며, 모든 명령은 REFUSING TO DIAL과 함께 3으로 종료됩니다. 이는 의도적입니다: 사람이 사무소의 공식 게시 페이지에서 번호를 읽어 source_url과 source_checked를 기록한 경우에만 파일에 번호가 입력됩니다. 실행하기 전에 자신의 항목을 추가하십시오.

드라이 런 출력을 즉시 보려면, 테스트 픽스처에 유효한 가상 번호가 포함되어 있습니다:

node scripts/call.mjs --offices ../../test/fixtures/offices.test.json \
  --office fixture-sourced --procedure "perpanjangan paspor"

이 기술을 사용하지 말아야 할 경우

  • 긴급 상황. 이는 몇 분의 지연 시간이 있는 요구사항 조회입니다. 긴급하게 누군가에게 연락하는 방법이 아닙니다.
  • 게시된 신뢰할 수 있고 최신의 요구사항 페이지가 있는 사무소. 웹사이트가 정확하다면, 웹사이트를 읽으십시오. 게시된 답변이 불완전한 것으로 알려진 경우에만 전화가 정당화됩니다.
  • 자동 시스템으로부터의 전화를 거부하도록 요청한 기관, 또는 현지 법률이 자동 전화를 제한하는 경우. 사무소를 추가하기 전에 확인하십시오.
  • 대량 조회. 설계상 하루에 사무소당 절차당 한 통이 상한입니다. 대량이 필요하다면, 전화가 아닌 데이터 공유 계약이 필요합니다.
  • 잘못되는 것이 저렴한 경우. 이 기술의 가치는 낭비된 여행 비용에서 비롯됩니다. 사용자가 그냥 가서 확인할 수 있다면, 그렇게 하도록 하십시오.

정직한 한계

  • 적용 범위는 시드 파일에 있는 사무소로 제한되며, 각각 게시된 출처 URL이 있습니다.
  • 공공 서비스 회선의 응답률은 사무소와 시간대에 따라 다르며, 많은 호출이 응답되지 않습니다. 이러한 불안정성이 이 기술이 존재하는 이유이며, 숨기지 않고 보고됩니다.
  • 결과는 특정 날짜의 한 직원의 답변입니다. 증거일 뿐, 보장이 아닙니다.

관련 스킬