Tool Confirmation 与安全认证:在 Agent 行动前增加安全阀
Tool Confirmation 与安全认证:在 Agent 行动前增加安全阀
让 Agent 自动帮用户做事是方便,但有些操作有风险——删除数据、转账、发邮件。在这些操作执行前加上用户确认,就叫 Tool Confirmation。
Tool Confirmation:让用户确认后再执行
使用场景
- 删除操作(delete、drop)
- 财务操作(转账、付款)
- 信息泄露风险操作(发送邮件、发布内容)
- 高成本操作(调用付费 API)
实现方式
ADK Go 的 Tool 支持 Confirmation 字段:
type deleteTool struct{}
func (deleteTool) Name() string { return "delete_file" }
func (deleteTool) Description() string { return "Delete a file from the system" }
func (deleteTool) InputSchema() string { return `{"type":"object","properties":{"path":{"type":"string"}}}` }
func (t deleteTool) Confirmation(ctx context.Context, input string) (bool, error) {
var args struct {
Path string `json:"path"`
}
json.Unmarshal([]byte(input), &args)
fmt.Printf("⚠️ 确认:要删除文件 %s 吗?(y/N) ", args.Path)
var confirm string
fmt.Scan(&confirm)
return confirm == "y" || confirm == "Y", nil
}
func (t deleteTool) Call(ctx context.Context, input string) (string, error) {
// 实际删除逻辑
}
Confirmation() 返回 true 才执行 Call(),返回 false 则跳过。
Web 模式下的确认
CLI 模式下 fmt.Scan 可以工作,但 Web 模式下不行。更通用的方式是返回一个确认 UI 的提示:
func (t deleteTool) Confirmation(ctx context.Context, input string) (bool, error) {
return false, tool.ErrConfirmationRequired // 告诉 Agent 需要用户确认
}
ADK Go 会把 ErrConfirmationRequired 转换成 Web 界面的确认弹窗。
API Key 管理
场景:多个 Tool 用不同的 Key
一个 Agent 挂了多个 Tool,每个 Tool 用不同的 API Key:
type weatherTool struct{ apiKey string }
type stockTool struct{ apiKey string }
func main() {
weatherTool := newWeatherTool(os.Getenv("WEATHER_API_KEY"))
stockTool := newStockTool(os.Getenv("STOCK_API_KEY"))
agent, _ := llmagent.New(llmagent.Config{
Tools: []tool.Tool{weatherTool, stockTool},
})
}
Key 不写入代码
通过环境变量或 Secret Manager 注入,不要硬编码:
type toolWithKey struct {
apiKey string
}
func newToolWithKey() *toolWithKey {
return &toolWithKey{
apiKey: os.Getenv("MY_TOOL_API_KEY"), // 从环境变量读取
}
}
OAuth 认证
如果 Tool 需要访问用户授权的资源(如 Google Calendar、GitHub):
import "google.golang.org/adk/auth"
oauthTool, err := auth.NewOAuthTool(ctx,
auth.WithConfig(auth.OAuthConfig{
ClientID: os.Getenv("OAUTH_CLIENT_ID"),
ClientSecret: os.Getenv("OAUTH_CLIENT_SECRET"),
AuthURL: "https://accounts.google.com/o/oauth2/auth",
TokenURL: "https://oauth2.googleapis.com/token",
Scopes: []string{"https://www.googleapis.com/auth/calendar.readonly"},
}),
)
最小权限原则
每个 Tool 用的 Key,应该只有执行这个 Tool 所需的最小权限:
| Tool | Key 权限 |
|---|---|
| 天气查询 | 只读天气 API |
| 日历读取 | 只读日历 |
| 邮件发送 | 只发邮件 |
| 文件删除 | 只操作指定目录 |
常见问题
Q:Confirmation 回调卡住不动
A:在 Web 模式下不要用 fmt.Scan,改用 ErrConfirmationRequired 返回错误,让框架处理 UI 确认。
Q:Tool 报错 permission denied,但 Key 是对的
A:确认 Key 有对应 API 的权限。不同 API 的 Key 权限是分开的。
Q:OAuth token 过期了怎么办 A:实现 token refresh 逻辑,或使用框架内置的 token 自动刷新。
小结
模块 3 完成。学习了:
- Function Tool 编写基础
- Function Tool 性能优化
- MCP Server 接入
- OpenAPI Tool
- Tool Confirmation 与安全认证
接下来进入模块 4:记忆与上下文——Agent 是如何记住对话历史、管理状态的。
想跟着学更多 Go ADK 实战?关注「全栈之巅-梦兽编程」公众号,每周更新 Go / AI 编程实战干货。
