Day 27 的目標很清楚:使用者說一次需求,Agent 先交出完成八成的申請草稿,使用者集中調整一次,再完成送出。
接下來要處理真正的技術問題。Agent 要去哪裡查資料表、怎麼取得欄位和資料等級、誰負責套用 housekeeping 規則、正式送出時又如何確保只建立一張單。
目前這些行為已經存在 DAP 裡,只是分散在 Vue 表單、watch、Pinia Store、API 包裝與送出流程中。第四代要把它們整理成 Agent 能安全使用的能力與工具。

draft_id、版本、確認憑證與 idempotency key,Payload 由伺服器保存的草稿產生。我先沿著目前程式碼,把一張 Rawdata 申請的資料路徑走一次。
選擇資料表時,TableSelect.vue 會查詢資料表清單,帶回資料等級、更新頻率、更新方法、資料位置與擁有單位。選定資料表後,rawdata.vue 再查欄位 Metadata、判斷聯徵條件,並依欄位類型組出去識別化規則。
畫面上的 watch 接著處理欄位連動:
refresh 或受限制的目標環境會略過 housekeeping。正式送出時,EdbCartPanel.vue 會逐筆呼叫 gen_code,全部成功後,再組成一份申請送到 Postgres 申請 API,最後保存摘要與回傳結果。
查資料表
↓
取得 Metadata 與欄位
↓
套用規則、組 Payload、加入購物車
↓
逐筆產生程式內容
↓
統一送出申請
↓
保存摘要與單據結果
這些能力已經存在。現在的入口是 Vue 元件與按鈕;第四代會增加一層穩定介面,Agent 透過這層介面完成任務,DOM 繼續服務頁面操作。
Capability Contract 是本系列採用的工作名稱,用來固定使用者目標、資料來源、規則、副作用與確認點,格式不綁定特定 Agent framework。
我把 Rawdata 申請整理成一項 Capability:
| 欄位 | data-copy.create |
|---|---|
| 目的 | 將指定資料表依資料規則與權限抄寫到目標環境 |
| 使用角色 | 已登入且具備申請資格的員工 |
| 使用者輸入 | 資料表、用途、專案、權限對象與例外條件 |
| 系統脈絡 | 身分、Metadata、資料等級、更新資訊與現有購物車 |
| 固定規則 | 去識別化、housekeeping、目標環境與重複申請檢查 |
| 產出 | 申請草稿、Payload 預覽、驗證結果與正式單據 |
| 副作用 | 正式送出會建立申請單並啟動後續流程 |
| 人工卡點 | 正式送出前確認草稿版本與影響 |
| 完成證據 | 規則版本、確認紀錄、API 結果與單據編號 |
Capability 保持在使用者目標這一層。即使未來頁面改版、API 換路徑,data-copy.create 仍然代表同一件事。
Tool 則是 Agent 完成這項能力時可以採取的動作。
我先規劃五個 Tool:
| Tool | 用途 | 副作用 | 人工確認 |
|---|---|---|---|
dap_rawdata_search_tables |
依關鍵字找出使用者可申請的資料表 | 無 | 免確認 |
dap_rawdata_get_context |
取得 Metadata、欄位、資料等級、模板與合法選項 | 無 | 免確認 |
dap_rawdata_prepare_draft |
套用規則、產生建議、驗證並建立草稿 | 只建立草稿 | 免確認 |
dap_rawdata_submit_application |
使用已確認草稿建立正式申請單 | 建立單據 | 需要 |
dap_application_get_status |
查詢單據目前階段與處理狀態 | 無 | 免確認 |
這五個 Tool 依 Agent 的工作目的命名。
現有 API 仍可放在 Tool 裡面。例如 dap_rawdata_get_context 可以整合資料表清單、欄位、聯徵判斷與權限帳號查詢,再回傳 Agent 真正需要的摘要。Tool 會封裝 endpoint 呼叫順序與低階回應,Agent 只讀取下一步所需的脈絡。
Anthropic 的 Tool 設計文章建議先建立少量、目的明確的高價值 Tool,並避免功能重疊。文章也提到 Tool 可以在內部整合多次 API 呼叫,只把有用的脈絡回傳給 Agent。
dap_rawdata_get_context 可以回傳這種結構:
table:
name: selected_table
description: 業務資料表
data_level: classified
update_frequency: daily
update_method: append
allowed_targets:
- standard
- restricted
recommendations:
reference_column: snapshot_date
housekeeping:
keep_months: 3
keep_month_end: true
requirements:
sensitive_confirmation: true
additional_fields: []
evidence:
metadata_version: 2026-09-19
rule_set: rawdata-rules-v1
公開範例使用匿名名稱,實際 database、資料表、帳號與欄位仍留在內部系統。
Agent 需要的是合法選項、建議與下一步要求。完整欄位明細可以透過 response_format: detailed 另外取得,平常先回傳精簡版本。
清楚的回傳內容能減少兩種錯誤:Agent 從大量資料中挑錯欄位,以及 Agent 用自己的常識補上系統沒有提供的值。
dap_rawdata_prepare_draft 負責將 Day 27 的一句需求轉成可檢查的草稿。它會接收使用者意圖與已選資料,從登入 Session 取得申請人,再套用固定規則和模板。
name: dap_rawdata_prepare_draft
purpose: 建立並驗證 Rawdata 申請草稿
side_effect: draft_only
input:
source_table: string
intent:
project_name: string
reason: string
permission_targets: string[]
requested_frequency: string
preferences:
target_environment: string | null
retention_months: number | null
output:
draft_id: string
draft_version: integer
resolved_values: object
recommendations: object[]
needs_confirmation: object[]
validation:
status: valid | needs_input | blocked
issues: object[]
payload_preview: object
evidence: object
申請人身分由 Tool 從已驗證的登入 Session 取得,模型輸入只保留使用者意圖與偏好。這個邊界會固定申請人與權限範圍。
resolved_values 放系統查到或固定規則決定的內容;recommendations 放模板建議與理由;needs_confirmation 只留下真正需要使用者決定的項目。這三類資料分開後,Agent 才能用清楚的方式呈現草稿。
正式送出是整條流程中風險最高的 Tool。
最後一步的輸入固定為已確認草稿的識別資訊。dap_rawdata_submit_application 只接受以下資料:
name: dap_rawdata_submit_application
input:
draft_id: string
draft_version: integer
confirmation_token: string
idempotency_key: string
output:
application_id: string
status: submitted
submitted_at: datetime
result_summary: object
送出 Tool 從伺服器取回同一份草稿,確認版本與使用者看到的版本一致,再執行目前 EdbCartPanel.vue 裡的兩段流程:逐筆 gen_code,全部成功後統一送出申請。
這樣可以固定三件事:
idempotency_key,後端據此維持單據唯一。目前前端 Store 已經有購物車防重複與簡易 hash;正式 Agent Tool 還需要後端層級的 idempotency。這是第四代實作前必須補上的能力。
現在的畫面可以顯示「請完整填寫表單」或「送出失敗」。Agent Tool 需要更具體的結構化錯誤:
{
"code": "TARGET_DATABASE_CONFLICT",
"field": "target_environment",
"message": "目前草稿已有另一個目標環境",
"recoverable": true,
"next_action": "請使用者選擇保留現有環境,或另建一張申請單"
}
Agent 看到 recoverable: true,可以說明衝突並提出選項。遇到權限不足、Metadata 缺失或規則來源不明時,Tool 回傳 blocked,Agent 停止執行並轉交人工。
錯誤訊息同時是 Agent 的操作說明。錯誤碼、欄位、可恢復性與下一步寫清楚,能減少無效重試。
MCP Tool 規格提供一組實用的 Tool annotations;MCP 官方文章將它們整理成四種風險提示:
readOnlyHint:是否只讀。destructiveHint:是否可能造成破壞性修改。idempotentHint:相同參數重試是否安全。openWorldHint:是否會接觸外部世界或不受控內容。放到 DAP 可以先這樣標示:
| Tool | read-only | destructive | idempotent | confirmation |
|---|---|---|---|---|
| 搜尋資料表 | 是 | 否 | 是 | 無 |
| 取得申請脈絡 | 是 | 否 | 是 | 無 |
| 建立草稿 | 否 | 否 | 是 | 無 |
| 正式送出 | 否 | 否,屬新增單據 | 需要後端保證 | 必須 |
| 查詢狀態 | 是 | 否 | 是 | 無 |
MCP 對 Tool annotations 的說明也將這些欄位定位為提示。DAP 的安全控制放在登入 Session、API 授權、規則驗證、確認憑證與後端 idempotency。
Agent 完成一張申請後,我希望能重建整段執行過程:
誰提出需求
↓
Agent 選了哪一項 Capability
↓
呼叫哪些 Tool、使用哪個規則版本
↓
草稿如何產生、使用者改了什麼
↓
確認的是哪個 draft version
↓
送出 API 回傳哪個單據編號
每次 Tool 呼叫至少保存:
trace_id 與 Tool 名稱。draft_id、版本與內容 hash。這些紀錄會直接成為 Day 29 的 Eval 與風險分級資料。
先挑一個會被 Agent 呼叫的動作,填完下面欄位:
# Tool Contract
- 名稱與用途:
- 何時使用:
- 何時停止或轉人工:
- 輸入 Schema:
- 輸出 Schema:
- 身分與權限來源:
- 讀取或寫入:
- 副作用與可逆性:
- 是否可安全重試:
- 是否需要人工確認:
- 結構化錯誤:
- Audit evidence:
- 對應的 Spec/Scenario/API:
Tool protocol 可以是既有 API 包裝、function calling、MCP server 或其他形式。Contract 先固定 Agent 看得到的能力、風險與證據,再決定實作方式。
Day 27 先把表單改成一到兩個回合的服務。Day 28 再把這段服務拆成 Capability 與五個受控 Tool。
這一步最重要的成長,是把「Agent 會操作系統」拆成可以被檢查的動作。查詢 Tool 提供真實脈絡,草稿 Tool 套用固定規則,送出 Tool 只接受已確認的版本,狀態 Tool 回報最後結果。
介面清楚之後,下一個問題就出現了:哪些 Tool 可以自動呼叫,哪些動作一定要停下來,以及如何證明 Agent 每次都在正確的位置停住。
Day 29 會建立 autonomy matrix 與 Eval Set,決定第四代 DAP 的自主範圍。