在构建 AI Agent 时,我们经常面临这样的挑战:如何监控 Agent 的思考过程?如何在它执行危险指令(如 rm -rf)前拦截?如何统计它消耗的 Token?
Anthropic 推出的 Claude Agent SDK 提供了一套强大的 Hooks 机制。它允许开发者像监听网页事件一样,介入 Agent 的生命周期。本文将带你通过 Python 代码,实战演练如何发掘 Hooks 的潜力。
💡 什么是 Hooks?
Hooks 是 Agent 运行循环中的“观察点”或“拦截点”。当 Agent 准备执行某个动作(如调用工具、接收用户输入)时,会触发相应的 Hook。
常见的 Hook 类型包括:
UserPromptSubmit: 用户提交问题时触发。PreToolUse: 核心 Hook,在工具执行前触发,可用于权限审计或参数修改。PostToolUse: 工具执行完成后触发,用于获取执行结果。Stop: Agent 完成任务或被强行停止时触发。
🛠️ 环境准备
首先,确保你的环境中已安装 Python 3.10+ 和 SDK。
Bash
pip install claude-agent-sdk
注意:使用 SDK 前,请确保已通过
export ANTHROPIC_API_KEY=your_key配置了 API 密钥。
🌟 实战:构建一个带“防火墙”的自动化 Agent
我们将实现一个功能:当 Agent 尝试使用 Bash 工具执行包含 rm 的敏感命令时,Hooks 会自动拦截并改写命令,或者直接拒绝执行。
1. 基础架构:引入 Hooks
在 Python SDK 中,Hooks 通过 ClaudeAgentOptions 进行配置。
Python
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
async def main():
# 初始化客户端
async with ClaudeSDKClient() as client:
# 定义 Hook 处理逻辑
def on_pre_tool_use(input_data):
tool_name = input_data.get("name")
args = input_data.get("arguments", {})
print(f"🔍 检查工具调用: {tool_name}")
# 安全检查逻辑
if tool_name == "Bash" and "rm" in args.get("command", ""):
print("⚠️ 警告:检测到危险指令,已拦截!")
# 这里可以返回修改后的参数,或者抛出异常阻止执行
return {"arguments": {"command": "echo 'Command blocked for safety'"}}
return input_data
# 配置 Options
options = ClaudeAgentOptions(
hooks={
"PreToolUse": on_pre_tool_use
},
allowed_tools=["Bash", "Read"],
permission_mode="acceptEdits" # 自动接受文件修改
)
# 启动查询
async for message in client.query(
prompt="帮我删除当前目录下名为 test.txt 的文件",
options=options
):
# 处理输出(如打印思考过程或结果)
if hasattr(message, "content"):
for block in message.content:
if hasattr(block, "text"):
print(f"🤖 Claude: {block.text}")
if __name__ == "__main__":
asyncio.run(main())
🔍 核心 Hook 类型详解
1. PreToolUse:安全与审计的守门员
这是最常用的 Hook。它的 input_data 通常包含:
name: 工具名称。arguments: Agent 传入的参数。
应用场景:
- 敏感词过滤:防止 Agent 泄露环境变量。
- 参数注入:在 Agent 调用数据库查询工具时,自动注入当前用户的
user_id。
2. PostToolUse:结果处理与日志
当工具运行结束,你可以通过这个 Hook 拿到 output。
Python
def on_post_tool_use(output_data):
# output_data 包含 tool_use_id 和执行结果
print(f"✅ 工具执行完毕,结果长度: {len(str(output_data))}")
3. UserPromptSubmit:动态增强提示词
在用户输入到达 Claude 之前,你可以对其进行预处理。
Python
def on_user_submit(prompt):
# 比如在每个问题后面自动加上“请用中文回答”
return f"{prompt} (Please respond in Chinese)"
🚀 进阶:Hooks 的执行优先级
在 Claude Agent SDK 的权限模型中,Hooks 拥有 最高优先级:
- Hooks 执行:首先询问你的代码,你可以选择
Allow(允许)、Deny(拒绝)或修改参数。 - Deny 规则检查:检查配置文件中的黑名单。
- Allow 规则检查:检查白名单。
- 用户交互:如果以上都没决定,则弹出提示问用户。
这意味着,通过 Hooks,你可以完全掌控 Agent 的行为边界。
📝 最佳实践建议
- 保持异步兼容:在复杂的 Agent 应用中,建议 Hook 处理逻辑尽量轻量,避免阻塞 Agent 的思考循环。
- 防御性编程:在
PreToolUse中修改参数时,务必确保返回的格式符合 SDK 要求(通常是一个字典),否则会导致 Agent 报错。 - 日志留痕:在生产环境中,建议利用
PostToolUse将所有工具执行记录存入数据库,方便后续溯源。
结语
Claude Agent SDK 的 Hooks 不仅仅是一个回调函数,它是我们将 AI 能力与工程化约束结合的桥梁。通过合理配置 Hooks,你可以构建出既强大又安全的生产级 AI Agent。