本手冊會說明如何把你既有的 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 */ }
}
在每一輪對話中,模型都只憑那段文字問自己:
- 我到底該不該呼叫工具? → 由名稱 + 描述決定。
- 呼叫哪一個? → 由各個描述彼此之間有多明顯不同決定。
- 用什麼參數? → 由輸入 schema決定(欄位名稱、型別、
required、描述、enum、預設值)。 - 我拿回了什麼/要告訴使用者什麼? → 由輸出 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_KEY、Bearer 或 None。 |
| 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 的詞彙。依序觀察三件事:
- 它到底有沒有呼叫?沒有的話,表示描述沒有講清楚觸發時機。
- 它呼叫的是對的工具嗎?不是的話,表示有兩個描述重疊了。
- 參數對嗎?不對的話,表示欄位描述缺了格式、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-11和16:00,而不是"next Tuesday"或"4 PM"。 required:列出沒有就無法運作的欄位。模型會持續追問使用者,直到取得它們為止。- 預設值與界限:帶有
default、minimum、maximum的數值欄位,模型可以省略它,而不良的值會在送達你的伺服器之前被拒絕。 - 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、格式、enum、required、預設值 |
| 模型重複寫入或陷入迴圈 | 描述從未說明什麼情況不該呼叫 | 收緊描述中的否定範圍;把工具限定在它該出現的 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. 一頁回顧
- 兩個物件:一個 OutboundAPI(URL + API key)+ 每個 function 一個 CallFunc (名稱、描述、method、path、輸入 schema、輸出 schema)。
- 模型只看到名稱 + 描述 + 輸入 schema + 輸出 schema — 把它們寫給一位聰明的陌生人看。
- 描述 = 它做什麼 + 何時使用它(+ 它回傳什麼,+ 不該做什麼)。
- 輸入 schema = 欄位名稱、型別、
required、格式、預設值、enum。 - 輸出 schema = 回傳什麼,讓模型正確讀取結果。
- 這是 HTTP + 受管理的防護機制,無需程式碼 — 你已經能呼叫的端點,就能變成 agent 用得上的工具。