在 AI Agent(智能体)的开发浪潮中,工具使用(Tool Use) 是连接大模型与物理世界的桥梁。
在这里插入图片描述

本文将跳过复杂的第三方框架(如 LangChain),回归本源,直接使用 Anthropic 原生 Python SDK,构建一个能够自主感知文件系统、并执行整理任务的“文件整理机器人”。我们将利用 Claude 3.5 Sonnet 强大的逻辑推理和编码能力,实现从“感知”到“行动”的完整闭环。

1. 为什么选择原生 SDK?

虽然 Agent 编排框架提供了便利,但在学习阶段,直接操作原生 SDK 能让我们更深刻地理解 Agent 的核心循环:感知 (Perception) -> 思考 (Reasoning) -> 行动 (Action) -> 观察 (Observation)。

1.1 痛点:我们为什么需要 Agent?

很多人第一次用大模型,会停留在“问答聊天”阶段:

你问,它答。

但真实工程/办公场景里,问题往往是“要把事情做完”,而不仅仅是“解释一下怎么做”。

比如你电脑 Download 目录堆满了:

  • 截图、PDF、zip 包、视频、临时文件
  • 同名冲突、重复文件、不知道哪些该删
  • 想按规则归档并生成报告(移动了哪些、跳过了哪些、原因是什么)

这类任务的关键不是生成文字,而是能在受控边界内:

  1. 看文件(感知)
  2. 制定整理计划(思考)
  3. 创建目录、移动文件(行动)
  4. 检查结果并继续优化(观察)

这就是 Agent 的核心价值:让模型从“会说”变成“能做”。


1.2 核心概念:什么是 Tool Use(Function Calling)?

在 Anthropic 的定义里,Tool Use 的关键是:
你把“工具的定义”(名字、用途、输入 JSON Schema)提供给 Claude,Claude 会在需要时返回一个 tool_use 内容块,请求你执行某个工具;你执行完把结果以 tool_result 回传,Claude 再继续推理。:contentReference[oaicite:0]{index=0}

你可以把它理解成:

  • Claude = 大脑(负责分析和决策)
  • Tools = 手脚(负责访问系统、读写文件、调用 API)
  • Agent Loop = 感知 → 思考 → 行动 → 观察 的闭环

这就是“从聊天到解决问题”的关键一跳。


1.3 为什么用 Anthropic SDK 手搓,而不是上来就用框架?

框架(LangChain / LlamaIndex / AutoGen…)很快,但它也会:

  • 隐藏核心机制
  • 带来不必要的抽象层和调试成本
  • 让你难以做到生产级安全控制(命令白名单、路径沙箱等)

2. 环境准备

首先,确保你已安装了 anthropic 官方库,并拥有 API Key。

pip install anthropic

3. 核心组件:定义“双手” (Tools)

Agent 的智能体现在它如何调用工具。对于“文件整理”任务,我们需要赋予 Claude 两个核心能力:

1、观察环境: 查看某个文件夹里有哪些文件。

2、执行操作: 将文件移动到指定位置。

我们需要定义 Python 函数,并编写对应的 JSON Schema 描述,这样 Claude 才能理解如何使用它们。

import os
import shutil
from anthropic import Anthropic

client = Anthropic(api_key="your_api_key_here")

# --- 1. 定义实际执行的 Python 函数 ---
def list_files(directory):
    """列出目录下的所有文件,用于感知环境"""
    try:
        if not os.path.exists(directory):
            return f"Error: 目录 {directory} 不存在"
        # 过滤掉隐藏文件,只看普通文件
        files = [f for f in os.listdir(directory) if not f.startswith('.')]
        return str(files)
    except Exception as e:
        return f"Error: {e}"

def move_file(filename, source_dir, target_dir):
    """执行移动操作"""
    try:
        if not os.path.exists(target_dir):
            os.makedirs(target_dir) # 自动创建目标文件夹
        shutil.move(os.path.join(source_dir, filename), os.path.join(target_dir, filename))
        return f"Success: 已将 {filename} 移动到 {target_dir}"
    except Exception as e:
        return f"Error: {e}"

 #  2. 定义传给 Claude 的工具描述 (Schema) ---

tools = [
    {
        "name": "list_files",
        "description": "列出目标文件夹中的文件名。在执行整理前,必须先调用此工具查看文件列表。",
        "input_schema": {
            "type": "object",
            "properties": {
                "directory": {"type": "string", "description": "目标文件夹的绝对路径"}
            },
            "required": ["directory"]
        }
    },
    {
        "name": "move_file",
        "description": "将文件从源目录移动到目标目录(分类整理)。",
        "input_schema": {
            "type": "object",
            "properties": {
                "filename": {"type": "string", "description": "要移动的文件名"},
                "source_dir": {"type": "string", "description": "源目录路径"},
                "target_dir": {"type": "string", "description": "目标目录路径"}
            },
            "required": ["filename", "source_dir", "target_dir"]
        }
    }
]

4. 构建 Agent 的“大脑”循环

这是实现 Agent 自主性的关键。我们需要构建一个 while 循环,让 Claude 能够连续思考和行动,直到任务完成。

核心逻辑:

1、将用户指令发给 Claude。

2、检查 Claude 的回复:

  • 如果是 文本:说明它在向用户提问或汇报结果。

  • 如果是 tool_use:说明它想调用工具。

4、如果是调用工具,我们在本地运行对应的 Python 函数。

关键点: 将工具运行的结果(Success/Error)作为新的消息追加到历史记录中,再次发给 Claude。

def run_file_organizer(user_prompt):
    print(f"🤖 User: {user_prompt}")
    messages = [{"role": "user", "content": user_prompt}]
    
    while True:
        # 请求 Claude,带上 tools 定义
        response = client.messages.create(
            model="claude-3-5-sonnet-20240620",
            max_tokens=1024,
            tools=tools,
            messages=messages
        )
        
        # 将 Claude 的回复加入上下文
        messages.append({"role": "assistant", "content": response.content})
        
        # 判断停止原因
        if response.stop_reason == "end_turn":
            # 任务完成,打印最终回复
            print(f"💡 Agent: {response.content[0].text}")
            break
            
        elif response.stop_reason == "tool_use":
            tool_results = []
            
            # 处理 Claude 可能发出的多个工具调用
            for block in response.content:
                if block.type == "tool_use":
                    print(f"🔧 Claude 想要执行: {block.name} -> 参数: {block.input}")
                    
                    # 动态分发函数调用
                    result = ""
                    if block.name == "list_files":
                        result = list_files(block.input["directory"])
                    elif block.name == "move_file":
                        result = move_file(**block.input)
                    
                    print(f"   ✅ 执行结果: {result}")
                    
                    # 构造工具回传消息
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": result
                    })
            
            # 将执行结果反馈给 Claude,触发下一次思考
            messages.append({
                "role": "user",
                "content": tool_results
            })
  1. 运行效果演示
    假设我们在 ./downloads 目录下有一堆混乱的图片和文档:
if __name__ == "__main__":
    prompt = "帮我整理 ./downloads 文件夹。把所有的图片(jpg, png)放进 'Images' 文件夹,文档(txt, md)放进 'Docs' 文件夹。"
    run_file_organizer(prompt)

控制台输出模拟:

User: 帮我整理... 🔧 Claude 想要执行: list_files -> 参数: {'directory': './downloads'} ✅ 执行结果: ['photo1.jpg', 'note.txt', 'image2.png'] 🔧 Claude 想要执行: move_file -> 参数: {'filename': 'photo1.jpg', 'target_dir': './downloads/Images'...} 🔧 Claude 想要执行: move_file -> 参数: {'filename': 'note.txt', 'target_dir': './downloads/Docs'...} ... 💡 Agent: 整理完成!我已经将图片移动到了 Images 文件夹,文档移动到了 Docs 文件夹。
  1. 总结
    在这里插入图片描述通过不到 80 行代码,我们实现了一个具有基本推理能力的 Agent。它不仅能听懂“整理”这个模糊指令,还能自动将其拆解为“先查看文件”、“再逐个移动”的具体步骤。这正是 Agent 开发的魅力所在:通过定义边界清晰的工具,赋予 LLM 改变现实世界的能力。

关于木卫四科技

公司:专注智能网联汽车和智能化设备安全,推动行业从「安全」到「安心」
领域:网络安全 / 功能安全 / AI安全/机器人安全/具身智能/低空飞行器
底座:自主可控 + 数据与AI驱动+蝴蝶大模型+安全智能体群
产品:VSOC / VTI / TARA 合规智能体 / 用车安心Agent / 维修助手Agent

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐