简单易懂的 AI Agent 框架解析:让你五分钟看懂复杂代码
作为一个新手,你可能会觉得复杂的代码就像外星语一样难以理解。别担心!今天我就带你一步一步地了解一个叫”Agent”的人工智能助手是如何工作的。我们不会讲太多复杂的理论,而是像剥洋葱一样,一层一层地揭开它的神秘面纱。
什么是 AI Agent?
简单来说,AI Agent 就像是一个智能小助手,它能听懂你说的话,想一想该怎么做,然后真的去执行一些任务。就像你告诉 Siri “帮我设个闹钟”,它就会思考怎么设置闹钟,然后真的帮你设置了。
在这个项目里,我们创建了一个叫 ReActAgent 的 AI 助手,它遵循一种叫 ReAct 的工作模式:
- 思考(Thought)- 先想想应该做什么
- 行动(Action)- 然后做点什么
- 观察(Observation)- 看看做了之后有什么结果
- 重复上面三个步骤,直到解决问题
整体架构一览
我们的 AI Agent 项目由几个核心部分组成:
- 主控制器(agent.py)- 控制整个流程的核心大脑
- 提示模板(prompt_template.py)- 告诉 AI 如何按照规定格式交流
- 配置文件(pyproject.toml)- 记录项目依赖关系
- 使用说明(README.md)- 告诉别人怎么用这个项目
接下来,我会带你深入了解每一部分的细节。
深入 agent.py - AI 助手的大脑
让我们从最重要的 agent.py 文件开始。你可以把它想象成 AI 助手的大脑,控制着整个思考和行动的过程。
核心类:ReActAgent
1 2 3 4 5 6 7 8 9
| class ReActAgent: def __init__(self, tools: List[Callable], model: str, project_directory: str): self.tools = { func.__name__: func for func in tools } self.model = model self.project_directory = project_directory self.client = OpenAI( base_url="https://openrouter.ai/api/v1", api_key=ReActAgent.get_api_key(), )
|
这段代码定义了我们的 AI 助手类。构造函数(init)接受三个参数:
- tools: 可用的工具列表(比如读文件、写文件、执行命令)
- model: 使用的 AI 模型名称
- project_directory: 项目所在的目录
这里还初始化了一个 OpenAI 客户端,用来和 AI 模型通信。
主循环:run 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| def run(self, user_input: str): messages = [ {"role": "system", "content": self.render_system_prompt(react_system_prompt_template)}, {"role": "user", "content": f"<question>{user_input}</question>"} ]
while True: content = self.call_model(messages)
if "<final_answer>" in content: final_answer = re.search(r"<final_answer>(.*?)</final_answer>", content, re.DOTALL) return final_answer.group(1)
action_match = re.search(r"<action>(.*?)</action>", content, re.DOTALL) tool_name, args = self.parse_action(action) observation = self.tools[tool_name](*args) messages.append({"role": "user", "content": f"<observation>{observation}</observation>"})
|
这是整个 AI 助手最核心的部分。它的工作流程是这样的:
- 准备初始消息:包括系统指令和用户问题
- 进入一个无限循环,直到得到最终答案:
- 调用 AI 模型获取响应
- 如果是最终答案就返回
- 如果是动作指令就执行相应的工具
- 把执行结果告诉 AI 模型,继续下一轮
工具系统
AI 助手的强大之处在于它可以使用工具。目前有三个内置工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def read_file(file_path): """读取文件内容""" with open(file_path, "r", encoding="utf-8") as f: return f.read()
def write_to_file(file_path, content): """将内容写入文件""" with open(file_path, "w", encoding="utf-8") as f: f.write(content.replace("\\n", "\n")) return "写入成功"
def run_terminal_command(command): """执行终端命令""" import subprocess run_result = subprocess.run(command, shell=True, capture_output=True, text=True) return "执行成功" if run_result.returncode == 0 else run_result.stderr
|
这些工具让 AI 助手可以真正地”做事”,而不仅仅是聊天:
- 读取任何文件的内容
- 创建或修改文件
- 执行电脑上的命令
深入 prompt_template.py - AI 的行为准则
prompt_template.py 文件定义了 AI 应该如何表现和沟通。我们可以把它想象成教 AI 如何说话的”教材”。
ReAct 框架模板
1 2 3 4 5 6 7 8 9
| react_system_prompt_template = """ 你需要解决一个问题。为此,你需要将问题分解为多个步骤。对于每个步骤,首先使用 <thought> 思考要做什么,然后使用可用工具之一决定一个 <action>。接着,你将根据你的行动从环境/工具中收到一个 <observation>。持续这个思考和行动的过程,直到你有足够的信息来提供 <final_answer>。
所有步骤请严格使用以下 XML 标签格式输出: - <question> 用户问题 - <thought> 思考 - <action> 采取的工具操作 - <observation> 工具或环境返回的结果 - <final_answer> 最终答案
|
这部分告诉 AI 必须按照特定的格式来交流。就像我们说话要有主谓宾一样,AI 的每句话都要放在对应的”标签”里:
<thought>: AI 在想什么
<action>: AI 要做什么
<observation>: AI 看到了什么结果
<final_answer>: AI 的最终答案
举例说明
模板中包含了两个具体的例子帮助 AI 理解应该如何工作:
1 2 3 4 5 6 7
| 例子 1: <question>埃菲尔铁塔有多高?</question> <thought>我需要找到埃菲尔铁塔的高度。可以使用搜索工具。</thought> <action>get_height("埃菲尔铁塔")</action> <observation>埃菲尔铁塔的高度约为330米(包含天线)。</observation> <thought>搜索结果显示了高度。我已经得到答案了。</thought> <final_answer>埃菲尔铁塔的高度约为330米。</final_answer>
|
通过这种方式,AI 学会了如何一步步解决问题,而不是直接给出答案。
工具列表注入
模板还有一个重要的特性,就是它会在运行时插入实际可用的工具列表:
这样 AI 就知道它能使用哪些工具了。
配置文件和其他辅助部分
除了主要的代码文件,还有一些配置和辅助文件也很重要。
pyproject.toml - 项目依赖管理
1 2 3 4 5 6 7 8 9 10
| [project] name = "agent" version = "0.1.0" description = "Add your description here" requires-python = ">=3.12" dependencies = [ "click>=8.2.1", "openai>=1.91.0", "python-dotenv>=1.1.1", ]
|
这个文件告诉我们项目需要哪些依赖:
click: 用于创建命令行界面
openai: 用于与 AI 模型通信
python-dotenv: 用于加载环境变量
README.md - 使用说明
1 2 3 4 5 6 7 8 9 10 11 12
| # 运行方法
首先请确保你已经安装了 uv,如果没有的话,请按以下页面的要求安装: https://docs.astral.sh/uv/guides/install-python/
然后在当前目录下,新建一个叫做 .env 的文件,输入以下内容: OPENROUTER_API_KEY=xxx
xxx 就是你在 OpenRouter 上配好的 API Key。
确保 uv 已经安装成功后,进入到当前文件所在目录,然后执行以下命令即可启动: uv run agent.py snake
|
这个文件告诉使用者如何安装和运行这个 AI 助手。
命令行接口
最后,agent.py 文件末尾还定义了命令行接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @click.command() @click.argument('project_directory', type=click.Path(exists=True, file_okay=False, dir_okay=True)) def main(project_directory): project_dir = os.path.abspath(project_directory)
tools = [read_file, write_to_file, run_terminal_command] agent = ReActAgent(tools=tools, model="openai/gpt-4o", project_directory=project_dir)
task = input("请输入任务:")
final_answer = agent.run(task)
print(f"\n\n✅ Final Answer:{final_answer}")
if __name__ == "__main__": main()
|
这一部分让用户可以通过命令行来启动 AI 助手,并指定要处理的项目目录。
总结
通过以上分析,我们可以看到这个 AI Agent 项目的整体工作原理:
- 初始化阶段:创建 ReActAgent 实例,配置好 AI 模型和可用工具
- 准备阶段:构建系统提示,告诉 AI 它的任务和沟通格式
- 执行阶段:进入主循环,不断与 AI 交互直到得到最终答案
- 交互流程:AI 思考 → AI 行动 → 执行工具 → 返回结果 → 继续循环
整个系统的设计非常巧妙,它将复杂的 AI 交互过程标准化,使得 AI 可以像人一样通过”思考-行动-观察”的循环来解决问题。
最重要的是理解这个框架的核心思想:不是让 AI 一次性解决所有问题,而是让它一步步地思考和行动,在每一步都验证结果,最终达成目标。
这种设计思路其实很像我们人类学习新技能的过程——先思考要做什么,然后动手尝试,观察结果,再调整策略,如此反复直到掌握。
希望这篇博客能帮助你更好地理解 AI Agent 的工作机制!