工具注解系统为每个工具提供安全元数据,用于自动化权限决策和风险评估。
工具注解 (ToolAnnotations) 描述工具的安全特征:
type ToolAnnotations struct {
ReadOnly bool // 是否只读(不修改任何状态)
Destructive bool // 是否具有破坏性(可能导致数据丢失)
Idempotent bool // 是否幂等(多次执行结果相同)
OpenWorld bool // 是否涉及外部系统(网络、第三方API)
RiskLevel int // 风险级别 (0-4)
Category string // 工具分类
RequiresConfirmation bool // 是否需要用户确认
}
| 级别 | 名称 | 说明 | 示例工具 |
|---|---|---|---|
| 0 | Safe | 安全操作,无副作用 | Read, Glob |
| 1 | Low | 低风险操作 | Write(覆盖写入) |
| 2 | Medium | 中等风险 | WebFetch, 数据库写入 |
| 3 | High | 高风险,可能破坏性 | Bash, 文件删除 |
| 4 | Critical | 极高风险,需要特别审批 | 系统修改、批量删除 |
import "github.com/astercloud/aster/pkg/tools"
// 安全只读操作(如 Read, Glob, Grep)
tools.AnnotationsSafeReadOnly
// 安全写入操作(如 Write)
tools.AnnotationsSafeWrite
// 破坏性写入(如删除文件)
tools.AnnotationsDestructiveWrite
// 命令执行(如 Bash)
tools.AnnotationsExecution
// 网络只读(如 WebFetch, WebSearch)
tools.AnnotationsNetworkRead
// 网络写入(如 HTTP POST)
tools.AnnotationsNetworkWrite
// 数据库只读
tools.AnnotationsDatabaseRead
// 数据库写入
tools.AnnotationsDatabaseWrite
// MCP 工具(动态加载)
tools.AnnotationsMCPTool
// 用户交互工具
tools.AnnotationsUserInteraction
实现 AnnotatedTool 接口:
import "github.com/astercloud/aster/pkg/tools"
type MyCustomTool struct {
// ...
}
// 实现 Tool 接口
func (t *MyCustomTool) Name() string { return "MyTool" }
func (t *MyCustomTool) Description() string { return "自定义工具" }
func (t *MyCustomTool) InputSchema() map[string]any { return nil }
func (t *MyCustomTool) Execute(ctx context.Context, input map[string]any, tc *tools.ToolContext) (any, error) {
// ...
}
func (t *MyCustomTool) Prompt() string { return "" }
// 实现 AnnotatedTool 接口
func (t *MyCustomTool) Annotations() *tools.ToolAnnotations {
return &tools.ToolAnnotations{
ReadOnly: false,
Destructive: false,
Idempotent: true,
OpenWorld: false,
RiskLevel: tools.RiskLevelLow,
Category: "custom",
}
}
基于工具注解自动判断是否需要审批:
import "github.com/astercloud/aster/pkg/types"
config := &types.AgentConfig{
PermissionMode: types.PermissionModeSmartApprove,
}
SmartApprove 规则:
// 获取工具注解(兼容未实现接口的工具)
ann := tools.GetAnnotations(myTool)
// 判断是否可自动批准
if tools.IsToolSafeForAutoApproval(myTool) {
// 自动执行
}
// 获取风险级别
riskLevel := tools.GetToolRiskLevel(myTool)
fmt.Printf("风险级别: %s\n", ann.RiskLevelName())
| 工具 | ReadOnly | Destructive | OpenWorld | RiskLevel |
|---|---|---|---|---|
| Read | ✅ | ❌ | ❌ | Safe |
| Glob | ✅ | ❌ | ❌ | Safe |
| Grep | ✅ | ❌ | ❌ | Safe |
| Write | ❌ | ❌ | ❌ | Low |
| Bash | ❌ | ✅ | ✅ | High |
| WebFetch | ✅ | ❌ | ✅ | Low |
| WebSearch | ✅ | ❌ | ✅ | Low |
OpenWorld: true