CClaude 中文站
入门

Agent 是什么:定义、组成与最小项目骨架

15 分钟阅读·学习笔记 · 梅奥整理

从定义出发理解 Agent 与 ChatBot 的本质区别,拆解 Agent 的六大组成模块,并搭好 Python + uv 的最小项目骨架。

这篇笔记解决什么问题

"Agent" 这个词现在到处都是,但很多人对它的理解停留在"更聪明的聊天机器人"。这篇笔记要把三件事讲清楚:第一,Agent 的严格定义是什么,它和你每天用的 ChatBot 到底差在哪;第二,一个 Agent 拆开来由哪几块组成,每一块承担什么职责;第三,如果你想自己动手写一个 Agent,第一步的项目骨架应该怎么搭——包括 Python 环境、包管理器、API key 和目录结构。

读完这篇你不会立刻拥有一个能干活的 Agent,但你会知道接下来要造的东西长什么样、由哪些零件构成,并且本地环境已经准备就绪,随时可以开始写第一行代码。

核心概念:Agent 的四个要素

先给出一个可操作的定义:

Agent 是一个以目标为导向的任务执行系统——它能感知外部环境,自主做出决策,并通过调用工具来实际改变世界,直到目标达成。

这个定义里有四个关键词,缺一个都不算真正的 Agent:

自主(Autonomy)。你只需要交代"要什么",不需要交代"每一步怎么做"。Agent 拿到目标后,自己决定先干什么、后干什么、遇到岔路走哪条。如果每一步都要人类点头,那只是一个带确认框的脚本。

感知(Perception)。Agent 必须能观察环境的当前状态:读文件、查数据库、看命令的返回值、接收 API 响应。没有感知能力的系统只能按预设剧本执行,无法应对"世界和预期不一样"的情况——而真实任务里,世界几乎总是和预期不一样。

工具(Tools)。语言模型本身只会输出文字,是工具让它的决策落地为动作。工具集合直接决定了 Agent 的能力边界:给它文件读写工具,它就能整理文档;给它 shell 执行权限,它就能部署服务。可以说,Agent 的能力清单就是它的工具清单。

目标(Goal)。Agent 的一切行为都要收敛到一个明确的任务目标上。它不是陪聊的,每一轮思考、每一次工具调用都应该在回答同一个问题:"我离完成任务还差什么?"

Agent 与 ChatBot:数字员工 vs 百科全书

用一个具体场景来对比。假设你的需求是:

把这个月服务器日志里的报错按类型归类,统计每类出现的次数,写一份故障分析文档存到项目目录里。

把这句话丢给一个普通的 ChatBot(不管背后的模型多强),你会得到一段很有条理的文字:教你用什么命令提取报错、建议按什么维度归类、给你一份文档模板。它什么都懂,但什么都没做——日志还在服务器上原封不动,文档一个字都没生成。ChatBot 的本质是一本会对话的百科全书:知识渊博,有问必答,但它的输出永远停留在"说"。

同样的需求交给 Agent,过程完全不同:它会先调用工具列出日志文件,读取内容,自己写脚本提取和统计报错,把结果整理成 Markdown,最后把文件写进你指定的目录。中间如果发现歧义——比如日志目录里有三个月的文件,它可能会停下来问你一句"只处理 6 月的对吗"——确认后继续干。任务结束时,你得到的不是一段建议,而是一份真实存在的文档。

这就是两者的本质区别:ChatBot 是被动应答的知识库,一问一答就结束;Agent 是主动执行的数字员工,接下任务就要负责交付结果。 中间的鸿沟不是模型能力,而是"能不能作用于环境"——也就是上面说的感知与工具。

关键机制:Agent 的六大组成模块

把一个能干活的 Agent 拆解开,会看到六个协作的模块:

模块职责类比
大模型理解输入、推理决策、生成输出,是整个系统的"发动机"大脑
角色设定通过系统提示词约束 Agent 的身份、风格和行为边界岗位职责说明书
记忆短期记忆跟踪当前任务的上下文,长期记忆沉淀跨会话的经验和偏好工作笔记 + 个人经验
工具一组可被模型调用的函数或外部接口,是行动能力的来源双手和设备
规划把复杂目标拆成有序的子步骤,处理多步推理和依赖关系项目排期
循环驱动"思考 → 行动 → 观察结果 → 再思考"不断迭代,直到任务完成或达到上限工作节奏

这六个模块里,最容易被低估的是循环。很多人以为 Agent 的核心是模型或工具,但真正让 Agent "活起来"的是那个不断运转的执行环:模型每轮决定"接下来做什么",系统执行动作后把结果喂回给模型,模型再基于新信息做下一轮决策。没有这个环,工具调用只是一次性的函数执行;有了这个环,系统才具备"根据反馈调整行为"的能力——这正是"自主"的技术实现。

另一个容易混淆的点是记忆和上下文的关系。短期记忆基本等于当前对话的消息列表(上下文窗口内的内容),长期记忆则需要额外的存储机制(文件、向量库等)在会话之间传递信息。本系列后续会专门拆解记忆、规划、多 Agent 协作这些模块,这一篇先建立整体地图。

代码模式:从一次模型调用到一个执行环

虽然正式写代码是下一步的事,但先看两段骨架代码,能帮你把上面的概念落到实处。

第一段:最基础的 LLM 调用。国内外主流模型服务(DeepSeek、Kimi、GLM、Qwen 等)几乎都提供 OpenAI 兼容接口,所以只用 openai 这一个 SDK,换 base_url 和模型名就能切换厂商:

import os
from openai import OpenAI

# base_url 指向任意 OpenAI 兼容服务,不绑定单一厂商
client = OpenAI(
    api_key=os.environ["LLM_API_KEY"],
    base_url=os.environ["LLM_BASE_URL"],   # 例如 https://api.deepseek.com/v1
)

resp = client.chat.completions.create(
    model=os.environ["LLM_MODEL"],
    messages=[
        {"role": "system", "content": "你是一个严谨的运维助手。"},
        {"role": "user", "content": "解释一下什么是幂等操作"},
    ],
)
print(resp.choices[0].message.content)

这段代码只是一个 ChatBot:一问一答,没有行动能力。

第二段:给它套上执行环,就有了 Agent 的雏形。下面是伪代码级别的骨架,重点看结构而不是细节:

MAX_STEPS = 20  # 防止死循环的保险丝

def run_agent(goal: str) -> str:
    history = [
        {"role": "system", "content": AGENT_PERSONA},  # 角色设定
        {"role": "user", "content": goal},             # 目标
    ]
    for _ in range(MAX_STEPS):                         # 循环
        reply = call_llm(history, tools=TOOL_SCHEMAS)  # 大模型 + 工具声明
        if not reply.tool_calls:
            return reply.content                       # 没有动作请求 = 任务收尾
        history.append(reply)                          # 短期记忆
        for tc in reply.tool_calls:
            outcome = execute_tool(tc.name, tc.arguments)  # 行动
            history.append({                               # 感知:结果回灌
                "role": "tool",
                "tool_call_id": tc.id,
                "content": outcome,
            })
    return "已达最大步数,任务中止"

注意每一行注释和六大模块的对应关系:AGENT_PERSONA 是角色,history 是短期记忆,TOOL_SCHEMAS 声明工具,for 循环就是执行环,而"把工具结果追加回消息列表"这一步实现了感知。规划能力在这个最小版本里由模型隐式完成(它自己决定调用顺序),更复杂的显式规划后面再加。

实践:搭建最小项目骨架

概念清楚了,把开发环境立起来。

1. Python 与 uv

需要 Python 3.12 及以上。包管理推荐 uv——它同时管依赖和虚拟环境,速度比 pip 快一个量级。安装(macOS / Linux):

curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version   # 输出版本号即安装成功

Windows 用户在 PowerShell 里执行官网给出的安装命令即可,验证方式相同。

2. 准备一个 API key

到任意一家提供 OpenAI 兼容接口的模型服务商注册并创建 API key。DeepSeek、Kimi(月之暗面)、GLM(智谱)都是低成本的选择,新账号通常有免费额度,学习阶段的调用开销可以忽略不计。key 创建后立即复制保存——多数平台只展示一次。

3. 目录骨架

建一个项目目录,里面只需要两个子目录:

mkdir agent-lab && cd agent-lab
mkdir backend    # 所有 Python 源码
mkdir workspace  # Agent 运行时的工作区:配置、会话记录、产出文件

把"代码"和"运行产物"从第一天就分开,是个值得坚持的习惯:backend 进版本控制,workspace 是 Agent 读写的沙盒,两者互不污染。

4. 环境变量与 .env

在项目根目录创建 .env,写入三个变量:

LLM_API_KEY=你的key
LLM_BASE_URL=https://api.deepseek.com/v1
LLM_MODEL=deepseek-chat

换厂商时只改后两行,代码一个字不用动——这就是坚持用 OpenAI 兼容接口的好处。

5. .gitignore

如果用 Git 管理项目(建议用),根目录加一个 .gitignore

.env
.venv/
__pycache__/
workspace/

最终结构:

agent-lab/
├── .env         # 密钥与模型配置(不入库)
├── .gitignore
├── backend/     # 源码
└── workspace/   # 运行时工作区(不入库)

常见坑

  • 把 API key 写进代码或提交到 Git。 这是最高频也最危险的错误。key 只放 .env.gitignore 第一行就是它。一旦不小心推到公开仓库,立刻去平台吊销重建,删除提交记录是来不及的。
  • 循环不设上限。 Agent 可能因为工具持续报错而反复重试,没有 MAX_STEPS 这类保险丝,就是无限烧 token。上限、超时、预算控制从最小版本就要有。
  • 把 Agent 理解成"更强的提示词工程"。 提示词只影响六大模块中的"角色",Agent 的核心竞争力在工具、循环和记忆这些工程结构上,光调提示词造不出数字员工。
  • 一开始就绑死某个厂商的私有 SDK。 用 OpenAI 兼容接口写代码,模型层随时可换,做实验对比不同模型的表现也只是改两行配置的事。
  • 忽视 workspace 的边界。 Agent 有文件写入能力后,一定要限定它只能在工作区内操作,否则一次跑偏的 rm 或误写就可能伤到项目源码甚至系统文件。

动手清单

  1. 安装 Python 3.12+ 和 uv,用 python --versionuv --version 确认两者可用。
  2. 在一家 OpenAI 兼容的模型平台注册并创建 API key,写入项目根目录的 .env
  3. 按上文搭好 agent-lab/(含 backend/workspace/.env.gitignore),并 git init 后确认 git status 里看不到 .env
  4. backend/ 里用 uv init 初始化环境,uv add openai python-dotenv,把本文第一段调用代码跑通,看到模型的回复。
  5. 口头练习:不看笔记,向别人(或自己)讲清楚 Agent 的四个要素和六大模块,以及"执行环"为什么是 Agent 区别于 ChatBot 的关键。

*本文为学习笔记,知识框架参考自叶小钗「生产级 Agent」系列课程;文字与代码示例为本站原创整理。*

#Agent 定义#环境搭建#uv