从零搭建智能体:150行Python代码实现Agent核心机制
作者:菠萝爱吃肉2026.11.07 01:41浏览量:0简介:本文从理论到实践,深入剖析AI Agent的四大核心组件:LLM大脑、规划能力、记忆系统与工具调用。通过一个仅150行Python代码的完整示例,展示如何利用函数调用机制让大模型连接真实世界,实现文件读写、代码执行等自主操作。文章将揭示提示词工程在工具描述中的关键作用,并给出通用的Agent架构设计思路,助你快速构建自己的AI智能体应用。
引言:从被动问答到主动执行
我们正站在软件开发范式转移的临界点。传统的软件工程(我们可称之为Software 2.0)强调“如何实现”——开发者需要精确编写每一行逻辑,定义每一个分支。而大语言模型(LLM)的崛起,开启了Software 3.0的序幕:开发者的核心任务从“编码实现”转变为“定义目标与约束”。
在这个新范式下,AI Agent成为第一个真正意义上的工程实体。可以用一个通俗类比来理解:
- LLM是足不出户的专家,拥有海量知识,但无法触碰外部世界。
- Agent是给这位专家配上手脚和记忆的全能助理,能主动查阅资料、执行操作、完成任务。
传统的大模型交互模式本质是“被动响应”——用户提问,模型回答,对话结束即遗忘。这种模式缺乏三个关键能力:
- 主动性:无法在用户未明确指示时自主规划行动
- 环境交互:不能读取文件、调用API、执行代码
- 持久记忆:会话结束后,所有上下文信息全部丢失
AI Agent的核心价值,就是通过一个简洁的工程架构,系统性解决上述三个问题。其核心公式可以表述为:
AI Agent = LLM(大脑) + Planning(规划) + Memory(记忆) + Tools(手脚)
这并非玄学的概念包装,而是可落地的工程实践。下面,我们将一步步拆解每个组件,并通过一个完整的150行Python代码示例,展示如何从零构建一个可运行的AI Agent。
组件一:Tools(工具)——连接真实世界的桥梁
大语言模型本质上是文本生成模型,只能输出字符串。要让模型具备“行动力”,必须为其提供一组可调用的外部函数。当前主流实现方案是函数调用(Function Calling)机制。
该机制的工作原理是:
- 开发者定义一组工具函数的描述信息(Schema),包括函数名、功能描述、参数结构
- 将这些描述随用户提问一同发送给LLM
- LLM根据用户意图,决定是否需要调用工具,以及调用哪个工具、传入什么参数
- 模型返回结构化的调用请求,而非直接执行代码
- 应用层负责执行实际的函数调用,将结果返回给模型继续推理
在我们的实现中,定义了五个基础工具:
TOOLS = [{"name": "read_file", "description": "读取指定路径的文件内容"},{"name": "write_file", "description": "将文本内容写入指定文件"},{"name": "list_directory", "description": "列出指定目录下的所有文件和子目录"},{"name": "execute_python", "description": "在沙箱环境执行Python代码片段(超时限制10秒)"},{"name": "search_code", "description": "在代码库中递归搜索指定关键词"},]
这里有个关键的工程经验:工具描述的质量直接影响调用准确率。一个反直觉的现象是,工具描述写得好不好,比工具本身的实现逻辑更重要。
举例说明,如果execute_python的描述简略地写成“执行代码”,LLM在需要读取文件内容时,可能会错误地将文件路径作为参数传入执行代码的功能。但当我们把描述改为“执行Python代码片段,而非文件路径。仅接受代码字符串,不接受路径”,调用错误率明显下降。
这就好比给新同事写操作手册:描述越具体,包含边界条件,对方就越不会误用。在工具描述中,应当包括:
- 函数的具体职责
- 参数的精确类型与格式
- 明确的不适用场景(反面示例)
- 与其他工具的区分点
组件二:Planning(规划)——拆解复杂任务的思维链
Agent与简单函数调用的根本区别在于,它具备任务拆解与规划能力。当用户提出一个复杂需求(如“分析项目代码结构并生成优化建议”),Agent不能一步到位,需要通过多轮推理来分解任务。
业界常用的规划范式是ReAct(Reasoning + Acting)模式。它将推理过程和行动过程交替进行:
思考(Thought)→ 行动(Action)→ 观察(Observation)→ 新的思考...
在每个循环中:
- 思考:LLM根据当前信息,分析需要做什么,推理下一步操作
- 行动:决定调用哪个工具,传入什么参数,或直接给出最终答案
- 观察:获取工具执行返回的结果,将其融入上下文
这种“思考-行动-观察”的循环机制,让Agent能够处理需要多步骤才能完成的任务。核心代码实现如下:
def run_agent(task):messages = [{"role": "system", "content": "你是一个能自主完成任务的AI助手。"}]messages.append({"role": "user", "content": task})max_iterations = 10for step in range(max_iterations):response = llm.chat(messages, tools=TOOLS)messages.append(response)if response.finish_reason == "stop":return response.contentif response.tool_calls:for call in response.tool_calls:result = execute_tool(call.name, call.arguments)messages.append({"role": "tool","tool_call_id": call.id,"content": result})
循环的终止条件有两种:
- 自然完成:LLM认为信息已足够,直接生成最终回复
- 达到上限:当任务极其复杂时,限制最大迭代次数(如10次)防止无限循环
任务规划能力的强弱,很大程度上依赖底层LLM的推理水平。但在工程层面,我们可以通过优化提示词(如“请优先确定问题类型,再选择合适工具,最后汇总结果”)来引导更严谨的推理路径。
组件三:Memory(记忆)——从无状态到有上下文
早期的大模型对话是“无状态”的——每次请求都是独立处理,模型不记得之前的对话内容。Agent需要记忆机制来解决这个问题。
在实现中,记忆分为工作记忆和长期记忆:
工作记忆:即在当前会话上下文中存储的消息序列。在代码实现中,我们使用messages列表来维护:
messages = [] # 存储所有对话历史、工具调用、工具结果
每轮交互后,我们都会将以下内容追加至列表:
- 用户的新输入
- 模型的思考与行动
- 工具执行结果
这使得模型能“记住”之前的操作和结论,进行多轮推理。
长期记忆:跨会话持久化的信息。实现方案可以是:
- 将关键信息存入本地文件(如JSON)
- 使用向量数据库存储嵌入表示
- 在下次会话初始化时加载历史摘要
一个轻量级的实现思路是:当Agent完成一项任务后,将“任务描述—执行步骤—最终结果”压缩成一段文本,存为本地笔记文件。下一次遇到相似问题时,Agent先读取记忆文件进行参考。
但需要注意记忆容量管理:
- 过长的上下文会稀释关键信息,且增加Token消耗
- 需要设计摘要机制,定期压缩旧对话,仅保留要点
- 记忆内容应分优先级,如“用户偏好”高于“工具输出详情”
组件四:LLM(大脑)——核心推理引擎
作为Agent的“大脑”,LLM承担以下职责:
- 理解与推理:解析用户意图、分析工具返回结果
- 决策:选择合适工具并生成参数
- 回答生成:将中间结果整合为最终用户可读的答案
在工程实现中,需要注意以下几点:
温度参数:在需要精确执行的任务(如生成代码)中将温度调低(如0.2),在创意任务中调高。
上下文管理:在每次调用时,注意控制发送给模型的总Token数。当历史记录过长,需要进行截断或摘要,保留核心信息。
错误恢复:当工具执行失败时,应引导模型分析失败原因并调整策略,而非简单重复同一操作:
if tool_result.startswith("ERROR:"):messages.append({"role": "assistant","content": f"工具执行返回错误,请分析原因并提出新的方案。错误信息:{tool_result}"})
完整实现:150行Python代码示例
下面给出一个极简但功能完整的Agent实现,使用伪代码风格展示核心逻辑:
import jsonimport subprocessfrom pathlib import Pathclass MiniAgent:def __init__(self, llm_client):self.llm = llm_clientself.messages = []self.tools = [{"name": "read_file", "description": "读取文件内容", "parameters": {"path": "string"}},{"name": "write_file", "description": "写入文件", "parameters": {"path": "string", "content": "string"}},{"name": "list_directory", "description": "列出目录", "parameters": {"path": "string"}},{"name": "execute_python", "description": "执行Python代码片段,非文件路径", "parameters": {"code": "string"}},{"name": "search_code", "description": "搜索关键词", "parameters": {"keyword": "string", "path": "string"}},]def call_tool(self, name, args):if name == "read_file":return Path(args["path"]).read_text()elif name == "write_file":Path(args["path"]).write_text(args["content"])return "写入成功"elif name == "list_directory":return "\n".join(str(p) for p in Path(args["path"]).iterdir())elif name == "execute_python":try:result = subprocess.run(["python", "-c", args["code"]],capture_output=True, timeout=10, text=True)return result.stdout or result.stderrexcept subprocess.TimeoutExpired:return "ERROR: 执行超时"elif name == "search_code":results = []for p in Path(args["path"]).rglob("*"):if p.is_file() and args["keyword"] in p.read_text(errors='ignore'):results.append(str(p))return "\n".join(results)return "ERROR: 未知工具"def run(self, task):self.messages = [{"role": "system", "content": "你是一个能自主完成任务的AI助手。"}]self.messages.append({"role": "user", "content": task})for _ in range(15):response = self.llm.chat(self.messages, tools=self.tools)self.messages.append(response)if response.finish_reason == "stop":return response.contentif response.tool_calls:for call in response.tool_calls:result = self.call_tool(call.name, json.loads(call.arguments))self.messages.append({"role": "tool","tool_call_id": call.id,"content": str(result)})return "任务未在指定步数内完成"
整个核心逻辑约150行。该实现展示了Agent的基本闭环:
- 接收用户任务
- LLM推理决定行动方案
- 执行工具得到观察结果
- 循环直至完成
工程实践:从Demo到生产级系统的关键考量
上述Demo展示了Agent的核心原理,要将其应用于生产环境,还需考虑以下工程化问题:
安全与权限控制
- 工具白名单:仅暴露已审计的工具函数
- 沙箱隔离:在容器或受限环境中执行用户输入触发的代码
- 资源限额:对每个工具的调用次数、执行时间进行限制
可观测性
建议为Agent增加日志追踪:
logging.info(f"Step {step}: Action={call.name}, Arguments={call.arguments}")logging.info(f"Step {step}: Observation={result[:200]}")
生产级系统应可视化Agent的完整推理链条,包括每个思考、行动和观察,便于调试和优化。
成本控制
大模型调用成本不容忽视。以下策略可降低Token消耗:
- 精简消息历史:只保留最近的N轮对话
- 缩短工具输出:对长文件只返回开头部分
- 使用缓存机制:相同问题的相似请求可复用结果
总结与展望
通过在150行代码中实现一个完整的AI Agent,可以看到核心架构并不复杂:LLM承担推理决策,工具连接真实世界,记忆维持上下文,规划驱动多步执行。
然而,工程落地的挑战在于:
- 工具描述需要持续优化迭代
- 任务规划需要设计合理的引导策略
- 错误恢复和边界情况处理是稳定性关键
- 安全与成本控制必须前置设计
当前AI Agent仍处于早期阶段,但随着模型能力的持续提升和工具生态的不断完善,它将成为未来应用开发的核心范式。开发者的角色正在从“实现功能的人”转变为“定义目标的人”——这种转变,正在重新定义软件开发的本质。

登录后可评论,请前往 登录 或 注册