給 Custom App 的預建能力:SDK 全景

這是本手冊最重要的一章。

當您在 AI GO 上開發應用程式時,有一大類工作不需要做——資料庫連線、租戶隔離、權限檢查、ERP 業務邏輯、簽核流程、向量檢索、外部 API 的安全出口、金鑰保管、加解密。平台把這些預先建好,以 SDK 的形式交到您手上。

SDK 分兩側:伺服器端的 ctx 物件(在 Action 中使用)與前端的六支 TypeScript SDK


伺服器端:ctx 物件

每個 Action 都是一個接收 ctx 的函式:

def execute(ctx):
    ...

ctx 上掛著平台的全部能力。

執行脈絡屬性

屬性內容
ctx.params呼叫端傳入的參數
ctx.app_id執行中的應用程式識別碼
ctx.tenant_id所屬組織識別碼
ctx.action_name當前執行的 Action 名稱
ctx.env執行環境(online / dev
ctx.user_id觸發者的使用者識別碼
ctx.user_roles觸發者的角色名稱清單(唯讀快照)
ctx.user_permissions觸發者的權限標籤清單(唯讀快照)

判斷授權請用 user_permissions 而不是 user_roles——角色名稱可以被改名,權限標籤是穩定的識別。


ctx.db — 資料存取

存取兩類資料:ERP 內建表與自建表。

方法用途
query(table, filters, order_by, limit, offset)查詢 ERP 表
insert(table, data)新增 ERP 表記錄
update(table, row_id, data)更新 ERP 表記錄
remove(table, row_id)刪除 ERP 表記錄
list_tables()列出組織的自建表
query_table(name, filters, ...)查詢自建表
insert_row(name, data)新增自建表記錄
update_row(name, row_id, data)更新自建表記錄
delete_row(name, row_id)刪除自建表記錄

典型場景:任何需要讀寫企業資料的地方。查詢支援完整的過濾、排序、分頁——不是只有「取全部」。

orders = ctx.db.query('sale_orders',
    filters=[
        {'column': 'state', 'op': 'eq', 'value': 'sale'},
        {'column': 'amount_total', 'op': 'gte', 'value': 10000},
    ],
    order_by=[{'column': 'created_at', 'direction': 'desc'}],
    limit=50)

授權:讀取需 db.read / data_table.read,寫入需 db.write / data_table.write。ERP 表另外受引用宣告約束——沒宣告的表與欄位存取不到。


ctx.erp — 觸發業務引擎

這是最容易被低估的模組。它不是「寫一筆資料」,而是觸發平台預建的完整業務流程

方法觸發什麼
confirm_sale_order(id)確認銷售訂單(連動出貨與開票準備)
confirm_purchase_order(id)確認採購訂單
create_invoice(order_id)從銷售訂單開立銷項發票。order_id 可傳清單——多張訂單合併開一張發票
create_bill(order_id)從採購訂單建立進項帳單。同樣支援清單合併
validate_picking(id)驗證揀貨單(連動庫存移動與存貨計價)
post_move(id)過帳會計傳票
confirm_payment(id)確認收付款(連動自動沖銷)
reconcile_payment(id)補跑已過帳付款的沖銷引擎
confirm_payroll_run(id)確認薪資結算批次(連動應付薪資傳票)
cancel_payroll_run(id)撤銷薪資批次(自動產生沖銷分錄)

典型場景:您做了一個「業務快速結單」的應用。使用者按下按鈕後,訂單確認、發票開立、庫存扣減、會計傳票——全部由一次 ctx.erp 呼叫連鎖完成,您不需要知道會計科目怎麼帶、稅率怎麼算。

合併開票值得特別說明:傳入訂單 id 清單時,會把清單內所有訂單的明細彙總進同一張發票(要求同客戶、同組織)。這解掉了「月結客戶要合併開票」這個常見需求。

授權:各方法對應獨立的 scope(如 erp.sale_order.confirm),全部屬於高風險等級。


ctx.approval — 簽核

方法用途
list_pending()取得觸發者本人的待簽核清單
get_record_status(res_model, res_id)查某筆記錄的簽核狀態與各關卡明細
approve(request_line_id, comment)以觸發者身分核准一層
reject(request_line_id, comment)以觸發者身分駁回
cancel(request_id, reason)取消簽核申請(限申請人本人、限進行中)

典型場景:在您的部門工具裡做一個「我的待辦」面板,讓主管不必登入主控台就能完成簽核。

重要語意:這些方法綁使用者身分approve 會驗證觸發者是否為該關卡的合格審核人,不是就拒絕。最後一關通過時會自動執行被攔截的原操作。

授權:讀取需 approval.read(低風險),決定需 approval.decide(高風險)。


ctx.knowledge — 企業知識檢索

方法用途
search(query, top_k, score_threshold)向量檢索,回傳片段與相關度分數
get_content(file_id)取單一知識檔案的完整解析文字

典型場景:做一個內部問答助理。檢索企業規章與產品文件取得脈絡,再用您自己的模型金鑰產生回答。

設計要點:這是純檢索、不生成——不呼叫任何語言模型,回傳原文片段。生成留給您自己的邏輯與金鑰,成本與模型選擇由您掌控。檢索結果自動套用檔案級存取政策(見第 6 章)。

授權knowledge.read,高風險等級。


ctx.http — 呼叫外部 API

方法用途
call(service, path, method, body, headers, params)透過已授權的外部服務呼叫 API
fetch(url, ...)抓取任意公開網址(仍受安全限制)

典型場景:串接物流查詢、簡訊網關、發票加值中心、您公司既有的內部系統。

兩個容易踩到的地方

  1. 第三個位置參數是 method(字串),不是 body。要送 body 請用具名參數。
  2. call 不拋例外,回傳 {status, headers, data}——請務必檢查 status。失敗時 data 會帶 error_typeerrorfix(一句可直接轉述給使用者的修復指引)。
resp = ctx.http.call('logistics', '/track', method='POST',
                     body={'no': ctx.params['tracking_no']})
if resp['status'] != 200:
    return ctx.response.json({'error': resp['data'].get('fix')})

授權http,高風險等級,且外部網域須經白名單授權。


ctx.messaging — 通訊中心

方法用途
list_channels() / add_channel() / update_channel() / remove_channel()管理通訊渠道
inject_inbound()注入外部進來的訊息
save_ai_outbound()儲存 AI 產生的回覆
get_ai_config()讀取 AI 回覆設定

典型場景:在您的應用裡做一個客服對話介面,把外部渠道(如通訊軟體)的訊息接進來,與 CRM 客戶資料綁定,讓營運同仁在同一個畫面內回覆。

授權:讀取需 messaging.read(低風險),寫入需 messaging.write,渠道管理需 messaging.channel(均為高風險)。


ctx.secrets — 金鑰保管

方法用途
get(key_name)取得金鑰值
list_keys()列出可用的金鑰名稱

典型場景:您的應用需要呼叫第三方服務或自己的模型 API。金鑰存放在 App Secrets 中,不會出現在原始碼裡,也不會傳到前端

授權secret.read,高風險等級。


ctx.crypto — 加解密與簽章

方法用途
hash(algorithm, data)雜湊(sha256 等)
hmac_sign(key_name, data)HMAC 簽章(金鑰名而非金鑰值)
base64_encode(data) / base64_decode(data)Base64 編解碼
aes_encrypt(key_name, plaintext)AES-256 加密
aes_decrypt(key_name, ciphertext, iv)AES-256 解密

典型場景:驗證 Webhook 來源的簽章、產生對外 API 需要的簽名、加密儲存敏感欄位。

注意 hmac_sign 與 AES 方法接受的是金鑰名稱而不是金鑰值——實際的金鑰值永遠不經過您的程式碼。

授權crypto,低風險等級。


ctx.mcp — 外部工具協定

方法用途
execute(task, wait=True)同步執行 MCP 任務
trigger(task)非同步觸發,回傳任務識別碼
get_status(task_id)查詢非同步任務狀態

授權mcp,高風險等級。


ctx.responsectx.csv — 回應控制

方法用途
ctx.response.json(data)回傳 JSON
ctx.response.file(content, filename, mime)回傳檔案下載
ctx.csv.export(rows, columns, filename)一行匯出 CSV

這兩個模組在執行環境本地處理,不需要 scope 授權。


前端 SDK

前端有六支平台提供的 TypeScript SDK,放在 src/ 底下,開箱即用。

src/db.ts — ERP 表存取

在前端直接查詢與寫入已引用的 ERP 表,語意與 ctx.db 對應。適合列表頁、詳情頁這類直接的資料呈現。

src/api.ts — 自建表存取

存取組織的自建表。同樣支援過濾、排序、分頁。

src/action.ts — 呼叫伺服器端 Action

前端呼叫 Action 的官方管道。凡是需要金鑰、需要高權限、或不該讓使用者看到邏輯的操作,都應該放進 Action 再由這裡呼叫。

import { callAction } from './action';

const result = await callAction('confirm_orders', { ids: selectedIds });

src/approval.ts — 簽核(Internal 專屬)

取得待簽核清單、查詢簽核狀態、執行核准與駁回。可以直接組出簽核面板。

src/user.ts — 使用者脈絡(Internal 專屬)

取得當前使用者的角色與權限標籤,用來決定介面上顯示什麼:

import { getUser } from './user';

const user = await getUser();
if (user.permissions.includes('accounting.write')) {
  // 顯示過帳按鈕
}

注意:前端的權限判斷是體驗優化,不是安全邊界。真正的授權在伺服器端執行——前端藏起來的按鈕,直接呼叫 API 一樣會被擋。

src/auth.ts — 登入註冊(External 專屬)

External App 的使用者註冊、登入、登出與密碼修改流程。


授權模型一覽

每個 SDK 方法都對應一個 scope(能力群)。應用程式必須宣告需要哪些 scope,由管理員核可後才生效。

風險等級Scope核可方式
低風險db.readdata_table.readmessaging.readapproval.readcrypto管理員核可
高風險db.writedata_table.writeerp.*approval.decideapproval.cancelknowledge.readmessaging.writemessaging.channelhttpmcpsecret.read管理員核可 + 擁有者當場密碼再驗證

Scope 是能力群的開關;細粒度的邊界另有其他機制——ERP 表看引用宣告、外部服務看網域白名單、金鑰看可用清單。兩層疊加。

每一次 SDK 呼叫都會留下稽核紀錄。詳見第 10 章。