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

相关推荐
zzzzls~20 小时前
Vibe Coding 最佳实践:Claude Code 检查点回溯与 Git 自动存档每轮对话
git·ai·claude·vibe coding·checkpointing
闲云一鹤1 天前
Claude Code 接入第三方AI模型(MiMo-V2-Flash)
前端·后端·claude
roamingcode2 天前
IncSpec 面向 AI 编程助手的增量规范驱动开发工具
人工智能·agent·claude·cursor·fe·规范驱动开发
极客密码3 天前
也是吃上细糠了。用上了Claude Code的无限中转API
ai编程·claude·cursor
坐吃山猪5 天前
ClaudeCode安装记录
llm·claude
三斗米6 天前
mac本地搭建claude code+通义千问
claude·vibecoding
Cloud Traveler6 天前
Amazon Bedrock × Claude 实战:从扫描文档到结构化数据的智能处理流程
claude·amazon bedrock
luoyayun3618 天前
Linux下安装使用Claude遇到的问题及解决方案
linux·claude
win4r10 天前
🚀Claude Code被封号?用谷歌Antigravity+Claude Opus 4.5轻松替代!实测项目重构+全栈开发效果惊艳!Opus 4.5 才王道
claude·gemini·vibecoding