Day 29:AI 应用工程架构
学习目标
今天进入 Week 5,主题是工程化、Eval、安全与部署。前四个星期,我们分别建立了 AI 全景认知、掌握了 API 调用与结构化输出、完成了 RAG 知识库系统、理解了 Workflow 与 Agent 架构。这些能力已经足够做出一个”能用”的 Demo。但 Demo 离”可交付的产品”之间,隔着一整座工程架构的大山。
今天的目标是理解 AI 应用的工程架构设计。具体来说:一个 AI 应用项目应该怎么组织代码目录?服务层怎么拆?数据库怎么设计?各模块之间怎么通信?怎么做到改一个模块不影响其他模块?学完这一天,你应该能画出一套完整的 AI 应用工程架构图,并且说清楚每一个模块的职责、边界和交互方式。
工程架构不是”锦上添花”,而是让 Demo 变成 MVP 的基础。没有好的架构,你的项目会越改越乱、越跑越慢、越加 bug 越多。
核心概念
前后端分层
先说一个最基本的架构原则:前端和后端必须分离。
什么是前端?前端是用户直接看到的界面:网页、App、小程序、桌面客户端。用户通过前端输入数据、查看结果、操作系统。在 AI 应用里,前端通常包括:输入表单(用户填行业名称、上传文档)、进度展示(显示 Agent 正在执行哪一步)、结果展示(展示分析报告、评分表、图表)、交互控件(按钮、选择器、拖拽组件)。
什么是后端?后端是看不见的逻辑层:接收请求、调用模型、处理数据、存储结果、返回响应。在 AI 应用里,后端承担了绝大部分工作:模型调用、Prompt 管理、RAG 检索、Agent 执行、报告生成、权限校验、日志记录。
为什么要分层?三个原因。第一,关注点分离。前端只关心怎么展示,后端只关心怎么处理。前端改了按钮颜色,后端完全不受影响;后端换了模型,前端只需要知道返回格式没变就行。第二,独立迭代。前端可以单独优化用户体验,后端可以单独优化性能和稳定性,两边并行开发互不干扰。第三,可替换性。未来你想把网页版换成桌面客户端,后端不需要改一行;你想把后端从 Python 换成 Go,前端不需要改一行。
很多初学者做 AI 应用的时候喜欢用 Jupyter Notebook 或者 Gradio 做一个”能跑”的界面。这没问题,做 Demo 够用了。但一旦要交付给客户、要长期维护、要加功能,这种”前后端揉在一起”的方式就会让你非常痛苦。
实际操作中,AI 应用的前端框架常见选择有 React、Vue、Next.js;后端常见选择有 FastAPI(Python)、Flask(Python)、Express(Node.js)。我们这门课以 FastAPI 为后端框架,因为 Python 生态跟 AI 工具链最契合。
服务层设计
后端内部也要分层,不能把所有逻辑都塞在一个文件里。服务层设计就是把后端按功能拆成不同的模块,每个模块负责一个明确的领域。
一个典型的 AI 应用后端至少包含以下服务层。
API 层(也叫 Controller 层或 Handler 层):负责接收 HTTP 请求、解析参数、调用服务层、返回响应。这一层只做”接线”,不包含业务逻辑。比如收到一个”分析行业”的请求,API 层做的事情就是:验证参数(行业名称是不是空字符串)、调用行业分析服务、把结果包装成标准响应格式返回。API 层不关心模型怎么调、Prompt 怎么写、结果怎么存。
Service 层(业务逻辑层):负责具体的业务逻辑。行业分析服务负责:选择 Prompt 模板、组装上下文、调用模型、解析输出、格式校验、结果持久化。这一层是系统的核心,也是最复杂的部分。
DAL 层(数据访问层,Data Access Layer):负责跟数据库交互。增删改查的细节封装在这一层。Service 层不直接写数据库语句,而是调用 DAL 层的方法。比如 Service 层说”保存这个分析结果”,DAL 层负责把它写入数据库的 analysis_results 表。
为什么要这么分?因为每一层都有可能独立变化。假设你原来用 MySQL,现在要换成 PostgreSQL,只需要改 DAL 层。假设你原来用 OpenAI 的模型,现在要换成 Anthropic 的,只需要改 Service 层里模型调用的部分。假设你要加一个新的接口,只需要在 API 层加一个路由,调用已有的 Service。
服务层设计有一个常见的误区:过度设计。一个只有三个接口的项目,没必要拆成五层。初学者做 AI 应用,建议先分三层(API - Service - DAL),够用了。等项目复杂度上来了,再考虑加缓存层、消息队列层、事件总线这些更高级的架构。
模型调用层
模型调用层是 AI 应用独有的架构组件。它负责封装所有与大语言模型交互的细节。
为什么要把模型调用单独抽一层?因为模型调用是整个系统里最不稳定、最昂贵、最需要管控的部分。
不稳定体现在:模型 API 会偶尔超时、返回格式偶尔不符合预期、限流(Rate Limit)会导致请求失败。这些不稳定性不应该暴露给 Service 层。Service 层应该只关心”我要调用模型,给我结果”,至于重试几次、超时怎么处理、降级用什么模型,都是模型调用层的事。
昂贵体现在:每次模型调用都要花钱。一次行业分析可能需要调用模型五到十次(理解需求、行业概览、岗位拆解、流程拆解、报告生成)。如果不做成本管控,一个用户的一套分析可能烧掉几块钱甚至几十块钱。模型调用层应该记录每次调用的 Token 用量和成本,并且支持成本上限设置。
管控体现在:不同的 Service 可能需要不同的模型、不同的参数、不同的 Prompt 格式。模型调用层提供统一的接口,屏蔽这些差异。比如行业概览用 GPT-4o(需要质量),简单的格式校验用 GPT-4o-mini(省钱),Embedding 用 text-embedding-3-large(专用模型)。Service 层不需要知道这些细节。
模型调用层的核心功能包括:统一的调用接口(chat 方法、stream 方法)、自动重试机制(网络错误重试、限流重试)、超时控制(不同任务不同超时时间)、Token 用量统计(每次调用记录输入 Token、输出 Token)、成本计算(根据模型单价换算成本)、降级策略(主模型不可用时切换备用模型)、调用日志(谁在什么时候调了什么模型、花了多少钱、返回了什么)。
这些功能不是可有可无的”高级特性”,而是让系统从”能跑”变成”能上线”的必要基础设施。
Prompt 管理层
Prompt 是 AI 应用的”业务逻辑”。一个行业分析系统里可能有几十个 Prompt,每个 Prompt 有自己的版本、参数、测试集。如果 Prompt 散落在代码各处,维护起来就是噩梦。
Prompt 管理层要解决的问题是:把 Prompt 当成可管理、可版本化、可测试的资产来对待。
最基本的做法是把所有 Prompt 模板集中存放在一个目录或数据库里,每个 Prompt 有唯一标识符(Prompt ID)、版本号、输入参数定义、输出格式定义、测试样例。
更成熟的做法是建一个 Prompt 管理系统,支持:版本管理(每次修改 Prompt 都有记录,可以回滚到任意版本)、A/B 测试(同一个任务用两个不同版本的 Prompt,对比效果)、效果追踪(记录每个 Prompt 版本在实际使用中的表现)。
为什么 Prompt 需要版本管理?因为 Prompt 的修改是非常频繁的。你可能今天调了一个 Prompt 觉得效果好,明天换了一批测试数据发现效果又不行了,需要回滚到昨天的版本。如果没有版本管理,你只能凭记忆回忆”昨天那个版本是怎么写的”。
Prompt 管理层跟模型调用层的关系:Prompt 管理层负责”用什么 Prompt”,模型调用层负责”怎么调模型”。Service 层从 Prompt 管理层获取模板,填入参数,然后交给模型调用层执行。
我们在 Day 30 会专门深入 Prompt 管理系统的设计。
RAG 服务层
如果你的应用有知识库功能(Week 3 的内容),就需要一个独立的 RAG 服务层。
RAG 服务层封装了知识库的全部逻辑:文档上传、文档解析、文本切块、向量化、存储到向量数据库、语义检索、结果排序、上下文拼接。
为什么要把 RAG 抽成独立的服务层?三个原因。
第一,RAG 的技术栈跟模型调用完全不同。RAG 涉及向量数据库(Milvus、Qdrant、Chroma)、Embedding 模型、文档解析库(PyMuPDF、python-docx)、分词器、Reranker。这些组件跟模型调用层的关注点完全不一样,混在一起会让代码难以维护。
第二,RAG 的性能瓶颈跟模型调用不同。模型调用的瓶颈是 API 响应时间和 Token 限制;RAG 的瓶颈是向量检索的延迟和准确率、文档处理的速度、存储空间的管理。分开之后可以独立优化。
第三,RAG 是可复用的。多个 Service 可能都需要知识库能力。比如行业分析 Agent 需要检索行业报告,客服 Agent 需要检索产品文档,质检 Agent 需要检索工艺标准。如果 RAG 是一个独立的服务层,这些 Agent 都可以复用同一套 RAG 基础设施。
RAG 服务层对外提供的接口应该简洁:上传文档(输入文档文件,输出文档 ID 和处理状态)、查询知识库(输入问题,输出相关文档片段和来源)、管理文档(删除、更新、查看文档列表)。调用者不需要知道内部是用的什么向量数据库、什么切块策略、什么 Embedding 模型。
Agent 服务层
Agent 是 Week 4 的核心内容。在工程架构里,Agent 也需要独立的服务层。
Agent 服务层负责管理 Agent 的生命周期:创建 Agent、配置 Agent(设定目标、分配工具、加载 Prompt)、执行 Agent(启动执行循环、监控执行状态、处理异常)、获取结果(收集 Agent 执行过程中的所有中间结果和最终输出)。
Agent 服务层跟 Workflow 引擎的关系:Agent 执行本身就是一个动态的 Workflow。每一步执行什么动作、调用什么工具,由 Agent 自己决定,但执行框架(循环控制、状态管理、异常处理)是固定的。Agent 服务层就是提供这个固定框架的。
Multi-Agent 的编排也在这一层。Orchestrator Agent 怎么分派任务给专家 Agent?专家 Agent 的结果怎么汇总?Agent 之间怎么通信?这些都是 Agent 服务层要解决的问题。
Agent 服务层还要处理几个关键的工程问题。
执行持久化:Agent 的执行过程可能很长(几分钟到几十分钟)。如果执行到一半服务器重启了,需要能从断点继续,而不是从头开始。这要求把 Agent 的每一步状态都持久化到数据库。
并发控制:多个用户同时使用 Agent 系统,每个用户的 Agent 执行是独立的,不能互相干扰。这要求 Agent 服务层支持并发执行和资源隔离。
超时和成本控制:Agent 执行循环可能无限进行下去。Agent 服务层必须设置最大步数、最大时间、最大成本,达到上限就强制终止。
Eval 服务层
Eval(评估)是 Week 5 的核心主题之一。在工程架构里,Eval 也需要独立的服务层。
Eval 服务层负责:管理测试集(维护一批标准的输入-期望输出对)、运行评估(把测试集的输入送入系统,收集实际输出)、对比结果(把实际输出跟期望输出对比,计算各种维度的得分)、生成报告(汇总所有测试结果,输出评估报告)。
Eval 为什么需要独立的服务层?因为 Eval 的使用场景跟正常业务流程不一样。正常业务流程是”用户请求 - 系统处理 - 返回结果”,Eval 流程是”批量测试 - 自动打分 - 生成报告”。两者的执行频率不同(业务流程可能每秒几十次,Eval 可能每天跑一次)、资源消耗不同(Eval 需要跑完整个测试集,消耗大量 Token)、关注点不同(业务流程关心实时性能,Eval 关心整体准确率)。
把 Eval 抽成独立服务层的另一个好处是:它可以在不影响正常业务的情况下后台运行。你可以设定每天凌晨自动跑一次 Eval,监控系统的整体质量趋势。如果某次 Prompt 改动导致质量下降,Eval 报告会在第一时间发现问题。
我们在 Day 31 会深入 Eval 评估体系的设计。
数据库层
AI 应用的数据库层比一般 Web 应用更复杂,因为它需要同时管理结构化数据、文档数据和向量数据。
结构化数据用关系型数据库(MySQL、PostgreSQL)存储。包括:用户信息、项目信息、分析结果、评估记录、系统配置。这些数据有明确的结构,需要事务支持,适合用关系型数据库。
文档数据用对象存储(S3、MinIO)或文件系统存储。包括:上传的 PDF、生成的报告文件、导出的 Markdown。这些数据是大文件,不适合放进数据库。
向量数据用向量数据库(Milvus、Qdrant、Chroma、pgvector)存储。包括:文档切块的 Embedding 向量、用于 RAG 检索。向量数据库专门优化了相似度检索的性能。
数据库层的设计原则是:每类数据用最适合的存储方式,不要用关系型数据库存向量,也不要用向量库存结构化数据。初学者常见的错误是用一个 PostgreSQL 加 pgvector 插件解决所有问题,短期可以,长期向量检索性能会成为瓶颈。
数据库设计还要考虑以下几个表。
用户表:存储用户信息,包括用户 ID、名称、角色、创建时间。权限系统(Day 33 的内容)依赖这个表。
项目表:每个分析任务是一个项目,存储项目 ID、用户 ID、行业名称、状态(进行中/已完成/失败)、创建时间、完成时间。
分析结果表:存储每一步分析的结果,包括结果 ID、项目 ID、分析类型(行业概览/岗位拆解/流程拆解/AI 方案/风险审查)、结果 JSON、模型调用记录、Token 用量、成本、创建时间。
Prompt 表:存储 Prompt 模板,包括 Prompt ID、名称、版本号、模板内容、输入 Schema、输出 Schema、创建时间、更新时间。
评估记录表:存储 Eval 结果,包括评估 ID、测试集 ID、通过率、各维度得分、运行时间、Token 用量。
日志层
日志是 AI 应用运维的基石。没有好的日志系统,出了问题你只能猜。
AI 应用的日志比一般 Web 应用更重要,因为 AI 系统的行为不完全可预测。模型可能返回格式错误的结果、Agent 可能走了一条你没预料到的路径、RAG 可能检索到了不相关的文档。只有日志能帮你回溯到底发生了什么。
AI 应用需要记录的日志类型包括以下几种。
请求日志:每个 HTTP 请求的入参、出参、响应时间、状态码。这是最基本的日志,帮你了解系统的整体运行状况。
模型调用日志:每次调用模型的 Prompt、模型响应、Token 用量、成本、耗时、是否成功。这是 AI 应用最有价值的日志,帮你优化成本、排查质量问题。
Agent 执行日志:Agent 的每一步决策(选了什么工具、传了什么参数)、执行结果、状态变化。这是调试 Agent 行为的关键依据。
RAG 检索日志:每次检索的查询、返回的文档片段、相似度分数、检索耗时。这是评估 RAG 质量的核心数据。
错误日志:所有异常和错误的详细信息,包括堆栈跟踪。这是排障的第一手资料。
日志的存储建议用结构化格式(JSON),而不是纯文本。结构化日志方便后续检索和分析。比如你想查”过去一周所有模型调用失败的记录”,用 JSON 日志一条命令就能查出来,纯文本日志你得人工翻。
文件存储层
AI 应用涉及大量文件操作:用户上传的文档、系统生成的报告、导出的数据。这些文件需要一个专门的存储层来管理。
文件存储层的职责:文件上传(接收用户上传的文档,存储到指定位置,返回文件 ID)、文件下载(根据文件 ID 返回文件内容)、文件管理(列出文件、删除文件、更新文件元数据)、格式转换(把分析结果导出为 PDF、Markdown、Word 等格式)。
开发阶段可以用本地文件系统,上线阶段建议用对象存储服务(S3、MinIO、阿里云 OSS)。对象存储的好处是:容量几乎无限、支持 CDN 加速、支持权限控制、不用担心文件丢失。
文件存储层还需要考虑文件类型校验(只允许上传特定格式的文件)、文件大小限制(防止用户上传超大文件拖垮系统)、文件命名规范(避免文件名冲突和特殊字符问题)。
概念关系图
+------------------------------------------------------------------+
| AI 应用工程架构 |
+------------------------------------------------------------------+
| |
| +----------+ 请求/响应 +--------------------------------+ |
| | | <-------------> | | |
| | 前端 | | 后端 | |
| | (React) | | | |
| +----------+ | +--------+ +-------------+ | |
| | | API 层 |-->| Service 层 | | |
| | +--------+ +-------------+ | |
| | | | | |
| | v v | |
| | +----------+ +----------+ | |
| | | 中间件层 | | DAL 层 | | |
| | | (日志等) | | (数据库) | | |
| | +----------+ +----------+ | |
| +--------------------------------+ |
| |
| +--------------------------------------------------------------+ |
| | 基础服务层 | |
| | | |
| | +----------+ +----------+ +----------+ +----------+ | |
| | | 模型调用 | | Prompt | | RAG | | Agent | | |
| | | 层 | | 管理层 | | 服务层 | | 服务层 | | |
| | +----------+ +----------+ +----------+ +----------+ | |
| | | |
| | +----------+ +----------+ +----------+ +----------+ | |
| | | Eval | | 数据库层 | | 日志层 | | 文件存储 | | |
| | | 服务层 | | | | | | 层 | | |
| | +----------+ +----------+ +----------+ +----------+ | |
| +--------------------------------------------------------------+ |
+------------------------------------------------------------------+
架构的分层逻辑:前端通过 HTTP 跟后端 API 层通信;API 层调用 Service 层处理业务逻辑;Service 层调用基础服务层获取各种能力;基础服务层各自管理自己的资源(数据库、向量库、文件系统、外部 API)。
实战分析
重构项目目录
实战任务的第一步是重构项目目录。如果你之前四星期的代码是散落在各处的脚本和 Notebook,现在是时候把它们组织成一个正式的项目结构了。
项目目录设计的核心原则:按功能模块分目录、配置与代码分离、入口文件清晰。
一个推荐的 AI 应用项目结构如下。
根目录放项目的核心配置文件(依赖声明、环境配置、启动脚本)。然后按功能分目录:API 目录放路由和请求处理;Services 目录放业务逻辑,每个子目录对应一个服务(模型调用、Prompt 管理、RAG、Agent、Eval);Models 目录放数据模型定义(数据库表的 Schema);Utils 目录放工具函数(日志、格式转换、异常处理);Config 目录放配置文件(数据库连接、模型配置、权限配置);Tests 目录放测试代码。
重构项目目录不是简单地移动文件。你需要做的是:梳理现有代码的功能归属、定义模块之间的接口、把散落的逻辑集中到对应的模块里。这个过程本身就是一次对系统架构的深度理解。
拆分服务模块
拆分服务模块的关键是”找边界”。怎么判断一个功能属于哪个模块?问自己三个问题:这个功能的核心职责是什么?它依赖哪些外部资源?谁会调用它?
比如”用模型生成行业概览”这个功能。核心职责是调用模型获取结构化结果。依赖的外部资源是模型 API 和 Prompt 模板。调用者是行业分析 Service。所以这个功能应该放在模型调用层(核心执行)和行业分析 Service(业务编排)的交界处。Service 层从 Prompt 管理层拿到模板、填入参数、交给模型调用层执行、拿到结果后做格式校验、最后通过 DAL 层存入数据库。
拆分过程中最容易犯的错误有两个。第一,Service 层太薄,所有逻辑都在 API 层。这会导致 API 层既处理请求又处理业务,非常混乱。第二,Service 层太厚,把数据库操作、模型调用、格式转换全塞在一个方法里。这会导致 Service 方法动辄几百行,改一处牵动全局。
好的 Service 方法应该控制在一屏以内(大约 30-50 行),做的是”编排”而不是”执行”。它调用其他层的方法来完成具体工作,自己只负责流程控制。
设计数据库表
数据库表设计要从”系统需要存什么数据”出发,而不是”代码里有什么变量”。
AI 应用最核心的数据实体有几个。
用户:系统的使用者。字段包括 ID、名称、角色、创建时间。
项目:一次完整的分析任务。字段包括 ID、用户 ID、行业名称、状态、创建时间、完成时间。
分析结果:项目中的每一步分析输出。字段包括 ID、项目 ID、步骤类型、结果内容(JSON)、模型调用信息、Token 用量、成本。
Prompt 模板:所有 Prompt 的集中管理。字段包括 ID、名称、版本号、模板内容、输入定义、输出定义、创建时间。
评估记录:每次 Eval 运行的结果。字段包括 ID、测试集名称、通过数量、总数量、各维度得分、运行时间。
设计数据库表时的注意事项:每个表必须有主键(推荐用自增 ID 或 UUID);每个表必须有创建时间和更新时间字段;外键关系要明确(分析结果表通过项目 ID 关联到项目表);字段类型要合理(JSON 数据用 JSON 类型而不是 TEXT 类型);适当加索引(查询频繁的字段要加索引)。
画工程架构图
工程架构图是整个系统的”地图”。它不是给客户看的 PPT,而是给开发团队看的施工图。
画架构图时要注意三点。第一,分层清晰。从上到下依次是前端、API 层、Service 层、基础服务层、数据层。同一层内的模块并列排放。第二,标注交互方式。模块之间用什么方式通信(HTTP 调用、函数调用、消息队列、数据库查询)要标清楚。第三,标注数据流向。数据从哪里来、经过哪些处理、最终存到哪里,用箭头标出来。
好的架构图能让新加入的团队成员在十分钟内理解系统全貌。如果你的架构图画了自己都看不懂,说明架构本身有问题,或者图画得不够清晰。
当日产物说明
《AI 应用工程架构图》
一张完整的架构图,包含前端、后端各层、基础服务层、数据层。每个模块标注名称和核心职责。模块之间标注交互方式。这张图是后续所有开发工作的参考蓝图。
质量标准:层次分明、模块职责清晰、交互方式明确、新成员能看懂。
《项目目录结构》
一份文档,描述项目的目录组织方式,每个目录包含什么类型的文件、每个核心文件的职责。这份文档是团队协作的基础约定。
质量标准:目录层级不超过四级、命名规范统一、每个目录都有说明。
《数据库表设计》
一份文档,列出所有数据库表的表名、字段名、字段类型、是否必填、默认值、外键关系、索引。每个表附带一句话说明其用途。
质量标准:字段类型合理、外键关系正确、有索引说明、有示例数据。
《服务模块说明》
一份文档,列出每个服务模块的名称、职责、对外接口、依赖的其他模块。这份文档是模块间协作的契约。
质量标准:每个模块职责用一段话说清楚、接口定义包含输入和输出、依赖关系明确。
常见误区与避坑
误区一:架构设计过度
初学者容易犯的错误是还没写几行代码就开始画架构图,搞了七八层架构,结果实现的时候发现大部分层是空的。架构是随着系统复杂度增长逐步演进的,不是一开始就设计到完美状态。先从三层架构(API - Service - DAL)开始,够用就好。等系统复杂了再加层。
误区二:所有逻辑都塞在一个文件里
另一个极端是没有任何架构意识,所有代码写在一个 main.py 里。这样做的后果是:改一个功能可能影响其他功能;调试困难(不知道问题出在哪);无法并行开发。即使项目很小,也至少应该把 API 路由、业务逻辑、数据访问分成三个文件。
误区三:忽略日志和监控
很多人做 AI 应用只关心”功能能不能跑”,完全不考虑日志和监控。结果上线后模型调用失败了不知道、成本突然涨了不知道、响应变慢了不知道。日志和监控不是”锦上添花”,是运维的必要条件。在架构设计阶段就要把日志层规划好。
误区四:数据库设计随意
AI 应用的数据库设计常犯的错误包括:把 JSON 数据直接存成 TEXT 字符串(查询和统计非常困难)、没有记录创建时间和更新时间(无法做时间维度的分析)、没有做数据关联(想查某个项目的所有分析结果得全表扫描)。数据库设计要在一开始就做好,后期改数据库的成本非常高。
误区五:把 Prompt 写死在代码里
Prompt 是 AI 应用最常改的东西。如果 Prompt 直接写在代码的字符串里,每次改 Prompt 都要改代码、重新部署。正确做法是把 Prompt 放在外部配置或数据库里,跟代码分离。这就是 Prompt 管理层存在的意义。
延伸思考
今天的工程架构设计是后续几天内容的基础。
Day 30 的 Prompt 管理系统,就是架构里 Prompt 管理层的具体实现。你会把今天设计的 Prompt 存储方案变成可运行的管理系统。
Day 31 的 Eval 评估体系,对应架构里的 Eval 服务层。理解了 Eval 在架构中的位置,你就能更好地设计评估流程和数据流。
Day 32 的成本与性能优化,跟模型调用层和日志层直接相关。成本数据从哪里来?从模型调用日志里来。优化在哪里做?在模型调用层和缓存层里做。
Day 33 的安全与权限系统,横跨多个层级。用户权限在 API 层校验,数据权限在 DAL 层控制,工具权限在 Agent 服务层管理,审计日志在日志层记录。
Day 34 的部署与上线,是把今天设计的架构变成可运行的服务。Docker 化、环境变量配置、健康检查,都是为了在真实环境中运行这套架构。
工程架构不是一次设计就永远不变的。随着业务增长、用户增加、功能扩展,架构会持续演进。但一个好的初始架构能让演进过程平滑可控,而不是推倒重来。
自测问题
- 前后端分层的好处是什么?如果前后端不分会遇到什么问题?
- 服务层设计的核心原则是什么?API 层、Service 层、DAL 层各自的职责是什么?
- 为什么模型调用需要单独抽一层?模型调用层应该包含哪些功能?
- Prompt 为什么需要管理?散落在代码里会有什么后果?
- RAG 服务层跟模型调用层的区别是什么?为什么它们需要分开?
- Agent 服务层需要处理哪些工程问题?
- AI 应用的数据库层一般需要几种存储方式?分别存什么数据?
- 日志层需要记录哪些类型的日志?每种日志的作用是什么?
- 如果让你从零开始搭建一个 AI 应用项目,你会怎么组织目录结构?
- 架构设计中最容易犯的错误是什么?怎么避免?
关键词
- 前后端分层:前端负责展示和交互,后端负责业务逻辑和数据处理,两者通过 API 通信
- 服务层设计:按职责将后端拆分为 API 层、Service 层、DAL 层等模块
- 模型调用层:封装所有大模型 API 交互细节的专用服务层
- Prompt 管理层:集中管理 Prompt 模板的版本、参数、测试和效果追踪
- RAG 服务层:封装知识库的文档处理、向量化、检索等全部逻辑
- Agent 服务层:管理 Agent 的创建、配置、执行、结果收集的生命周期
- Eval 服务层:管理测试集、运行评估、对比结果、生成报告的评估系统
- DAL 层:数据访问层,封装所有数据库操作细节
- 结构化日志:以 JSON 格式记录的日志,便于检索和分析
- 文件存储层:管理文档上传、下载、格式转换的专用服务层