第33讲|构建 AI 编程 Agent:让工具自主完成复杂任务

3 阅读1分钟

金句:Copilot 是一个会开车的副驾驶,Agent 是一个能自己开车去目的地的司机——你只需要告诉它"去机场",而不是每一个路口怎么转弯。


一、什么是 AI Agent?

AI Agent(智能体) 是能够感知环境、自主决策、使用工具完成目标的 AI 系统。

普通 AI 调用:
用户输入 → LLM → 文本输出

AI Agent:
目标输入 → [规划 → 选择工具 → 执行 → 观察结果 → 调整计划] → 目标达成
               ↑__________________________________|
                    持续循环直到目标完成

核心要素

  • 目标:要完成什么
  • 工具(Tools):可以调用的能力(搜索、代码执行、文件操作)
  • 记忆(Memory):当前任务的上下文
  • 规划能力:如何分解目标、使用工具

二、构建代码调试 Agent

需求

一个能自动调试代码的 Agent:

  1. 运行代码,获取报错信息
  2. 分析报错原因
  3. 修改代码
  4. 再次运行,验证修复
  5. 循环直到通过

实现

# code_debug_agent.py
import subprocess
import tempfile
import os
from anthropic import Anthropic

client = Anthropic()

# 工具定义
tools = [
    {
        "name": "run_python_code",
        "description": "运行 Python 代码并返回输出或错误信息",
        "input_schema": {
            "type": "object",
            "properties": {
                "code": {
                    "type": "string",
                    "description": "要运行的 Python 代码"
                }
            },
            "required": ["code"]
        }
    },
    {
        "name": "read_file",
        "description": "读取文件内容",
        "input_schema": {
            "type": "object",
            "properties": {
                "filepath": {
                    "type": "string",
                    "description": "文件路径"
                }
            },
            "required": ["filepath"]
        }
    },
    {
        "name": "write_file",
        "description": "写入文件内容",
        "input_schema": {
            "type": "object",
            "properties": {
                "filepath": {"type": "string"},
                "content": {"type": "string"}
            },
            "required": ["filepath", "content"]
        }
    }
]

def run_python_code(code: str) -> str:
    """执行 Python 代码,返回输出或错误"""
    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
        f.write(code)
        temp_file = f.name
    
    try:
        result = subprocess.run(
            ["python", temp_file],
            capture_output=True,
            text=True,
            timeout=30
        )
        if result.returncode == 0:
            return f"✅ 执行成功\n输出:\n{result.stdout}"
        else:
            return f"❌ 执行失败\n错误:\n{result.stderr}"
    except subprocess.TimeoutExpired:
        return "❌ 超时(30秒)"
    finally:
        os.unlink(temp_file)

def process_tool_call(tool_name: str, tool_input: dict) -> str:
    """处理工具调用"""
    if tool_name == "run_python_code":
        return run_python_code(tool_input["code"])
    elif tool_name == "read_file":
        with open(tool_input["filepath"], 'r') as f:
            return f.read()
    elif tool_name == "write_file":
        with open(tool_input["filepath"], 'w') as f:
            f.write(tool_input["content"])
        return f"✅ 文件已写入:{tool_input['filepath']}"
    return "未知工具"

def debug_agent(buggy_code: str, max_iterations: int = 5) -> str:
    """自动调试代码的 Agent"""
    
    system_prompt = """你是一个代码调试专家。
你的任务是通过运行代码、分析错误、修改代码来修复代码中的 Bug。

工作流程:
1. 先运行原始代码,查看错误
2. 分析错误原因
3. 修改代码
4. 再次运行验证
5. 重复直到代码正确运行

每次修改代码后,必须重新运行验证是否修复。
最多尝试 5 次。"""
    
    messages = [
        {
            "role": "user",
            "content": f"请帮我调试以下代码,找出并修复所有 Bug:\n\n```python\n{buggy_code}\n```"
        }
    ]
    
    iteration = 0
    
    while iteration < max_iterations:
        iteration += 1
        print(f"\n{'='*50}")
        print(f"调试迭代 #{iteration}")
        
        response = client.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=4096,
            system=system_prompt,
            tools=tools,
            messages=messages
        )
        
        # 检查是否完成
        if response.stop_reason == "end_turn":
            print("✅ Agent 认为任务完成")
            # 提取最终答案
            for block in response.content:
                if hasattr(block, 'text'):
                    return block.text
            break
        
        # 处理工具调用
        if response.stop_reason == "tool_use":
            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"   参数:{block.input}")
                    
                    result = process_tool_call(block.name, block.input)
                    print(f"   结果:{result[:200]}...")  # 截断显示
                    
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": result
                    })
            
            messages.append({"role": "user", "content": tool_results})
    
    return "调试完成"

# 使用示例
buggy_code = """
def calculate_average(numbers):
    total = 0
    for num in numbers:
        total = total + num
    return total / len(numbers)

# 测试
print(calculate_average([1, 2, 3, 4, 5]))
print(calculate_average([]))  # 这行会出错
print(calculate_average("hello"))  # 这行也会出错
"""

result = debug_agent(buggy_code)
print(f"\n最终结果:\n{result}")

三、Agent 的高级模式

ReAct 模式(Reason + Act)

思考:我需要找出代码中的问题
行动:运行代码
观察:出现了 ZeroDivisionError
思考:需要添加空列表检查
行动:修改代码,添加 if not numbers: return None
观察:执行成功
思考:还有类型检查问题
行动:添加类型验证
观察:所有测试通过
结束

Reflection 模式(反思)

Agent 完成任务后,评估自己的输出质量,如果不满意则重做:

def reflection_agent(task: str) -> str:
    # 第一轮:完成任务
    initial_output = generate_code(task)
    
    # 反思:评估输出质量
    reflection = evaluate_output(initial_output, criteria=[
        "代码是否可以运行?",
        "是否有安全漏洞?",
        "是否符合最佳实践?",
        "是否有测试用例?"
    ])
    
    if reflection["needs_improvement"]:
        # 根据反思结果改进
        improved_output = improve_code(initial_output, reflection["issues"])
        return improved_output
    
    return initial_output

四、Agent 的限制与安全边界

# 安全的 Agent 配置
SAFE_AGENT_CONFIG = {
    # 允许的操作
    "allowed_actions": [
        "read_file",      # 读取文件
        "run_python",     # 运行 Python(沙箱中)
        "search_web",     # 网络搜索
        "query_database", # 数据库查询(只读)
    ],
    
    # 禁止的操作
    "forbidden_actions": [
        "delete_file",    # 禁止删除文件
        "modify_system",  # 禁止修改系统配置
        "send_email",     # 禁止发送邮件(需人工确认)
        "execute_shell",  # 禁止执行任意 shell 命令
    ],
    
    # 需要确认的操作
    "require_confirmation": [
        "write_file",     # 写文件需要确认
        "api_call",       # 外部 API 调用需要确认
    ],
    
    # 资源限制
    "max_iterations": 10,
    "timeout_seconds": 120,
    "max_cost_usd": 1.0,  # 单次任务最大 API 费用
}

章节小结:AI Agent 是 Vibe Coding 的终极形态——你描述目标,Agent 自主完成。构建一个 Agent 需要:定义工具集、设计 Agent 循环、处理工具调用结果、设置安全边界。从代码调试 Agent 开始,逐步扩展到测试生成、文档更新、自动化发布,让 AI 真正帮你"干活"而不只是"出主意"。