上一篇 下一篇 分享链接 返回 返回顶部

从零手写一个 AI Agent:原理、流程和 Python 源码全讲透

发布人:慈云数据-客服中心 发布时间:23小时前 阅读量:4

AI Agent 新手入门指南|附源码

近年来,AI Agent(智能体)成为人工智能领域最热门的方向之一。相比只能“回答问题”的传统大模型应用,AI Agent 更像一个能够理解目标、拆解任务、调用工具、执行动作并根据结果继续调整策略的“智能助手”。本文将从零开始介绍 AI Agent 的核心概念、工作原理、典型架构,并提供一个可运行的 Python 示例源码,帮助新手快速入门。


一、什么是 AI Agent?

AI Agent 可以理解为一种具备“自主执行能力”的人工智能程序。它不仅能够像 ChatGPT 一样进行自然语言对话,还可以根据用户给出的目标,主动思考下一步应该做什么,并调用外部工具完成任务。

举个简单例子:

如果你问普通大模型:

“帮我查一下今天北京天气,并告诉我是否适合跑步。”

普通大模型如果没有联网能力,可能只能根据已有知识进行泛泛回答。

但一个 AI Agent 可以这样工作:

  1. 理解你的需求:查询北京今天的天气,并判断是否适合跑步;
  2. 调用天气查询工具;
  3. 获取实时天气数据;
  4. 根据温度、空气质量、降雨概率等信息进行分析;
  5. 给出建议,例如“今天气温适宜,但空气质量较差,不建议户外跑步”。

这就是 AI Agent 与普通聊天机器人的区别:
AI Agent 不只是生成文本,而是能围绕目标进行推理、决策和行动。


二、为什么 AI Agent 很重要?

大语言模型本身已经非常强大,但它仍然存在一些限制:

  • 无法直接获取实时信息;
  • 无法直接操作文件、数据库、浏览器等外部系统;
  • 对复杂任务缺乏持续规划能力;
  • 容易在长任务中丢失上下文;
  • 不能真正“执行”现实世界中的动作。

AI Agent 的出现,正是为了解决这些问题。它通过工具调用、任务规划、记忆机制和反馈循环,让大模型从“会说”进一步变成“会做”。

常见应用场景包括:

场景 示例
智能客服 自动查询订单、处理退款、生成回复
数据分析 自动读取表格、生成统计报告、绘制图表
编程助手 根据需求编写代码、运行测试、修复 Bug
办公自动化 自动整理会议纪要、生成邮件、安排日程
搜索研究 联网检索资料、总结观点、输出报告
个人助理 规划旅行、管理待办事项、提醒日程

可以说,AI Agent 是大模型从“聊天工具”走向“生产力工具”的关键一步。


三、AI Agent 的核心组成

一个基础的 AI Agent 通常由以下几个部分组成。

1. 大语言模型:大脑

大语言模型是 AI Agent 的核心,负责理解语言、推理、生成计划和判断下一步动作。

常见模型包括:

  • GPT 系列;
  • Claude;
  • Gemini;
  • Llama;
  • Qwen;
  • DeepSeek;
  • GLM。

在 Agent 系统中,大模型通常承担以下职责:

  • 理解用户目标;
  • 判断是否需要调用工具;
  • 生成工具调用参数;
  • 根据工具返回结果继续推理;
  • 最终生成自然语言回复。

2. 工具:手和脚

工具是 AI Agent 与外部世界交互的方式。

工具可以是:

  • 搜索引擎;
  • 天气 API;
  • 数据库查询函数;
  • Python 代码执行器;
  • 文件读写接口;
  • 邮件发送服务;
  • 日历管理接口;
  • 浏览器自动化工具。

例如,一个计算器工具可以这样定义:

def calculator(expression: str) -> str:
    return str(eval(expression))

当用户问:

“帮我计算 128 * 36 + 952”

Agent 可以判断自己应该调用计算器工具,而不是仅凭模型猜测答案。


3. 规划能力:任务拆解

复杂任务往往不能一步完成,需要拆解成多个子任务。

例如用户提出:

“帮我写一份关于新能源汽车行业的分析报告。”

一个成熟的 Agent 可能会拆解为:

  1. 查询新能源汽车行业现状;
  2. 查找主要企业和市场份额;
  3. 分析政策环境;
  4. 总结行业趋势;
  5. 生成结构化报告;
  6. 检查内容是否完整。

这类能力通常依赖 Prompt 设计、任务规划算法或专门的 Agent 框架。


4. 记忆机制:上下文管理

AI Agent 需要记住过去发生的事情,否则它就无法完成连续任务。

记忆通常分为两种:

短期记忆

短期记忆就是当前对话上下文。例如用户刚刚说过自己的名字、偏好、任务要求等。

长期记忆

长期记忆用于保存跨会话的信息,例如:

  • 用户喜欢简洁风格;
  • 用户常用 Python;
  • 用户所在城市是上海;
  • 某个项目的长期背景资料。

长期记忆通常可以借助数据库、向量数据库或文件系统实现。


5. 反馈循环:观察与调整

Agent 的典型执行过程可以概括为:

目标 -> 思考 -> 行动 -> 观察 -> 再思考 -> 再行动 -> 最终回答

例如:

  1. 用户要求查询天气;
  2. Agent 调用天气工具;
  3. 工具返回“查询失败”;
  4. Agent 判断可能是城市名称不明确;
  5. Agent 询问用户具体城市;
  6. 用户补充信息;
  7. Agent 再次调用工具;
  8. Agent 给出最终建议。

这种循环使 Agent 具备了一定的自主性和容错能力。


四、AI Agent 的基本工作流程

一个简单 Agent 的运行流程如下:

用户输入
   ↓
大模型理解任务
   ↓
判断是否需要工具
   ↓
如果需要:生成工具名称和参数
   ↓
执行工具
   ↓
将工具结果返回给大模型
   ↓
大模型生成最终答案

如果是更高级的 Agent,则可能包含多轮工具调用和多阶段规划。

例如:

用户目标
   ↓
制定计划
   ↓
执行步骤 1
   ↓
观察结果
   ↓
执行步骤 2
   ↓
观察结果
   ↓
检查是否完成目标
   ↓
输出最终结果

五、新手应该如何学习 AI Agent?

对于刚接触 AI Agent 的开发者,建议按照以下路径学习。

第一步:掌握大模型基础

你需要了解:

  • Prompt 是什么;
  • System Prompt、User Prompt、Assistant Message 的区别;
  • Temperature、Top-p、Max Tokens 等参数;
  • 上下文长度限制;
  • 模型幻觉问题;
  • 结构化输出。

如果你不了解大模型的基本用法,直接学习 Agent 容易感到混乱。


第二步:理解工具调用

工具调用是 AI Agent 的关键。
你需要学会如何把一个普通函数封装成工具,并让模型知道什么时候使用它。

例如:

def search_web(query: str) -> str:
    return f"搜索结果:关于 {query} 的资料"

对于模型来说,工具不是天然存在的。开发者必须告诉模型:

  • 有哪些工具;
  • 每个工具能做什么;
  • 工具需要哪些参数;
  • 什么时候应该调用工具;
  • 工具返回结果后如何继续处理。

第三步:学习 Agent 循环

不要一开始就追求复杂框架。
先手写一个最简单的 Agent 循环,你会更容易理解 Agent 的本质。

核心逻辑就是:

模型决定动作 -> 执行动作 -> 把结果告诉模型 -> 模型继续决定

第四步:再学习框架

等你理解基本原理后,可以学习成熟框架,例如:

  • LangChain;
  • LlamaIndex;
  • AutoGen;
  • CrewAI;
  • Semantic Kernel;
  • LangGraph。

这些框架可以帮助你快速构建复杂 Agent,但如果完全不了解底层原理,很容易陷入“只会调库,不懂机制”的状态。


六、从零实现一个简单 AI Agent

下面我们用 Python 实现一个非常简化版的 AI Agent。

它具备以下能力:

  • 接收用户输入;
  • 判断是否需要调用工具;
  • 支持计算器工具;
  • 支持天气查询工具;
  • 根据工具结果生成回复。

为了让代码更容易理解,示例中我们不直接调用真实大模型 API,而是用一个简化的规则模拟模型决策。
如果你后续接入 OpenAI、DeepSeek、Qwen 等 API,只需要替换 mock_llm 部分即可。


七、完整源码

1. 项目结构

simple-ai-agent/
├── agent.py
└── README.md

2. agent.py

import json
import re
from typing import Callable, Dict, Any


class Tool:
    """
    工具类:用于描述一个 Agent 可以调用的外部能力
    """

    def __init__(self, name: str, description: str, func: Callable[[Dict[str, Any]], str]):
        self.name = name
        self.description = description
        self.func = func

    def run(self, arguments: Dict[str, Any]) -> str:
        return self.func(arguments)


def calculator_tool(arguments: Dict[str, Any]) -> str:
    """
    计算器工具
    参数示例:
    {
        "expression": "128 * 36 + 952"
    }
    """
    expression = arguments.get("expression", "")

    # 安全限制:只允许数字、运算符、小数点、括号和空格
    if not re.match(r"^[0-9+\-*/().\s]+$", expression):
        return "计算表达式包含非法字符,无法计算。"

    try:
        result = eval(expression, {"__builtins__": {}})
        return f"计算结果是:{result}"
    except Exception as e:
        return f"计算失败:{str(e)}"


def weather_tool(arguments: Dict[str, Any]) -> str:
    """
    天气查询工具
    注意:这里为了演示使用模拟数据。
    实际项目中可以接入真实天气 API。
    """
    city = arguments.get("city", "")

    mock_weather = {
        "北京": "北京今天晴,气温 18-27℃,空气质量良好,适合户外运动。",
        "上海": "上海今天多云,气温 22-29℃,湿度较高,外出建议带伞。",
        "深圳": "深圳今天有阵雨,气温 24-30℃,不太适合长时间户外活动。",
        "杭州": "杭州今天阴,气温 20-26℃,体感舒适,适合散步。"
    }

    return mock_weather.get(city, f"暂时没有查询到 {city} 的天气信息。")


class SimpleLLM:
    """
    一个模拟大模型的类。
    在真实项目中,你可以把这里替换为大模型 API 调用。
    """

    def decide(self, user_input: str) -> Dict[str, Any]:
        """
        根据用户输入决定:
        1. 是否调用工具;
        2. 调用哪个工具;
        3. 使用什么参数。
        """

        # 判断是否是计算类问题
        if any(op in user_input for op in ["+", "-", "*", "/", "计算"]):
            expression = self.extract_expression(user_input)
            return {
                "type": "tool_call",
                "tool_name": "calculator",
                "arguments": {
                    "expression": expression
                }
            }

        # 判断是否是天气类问题
        if "天气" in user_input:
            city = self.extract_city(user_input)
            return {
                "type": "tool_call",
                "tool_name": "weather",
                "arguments": {
                    "city": city
                }
            }

        # 默认直接回答
        return {
            "type": "final_answer",
            "content": "我暂时无法调用合适的工具,但我可以和你继续讨论这个问题。"
        }

    def respond(self, user_input: str, tool_result: str) -> str:
        """
        根据工具返回结果生成最终回答。
        真实项目中,这一步通常由大模型完成。
        """
        return f"根据你的问题:{user_input}\n我调用工具得到结果:{tool_result}"

    @staticmethod
    def extract_expression(text: str) -> str:
        """
        从文本中提取数学表达式
        """
        match = re.findall(r"[0-9+\-*/().\s]+", text)
        if match:
            return max(match, key=len).strip()
        return ""

    @staticmethod
    def extract_city(text: str) -> str:
        """
        从文本中提取城市名称
        这里使用非常简化的规则
        """
        cities = ["北京", "上海", "深圳", "杭州"]
        for city in cities:
            if city in text:
                return city
        return ""


class Agent:
    """
    简单 AI Agent
    """

    def __init__(self, llm: SimpleLLM):
        self.llm = llm
        self.tools: Dict[str, Tool] = {}

    def register_tool(self, tool: Tool):
        self.tools[tool.name] = tool

    def run(self, user_input: str) -> str:
        decision = self.llm.decide(user_input)

        if decision["type"] == "final_answer":
            return decision["content"]

        if decision["type"] == "tool_call":
            tool_name = decision["tool_name"]
            arguments = decision["arguments"]

            if tool_name not in self.tools:
                return f"工具 {tool_name} 未注册,无法执行。"

            tool = self.tools[tool_name]
            tool_result = tool.run(arguments)

            final_answer = self.llm.respond(user_input, tool_result)
            return final_answer

        return "无法理解模型决策。"


def main():
    llm = SimpleLLM()
    agent = Agent(llm)

    calculator = Tool(
        name="calculator",
        description="用于执行数学表达式计算",
        func=calculator_tool
    )

    weather = Tool(
        name="weather",
        description="用于查询城市天气",
        func=weather_tool
    )

    agent.register_tool(calculator)
    agent.register_tool(weather)

    print("Simple AI Agent 已启动,输入 exit 退出。")

    while True:
        user_input = input("\n用户:")

        if user_input.lower() in ["exit", "quit"]:
            print("Agent:再见!")
            break

        answer = agent.run(user_input)
        print(f"Agent:{answer}")


if __name__ == "__main__":
    main()

八、运行效果示例

启动程序:

python agent.py

输入:

用户:帮我计算 128 * 36 + 952

输出:

Agent:根据你的问题:帮我计算 128 * 36 + 952
我调用工具得到结果:计算结果是:5560

继续输入:

用户:北京今天天气怎么样,适合跑步吗?

输出:

Agent:根据你的问题:北京今天天气怎么样,适合跑步吗?
我调用工具得到结果:北京今天晴,气温 18-27℃,空气质量良好,适合户外运动。

九、代码讲解

1. Tool 类

Tool 类用于封装工具信息:

class Tool:
    def __init__(self, name, description, func):
        self.name = name
        self.description = description
        self.func = func

它包含三个核心字段:

  • name:工具名称;
  • description:工具描述;
  • func:真正执行工具逻辑的函数。

这样设计的好处是,Agent 不需要关心工具内部如何实现,只需要根据工具名调用即可。


2. calculator_tool

这是一个计算器工具。

def calculator_tool(arguments):
    expression = arguments.get("expression", "")

它从参数中取出表达式,然后执行计算。

不过需要注意,直接使用 eval 是有风险的。
所以示例中加入了正则限制:

if not re.match(r"^[0-9+\-*/().\s]+$", expression):
    return "计算表达式包含非法字符,无法计算。"

这可以避免用户输入危险代码,例如:

__import__("os").system("rm -rf /")

当然,在真实生产项目中,更推荐使用专门的表达式解析库,而不是直接使用 eval


3. weather_tool

天气工具使用了模拟数据:

mock_weather = {
    "北京": "北京今天晴,气温 18-27℃,空气质量良好,适合户外运动。",
    "上海": "上海今天多云,气温 22-29℃,湿度较高,外出建议带伞。"
}

在实际项目中,你可以替换为真实天气接口,例如:

  • 高德天气 API;
  • 和风天气 API;
  • OpenWeatherMap;
  • 自建气象数据服务。

4. SimpleLLM

SimpleLLM 模拟了大模型的决策过程。

它会根据用户输入判断是否需要调用工具:

if any(op in user_input for op in ["+", "-", "*", "/", "计算"]):
    ...

如果发现用户输入中包含计算符号或“计算”两个字,就调用计算器工具。

如果发现包含“天气”,就调用天气工具。

虽然这个逻辑很简单,但它已经体现了 Agent 的基本思想:

根据用户输入,决定下一步行动。

真实大模型会比这个规则系统复杂得多,它可以理解更自然、更模糊的表达。


5. Agent 类

Agent 类是整个程序的核心。

class Agent:
    def __init__(self, llm):
        self.llm = llm
        self.tools = {}

它包含:

  • 一个 LLM;
  • 一组可用工具;
  • 一个运行入口 run

run 方法中:

  1. 先让模型做决策;
  2. 如果模型决定直接回答,就返回答案;
  3. 如果模型决定调用工具,就查找对应工具;
  4. 执行工具;
  5. 将工具结果交给模型生成最终回复。

这就是一个最小可用 Agent 的基本流程。


十、接入真实大模型 API 的思路

上面的示例是为了教学而简化的。
如果要接入真实大模型,你可以把 SimpleLLM 替换成 API 调用。

以伪代码为例:

class RealLLM:
    def decide(self, user_input: str):
        messages = [
            {
                "role": "system",
                "content": """
你是一个 AI Agent。
你可以使用以下工具:
1. calculator:用于数学计算,参数为 expression
2. weather:用于查询天气,参数为 city

如果需要调用工具,请严格返回 JSON:
{
  "type": "tool_call",
  "tool_name": "...",
  "arguments": {...}
}

如果不需要调用工具,请返回:
{
  "type": "final_answer",
  "content": "..."
}
"""
            },
            {
                "role": "user",
                "content": user_input
            }
        ]

        response = call_llm_api(messages)
        return json.loads(response)

真实模型输出可能不是稳定 JSON,因此生产环境中通常还要增加:

  • JSON 修复;
  • 参数校验;
  • 异常处理;
  • 重试机制;
  • 日志记录;
  • 调用次数限制;
  • 权限控制。

十一、一个更真实的 Agent Prompt 示例

下面是一个可用于真实模型的 System Prompt 示例:

你是一个具备工具调用能力的 AI Agent。

你的目标是帮助用户完成任务,而不仅仅是聊天。

你可以使用以下工具:

1. calculator
描述:用于执行数学表达式计算。
参数:
{
  "expression": "字符串,合法数学表达式"
}

2. weather
描述:用于查询指定城市的天气。
参数:
{
  "city": "城市名称,例如北京、上海、深圳"
}

工作规则:
1. 如果用户问题需要实时天气信息,必须调用 weather 工具。
2. 如果用户问题需要精确数学计算,必须调用 calculator 工具。
3. 如果不需要工具,可以直接回答。
4. 工具调用必须使用严格 JSON 格式。
5. 不要编造工具结果。
6. 工具返回结果后,需要基于结果给出自然语言总结。

输出格式:
如果需要调用工具:
{
  "type": "tool_call",
  "tool_name": "工具名称",
  "arguments": {
    "参数名": "参数值"
  }
}

如果直接回答:
{
  "type": "final_answer",
  "content": "回答内容"
}

这个 Prompt 的重点是让模型明确:

  • 自己是什么角色;
  • 可以使用哪些工具;
  • 工具参数格式是什么;
  • 什么时候该调用工具;
  • 输出格式必须是什么。

十二、新手常见误区

1. 以为 Agent 越复杂越好

很多新手一上来就想做一个“全能 Agent”,既能写代码,又能联网搜索,还能发邮件、操作数据库、管理日程。

但 Agent 工程有一个重要原则:

能简单就不要复杂,能确定就不要让模型猜。

工具越多,模型越容易选错工具。任务越复杂,出错概率也越高。
新手最好从一个非常小的场景开始,比如“天气查询 Agent”或“Excel 数据分析 Agent”。


2. 过度依赖框架

LangChain、CrewAI 等框架非常强大,但如果你不了解 Agent 的底层循环,只会复制示例代码,遇到问题时很难排查。

建议学习顺序是:

先手写 Agent -> 再使用框架 -> 最后优化工程化能力

3. 忽视工具安全

如果 Agent 可以执行代码、访问文件、操作数据库,那么安全问题非常重要。

常见风险包括:

  • Prompt Injection;
  • 非授权数据访问;
  • 执行危险命令;
  • 泄露 API Key;
  • 删除重要文件;
  • 误发邮件或消息。

因此生产环境中必须加入:

  • 权限控制;
  • 参数白名单;
  • 审批机制;
  • 操作日志;
  • 沙箱环境;
  • 敏感操作二次确认。

4. 忽视错误处理

工具调用失败是很常见的,比如:

  • API 超时;
  • 参数错误;
  • 网络异常;
  • 返回数据为空;
  • JSON 格式错误;
  • 模型选择了不存在的工具。

如果没有错误处理,Agent 很容易直接崩溃。
一个可靠的 Agent 应该知道失败后如何恢复,例如重试、换工具、询问用户补充信息等。


十三、AI Agent 的进阶方向

当你掌握基础后,可以继续学习以下内容。

1. 多工具 Agent

让 Agent 同时具备搜索、计算、文件读写、数据库查询等能力。

2. 多轮规划 Agent

让 Agent 先制定计划,再按步骤执行任务。

3. Reflection 机制

让 Agent 在完成任务后自我检查:

  • 答案是否完整;
  • 是否遗漏用户要求;
  • 工具结果是否可信;
  • 是否需要重新执行某一步。

4. RAG 与 Agent 结合

RAG,即检索增强生成。
当 Agent 需要回答企业内部知识库问题时,可以先从文档库中检索资料,再基于资料生成回答。

5. 多 Agent 协作

多个 Agent 分工协作,例如:

  • 研究员 Agent 负责查资料;
  • 分析师 Agent 负责提炼观点;
  • 写作 Agent 负责生成文章;
  • 审稿 Agent 负责检查质量。

这类模式适合复杂任务,但成本和不确定性也更高。


十四、如何把示例扩展成真实项目?

你可以按照以下路线逐步升级:

阶段一:接入真实模型

SimpleLLM 替换为真实大模型 API。

阶段二:增加工具描述

把工具名称、功能、参数 Schema 写清楚,让模型更容易正确调用。

阶段三:支持多轮工具调用

当前示例只支持一次工具调用。
真实 Agent 往往需要多次调用工具,例如先搜索,再总结,再计算。

你可以增加循环:

for step in range(max_steps):
    decision = llm.decide(context)
    if decision["type"] == "tool_call":
        result = run_tool(...)
        context.append(result)
    else:
        return decision["content"]

阶段四:增加记忆系统

可以使用:

  • SQLite;
  • Redis;
  • PostgreSQL;
  • Milvus;
  • Chroma;
  • FAISS。

短期记忆用于保存当前会话,长期记忆用于保存用户偏好和历史任务。

阶段五:增加安全控制

对于高风险工具,例如发送邮件、删除文件、执行 Shell 命令,应加入人工确认:

Agent:我准备删除 temp 文件夹下的 20 个文件,是否确认?
用户:确认
Agent:已执行删除操作。

十五、总结

AI Agent 的本质并不神秘。
它可以简单理解为:

大语言模型 + 工具调用 + 任务规划 + 记忆机制 + 反馈循环。

对于新手来说,学习 AI Agent 最重要的不是一开始就掌握复杂框架,而是理解它的基本运行逻辑:

理解目标 -> 决定行动 -> 调用工具 -> 观察结果 -> 继续推理 -> 输出答案

本文提供的示例虽然简单,但已经包含了 AI Agent 的核心思想:

  • 工具注册;
  • 工具选择;
  • 参数提取;
  • 工具执行;
  • 结果整合;
  • 最终回复。

如果你能把这个最小示例跑通,并尝试接入真实大模型 API,你就已经迈出了学习 AI Agent 的第一步。

未来,AI Agent 很可能成为软件开发、数据分析、办公自动化、企业服务和个人助理领域的重要基础设施。对于开发者而言,越早理解它的原理和工程实现方式,就越容易抓住下一波 AI 应用浪潮。

目录结构
全文