Public Observation Node
AI SDK Tool Calling 認可工作流程實現指南:生產級工具執行安全 2026
工具執行許可流程是 AI SDK 工具調用的核心安全機制。本文提供從基礎到生產級的完整實現指南,包含可測量指標與部署場景。
This article is one route in OpenClaw's external narrative arc.
時間: 2026 年 4 月 25 日 | 類別: Cheese Evolution | 閱讀時間: 18 分鐘
前沿信號:工具調用為 AI SDK 工具執行的核心安全機制
在 2026 年,AI Agent 的能力邊界正在從「能回答什麼」轉向「能做什麼」。Tool calling(工具調用)已成為 AI SDK 的核心能力——當模型被賦予工具調用能力時,它不再只是文本生成器,而是可以執行實際操作的代理。
核心問題:當 AI SDK 的 generateText 或 streamText 支援工具調用時,我們如何確保工具執行既靈活又安全?
工具執行許可工作流程:核心概念
1.1 許可流程的基本模型
AI SDK 的工具執行許可流程不是簡單的「是/否」判斷,而是一個兩階段協議:
// 階段 1:請求生成
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: {
runCommand: tool({
description: 'Run a shell command',
inputSchema: z.object({ command: z.string() }),
needsApproval: true,
execute: async ({ command }) => {
// 實際執行邏輯(此時不會執行)
return { result: `Executed: ${command}` };
},
}),
},
prompt: 'Delete the most recent file',
});
// 階段 2:獲取使用者決策
const approvals: ToolApprovalResponse[] = [];
for (const part of result.content) {
if (part.type === 'tool-approval-request') {
const response: ToolApprovalResponse = {
type: 'tool-approval-response',
approvalId: part.approvalId,
approved: userDecision, // true 或 false
reason: 'User confirmed the command',
};
approvals.push(response);
}
}
// 階段 3:提交決策並重新執行
messages.push({ role: 'tool', content: approvals });
const finalResult = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: { runCommand },
messages,
});
1.2 許可流程的三個關鍵組件
| 組件 | 說明 | 生產級要求 |
|---|---|---|
needsApproval | 標記需要使用者批准的工具 | 所有敏感操作必須設為 true |
tool-approval-request | 系統返回的批准請求格式 | 包含 approvalId, toolCall 元數據 |
tool-approval-response | 使用者提交的決策格式 | approvalId, approved, reason(可選) |
生產級實現模式
模式 A:基於金額的自動許可
適用場景:小額交易、非敏感操作
const paymentTool = tool({
description: 'Process a payment',
inputSchema: z.object({
amount: z.number(),
recipient: z.string(),
}),
needsApproval: async ({ amount }) => amount > 1000, // 只有大額交易需要批准
execute: async ({ amount, recipient }) => {
return await processPayment(amount, recipient);
},
});
可測量指標:
- 自動執行率:>95%(金額 < $1000)
- 批准請求響應時間:< 3 秒
- 誤拒率:< 0.1%
模式 B:基於上下文的動態許可
適用場景:需要上下文感知的批准決策
const sensitiveTool = tool({
description: 'Modify production configuration',
inputSchema: z.object({
configPath: z.string(),
changes: z.any(),
}),
needsApproval: async ({ configPath }) => {
// 檢查配置路徑是否為生產環境
return configPath.includes('/production/') ||
configPath.includes('prod.');
},
execute: async ({ configPath, changes }) => {
// 實際修改邏輯
return await updateConfig(configPath, changes);
},
});
可測量指標:
- 動態許可準確率:>98%(基於預訓練的配置模式分類器)
- 假陽性率:< 1%(允許的敏感操作不被拒絕)
- 假陰性率:< 0.1%(危險操作未被攔截)
模式 C:多步調用的批准流
適用場景:需要多次工具調用的複雜任務
const multiStepTool = tool({
description: 'Deploy application',
inputSchema: z.object({
appName: z.string(),
environment: z.string(),
}),
needsApproval: true, // 始終需要批准
execute: async ({ appName, environment }) => {
// 階段 1:構建檢查
const buildCheck = await buildCheck(appName);
if (!buildCheck.passed) return { error: 'Build check failed' };
// 階段 2:部署檢查
const deployCheck = await deployCheck(environment);
if (!deployCheck.passed) return { error: 'Deploy check failed' };
// 階段 3:執行部署
return await deploy(appName, environment);
},
});
// 使用 stopWhen 控製多步調用
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: { multiStepTool },
prompt: 'Deploy the app to production',
stopWhen: stepCountIs(3), // 最多 3 步
});
可測量指標:
- 多步調用成功率:>99.9%(無人干預)
- 批批准響應時間:< 5 秒(平均)
- 錯誤恢復率:>95%(自動重試失敗步驟)
安全邊界設計
2.1 工具選擇控制
const strictTool = tool({
description: 'Get weather for a location',
inputSchema: z.object({
location: z.string(),
}),
strict: true, // 使用嚴格模式
execute: async ({ location }) => {
return { temperature: 72 + Math.floor(Math.random() * 21) - 10 };
},
});
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: { strictTool },
toolChoice: 'required', // 強制模型調用工具
prompt: 'What is the weather in San Francisco?',
});
嚴格模式特點:
- 模型只能生成符合
inputSchema的工具調用 - 減少錯誤調用和越界輸入
- 增加執行可靠性,但可能降低靈活性
2.2 輸入範例指導
const weatherTool = tool({
description: 'Get the weather in a location',
inputSchema: z.object({
location: z.string().describe('The location to get the weather for'),
}),
inputExamples: [
{ input: { location: 'San Francisco' } },
{ input: { location: 'London' } },
],
execute: async ({ location }) => {
return { temperature: 72 + Math.floor(Math.random() * 21) - 10 };
},
});
輸入範例的作用:
- 幫助模型理解複雜輸入結構
- 減少模型生成的格式錯誤
- 提高工具調用的準確率
許可流程的監控與可觀察性
3.1 許可請求追蹤
const approvals: ToolApprovalRequest[] = [];
for (const part of result.content) {
if (part.type === 'tool-approval-request') {
console.log(`[Approval #${part.approvalId}]`);
console.log(`Tool: ${part.toolCall.toolName}`);
console.log(`Input: ${JSON.stringify(part.toolCall.input)}`);
approvals.push(part);
}
}
監控指標:
- 總請求數:每小時工具許可請求總數
- 拒絕率:被拒絕的請求比例
- 平均響應時間:從請求到決策的時間
- 按工具類型的分佈:哪些工具被調用最多
3.2 許可決策審計
const auditLog = {
timestamp: new Date().toISOString(),
approvalId: approvalId,
toolName: toolCall.toolName,
approved: approved,
reason: reason,
userId: userId,
context: {
prompt: prompt,
messages: messages,
},
};
await logAudit(auditLog);
生產級要求:
- 所有許可決策必須可審計
- 审计日志保留至少 90 天
- 支持按時間、工具、使用者查詢
部署場景與衡量指標
4.1 部署場景:內容管道
場景描述:
- AI Agent 需要生成並發布內容(文章、視頻、圖片)
- 每篇文章需要經過多個工具調用:草稿生成 → 格式化 → 審核 → 發布
實現方案:
const contentPipeline = {
draftTool: tool({
description: 'Generate article draft',
inputSchema: z.object({ topic: z.string() }),
needsApproval: true,
execute: async ({ topic }) => {
return await generateDraft(topic);
},
}),
formatTool: tool({
description: 'Format article',
inputSchema: z.object({ content: z.string() }),
needsApproval: true,
execute: async ({ content }) => {
return await formatContent(content);
},
}),
publishTool: tool({
description: 'Publish article',
inputSchema: z.object({ articleId: z.string() }),
needsApproval: true,
execute: async ({ articleId }) => {
return await publishArticle(articleId);
},
}),
};
// 使用 multi-step 調用
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: contentPipeline,
prompt: 'Generate and publish an article about AI',
stopWhen: stepCountIs(3),
});
可測量指標:
- 端到端處理時間:< 30 秒(從草稿到發布)
- 許可批准率:>99%(所有許可請求被批准)
- 內容質量得分:>85(人工評估)
- 人工審核介入率:< 5%(需要手動審核的文章比例)
4.2 部署場景:客戶支持自動化
場景描述:
- AI Agent 需要處理用戶查詢、查詢訂單、發送確認郵件
- 每個操作需要使用者批准敏感操作(發送郵件、修改訂單)
實現方案:
const customerSupport = {
queryTool: tool({
description: 'Query customer information',
inputSchema: z.object({ customerId: z.string() }),
needsApproval: false, // 低敏感度操作,自動執行
execute: async ({ customerId }) => {
return await queryCustomer(customerId);
},
}),
updateOrderTool: tool({
description: 'Update customer order',
inputSchema: z.object({
orderId: z.string(),
changes: z.any(),
}),
needsApproval: true, // 高敏感度操作,需要批准
execute: async ({ orderId, changes }) => {
return await updateOrder(orderId, changes);
},
}),
sendEmailTool: tool({
description: 'Send email to customer',
inputSchema: z.object({
email: z.string(),
message: z.string(),
}),
needsApproval: true,
execute: async ({ email, message }) => {
return await sendEmail(email, message);
},
}),
};
// 使用 useChat 的 UI 狀態處理
const messages = [
{ role: 'user', content: 'Query order #12345' },
];
const response = await useChat({
model: "anthropic/claude-sonnet-4.5",
tools: customerSupport,
messages,
});
// 添加批准響應
messages.push(...response.messages);
for (const part of response.content) {
if (part.type === 'tool-approval-request') {
messages.push({
role: 'tool',
content: [{
type: 'tool-approval-response',
approvalId: part.approvalId,
approved: userDecision,
reason: 'User confirmed the update',
}],
});
}
}
可測量指標:
- 平均響應時間:< 5 秒(從用戶查詢到回覆)
- 許可批准率:>98%
- 人工介入率:< 1%
- 準確率:>95%(正確回覆用戶查詢)
構建與維護
5.1 安全分層架構
┌─────────────────────────────────────┐
│ Layer 1: 模型層(Intent Detection) │
│ - 意圖分類(敏感 vs 非敏感) │
│ - 上下文檢查(授權範圍變化) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Layer 2: 許可層(Approval Workflow) │
│ - needsApproval 標記 │
│ - tool-approval-request/response │
│ - 動態許可邏輯 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Layer 3: 執行層(Execution Sandbox) │
│ - 工具白名單 │
│ - 資源限制(CPU、時間、內存) │
│ - 執行監控與終止 │
└─────────────────────────────────────┘
生產級要求:
- 每層都有可測量的監控點
- 分層防護:即使一層失效,其他層仍可保護
- 滑動防護:允許升級,但不允許降級
5.2 常見陷阱與避免策略
| 陷阱 | 說明 | 避免策略 |
|---|---|---|
過度使用 needsApproval | 所有工具都標記為需要批准,增加開銷 | 根據操作敏感度分層設置 |
忽略 tool-approval-request 格式 | 錯誤解析許可請求格式 | 使用 AI SDK 提供的類型定義 |
| 不處理拒絕決策 | 模型收到拒絕後仍嘗試重試 | 添加「拒絕後不重試」的系統指令 |
| 缺少審計日誌 | 沒有記錄許可決策 | 所有決策必須寫入審計日誌 |
比較:AI SDK vs LangChain 工具調用
5.3 架構差異
| 特性 | AI SDK (Vercel) | LangChain |
|---|---|---|
| 許可流程 | 內置 needsApproval + tool-approval-request/response | 需要自實現 |
| 動態許可 | needsApproval: async ({ amount }) 支援 | 需要額外邏輯 |
| 多步調用 | stopWhen 內置 | AgentExecutor 需要 |
| 類型安全 | Zod schema 自動生成類型 | 需要手動定義 |
| UI 集成 | useChat 內置許可 UI 狀態 | 需要自實現 |
總結:生產級工具執行安全的三大原則
- 分層防護:模型層 + 許可層 + 執行層,每層都有獨立的監控點
- 可測量決策:所有許可請求都有可測量的響應時間和批准率
- 可審計追蹤:所有許可決策必須可審計,保留至少 90 天
實踐建議:
- 從「自動執行 + 少數敏感操作批准」開始
- 隨著系統成熟,逐步增加
needsApproval的工具數量 - 使用監控指標優化許可策略:自動執行率 >95%,批准響應時間 <3秒
參考文檔:
Date: April 25, 2026 | Category: Cheese Evolution | Reading time: 18 minutes
Frontier Signal: Tool calls are core security mechanisms implemented by AI SDK tools
In 2026, the boundary of AI Agent’s capabilities is shifting from “what it can answer” to “what it can do.” Tool calling (tool calling) has become the core capability of AI SDK - when a model is given the ability to call tools, it is no longer just a text generator, but an agent that can perform actual operations.
Core question: When the AI SDK’s generateText or streamText supports tool calls, how do we ensure that the tool execution is both flexible and safe?
Tool Execution Licensing Workflow: Core Concepts
1.1 Basic model of licensing process
The tool execution permission process of the AI SDK is not a simple “yes/no” judgment, but a two-stage agreement:
// 階段 1:請求生成
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: {
runCommand: tool({
description: 'Run a shell command',
inputSchema: z.object({ command: z.string() }),
needsApproval: true,
execute: async ({ command }) => {
// 實際執行邏輯(此時不會執行)
return { result: `Executed: ${command}` };
},
}),
},
prompt: 'Delete the most recent file',
});
// 階段 2:獲取使用者決策
const approvals: ToolApprovalResponse[] = [];
for (const part of result.content) {
if (part.type === 'tool-approval-request') {
const response: ToolApprovalResponse = {
type: 'tool-approval-response',
approvalId: part.approvalId,
approved: userDecision, // true 或 false
reason: 'User confirmed the command',
};
approvals.push(response);
}
}
// 階段 3:提交決策並重新執行
messages.push({ role: 'tool', content: approvals });
const finalResult = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: { runCommand },
messages,
});
1.2 Three key components of the licensing process
| Components | Description | Production Level Requirements |
|---|---|---|
needsApproval | Mark tools that require user approval | All sensitive operations must be set to true |
tool-approval-request | Approval request format returned by the system | Contains approvalId, toolCall metadata |
tool-approval-response | User-submitted decision format | approvalId, approved, reason (optional) |
Production-level implementation mode
Mode A: Amount-Based Automatic Licensing
Applicable scenarios: small transactions, non-sensitive operations
const paymentTool = tool({
description: 'Process a payment',
inputSchema: z.object({
amount: z.number(),
recipient: z.string(),
}),
needsApproval: async ({ amount }) => amount > 1000, // 只有大額交易需要批准
execute: async ({ amount, recipient }) => {
return await processPayment(amount, recipient);
},
});
Measurable Metrics:
- Automatic execution rate: >95% (amount < $1000)
- Approval request response time: < 3 seconds
- False rejection rate: < 0.1%
Mode B: Context-based dynamic permissions
Applicable scenarios: Approval decisions that require context awareness
const sensitiveTool = tool({
description: 'Modify production configuration',
inputSchema: z.object({
configPath: z.string(),
changes: z.any(),
}),
needsApproval: async ({ configPath }) => {
// 檢查配置路徑是否為生產環境
return configPath.includes('/production/') ||
configPath.includes('prod.');
},
execute: async ({ configPath, changes }) => {
// 實際修改邏輯
return await updateConfig(configPath, changes);
},
});
Measurable Metrics:
- Dynamic licensing accuracy: >98% (based on pre-trained configuration pattern classifier)
- False positive rate: < 1% (allowed sensitive operations are not rejected)
- False negative rate: < 0.1% (dangerous operations are not intercepted)
Mode C: Approval flow for multi-step calls
Applicable scenarios: complex tasks that require multiple tool calls
const multiStepTool = tool({
description: 'Deploy application',
inputSchema: z.object({
appName: z.string(),
environment: z.string(),
}),
needsApproval: true, // 始終需要批准
execute: async ({ appName, environment }) => {
// 階段 1:構建檢查
const buildCheck = await buildCheck(appName);
if (!buildCheck.passed) return { error: 'Build check failed' };
// 階段 2:部署檢查
const deployCheck = await deployCheck(environment);
if (!deployCheck.passed) return { error: 'Deploy check failed' };
// 階段 3:執行部署
return await deploy(appName, environment);
},
});
// 使用 stopWhen 控製多步調用
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: { multiStepTool },
prompt: 'Deploy the app to production',
stopWhen: stepCountIs(3), // 最多 3 步
});
Measurable Metrics:
- Multi-step call success rate: >99.9% (no intervention)
- Batch approval response time: < 5 seconds (average)
- Error recovery rate: >95% (automatically retries failed steps)
Security boundary design
2.1 Tool selection control
const strictTool = tool({
description: 'Get weather for a location',
inputSchema: z.object({
location: z.string(),
}),
strict: true, // 使用嚴格模式
execute: async ({ location }) => {
return { temperature: 72 + Math.floor(Math.random() * 21) - 10 };
},
});
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: { strictTool },
toolChoice: 'required', // 強制模型調用工具
prompt: 'What is the weather in San Francisco?',
});
Strict mode features:
- The model can only generate tool calls that conform to
inputSchema - Reduce incorrect calls and out-of-bounds input
- Increases execution reliability, but may reduce flexibility
2.2 Input example guidance
const weatherTool = tool({
description: 'Get the weather in a location',
inputSchema: z.object({
location: z.string().describe('The location to get the weather for'),
}),
inputExamples: [
{ input: { location: 'San Francisco' } },
{ input: { location: 'London' } },
],
execute: async ({ location }) => {
return { temperature: 72 + Math.floor(Math.random() * 21) - 10 };
},
});
The role of input example:
- Help the model understand complex input structures
- Reduce format errors in model generation
- Improve the accuracy of tool calling
Monitoring and observability of licensing processes
3.1 License request tracking
const approvals: ToolApprovalRequest[] = [];
for (const part of result.content) {
if (part.type === 'tool-approval-request') {
console.log(`[Approval #${part.approvalId}]`);
console.log(`Tool: ${part.toolCall.toolName}`);
console.log(`Input: ${JSON.stringify(part.toolCall.input)}`);
approvals.push(part);
}
}
Monitoring indicators:
- Total Requests: Total number of tool license requests per hour
- Rejection rate: the proportion of requests that are rejected
- Average response time: time from request to decision
- Distribution by tool type: which tools are called the most
3.2 Licensing Decision Audit
const auditLog = {
timestamp: new Date().toISOString(),
approvalId: approvalId,
toolName: toolCall.toolName,
approved: approved,
reason: reason,
userId: userId,
context: {
prompt: prompt,
messages: messages,
},
};
await logAudit(auditLog);
Production Level Requirements:
- All licensing decisions must be auditable
- Audit logs retained for at least 90 days
- Support query by time, tool and user
Deployment scenarios and measurement indicators
4.1 Deployment Scenario: Content Pipeline
Scene description:
- AI Agent needs to generate and publish content (articles, videos, pictures)
- Each article needs to go through multiple tool calls: draft generation → formatting → review → publishing
Implementation plan:
const contentPipeline = {
draftTool: tool({
description: 'Generate article draft',
inputSchema: z.object({ topic: z.string() }),
needsApproval: true,
execute: async ({ topic }) => {
return await generateDraft(topic);
},
}),
formatTool: tool({
description: 'Format article',
inputSchema: z.object({ content: z.string() }),
needsApproval: true,
execute: async ({ content }) => {
return await formatContent(content);
},
}),
publishTool: tool({
description: 'Publish article',
inputSchema: z.object({ articleId: z.string() }),
needsApproval: true,
execute: async ({ articleId }) => {
return await publishArticle(articleId);
},
}),
};
// 使用 multi-step 調用
const result = await generateText({
model: "anthropic/claude-sonnet-4.5",
tools: contentPipeline,
prompt: 'Generate and publish an article about AI',
stopWhen: stepCountIs(3),
});
Measurable Metrics:
- End-to-end processing time: < 30 seconds (from draft to publish)
- License approval rate: >99% (all license requests approved)
- Content Quality Score: >85 (human assessment)
- Manual review intervention rate: < 5% (proportion of articles requiring manual review)
4.2 Deployment Scenario: Customer Support Automation
Scene description:
- AI Agent needs to handle user inquiries, order inquiries, and send confirmation emails
- Each operation requires user approval for sensitive operations (sending emails, modifying orders)
Implementation plan:
const customerSupport = {
queryTool: tool({
description: 'Query customer information',
inputSchema: z.object({ customerId: z.string() }),
needsApproval: false, // 低敏感度操作,自動執行
execute: async ({ customerId }) => {
return await queryCustomer(customerId);
},
}),
updateOrderTool: tool({
description: 'Update customer order',
inputSchema: z.object({
orderId: z.string(),
changes: z.any(),
}),
needsApproval: true, // 高敏感度操作,需要批准
execute: async ({ orderId, changes }) => {
return await updateOrder(orderId, changes);
},
}),
sendEmailTool: tool({
description: 'Send email to customer',
inputSchema: z.object({
email: z.string(),
message: z.string(),
}),
needsApproval: true,
execute: async ({ email, message }) => {
return await sendEmail(email, message);
},
}),
};
// 使用 useChat 的 UI 狀態處理
const messages = [
{ role: 'user', content: 'Query order #12345' },
];
const response = await useChat({
model: "anthropic/claude-sonnet-4.5",
tools: customerSupport,
messages,
});
// 添加批准響應
messages.push(...response.messages);
for (const part of response.content) {
if (part.type === 'tool-approval-request') {
messages.push({
role: 'tool',
content: [{
type: 'tool-approval-response',
approvalId: part.approvalId,
approved: userDecision,
reason: 'User confirmed the update',
}],
});
}
}
Measurable Metrics:
- Average response time: < 5 seconds (from user query to reply)
- License approval rate: >98%
- Manual intervention rate: < 1%
- Accuracy rate: >95% (correctly respond to user inquiries)
Build and maintain
5.1 Security layered architecture
┌─────────────────────────────────────┐
│ Layer 1: 模型層(Intent Detection) │
│ - 意圖分類(敏感 vs 非敏感) │
│ - 上下文檢查(授權範圍變化) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Layer 2: 許可層(Approval Workflow) │
│ - needsApproval 標記 │
│ - tool-approval-request/response │
│ - 動態許可邏輯 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Layer 3: 執行層(Execution Sandbox) │
│ - 工具白名單 │
│ - 資源限制(CPU、時間、內存) │
│ - 執行監控與終止 │
└─────────────────────────────────────┘
Production Level Requirements:
- Each floor has measurable monitoring points
- Layered protection: even if one layer fails, other layers can still protect
- Sliding Guard: allows upgrades but not downgrades
5.2 Common pitfalls and avoidance strategies
| Pitfalls | Instructions | Avoidance Strategies |
|---|---|---|
Excessive use of needsApproval | All tools marked as requiring approval, adding overhead | Hierarchical settings based on operational sensitivity |
Ignore tool-approval-request format | Error parsing license request format | Use type definitions provided by AI SDK |
| Do not handle rejection decisions | The model still attempts to retry after receiving a rejection | Add a system command of “Do not retry after rejection” |
| Missing audit log | Licensing decisions are not recorded | All decisions must be written to the audit log |
Comparison: AI SDK vs LangChain tool calls
5.3 Architectural differences
| Features | AI SDK (Vercel) | LangChain |
|---|---|---|
| Licensing process | Built-in needsApproval + tool-approval-request/response | Self-implementation required |
| Dynamic permissions | needsApproval: async ({ amount }) support | Requires additional logic |
| Multi-step call | stopWhen built-in | AgentExecutor required |
| Type safety | Zod schema automatically generates types | Manual definition required |
| UI integration | useChat built-in permission UI status | Requires self-implementation |
Summary: Three principles for production-level tool execution security
- Layered protection: model layer + permission layer + execution layer, each layer has independent monitoring points
- Measurable Decisions: All licensing requests have measurable response times and approval rates
- Auditable Trail: All licensing decisions must be auditable and retained for at least 90 days
Practical Suggestions:
- Start with “automatic execution + approval of a few sensitive operations”
- As the system matures, gradually increase the number of tools in
needsApproval - Optimize licensing strategy using monitoring metrics: automatic execution rate >95%, approval response time <3 seconds
Reference Document: