从零手写一个 AI Agent:原理、流程和 Python 源码全讲透
AI Agent 新手入门指南|附源码
近年来,AI Agent(智能体)成为人工智能领域最热门的方向之一。相比只能“回答问题”的传统大模型应用,AI Agent 更像一个能够理解目标、拆解任务、调用工具、执行动作并根据结果继续调整策略的“智能助手”。本文将从零开始介绍 AI Agent 的核心概念、工作原理、典型架构,并提供一个可运行的 Python 示例源码,帮助新手快速入门。
一、什么是 AI Agent?
AI Agent 可以理解为一种具备“自主执行能力”的人工智能程序。它不仅能够像 ChatGPT 一样进行自然语言对话,还可以根据用户给出的目标,主动思考下一步应该做什么,并调用外部工具完成任务。
举个简单例子:
如果你问普通大模型:
“帮我查一下今天北京天气,并告诉我是否适合跑步。”
普通大模型如果没有联网能力,可能只能根据已有知识进行泛泛回答。
但一个 AI Agent 可以这样工作:
- 理解你的需求:查询北京今天的天气,并判断是否适合跑步;
- 调用天气查询工具;
- 获取实时天气数据;
- 根据温度、空气质量、降雨概率等信息进行分析;
- 给出建议,例如“今天气温适宜,但空气质量较差,不建议户外跑步”。
这就是 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 可能会拆解为:
- 查询新能源汽车行业现状;
- 查找主要企业和市场份额;
- 分析政策环境;
- 总结行业趋势;
- 生成结构化报告;
- 检查内容是否完整。
这类能力通常依赖 Prompt 设计、任务规划算法或专门的 Agent 框架。
4. 记忆机制:上下文管理
AI Agent 需要记住过去发生的事情,否则它就无法完成连续任务。
记忆通常分为两种:
短期记忆
短期记忆就是当前对话上下文。例如用户刚刚说过自己的名字、偏好、任务要求等。
长期记忆
长期记忆用于保存跨会话的信息,例如:
- 用户喜欢简洁风格;
- 用户常用 Python;
- 用户所在城市是上海;
- 某个项目的长期背景资料。
长期记忆通常可以借助数据库、向量数据库或文件系统实现。
5. 反馈循环:观察与调整
Agent 的典型执行过程可以概括为:
目标 -> 思考 -> 行动 -> 观察 -> 再思考 -> 再行动 -> 最终回答
例如:
- 用户要求查询天气;
- Agent 调用天气工具;
- 工具返回“查询失败”;
- Agent 判断可能是城市名称不明确;
- Agent 询问用户具体城市;
- 用户补充信息;
- Agent 再次调用工具;
- 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 方法中:
- 先让模型做决策;
- 如果模型决定直接回答,就返回答案;
- 如果模型决定调用工具,就查找对应工具;
- 执行工具;
- 将工具结果交给模型生成最终回复。
这就是一个最小可用 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 应用浪潮。