Claude Code 的 Agent Skills 是什么?如何使用?

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

相关推荐
kyriewen21 小时前
我同时用了 Claude Code、Cursor 和 Codex,说说三个工具的真实差距——2026 年选错工具比不用 AI 更浪费时间
前端·ai编程·claude
Lsx_1 天前
基于 Claude Code 的 AI 编程工作流探索
前端·ai编程·claude
plainGeekDev1 天前
管道组合 + 结构化输出:让 Claude 和 grep 并肩作战
ai编程·claude
拖鞋王子猪1 天前
Claude Code / Codex 使用 CC-Switch 配置 API Key 和 base_url 教程
ai编程·claude
小碗细面1 天前
从 PRD 到上线:SpecKit 如何让 AI 真正参与前端交付
前端·ai编程·claude
阿拉斯攀登2 天前
安全与可控性:输出校验、权限控制
人工智能·chatgpt·agent·memory·claude·知识库·向量数据库
kyriewen2 天前
Godot 全面封杀 Vibe Coding,作为每天用 AI 写代码的人,我反而觉得这是件好事
前端·ai编程·claude
kebeiovo2 天前
2026超稳国内AI中转API平台|支持GPT/Claude/Gemini/Codex 免费可用
gpt·claude·codex·api key·中转站
plainGeekDev2 天前
Claude Code 的非交互模式:一条命令当 grep 用
ai编程·claude
犇驫聊AI2 天前
Claude Code 用了大半年才悟出来的 6 个技巧,第 3 个直接省一半 Token
前端·claude