第 11 章:实战 — 高级特性

本章是 MiniClaw 实战项目的最后一章。我们要给这个小助手装上"安全锁"、"闹钟"、 "团队协作"和"深度思考"四大能力,让它从一个能聊天的玩具变成一个真正靠谱的 AI 助手。

本章目标

经过前三章的努力,MiniClaw 已经有了对话引擎、记忆系统和工具生态。但还差几块拼图:

特性 解决什么问题
安全防护 防止 AI 执行危险命令、泄露敏感信息
定时任务 让 MiniClaw 能定期做一些自动化工作
多 Agent 协作 遇到专业问题交给专业的"子 Agent"处理
扩展思考 面对复杂问题时让 Claude 想得更深

本章结束后,MiniClaw 就是一个功能完整的项目了。


1. 安全防护(钩子实战)

还记得第 6 章学的钩子系统吗?现在把它用起来。安全防护分三层:

  1. PreToolUse 钩子 — 工具执行前拦截危险操作
  2. PostToolUse 钩子 — 工具执行后脱敏敏感信息
  3. 审计日志 — 记录所有工具调用,出了问题可以回溯

1.1 拦截危险命令

最可怕的事情是 AI 跑了一个 rm -rf /。我们必须在命令执行之前就拦住它:

async def block_dangerous_commands(input_data, tool_use_id, context):
    """PreToolUse 钩子:拦截危险的 Bash 命令。"""
    if input_data.get("tool_name") != "Bash":
        return {}  # 不是 Bash,放行

    command = input_data.get("tool_input", {}).get("command", "")

    # 危险命令关键词
    dangerous_patterns = ["rm -rf", "sudo ", "mkfs", "> /dev/", "dd if="]

    for pattern in dangerous_patterns:
        if pattern in command:
            return {
                "decision": "block",
                "reason": f"命令包含危险操作: {pattern}",
            }

    return {}  # 安全,放行

原理:在 Bash 工具执行之前检查命令关键词,发现危险就返回 "decision": "block" 拦掉。

1.2 敏感信息脱敏

AI 的回复里可能不小心包含 API Key、密码。PostToolUse 钩子在返回结果前做清洗:

async def redact_sensitive_info(input_data, tool_use_id, context):
    """PostToolUse 钩子:对工具输出中的敏感信息脱敏。"""
    response = input_data.get("tool_response", "")
    if not isinstance(response, str):
        return {}

    # 检测 API Key / Token / 密码等模式
    patterns = [
        r'(?i)(api[_-]?key|token|secret)\s*[:=]\s*["\']?[\w-]{20,}',
        r'(?i)(password|passwd)\s*[:=]\s*\S+',
    ]

    for pattern in patterns:
        if re.search(pattern, response):
            return {
                "hookSpecificOutput": {
                    "hookEventName": "PostToolUse",
                    "additionalContext": "检测到敏感信息,已提醒注意脱敏。",
                }
            }
    return {}

1.3 审计日志

所有工具调用都记录到 ~/.miniclaw/audit.log,方便事后审计:

async def audit_tool_use(input_data, tool_use_id, context):
    """PostToolUse 钩子:记录工具调用审计日志。"""
    log_file = Path.home() / ".miniclaw" / "audit.log"
    record = {
        "time": datetime.now().isoformat(),
        "tool": input_data.get("tool_name", "unknown"),
        "input": input_data.get("tool_input", {}),
    }
    with open(log_file, "a", encoding="utf-8") as f:
        f.write(json.dumps(record, ensure_ascii=False) + "\n")
    return {}  # 不影响正常流程

1.4 在引擎中集成钩子

把三个钩子组装到 ClaudeAgentOptions 里:

hooks = {
    "PreToolUse": [
        HookMatcher(matcher="Bash", hooks=[block_dangerous_commands]),
    ],
    "PostToolUse": [
        HookMatcher(matcher=None, hooks=[redact_sensitive_info, audit_tool_use]),
    ],
}

matcher 字段控制钩子针对哪些工具生效:"Bash" 只对 Bash 生效,"Write|Edit" 对 Write 和 Edit 生效,None 对所有工具生效。完整代码在 miniclaw/engine.py


2. 定时任务 (scheduler.py)

有时我们希望 MiniClaw 能定时做事,比如每小时检查系统状态。用 asyncio 做一个轻量调度器。

2.1 核心设计

@dataclass
class ScheduledTask:
    name: str                               # 任务名称
    interval_seconds: float                  # 执行间隔(秒)
    callback: Callable[[], Awaitable[Any]]  # 异步回调函数
    enabled: bool = True                     # 是否启用

调度器对每个任务启动一个 asyncio Task,循环执行回调然后睡一段时间。

2.2 使用示例

scheduler = Scheduler()

async def check_status():
    print(f"[{datetime.now()}] 系统状态正常")

scheduler.add_task(ScheduledTask(
    name="状态检查",
    interval_seconds=3600,  # 每小时一次
    callback=check_status,
))

await scheduler.start()
# ... 程序运行中 ...
await scheduler.stop()

在 CLI 中输入 /schedule 查看任务列表,/schedule toggle 心跳检测 切换任务开关。


3. 多 Agent 协作 (agents.py)

Claude Agent SDK 支持定义多个"子 Agent",每个有自己的专长。主 Agent 遇到特定任务时会自动把任务交给合适的子 Agent。

3.1 AgentDefinition

from claude_agent_sdk import AgentDefinition

code_reviewer = AgentDefinition(
    description="代码审查专家,检查代码质量和潜在问题",
    prompt="你是一个代码审查专家。仔细分析代码,找出 bug、性能问题和安全漏洞。",
    tools=["Read", "Grep", "Glob"],  # 只给读取权限
    model="sonnet",                   # 用 Sonnet,快且便宜
)
字段 含义
description 子 Agent 的自我介绍,主 Agent 据此判断何时调用
prompt 子 Agent 的系统提示词
tools 可使用的工具列表
model 模型:"sonnet"、"opus"、"haiku" 或 "inherit"

3.2 AgentManager

管理类统一注册所有子 Agent,预定义了三个:代码审查、文档写作、数据分析。

class AgentManager:
    def __init__(self):
        self._agents = {}
        self._register_defaults()  # 注册预定义 Agent

    def get_all(self):
        """返回所有 Agent,传给 ClaudeAgentOptions.agents"""
        return dict(self._agents)

3.3 注入到引擎

agent_manager = AgentManager()
options = ClaudeAgentOptions(
    agents=agent_manager.get_all(),
)

就这么简单!主 Agent 会根据对话内容自动决定是否调用子 Agent。输入 /agents 查看所有可用的子 Agent:

MiniClaw> /agents
可用的子 Agent:
  code-reviewer  代码审查专家,检查代码质量和潜在问题
  writer         文档写作专家,擅长写技术文档和说明
  analyst        数据分析专家,擅长分析数据和生成报告

4. 扩展思考模式

有些问题需要 Claude "多想一会儿"——复杂的数学推理、多步骤的逻辑分析。SDK 提供了扩展思考(Extended Thinking)功能。

4.1 三种思考模式

# 自适应 - Claude 自己决定要不要深度思考
thinking = {"type": "adaptive"}

# 启用 - 强制开启,指定思考预算(token 数量)
thinking = {"type": "enabled", "budget_tokens": 10000}

# 禁用 - 关闭思考
thinking = {"type": "disabled"}

4.2 effort 参数

不想操心 token 预算?用更简单的 effort

options = ClaudeAgentOptions(effort="high")
# 可选值:low / medium / high / max

thinkingeffort 同时设置时,thinking 优先级更高。一般用 effort 就够了。

4.3 什么时候用

场景 推荐设置
日常闲聊 不设置或 effort="low"
代码编写 effort="medium"
复杂 bug 排查 effort="high"
数学证明、逻辑推理 effort="max"

4.4 CLI 命令

MiniClaw> /think on       # 开启(默认 effort=high)
MiniClaw> /think off      # 关闭
MiniClaw> /think max      # 设置强度
MiniClaw> /think status   # 查看当前状态

5. 完整项目收尾

5.1 最终目录结构

miniclaw/
  __init__.py       # 包入口
  __main__.py       # 启动入口 (python -m miniclaw)
  auth.py           # 认证管理
  config.py         # 配置中心
  engine.py         # 对话引擎(集成钩子、Agent、思考模式)
  memory.py         # 记忆系统
  cli.py            # 命令行界面(全部命令)
  scheduler.py      # 定时任务调度器
  agents.py         # 多 Agent 管理
  tools/
    __init__.py     # 工具包入口
    registry.py     # 工具注册表
    builtin.py      # 内置工具

5.2 启动方式

export ANTHROPIC_API_KEY="你的key"
python -m miniclaw

5.3 命令一览

命令 功能
/help 显示帮助信息
/clear 清空对话历史
/save 保存当前对话
/load 加载历史对话
/tools 查看可用工具
/agents 查看子 Agent 列表
/think on\|off\|max 切换思考模式
/schedule 查看定时任务
/quit 退出

5.4 核心代码串讲

引擎启动时,一次性把所有高级特性组装好:

# engine.py 核心流程
async def connect(self):
    hooks = self._build_hooks()              # 1. 安全防护
    agents = self.agent_manager.get_all()    # 2. 多 Agent
    thinking = self._build_thinking_config() # 3. 思考模式

    options = ClaudeAgentOptions(
        system_prompt=self.config.system_prompt,
        hooks=hooks,
        agents=agents,
        thinking=thinking,
        permission_mode="bypassPermissions",
    )

    self._client = ClaudeSDKClient(options)
    await self._client.connect()
    await self.scheduler.start()             # 4. 定时任务

6. 回顾与展望

整个教程学了什么

章节 内容 核心概念
第 0 章 环境准备 SDK 安装、API Key
第 1 章 第一次对话 query() 函数
第 2 章 消息系统 Message 类型体系
第 3 章 配置选项 ClaudeAgentOptions
第 4 章 多轮对话 ClaudeSDKClient
第 5 章 自定义工具 MCP 工具
第 6 章 钩子系统 HookMatcher
第 7 章 权限控制 PermissionMode
第 8 章 项目架构 MiniClaw 设计
第 9 章 核心引擎 对话 + 记忆
第 10 章 工具生态 工具注册表
第 11 章 高级特性 安全、调度、Agent、思考

扩展方向

MiniClaw 还有很多可以玩的方向:

  1. Web 界面 — 用 FastAPI + WebSocket 做一个 Web 版
  2. 消息平台集成 — 接入飞书、钉钉、Slack
  3. 更多工具 — 数据库查询、HTTP 请求、文件上传
  4. RAG 增强 — 接入向量数据库,让记忆系统更强大
  5. 多用户支持 — 每个用户独立的对话和配置
  6. 监控面板 — 可视化审计日志和使用统计

恭喜你完成了整个 Claude Agent SDK 教程!现在你已经掌握了构建 AI Agent 应用的核心技能。去创造你自己的 AI 助手吧!