AI Agent 实战教程 11:如何设计一个 Agent 项目结构
从工程角度拆解 Agent 项目目录结构,理解 tools、workflows、memory、prompts、evals 和 logs 如何分层组织。
很多 Agent Demo 都可以在一个文件里跑起来:定义一个模型、写几个工具函数、拼一段提示词,然后让模型决定下一步做什么。这个阶段很适合验证想法,但如果继续用这种结构承载真实业务,项目很快会失控。
AI Agent 项目天然比普通应用更容易变复杂。它既有模型调用,也有工具系统;既有提示词,也有状态机;既要处理业务数据,也要处理权限、日志、评测和错误恢复。因此,Agent 项目从一开始就应该有清晰的工程结构。
项目结构设计的目标不是追求目录数量,而是让每个模块职责清楚:谁负责理解任务,谁负责执行工具,谁负责保存状态,谁负责记录日志,谁负责评测质量。结构清晰后,团队协作、问题排查和后续扩展都会简单很多。
为什么 Agent 项目容易变乱
普通应用的核心逻辑通常比较明确。后端服务围绕 controller、service、model 组织;前端项目围绕页面、组件、状态和 API 组织。而 Agent 项目同时包含多个维度的逻辑:模型推理、工具调用、提示词、工作流、记忆、权限、审计、评测。
如果没有拆分,这些内容很容易混在一起。例如一个文件里既写系统提示词,又写工具函数,还写 API 请求,还保存任务状态。短期看开发很快,长期看每改一个工具都可能影响整个 Agent。
常见混乱表现包括:
- 所有工具都写在一个 tools 文件里;
- prompt 文本散落在代码中,无法版本化;
- 工具返回格式不统一;
- 状态只存在内存变量里,任务中断后无法恢复;
- 权限判断写在模型提示词里,而不是系统逻辑里;
- 没有统一日志,无法知道 Agent 为什么做出某个决策;
- 没有 evals,改一次 prompt 就可能破坏旧能力。
这些问题在演示时不明显,因为演示通常任务短、路径固定、数据少。但一旦进入真实系统,用户会提出模糊需求,接口会失败,权限会不足,任务会中断,工具会越来越多,单文件结构就很难维护。
推荐的目录分层
一个中等复杂度的 Agent 项目,可以从下面这些目录开始:
textagents/ tools/ workflows/ memory/ prompts/ evals/ logs/ config/ types/
这些目录不是固定标准,而是一种职责划分思路。项目小的时候可以合并,项目变大后可以继续细分。
agents:定义 Agent 入口和角色
agents 目录用于定义不同 Agent 的角色和入口。例如:
- contentAgent:负责内容管理;
- codingAgent:负责代码修改;
- researchAgent:负责资料检索;
- taskAgent:负责待办和日程;
- reviewAgent:负责审查输出。
每个 Agent 不应该包含全部业务逻辑。它更像一个调度入口:接收用户目标,加载相关工具和 workflow,然后执行任务。
这样设计的好处是,新增一个 Agent 不会影响其他 Agent。比如你可以让 codingAgent 只加载文件和测试工具,而 contentAgent 只加载标签、文章和素材工具。
tools:封装外部能力
tools 是 Agent 能力的边界。所有外部操作都应该通过工具封装,例如:
- 查询标签;
- 创建文章;
- 上传图片;
- 读取文件;
- 调用搜索 API;
- 创建任务;
- 执行测试命令。
工具应该尽量原子化。一个工具只做一类事情,并提供明确的输入输出。不要把“创建教程并绑定文章”写成一个底层工具,因为它包含多个业务步骤,更适合放在 workflow 中。
一个工具定义通常包含:
- name:工具名称;
- description:什么时候使用;
- schema:参数定义;
- riskLevel:风险等级;
- execute:执行函数;
- output:返回结构。
工具层还应该负责参数校验。例如 URL 是否合法、文件是否存在、ID 是否是数字、用户是否有权限访问目标资源。不要把这些校验交给模型自由判断。
workflows:组织多步骤流程
workflow 负责把多个工具组合成流程。例如“创建 Treasure 标签并补图”不是一个原子工具,而是一个 workflow:
- 查询标签是否存在;
- 搜索合适图片;
- 上传图片到自有素材系统;
- 创建标签并绑定图片;
- 查询标签验证结果;
- 如果需要,加入标签集。
workflow 可以是简单顺序流程,也可以是状态机或图结构。它应该明确每一步的输入、输出、失败处理和验证方式。
把流程放在 workflow 层,而不是写进 prompt,有一个重要好处:流程可以测试,可以复用,也可以在失败后恢复。
memory:管理短期和长期记忆
memory 目录用于管理 Agent 的记忆系统。短期记忆可以保存当前任务状态,长期记忆可以保存用户偏好和历史经验。
例如用户要求“每篇文章标签不超过 3 个”,这就是一个长期偏好。又比如“treasure article create 需要先创建 draftId”,这是一个工具经验。
记忆系统应该有写入规则,不应该把所有对话都保存下来。还要支持查看、删除、过期和脱敏。
prompts:管理提示词
提示词应该作为项目资产管理,而不是散落在代码里。prompts 目录可以保存:
- 系统提示词;
- 工具使用说明;
- 输出格式模板;
- 审查提示词;
- 总结提示词;
- 任务拆解提示词。
提示词最好版本化。每次修改都应该知道改了什么、为什么改、影响了哪些评测。
evals:评测与回归测试
Agent 项目如果没有 evals,很容易越改越不可控。evals 目录可以保存测试用例,例如:
- 创建标签时必须先查重;
- 图片不能直接使用外链,必须上传到自有素材系统;
- 删除操作必须确认;
- 文章正文不能带一级标题;
- 每篇文章标签不能超过 3 个。
这些规则都可以变成评测项。每次改 prompt、工具或 workflow 后跑一遍,能减少回归问题。
logs:日志和 trace
logs 目录或日志模块用于记录 Agent 的执行过程。至少应该记录:用户目标、计划步骤、工具调用、参数、返回结果、错误信息、用户确认和最终输出。
生产环境中,不一定把日志写到本地目录,也可能写到数据库、对象存储或 observability 平台。但从项目结构上,日志能力应该是独立模块,而不是零散 console。
config:配置与密钥
config 管理模型配置、工具开关、API Base、权限策略、重试次数和环境变量。
密钥不要写进代码。对于 Agent 项目尤其要注意,因为工具可能访问很多外部系统。配置层应该明确哪些信息来自环境变量,哪些可以写入配置文件,哪些必须通过用户授权获得。
一个示例结构
下面是一个简化示例:
textsrc/ agents/ content-agent.ts coding-agent.ts tools/ treasure/ tag-tools.ts article-tools.ts material-tools.ts filesystem/ read-file.ts write-file.ts workflows/ create-tag-with-image.ts create-tutorial-series.ts memory/ preference-memory.ts task-state-store.ts prompts/ system.md reviewer.md evals/ create-tag.eval.json article-style.eval.json logs/ trace.ts config/ model.ts permissions.ts
这个结构的重点是:工具不直接决定业务流程,workflow 不直接写底层 API,Agent 不承载所有实现细节。
目录结构和团队协作
当团队多人协作时,清晰结构更加重要。负责工具的人可以维护 tools,负责内容质量的人可以维护 prompts 和 evals,负责平台稳定性的人可以维护 logs 和 config。
如果所有逻辑都在一个 Agent 文件里,任何人修改都可能影响全部能力。模块拆分后,变更边界更清楚,也更容易 code review。
常见误区
第一个误区是过早抽象。项目刚开始时不需要设计复杂框架,但至少要避免把工具、prompt 和流程混在一起。
第二个误区是只拆目录,不拆职责。目录很多但每个文件仍然互相调用、互相依赖,复杂度并没有降低。
第三个误区是忽略评测。Agent 项目最容易因为 prompt 改动产生隐性回归,没有 evals 很难发现。
第四个误区是忽略权限。工具目录里如果没有风险等级和权限说明,后续加审批会很痛苦。
小结
Agent 项目结构的目标,是让模型能力、工具能力和业务流程分离。agents 负责入口和角色,tools 负责外部能力,workflows 负责任务编排,memory 负责上下文和偏好,prompts 负责语言策略,evals 负责质量保障,logs 负责可观测性。
一个好的结构不会让项目一开始变复杂,而是让复杂度在增长时仍然可控。对于要进入真实业务的 AI Agent,这是非常值得提前设计的基础。