从零搭建一个AI Agent:Python实战指南

2026年最火的概念之一就是AI Agent------让大模型不再只是聊天机器人,而是能自主规划、调用工具、完成复杂任务的智能体。本文用纯Python从零实现一个可用的Agent,不依赖任何框架。

Agent的核心循环

Agent的本质就一个循环:思考→行动→观察→再思考。

复制代码
用户输入 → LLM推理 → 决定是否调用工具 → 执行工具 → 观察结果 → 继续推理 → 输出

最小实现

python 复制代码
import json
from openai import OpenAI

client = OpenAI()  # 确保API key已配置

# 定义工具
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"}
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "执行数学计算",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {"type": "string", "description": "数学表达式"}
                },
                "required": ["expression"]
            }
        }
    }
]

# 工具实现
def get_weather(city: str) -> str:
    # 实际项目中接入天气API
    return f"{city}今天晴,气温22°C"

def calculate(expression: str) -> str:
    try:
        result = eval(expression)  # 生产环境请用安全解析器
        return str(result)
    except Exception as e:
        return f"计算错误: {e}"

TOOL_MAP = {
    "get_weather": get_weather,
    "calculate": calculate,
}

def run_agent(user_input: str, max_steps: int = 5) -> str:
    messages = [{"role": "user", "content": user_input}]

    for step in range(max_steps):
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )

        msg = response.choices[0].message
        messages.append(msg)

        # 没有工具调用,直接返回结果
        if not msg.tool_calls:
            return msg.content

        # 执行工具调用
        for tool_call in msg.tool_calls:
            fn_name = tool_call.function.name
            fn_args = json.loads(tool_call.function.arguments)

            print(f"  🔧 调用工具: {fn_name}({fn_args})")
            result = TOOL_MAP[fn_name](**fn_args)

            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": result
            })

    return "达到最大步数限制"

实际运行

python 复制代码
# 简单查询
print(run_agent("北京天气怎么样?"))
# 🔧 调用工具: get_weather({'city': '北京'})
# 北京今天晴,气温22°C

# 多步推理
print(run_agent("北京和上海哪个更暖和?"))
# 🔧 调用工具: get_weather({'city': '北京'})
# 🔧 调用工具: get_weather({'city': '上海'})
# 根据查询结果,上海今天25°C,北京22°C,上海更暖和

加上记忆系统

单轮Agent只是开始。真正的Agent需要跨对话记住信息:

python 复制代码
import sqlite3

class AgentMemory:
    def __init__(self, db_path: str = "agent_memory.db"):
        self.conn = sqlite3.connect(db_path)
        self.conn.execute("""
            CREATE TABLE IF NOT EXISTS memories (
                id INTEGER PRIMARY KEY,
                key TEXT UNIQUE,
                value TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        self.conn.commit()

    def save(self, key: str, value: str):
        self.conn.execute(
            "INSERT OR REPLACE INTO memories (key, value) VALUES (?, ?)",
            (key, value)
        )
        self.conn.commit()

    def recall(self, key: str) -> str | None:
        row = self.conn.execute(
            "SELECT value FROM memories WHERE key = ?", (key,)
        ).fetchone()
        return row[0] if row else None

    def list_all(self) -> list[dict]:
        rows = self.conn.execute(
            "SELECT key, value FROM memories ORDER BY created_at DESC LIMIT 20"
        ).fetchall()
        return [{"key": r[0], "value": r[1]} for r in rows]

把记忆工具加入Agent的tools列表,Agent就能自主决定什么时候存取信息了。

关键设计原则

  1. 工具描述要精确------LLM根据description决定何时调用,描述模糊会导致错误调用
  2. 限制最大步数------防止死循环,5-10步足够大多数任务
  3. 错误处理要优雅------工具失败时返回有意义的错误信息,而不是抛异常
  4. 用streaming提升体验------长推理过程让用户看到中间输出

与框架对比

方案 灵活性 学习成本 适合场景
纯Python(本文) 最高 定制化Agent
LangChain Agent 中等 标准化工作流
CrewAI 较低 中等 多Agent协作
Dify 最低 零代码搭建

先用纯Python搞懂原理,再用框架提效,这是最稳的学习路径。

相关推荐
BingoGo4 小时前
PHP clone 之后,为什么改副本会影响原对象?
后端·php
JaguarJack5 小时前
PHP clone 之后,为什么改副本会影响原对象?
后端·php·服务端
小灰灰搞电子5 小时前
Rust+Slint 实现动态消息提示框源码分享
开发语言·后端·rust
小奏技术5 小时前
10 MB 的 Postman 替代品,启动不到 1 秒
后端
东风破_5 小时前
Text2SQL :用自然语言操作 SQLite 数据库
人工智能·后端
IT_陈寒10 小时前
Python的多线程就是个假把式,我算是体验到了
前端·人工智能·后端
码事漫谈10 小时前
如果 AI 要圈养人类,它可能不需要笼子
后端
newerp10 小时前
Golang 调度循环:Go runtime 如何永不停歇地找人干活
后端·程序员·go
明月_清风11 小时前
AI 时代,为什么架构师又开始谈"本体论"?
人工智能·后端·agent