适合:有基础Python能力、想搞懂Agent底层,不满足于直接调用现成平台的开发者;不做黑盒托管,聚焦轻量可运行的最小智能体实现,避开过度复杂的框架,理解核心思想。

 目录

 

1. 什么是AI Agent?它和普通对话机器人有什么不一样

2. AI Agent核心五要素(业界经典架构拆解)

3. 常见技术路线选型:框架 vs 手写最小实现

4. 最小可用Agent:从零手写一个简易版(可运行代码)

5. 能力扩展:工具调用、记忆、规划如何加上

6. 工程化注意事项、安全边界与局限

7. 后续进阶学习路径

 

 1. 什么是AI Agent?和普通Chatbot的区别

 

普通大模型对话:被动响应——你提问 → 模型生成回答,没有自主目标,不会主动拆分任务、反复迭代、调用外部能力。

 

AI Agent(智能代理):一个以「目标」为驱动的系统,可以自主完成:感知→思考→决策→行动→观察结果→迭代,直到目标达成或判定不可完成。

 

简单对比:

 

- Chatbot:“我问,它答”,对话是终点

- Agent:“给定目标,它自己想办法分步做”,回答是中间过程,完成任务才是终点

 

⚠️重要认知:Agent不是一种新模型,是一套「大模型作为大脑」的程序架构,可以基于任意支持Function‑call的大模型实现(OpenAI、通义千问、DeepSeek、智谱等)。

 

2. AI Agent经典五要素(核心架构,很多复杂框架本质都是这几块)

 

业界流传很广的 Agent五大组件,记住这5个,你就能看懂几乎所有Agent项目:

 

1. 🧠 规划器 Planner

 

接收用户总目标,拆解成子任务;遇到失败时反思、调整方案。常见模式:ReAct、CoT、Self‑Refine。

核心提示词思路: “先思考要做哪几步,再执行每一步” 

 

2. 📚 记忆 Memory

 

Agent的“回忆”,分3层:

 

- 瞬时记忆:本轮对话上下文(LLM本身的上下文窗口)

- 短期记忆:最近若干轮的思考‑行动‑观察记录,可做摘要

- 长期记忆:向量库/文件/数据库,持久化知识,需要检索(RAG)

 

3. 🛠️ 工具集 Tools

 

Agent可以调用的外部能力:查时间、HTTP接口、文件读写、计算器、数据库查询等。没有工具,Agent很难真正改变外部世界。

注意:工具必须做严格权限管控,防止越权操作。

 

4. 👀 感知 Observation

 

获取行动之后的反馈:调用工具返回结果、接口返回值、文件内容、外部环境信息,送回大脑用于下一轮思考。

 

5. 🎯 执行器 Actor

 

把大模型输出的决策,解析成可执行动作:解析函数名+参数,调用对应工具,捕获返回,再送回思考循环。

 

极简闭环公式:

目标 → 规划 → 行动 → 观测 →(判断是否完成:未完成则循环)→ 结束

也就是大名鼎鼎的 ReAct循环:Reason + Act,是绝大多数轻量Agent的基石。

 

👉 很多高大上Agent框架(LangGraph、AutoGPT、LlamaIndex),本质就是帮你把这5个组件做好封装;但初学者优先手写一遍最小版本,才不会只会调API不懂原理。

 

3. 技术路线怎么选?两条路

 

- 路线A:基于成熟框架(LangGraph / AutoGen)

优点:生态完善,自带记忆、状态管理,适合做复杂应用;缺点:抽象层级高,初学者容易“黑盒运行”,不知道内部发生了什么。

- 路线B:手写最小Agent(本文采用)

只用: 大模型SDK + python基础 + 少量工具 ,不引入重型Agent框架,理解ReAct循环本身。

 

前置条件:

 

- Python 3.10+

- 一个支持 function‑call 的大模型API Key(示例用兼容OpenAI接口格式的服务,可替换为国内模型)

- 仅学习用途,做好密钥管理:使用 .env ,禁止硬编码、上传密钥到代码仓库

 

依赖:

 

bash

pip install openai python-dotenv

 

 4. 动手实现:一个最小可用 ReAct‑Agent

 

⚠️ 这是教学最小原型,生产使用需要增加校验、鉴权、限流、沙箱隔离,不要直接开放给公网;工具能力不要随意赋予删除文件、高危系统调用权限。

 

项目结构

 

plaintext

mini_agent/

├─ main.py

├─ .env

└─ .gitignore

 

 

 .env 

 

env

LLM_BASE_URL=https://api.example.com/v1

LLM_API_KEY=sk-xxx

LLM_MODEL_NAME=your-model

 

 

 .gitignore 

 

plaintext

.env

__pycache__/

*.pyc

 

 

 main.py 

 

python

"""

最小ReAct Agent实现

逻辑循环:思考(Thought) → 行动(Action) → 观察(Observation),直到任务完成

支持的内置工具:get_current_time, calculator

"""

import os

import json

from datetime import datetime

from dotenv import load_dotenv

from openai import OpenAI

 

load_dotenv()

 

client = OpenAI(

    base_url=os.getenv("LLM_BASE_URL"),

    api_key=os.getenv("LLM_API_KEY")

)

MODEL = os.getenv("LLM_MODEL_NAME")

 

# ========== 1. 定义可用工具 ==========

TOOLS = {

    "get_current_time": {

        "desc": "获取当前时间,无参数",

        "func": lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    },

    "calculator": {

        "desc": "数学计算,参数 expr: 数学表达式字符串,例如 '123*45'",

        "func": lambda expr: str(eval(expr)) # ⚠️教学用途!生产严禁直接eval!!

    }

}

 

TOOL_DESC = "\n".join([f"- {k}: {v['desc']}" for k, v in TOOLS.items()])

 

# ========== 2. Agent主循环 ==========

SYSTEM_PROMPT = f"""

你是一个执行任务的智能体。每一轮输出严格遵循格式:

 

Thought: <你的思考,分析现在应该做什么>

Action: <工具名> | <参数,无参数就填空>

如果任务已经完成,输出:

Finish: <最终回答>

 

可用工具:

{TOOL_DESC}

 

不要额外输出其他内容!不要编造工具。最多循环5轮,超过直接结束。

"""

 

def run_agent(user_goal: str, max_loop: int = 5):

    messages = [

        {"role": "system", "content": SYSTEM_PROMPT},

        {"role": "user", "content": f"任务:{user_goal}"}

    ]

    print(f"\n🎯目标:{user_goal}\n")

 

    for step in range(max_loop):

        resp = client.chat.completions.create(

            model=MODEL,

            messages=messages,

            temperature=0

        )

        content = resp.choices[0].message.content.strip()

        print(f"📝第{step+1}轮输出:\n{content}\n")

 

        if content.startswith("Finish:"):

            return content.replace("Finish:", "").strip()

 

        # 解析 Thought / Action

        lines = [l for l in content.splitlines() if l.strip()]

        thought, action_line = "", ""

        for line in lines:

            if line.startswith("Thought:"):

                thought = line[len("Thought:"):].strip()

            elif line.startswith("Action:"):

                action_line = line[len("Action:"):].strip()

 

        if not action_line or "|" not in action_line:

            obs = "输出格式错误,请严格按照规则输出"

        else:

            tool_name, arg = action_line.split("|", 1)

            tool_name = tool_name.strip()

            arg = arg.strip()

            if tool_name not in TOOLS:

                obs = f"错误:不存在工具 {tool_name}"

            else:

                try:

                    if arg == "":

                        res = TOOLS[tool_name]["func"]()

                    else:

                        res = TOOLS[tool_name]["func"](arg)

                    obs = f"工具返回:{res}"

                except Exception as e:

                    obs = f"执行异常:{str(e)}"

 

        print(f"👀Observation:{obs}\n{'—'*40}")

        # 把本轮完整过程放回上下文,形成记忆

        messages.append({"role": "assistant", "content": content})

        messages.append({"role": "user", "content": f"Observation:{obs}"})

 

    return "达到最大轮次,任务未完成"

 

 

if __name__ == "__main__":

    result = run_agent("现在的时间是多少?另外计算 1234 × 5678 等于多少")

    print(f"\n✅Agent最终结果:{result}")

 

 

运行逻辑演示(理想输出)

 

1. Thought:我需要先获取当前时间,再调用计算器算1234×5678

2. Action: get_current_time |

3. Observation:工具返回:2026‑09‑09 ……

4. 下一轮:Thought:时间已拿到,接下来计算表达式……

5. Action: calculator | 1234*5678

6. Observation:工具返回xxxx

7. Finish:当前时间是……,计算结果是……

 

🚨重要安全警告:示例中 eval 仅用于教学演示!线上绝对不能使用,会带来任意代码执行漏洞;真实计算器应使用安全表达式解析库如  asteval 。

 

这个几十行代码,就是ReAct范式的灵魂:LLM负责思考,程序负责循环、解析动作、调用工具、喂回观测结果。所有复杂Agent,都是这个骨架的扩展。

 

5. 能力如何扩展?基于最小原型做增量升级

 

看懂上面的最小版之后,你可以依次叠加能力,而不是一下子上大框架:

 

① 更好的工具系统

 

- 不要自己解析文本格式:改用标准  function‑call (大模型原生支持),避免格式解析失败

- 工具做独立注册:名称、入参JSON Schema、权限标签、超时、异常处理

- 禁止高危工具:不要给Agent开放执行shell、随意读写系统目录的能力,工具沙箱化

 

② 记忆系统

 

- 短期记忆:目前我们直接把所有对话塞到messages里 → 缺点:容易超长。优化:定期摘要压缩,只保留关键事件。

- 长期记忆:引入向量数据库(Chroma、FAISS),当Agent需要历史知识时,做检索增强(RAG),把相关片段放进prompt,而不是全量加载。

 

简单实现思路:每完成一次任务,把  目标‑过程‑结果  向量化存入向量库;新任务开始前检索相似历史,作为参考。

 

③ 更强规划(Planner)

 

基础ReAct是“走一步看一步”,复杂任务容易跑偏。可以增加两种模式:

 

1. 先规划后执行:Agent第一步先生成完整步骤清单,后续每一步对照计划执行,发现偏离就修正计划。

2. 反思Self‑reflection:每做完一轮,额外调用一次LLM:“刚才的行动是否合理?哪里做错了?”,反思结果参与下一轮决策。

 

④ 状态管理

 

Agent每一步的:目标、计划、已完成动作、观测、中间结果 → 统一保存为状态(State),用字典/Pydantic模型管理。LangGraph本质就是一个强大的状态图引擎,用来管理状态流转、分支、回滚。

 

升级路径建议:手写ReAct → function‑call版Agent → 增加记忆/规划 → 学习LangGraph做状态图

 

6. 工程边界、安全与常见误区

 

1. ❌误区:Agent是“万能自动执行AI”

 

Agent依然很容易幻觉:错误调用工具、错误解析参数、自说自话。所有自主执行系统都必须有边界、人工复核通道,不能无人值守执行高危业务。

 

2. 🔒安全铁律(非常重要)

 

- 密钥、数据库账号、webhook 永远不在代码硬编码,用环境变量/密钥管理

- 工具最小权限原则:Agent能做什么,由你显式注册的工具决定,不要给过大权限

- 面向公网的Agent服务必须:鉴权、限流、输入校验、超时控制、操作日志完整留存,高危操作禁止自动执行,需要人工确认

- 不要让Agent发送消息、修改业务数据、发起支付等无人监管

 

3. 📌成本与稳定性

Agent每轮循环都要调用LLM接口,任务越复杂,调用次数越多,成本越高;要设置最大循环轮次、最大token消耗,防止死循环。

4. 📌可观测性

每一步:目标、thought、action、observation、耗时,都建议落日志,便于排查Agent为什么“做出奇怪的行为”。

 

7. 进阶学习路径

 

如果你想继续深入,可以按这个顺序学习:

 

1. 吃透 ReAct、CoT、Self‑Consistency、Reflexion 基础论文核心思想(不用啃全文,读中文解读+复现最小Demo)

2. 掌握 function‑call 标准用法,替换掉示例里的文本解析方式

3. 向量检索(RAG):Chroma / FAISS,给Agent加上长期记忆

4. LangGraph入门:状态图、节点、边、条件分支,构建多节点Agent

5. Multi‑Agent(多智能体协作,如AutoGen):不同Agent分工(规划、执行、评审)

6. 生产关注点:可观测性、限流、沙箱、权限、审计日志、成本控制

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐