開發者配套

CallFunc — 開發者參考手冊

在 Perxona 中設定工具 — 給建置者的實作指南

易讀的 HTML 版面 適用對象:把 HTTP API 變成 agent 工具的開發者
藍色區塊 在 console 中要執行的具體操作。
琥珀色區塊 常見陷阱、限制與注意事項。
綠色區塊 用來確認運作正常的檢查。
紫色區塊 可交給 AI 工具的提示片段。

本手冊會說明如何把你既有的 HTTP 端點變成 Perxona agent 可以呼叫的工具 — 而且同樣重要的是,如何把它寫得讓 LLM 真正理解何時、以及如何使用它。


1. LLM 如何「看見」一個工具

當 agent 運行時,Perxona 會把一份工具清單交給模型。每個工具本質上就是這樣(與 OpenAI 和 Anthropic 在底層使用的結構相同):

{
  "name": "verb_noun",
  "description": "What the tool does, and when the model should reach for it.",
  "parameters": { /* the INPUT JSON Schema */ }
}

在每一輪對話中,模型都只憑那段文字問自己:

  1. 我到底該不該呼叫工具? → 由名稱 + 描述決定。
  2. 呼叫哪一個? → 由各個描述彼此之間有多明顯不同決定。
  3. 用什麼參數? → 由輸入 schema決定(欄位名稱、型別、required、描述、enum、預設值)。
  4. 我拿回了什麼/要告訴使用者什麼? → 由輸出 schema協助(讓它知道會回傳哪些欄位、各是什麼型別)。

所以身為建置者,你的工作就是把那四件事寫清楚。這就是整門手藝的全部。

一次呼叫底層實際上發生了什麼

flowchart TB A["LLM 讀取 name + description + 輸入 schema
決定呼叫,並產生符合輸入 schema 的參數"] B["Perxona 驗證參數(JSON Schema → Pydantic),
注入你的密鑰,然後送出 HTTP 請求"] C["你的伺服器執行並回傳 JSON"] D["Perxona 把 JSON 回饋給 LLM
(輸出 schema 幫助它解讀),
LLM 接著寫出給使用者看的回覆 —— 或呼叫另一個工具"] A --> B --> C --> D

你只需要建置伺服器 + 那四個文字/結構訊號。Perxona 會負責驗證、secret 注入與 HTTP 呼叫。


2. Perxona 中的兩個建構區塊

設定一個工具一律是兩個物件

物件 它是什麼 你在裡面放什麼 LLM 看得到嗎?
OutboundAPI 連線:你的伺服器在哪 + 如何認證 Base URL、secret(API key) 否 — 純粹是基礎設施
CallFunc agent 可以呼叫的工具 名稱、描述、method、path、輸入 schema輸出 schema — 這就是契約
  • 為每個後端建立一個 OutboundAPI(一個 base URL + 一組 secret)。
  • 建立三個 CallFunc(每個 function 一個),全部指向那個 OutboundAPI。

CallFunc 存在於 Storyboard 的 Panel 內,因此一個工具可以只在它有意義的對話狀態(panel)中提供。


3. 設定一個工具

開始之前需要什麼

Perxona 是從雲端呼叫你的端點,因此打開後台之前,你需要:

  • 一個公開的 HTTPS base URL — 只存在於你自己機器上的位址連不到;
  • 一組驗證用的 secret,你的伺服器對每個請求檢查它(API key、bearer token,或者端點本來就公開則不需要)。

步驟 1 — 建立 OutboundAPI(連線)

在後台(Backend Core / Outbound API)中,為每個後端建立一筆項目:

欄位 要填什麼
Base URL 你的端點所掛的 scheme + host。個別路徑屬於各個 CallFunc,不寫在這裡。
Secret type API_KEYBearerNone
Header name 你的伺服器從哪個 header 讀取憑證。
Header value 憑證本身 — 加密儲存,於呼叫時注入。模型永遠看不到它。

打到同一個後端的每個 CallFunc 都指向這一筆,因此換金鑰或搬主機只需要改一個地方,不必逐一改每個工具。

步驟 2 — 建立 CallFunc(工具)

你希望 agent 能執行的每一項操作,各建立一個 CallFunc:

欄位 要填什麼 LLM 看得到嗎?
Type OUTBOUND_API
Name 彼此分明的 verb_noun(§4.1)
Method / Path HTTP 動詞,以及 OutboundAPI base URL 底下的路徑
Description 它做什麼以及何時使用它(§4.2)
Input schema 參數的 JSON Schema(§4.3)
Output schema 回傳內容的 JSON Schema(§4.4)

工具的數量要少、彼此要分明。兩個描述重疊的工具會逼模型在它們之間猜測,而它有時會猜錯。

步驟 3 — 在 panel 中測試

打開一個 panel 對話,用真實使用者會用的說法提出請求 — 而不是用你自己 schema 的詞彙。依序觀察三件事:

  1. 它到底有沒有呼叫?沒有的話,表示描述沒有講清楚觸發時機。
  2. 它呼叫的是對的工具嗎?不是的話,表示有兩個描述重疊了。
  3. 參數對嗎?不對的話,表示欄位描述缺了格式、enum 或 required

第 6 節把常見症狀對應到修法。


4. 手藝:撰寫 LLM 能理解的描述與 schema

這部分決定了 agent 給人聰明還是笨的感覺。以下是一些經驗法則,並附上前後對照。

4.1 名稱 = 模型用來比對的動詞

使用清楚的 verb_noun — 動詞說明它做什麼,名詞說明它作用在什麼上。讓名稱彼此分明,模型就永遠不必在兩個相似的工具之間猜測。

4.2 描述 = 何時使用它,而不只是它是什麼

描述會在每一輪,當模型決定是否要呼叫時被讀取。要說明它做什麼以及觸發時機(「在……時使用」),再加上任何限制。

❌ 含糊 ✅ 清楚
「查詢端點。」 「以 <鍵值> 查詢 <實體>。可選擇性地依 <欄位> 篩選。回傳 <欄位>。當使用者詢問 <觸發情境> 時使用。」
「建立一筆記錄。」 「以 <必填欄位> 建立 <實體>。只在使用者明確要求建立時使用。回傳含有新 id 的確認訊息。」

訣竅: - 逐欄提及它回傳什麼,讓模型知道這個工具能回答眼前的問題。 - 說明否定範圍(「只在使用者明確要求時」)以阻止過早或意外的呼叫 — 對寫入尤其重要。 - 不要傾倒實作細節(DB、framework)。模型不在意這些,而且會浪費模型用來推理的 context。

4.3 輸入 schema = 參數契約

每個 property 的描述都是模型用來填寫該欄位的提示。請對格式具體說明,因為模型會照抄你的措辭。

  • 格式:"Date, YYYY-MM-DD.""Local start time, 24h HH:MM." 會讓模型產生 2026-06-1116:00,而不是 "next Tuesday""4 PM"
  • required列出沒有就無法運作的欄位。模型會持續追問使用者,直到取得它們為止。
  • 預設值與界限:帶有 defaultminimummaximum 的數值欄位,模型可以省略它,而不良的值會在送達你的伺服器之前被拒絕。
  • Enum 很強大:{"type":"string","enum":["confirmed","tentative"]} 會把模型限制在有效的選項內。
  • 保持扁平且精簡。巢狀過深的輸入會讓模型更難可靠地填寫。

4.4 輸出 schema = 模型如何讀取結果(以及為什麼要請你加上它)

呼叫之後,模型會讀取你的 JSON 回應。輸出 schema 告訴它有哪些欄位存在、各代表什麼意思,讓它能:

  • 把正確的值帶進它的回覆(例如把連結欄位呈現為可點擊的連結,或逐字讀回訊息欄位);
  • 理解型別(知道計數欄位是數字、標籤欄位是清單);
  • 避免幻想出不存在的欄位。

用你描述輸入的相同方式來描述每個輸出欄位。註明連結欄位是 string | null,或註明某個狀態欄位會區分「真的寫入了」與「只是模擬」,能讓 agent 誠實地措辭確認訊息,而不會把發生的事講得比實際更滿。

4.5 黃金法則


5. 安全與 UX 旋鈕

旋鈕 它做什麼 用於
Secret type(API_KEY / Bearer / None) 於呼叫時注入認證 header,並以加密方式儲存 保持端點私密;絕不要把 key 放進描述中
Panel 範圍限定 一個 CallFunc 只存在於你加入它的那些 panel 中 在使用者進入「預約」狀態前隱藏預約工具

6. 疑難排解

症狀 可能原因 修正
模型從不呼叫該工具 描述太含糊/與另一個工具重疊 用清楚的「在……時使用」觸發語重寫描述;讓名稱分明
模型用錯誤的參數呼叫它 欄位描述不清,缺少格式/enum 加上 description、格式、enumrequired、預設值
模型重複寫入或陷入迴圈 描述從未說明什麼情況該呼叫 收緊描述中的否定範圍;把工具限定在它該出現的 panel
Public URL 404/逾時 base URL 換了,或伺服器停止 重新檢查 OutboundAPI 的 base URL,並確認該主機從你的網路之外連得到

7. Perxona CallFunc 的特色

前面談的都是你要寫的契約。這一節談平台拿它做了什麼,以及這套做法的邊界在哪裡。

你得到什麼

  • 不必寫、也不必託管任何程式碼。任何 HTTP API 只要貼上 base URL 與 JSON Schema 就變成工具。現有的後端能在幾分鐘內轉成 agent 工具,中間不需要多一層轉接服務。
  • 功能齊備。加密的 secret、每個工具的用量限制、human-in-the-loop 確認、context 範本化、text-to-SQL 安全、logging 與多租戶範圍限定,全都由平台提供。
  • 緊密的產品整合。工具存在於 persona 與故事板的流程內,可以做 panel 範圍限定 —— 只在它有意義的對話狀態才可用 —— 並與 memory、防護機制和對話逐字稿走在同一條 pipeline 上。
  • 輸出 schema 是一級欄位。你宣告回傳什麼,這有助於模型解讀結果,也讓它的回覆誠實反映實際發生的事。

邊界在哪裡

  • 一次 HTTP 來回。沒有串流、沒有長時間執行的工作、沒有具狀態的工具連線。
  • 事先設定好。工具在後台設定,沒有執行期的動態探索。要改工具就回後台改。
  • 端點由你託管。它必須能從 Perxona 連到,而它的 uptime、延遲、逾時與 TLS 都是你的責任。
  • JSON Schema,保持簡單。輸入與輸出使用 JSON Schema(Draft 2020-12);過於奇特的 schema 特性可能無法乾淨轉換。扁平而簡單對模型本來就比較好。

8. 一頁回顧

  1. 兩個物件:一個 OutboundAPI(URL + API key)+ 每個 function 一個 CallFunc (名稱、描述、method、path、輸入 schema、輸出 schema)。
  2. 模型只看到名稱 + 描述 + 輸入 schema + 輸出 schema — 把它們寫給一位聰明的陌生人看。
  3. 描述 = 它做什麼 + 何時使用它(+ 它回傳什麼,+ 不該做什麼)。
  4. 輸入 schema = 欄位名稱、型別、required、格式、預設值、enum。
  5. 輸出 schema = 回傳什麼,讓模型正確讀取結果。
  6. 這是 HTTP + 受管理的防護機制,無需程式碼 — 你已經能呼叫的端點,就能變成 agent 用得上的工具。