Claude Code 的 Agent Skills 使用指南
什么是 Agent Skills?
Agent Skills 是 Claude API 中的工具调用(Tool Use)机制,允许 Claude 自主决策并调用外部函数完成任务。核心特性:
- 自主决策 - Claude 判断是否需要调用工具及调用参数
- 循环执行 - 支持多轮工具调用,逐步完成复杂任务
- 结构化通信 - 基于 JSON Schema 定义工具接口规范
核心实现流程
1. 定义工具(Tool Definition)
python
import anthropic
tools = [
{
"name": "execute_python",
"description": "执行 Python 代码并返回输出结果。用于数据处理、计算、文件操作等。",
"input_schema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "要执行的 Python 代码片段(不包含输入提示)"
}
},
"required": ["code"]
}
},
{
"name": "read_file",
"description": "读取指定路径的文件内容。支持文本和二进制文件。",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "文件的绝对或相对路径"
},
"encoding": {
"type": "string",
"description": "文件编码方式,默认 utf-8",
"default": "utf-8"
}
},
"required": ["path"]
}
}
]
2. 初始化 Agent 请求
python
client = anthropic.Anthropic(api_key="your-api-key")
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
tools=tools,
messages=[
{
"role": "user",
"content": "读取 data.csv 文件,计算销售总额和平均值"
}
]
)
3. 循环处理工具调用
python
import subprocess
import json
def execute_tool(tool_name: str, tool_input: dict):
"""执行工具并返回结果"""
if tool_name == "execute_python":
try:
# 安全执行:使用 subprocess 隔离环境
result = subprocess.run(
["python", "-c", tool_input["code"]],
capture_output=True,
text=True,
timeout=30
)
return result.stdout or result.stderr
except subprocess.TimeoutExpired:
return "错误: 代码执行超时(超过30秒)"
except Exception as e:
return f"错误: {str(e)}"
elif tool_name == "read_file":
try:
with open(
tool_input["path"],
"r",
encoding=tool_input.get("encoding", "utf-8")
) as f:
return f.read()
except FileNotFoundError:
return f"错误: 文件不存在 - {tool_input['path']}"
except Exception as e:
return f"错误: {str(e)}"
# 持续循环直到 Agent 完成任务
messages = [
{"role": "user", "content": "读取 data.csv 文件,计算销售总额和平均值"}
]
while True:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
tools=tools,
messages=messages
)
# 检查是否有工具调用
if response.stop_reason == "tool_use":
# 找到工具调用块
assistant_message = {"role": "assistant", "content": response.content}
messages.append(assistant_message)
# 处理所有工具调用
tool_results = []
for content_block in response.content:
if content_block.type == "tool_use":
tool_result = execute_tool(
content_block.name,
content_block.input
)
tool_results.append({
"type": "tool_result",
"tool_use_id": content_block.id,
"content": tool_result
})
# 反馈工具结果
messages.append({
"role": "user",
"content": tool_results
})
else:
# Agent 已完成(stop_reason == "end_turn")
break
# 提取最终文本响应
final_response = next(
(b.text for b in response.content if hasattr(b, "text")),
None
)
print("Agent 响应:", final_response)
实战案例:完整的数据分析 Agent
python
import anthropic
import subprocess
import json
import os
class DataAnalysisAgent:
def __init__(self):
self.client = anthropic.Anthropic()
self.tools = self._define_tools()
def _define_tools(self):
return [
{
"name": "execute_python",
"description": "执行 Python 代码进行数据处理和分析",
"input_schema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Python 代码(可导入 pandas, numpy, matplotlib)"
}
},
"required": ["code"]
}
},
{
"name": "read_file",
"description": "读取文件内容",
"input_schema": {
"type": "object",
"properties": {
"path": {"type": "string", "description": "文件路径"}
},
"required": ["path"]
}
},
{
"name": "list_files",
"description": "列出目录中的文件",
"input_schema": {
"type": "object",
"properties": {
"directory": {
"type": "string",
"description": "目录路径,默认当前目录",
"default": "."
}
}
}
}
]
def _execute_tool(self, tool_name: str, tool_input: dict) -> str:
"""执行工具"""
if tool_name == "execute_python":
# 预配置 imports
code = f"""
import pandas as pd
import numpy as np
import json
{tool_input['code']}
"""
try:
result = subprocess.run(
["python", "-c", code],
capture_output=True,
text=True,
timeout=30,
cwd=os.getcwd()
)
if result.returncode != 0:
return f"执行错误:\n{result.stderr}"
return result.stdout or "(无输出)"
except subprocess.TimeoutExpired:
return "错误: 执行超时"
except Exception as e:
return f"错误: {str(e)}"
elif tool_name == "read_file":
try:
with open(tool_input["path"], "r", encoding="utf-8") as f:
content = f.read()
# 限制输出长度
return content[:5000] if len(content) > 5000 else content
except FileNotFoundError:
return f"文件不存在: {tool_input['path']}"
except Exception as e:
return f"读取错误: {str(e)}"
elif tool_name == "list_files":
try:
directory = tool_input.get("directory", ".")
files = os.listdir(directory)
return json.dumps(files, ensure_ascii=False, indent=2)
except Exception as e:
return f"列表错误: {str(e)}"
return "未知工具"
def run(self, user_task: str):
"""运行 Agent"""
messages = [{"role": "user", "content": user_task}]
iteration = 0
max_iterations = 10
while iteration < max_iterations:
iteration += 1
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
tools=self.tools,
messages=messages
)
print(f"\n--- 迭代 {iteration} ---")
print(f"停止原因: {response.stop_reason}")
if response.stop_reason == "end_turn":
# Agent 完成
final_text = next(
(b.text for b in response.content if hasattr(b, "text")),
None
)
print(f"\n✓ Agent 完成响应:\n{final_text}")
return final_text
elif response.stop_reason == "tool_use":
# 添加 Assistant 消息
messages.append({"role": "assistant", "content": response.content})
# 执行所有工具调用
tool_results = []
for block in response.content:
if block.type == "tool_use":
print(f" → 调用工具: {block.name}")
print(f" 参数: {json.dumps(block.input, ensure_ascii=False)}")
result = self._execute_tool(block.name, block.input)
print(f" 结果: {result[:200]}..." if len(result) > 200 else f" 结果: {result}")
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
messages.append({"role": "user", "content": tool_results})
else:
print(f"意外的停止原因: {response.stop_reason}")
break
print(f"\n✗ 超过最大迭代次数 ({max_iterations})")
return None
# 使用示例
if __name__ == "__main__":
agent = DataAnalysisAgent()
task = """
1. 列出当前目录的文件
2. 如果存在 sales.csv,读取前10行
3. 计算该文件中销售额的总和、平均值和最大值
4. 生成一份简要报告
"""
agent.run(task)
工具定义最佳实践
| 维度 | 最佳实践 | 反面示例 |
|---|---|---|
| 描述清晰度 | "执行 Python 代码进行数据处理" | "运行代码" |
| 参数验证 | 使用required 数组明确必填项 |
依赖可选参数 |
| 输出限制 | 返回不超过 10000 字符的结果 | 返回大型数据集 |
| 错误处理 | 返回结构化错误信息 | 不处理异常 |
| 命名规范 | snake_case(execute_python) | 混合大小写 |
关键注意事项
安全隔离
python
# ✓ 推荐:使用 subprocess 隔离执行环境
subprocess.run(
["python", "-c", code],
capture_output=True,
timeout=30
)
# ✗ 避免:直接 exec/eval
exec(code) # 危险!
成本控制
python
# 限制单次请求的 token 数
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2048, # 设置合理上限
tools=tools,
messages=messages
)
# 限制迭代次数
for iteration in range(10): # 最多10轮
if response.stop_reason == "end_turn":
break
结果验证
python
# 验证工具结果的有效性
if len(tool_result) > 50000:
tool_result = tool_result[:50000] + "\n[输出已截断]"
# 捕获所有异常
try:
result = execute_tool(tool_name, tool_input)
except Exception as e:
result = f"工具执行失败: {str(e)}"
Agent Skills 的核心在于明确的工具定义 + 完善的错误处理 + 高效的循环管理。遵循上述模式可快速构建可靠的自动化工作流。
博主的个人网站接入了claude haiku 4.5模型,欢迎访问:micefind.com