Communitygithub.com

edvcutjong/countercall

📞 在您出門前,幫您致電印尼政府服務櫃檯,取得一份經驗證的必備文件清單——若承辦人員不清楚,該項目就會留空。

countercall 是什麼?

這個技能專為CALL-E設計,能自動撥打印尼政府服務櫃檯的電話,詢問特定申辦項目所需文件,並回傳一份結構化的驗證清單,讓使用者截圖後攜帶出門。技能解決了官方公布資訊常不完整、過時或與現場要求矛盾的問題,透過實際通話取得最可靠的答案。支援檢查辦公室電話號碼格式(E.164)、驗證技能合約是否與最新API一致,並提供乾燥執行模式(dry-run)避免誤撥。結果以嚴謹的JSON Schema驗證,確保回傳的文件類型、付款方式、是否需要預約、承辦人員確定程度等欄位都符合預期,若承辦人員不確定則明確標示。技能內建安全邊界:每次通話前會表明身份,若對方拒絕回答則立即結束;每日同辦公室、同程序、同日期只允許一通電話,並在營業時間內撥打。最適合個人一次性、高風險的行政文件查詢,不適用於緊急情況或大量批次查詢。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add edycutjong/countercall

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

countercall 是做什麼的?

Pak Yanto 請了半天假,騎了四十分鐘車到 Samsat 櫃檯,卻因為他的影印本是 Folio 而非 A4 規格而被拒絕。他損失了一天的收入,而且仍然不知道明天還缺什麼資料。

公務櫃檯公布的必備文件清單常不完整、過時,或在櫃檯現場有不一樣的說法。唯一可靠的來源是辦公室電話,但那條線路經常佔線、經過語音選單層層轉接,而且常常要打到第四通才有人接聽。所以多數人不會打電話。他們直接跑一趟、排隊,然後因為一份文件而被拒絕。

這個技能會代替您打電話,並回傳一份可讓您截圖帶出門的檢查清單。

它很符合 CALL-E 的設計理念:低頻率、個人化、高風險的電話工作,處理的是人類原本需要花整個早上重撥的號碼。

開始之前

此技能會實際撥打電話到真正的公務辦公室。 請先向使用者確認:

  • 他們要詢問的是哪項程序,須使用辦公室自己的說法
  • 哪間辦公室,以及辦公室官網公布的電話號碼(E.164 格式)
  • 他們希望現在就打電話

絕不推測電話號碼。 不從目錄、不相近辦公室、不猜測國碼。只有當人類從辦公室自己的公開網頁讀取到號碼後,該號碼才能進入流程。打錯號碼意味著自動撥號系統會聯絡到陌生人,這是此技能最嚴重的錯誤。

安全邊界

此技能僅收集櫃檯要求資訊。

  • 它不會送出申請、預約、支付費用,或讓使用者有任何承諾。它只詢問並回報。
  • 它不會提供法律或移民建議。如果承辦人員建議替代方案,請逐字記錄為「承辦人員所說的話」,絕不能當成建議。
  • 承辦人員的口頭回答是資訊性,不具法律約束力,每份呈現的結果都會如此標示。規定會改變,且個別櫃檯有裁量權。
  • 通話開始時會清楚表明這是自動化助理,並說明來電原因。如果對方拒絕回答,它會感謝對方並結束通話。不會繼續追問、重複詢問,或當天再次撥打。
  • 每天每間辦公室每項程序僅限一通電話。 這些是公務服務專線,接待人員面前還有民眾在排隊。冪等性鍵(Idempotency-Key)強制執行此限制,請勿移除。
  • 若承辦人員不確定,結果會標示為「不確定」。絕不會用常見情況填補空缺,也絕不會將模糊陳述呈現為事實。使用者可能會穿越整座城市,依據此答案行動。
  • 僅在辦公室公布的營業時間內撥打電話。晚上十點鈴聲空響不是資料點,而是騷擾。

在將此技能套用至新機關前,請先閱讀 references/safety.md。部分受話對象根本不適合自動撥號系統。

它與逐字稿有何不同

大多數通話技能回傳文字,讓讀者自行解讀。此技能回傳一個固定的、驗證過的物件,且拒絕回傳其他內容。

Goal 的 result_schema 設定了 additionalProperties: false,並將四個欄位限制為列舉值——payment_method、appointment_required、originals_or_copies 和 clerk_certainty——每個都包含一個「承辦人員不知道」的值。如果通話回傳的格式不符,結果會被隔離,不會呈現。部分解析的檢查清單比完全沒有還糟,因為使用者會根據它行動。

完整契約請見 references/result-contract.md。

工作流程

1. 收集請求

必填項目:程序名稱、辦公室名稱、辦公室的 E.164 格式電話號碼,以及該號碼的公開來源 URL。

在進行任何其他操作前,先驗證號碼。 E.164 格式為一個加號、非零的國碼數字,後面跟 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 會以 camelCase 形式轉換為 publishedRunSpec.resultSchema。若僅以文件中的名稱讀取 TS 客戶端,會回傳 undefined 而非拋出例外——檢查機制會判定「沒有公布規格」,並拒絕每次撥號,同時看起來仍在正常運作。輔助函式會同時讀取兩種寫法。這讓我們損失了一整天,已在 repo 根目錄的 FEEDBACK.md 中記錄。

CALL-E 文件建議在部署變數變更前進行此比較。在每次執行時都做,只花費一次 API 呼叫,就能將無聲的失敗轉變為明確的拒絕。用過時的 Schema 撥打真實人員的電話,會產生看似正常但實際錯誤的結果。

3. 撥打一通電話

使用 goals.run,並搭配以辦公室、程序和日期為範圍的 Idempotency-Key,這樣重試就不會重複撥打公務專線:

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

4. 輪詢直到取得結果或錯誤

goals.waitForResult 有一個完成規則:當 result 或 error 其中之一非 null 時停止。已完成的通話可能短暫同時回傳 null,因為 CALL-E 正在解析結構化結果,請不要將那個視窗視為失敗。

5. 呈現結果,或誠實地回報失敗

全部八種已公布的 GoalRunError 代碼都對應到不同的結果。以下列表是 scripts/render.mjs 實作的項目——如果 CALL-E 新增代碼,請保持同步。

結果使用者看到的內容
有效結果檢查清單,包含承辦人員的逐字陳述和來源 URL
no_answer「線路無人接聽」。無檢查清單
declined「辦公室拒絕回答自動化來電」。無檢查清單
result_invalid通話完成但答案不符合契約。已隔離
result_unavailable通話完成但未產生結構化答案。無檢查清單
result_failed答案無法處理成檢查清單。無檢查清單
timed_out截止時間前「無可用答案」。無檢查清單
call_failed通話無法完成。無檢查清單
canceled在產生答案前被取消。無檢查清單

沒有任何分支會呈現部分檢查清單。 每個結果的實際範例請見 references/examples.md。

執行方法

scripts/call.mjs 預設為乾燥執行。它會印出將要發送的確切請求,但不會撥打任何電話。需要加上 --live 才會實際撥號:

# 乾燥執行——印出將發送的請求,不撥號,不需憑證
node scripts/call.mjs --office <id> --procedure "<procedure>"

# 實際撥打電話
node scripts/call.mjs --office <id> --procedure "<procedure>" --live

預設會撥號的技能,就是會意外撥號的技能。

data/offices.json 出廠時電話號碼已遮罩(+62XXXXXXXXXX),因此預設的條目無法撥號,對它下達的任何命令都會以退出碼 3 並顯示 REFUSING TO DIAL。這是刻意的:只有當人類從辦公室自己的公開網頁讀取號碼,並記錄了 source_url 和 source_checked 後,號碼才能加入檔案。請在執行任何操作前加入您自己的條目。

若要立即查看乾燥執行的輸出,測試 fixture 中包含了一個有效的虛擬號碼:

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

何時不該使用此技能

  • 緊急狀況。 這是需要數分鐘延遲的文件查詢,不是緊急聯絡方式。
  • 擁有已公布、可靠且最新的文件要求的辦公室。 如果網站資訊正確,請直接查閱網站。只有在已知公布的答案不完整時,才值得打電話。
  • 任何曾要求不要被自動化系統撥打的機構,或當地法律限制自動撥號的情況。加入辦公室前請先確認。
  • 大量查詢。 每天每間辦公室每項程序一通電話是設計上限。如果您需要批量查詢,您需要的是資料共享協議,而不是電話。
  • 任何「搞錯也無大礙」的情況。 此技能的價值來自於浪費一趟行程的代價。如果使用者可以乾脆直接去現場確認,那就讓他們去。

誠實的限制

  • 涵蓋範圍僅限於種子檔案中的辦公室,每個辦公室都有公布來源 URL。
  • 公務專線的接通率因辦公室和時段而異,且很大比例的電話將無人接聽。這種不可靠性正是此技能存在的原因,我們會如實回報,而非隱藏。
  • 結果是某一天某位承辦人員的答覆。它是證據,不是保證。

相關技能