尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI Agent实战:问数系统多Agent编排与MCP协议架构设计

AI Agent实战:问数系统多Agent编排与MCP协议架构设计 先说我为什么把「问数」作为这套 AI Agent 实战系列的第一个项目。过去几年只要在企业里做过数据平台就一定遇到过这类需求业务同事跑来问「帮我看看上季度华东区销量为什么跌了」「这个月转化率怎么变化」——这些问题的背后不是复杂建模而是大量的自然语言取数诉求。传统链路是业务提需求、数仓排期、写 SQL、跑数、做表、人工解读来回少说两天问数项目想做的事情就一句话让业务同学直接拿中文提问Agent 自己去理解意图、查元数据、生成 SQL、执行取数、整理结论。这个系列用的是 LCODER 内部的实战项目代号第一篇我先不碰具体代码而是把项目架构彻底讲清楚。因为问数智能体看着简单真正落地时会牵扯到大模型选型、工具调用协议、多 Agent 编排、数据权限、SQL 安全校验、上下文管理等一堆问题如果架构阶段没想明白后续每加一个数据源都要重构一次。这篇文章适合正在做 AI Agent 落地、准备上手自然语言查数、或者想了解 Agent 项目从零搭建时架构怎么设计的同学我会把设计取舍、技术选型、目录结构、核心链路和踩坑经验都梳理出来。1. 项目定位与需求拆解先搞清楚问数智能体到底在解决什么问题1.1 一个典型取数需求背后的真实链路我先把「问数」这个场景还原到具体的业务环境里。假设一家公司有订单表、用户表、商品表分布在不同业务库中日常经营分析全部靠数据团队用 SQL 取数。当管理层问「华东区上季度销量环比变化」时数据团队要做的事是确定业务口径华东区指哪些省份、销量是按订单金额还是件数、定位到正确的表和字段、写出 SQL、到数仓执行、验证结果合理性、再做成看板或表格给管理层。问数智能体的核心目标是把这条链路自动化。它不是一个简单的「SQL 生成器」而是把数据取用的完整过程抽象成智能体行为理解用户问题、确认口径、探查数据、生成查询、执行校验、解释结果。这件事的价值不只是省掉开发时间更重要的是把取数能力从少数数据人员手里释放出来让业务人员也能通过对话直接获得数据洞察。为了控制范围第一版问数项目我圈定了几个明确场景面向内部经营分析场景不面向公网开放用户是公司员工。数据源先支持 MySQL 和 ClickHouse 两类后续再考虑 API 类数据源。交互模式以多轮对话为主支持追问、澄清口径、修正查询条件。结果展示以表格和简单趋势描述为主复杂可视化放到二期。这样圈定之后整个架构就有了清晰的边界不会一上来就被各种长尾需求拖垮。1.2 核心需求拆解把「能聊天」变成「能查数」问数项目最容易被误解的地方是很多人以为把大模型接进来、能对话就是「问数」了。真正落地时会发现聊天只是表皮底下是三层完全不同的能力第一层是语义理解与任务拆解。用户说「看看华东区最近表现怎么样」这里要拆出时间范围最近、地域维度华东区、指标表现需要进一步明确是销量、毛利还是其他、比较对象默认环比或同比。这一层如果做不好后面的 SQL 生成就是空中楼阁。第二层是数据探查与查询生成。拿到语义之后Agent 要先去查数据字典、找对应的表和字段把业务术语映射成物理字段名再生成可执行的 SQL。这一步最大的难点不是 SQL 语法而是「语义对齐」用户说的是「销量」库里的字段可能叫order_amount也可能叫sales_volume不同表含义还不一样。第三层是结果解释与可信输出。SQL 执行出结果后Agent 不能只丢一张表要能用自然语言总结趋势、指出异常、给出初步归因方向。同时它要能回答「这个数是怎么算出来的」让用户信任这个结果而不是觉得黑盒在瞎编。三层能力对应的技术诉求也不同第一层依赖模型推理能力和 Prompt 设计第二层依赖工具调用链路和数据字典质量第三层依赖结果校验逻辑和生成策略。这也是为什么问数项目不适合用一个「超级 Prompt 一把梭」的原因三层诉求相互干扰时单 Agent 方案会越调越乱。1.3 边界划分一期项目坚决不做什么架构设计里最值钱的部分往往是「决定不做什么」。问数项目一期我在边界上做了几个硬性限制不做跨源联邦查询。一期只允许在一个数据源内完成查询跨 MySQL 和 ClickHouse 的联合分析以后再做避免引入分布式查询引擎的复杂度。不做写操作。所有数据库账号只读Agent 无论如何都不会生成 INSERT、UPDATE、DELETE 语句从机制上杜绝数据安全事故。不做实时同步。元数据通过定时任务同步到配置中心不要求毫秒级感知表结构变更跑批周期设为每天一次。不做复杂图表。结果输出以 Markdown 表格、趋势描述为主ECharts 配置生成放二期。这些边界保证了第一版能用最小的成本把链路跑通。实际上很多 Agent 项目死掉不是因为技术做不到而是因为想要的太多架构被各种前置需求撑爆最后连核心链路都不稳定。先把取数这件事做深做透比什么都重要。2. 项目架构设计思路为什么问数项目最终选择了多 Agent 编排模式2.1 单体 Agent 和编排式多 Agent 的真实取舍我在设计架构时第一轮对比的就是「用一个 Agent 干完所有事」还是「多个 Agent 分工协作」。先说单体方案它的优点非常明显链路短、调试简单、上下文不割裂一个会话里模型能完整看到用户从提问到取数的全过程。对于 demo 和几十个问题的内部试用单体方案完全够用。但单体方案在问数场景里有个绕不开的问题职责混杂导致 Prompt 无限膨胀。一个 Agent 既要理解用户意图又要做语义映射还要写 SQL还要解释结果这四类任务的最佳指令风格完全不同。意图理解需要少限制、多推理SQL 生成需要强约束、精确到字段结果解释又需要业务化的表达。全塞在一个 System Prompt 里模型在长对话中非常容易「人格分裂」该严格的地方发散该发散的地方死板。多 Agent 编排的逻辑是让每个 Agent 只干一件事通过调度关系串联。问数场景我拆成了三个角色调度 AgentDispatcher负责理解用户意图判断该走哪条处理链路执掌会话级上下文。取数 AgentQuery Agent负责元数据探查、SQL 生成、SQL 校验与执行。分析 AgentAnalysis Agent负责对查询结果进行解读、生成结论和可视化配置建议。每个 Agent 的 Prompt 独立维护、独立测试哪个环节效果不好就单独调哪个不会牵一发动全身。代价是增加了模块间通信和状态传递的复杂度但从工程可维护性角度来看这个代价完全值得。2.2 多 Agent 的三种协作模型与问数场景的选型多 Agent 不是只有一个套路实际工程里有三种常见的协作模型我分别评估了一遍第一种是顺序流水线模型。A Agent 处理完交给 BB 处理完交给 C没有回头路。优点是实现简单缺点是一旦前面的 Agent 理解错了后面全部白做问数场景里用户问题经常有歧义顺序模型很难兜底。第二种是路由分发模型。调度 Agent 根据意图把请求分发到不同的专业 Agent各 Agent 互不依赖。这个模式适合「任务类型差异极大」的场景但问数项目的核心其实只有一条取数链路路由分发解决不了链路内部的深度问题。第三种是「调度-执行-反馈」模型也是我最终采用的方案。调度 Agent 不直接生成 SQL而是维护一个任务队列取数 Agent 执行具体任务执行失败或发现信息不足时把错误信息和缺失项回报给调度 Agent调度 Agent 可以重新规划任务、让取数 Agent 换个思路再试。这个模型最接近人类数据分析师的工作方式先看问题再查数据发现不对就回头调整多轮迭代直到跑出可信结果。三类模型的对比我整理成了一张表协作模型优点缺点适用场景顺序流水线实现简单、链路清晰上游误差无法修正任务环节少且稳定的场景路由分发各 Agent 独立、扩展性好难以处理链路内部问题任务类型多且差异大的场景调度-执行-反馈能自我修正、贴近真实工作流状态管理复杂、调试成本高需要多轮迭代的复杂任务如取数问数项目最后选了第三种是因为自然语言取数天然是一个「需要试错」的过程用户不会一次性把条件说全Agent 也不可能一次就命中最优表反馈循环是刚需。2.3 架构分层的总览接入层、编排层、工具层的三级结构定了多 Agent 模式之后我再把整个项目按层次拆开。我习惯把 AI Agent 项目分成三层问数项目也不例外接入层负责处理外部请求包括 Web API、会话管理、用户认证和权限校验。这一层不关心业务细节只负责把用户请求安全地交给后端的编排层。编排层是智能体的核心包含调度 Agent、取数 Agent、分析 Agent 的编排逻辑、提示词管理、上下文管理和任务状态机。这一层决定 Agent 怎么思考、怎么决策、怎么调用工具。工具层把外部依赖包装成 Agent 可调用的工具包括元数据查询工具、SQL 执行工具、口径词典工具、权限校验工具等。工具层的设计直接决定了 Agent 的能力边界也是我后面会重点讲 MCP 协议的地方。三层之间通过统一的数据结构通信最核心的是一个叫做「查询任务上下文」的对象它贯穿调度、执行、分析全流程记录用户问题、确认后的口径、生成的 SQL、执行结果、错误信息等关键状态。这个对象是整个架构的毛细血管设计得好不好直接决定了多 Agent 协作顺不顺畅。3. 关键技术选型从大模型到 MCP 协议的落地决策3.1 技术栈选择的底层逻辑Java 主线还是 Python 主线问数项目技术栈的选择我重点评估过两条路线Python LangGraph 和 Java Spring AI Alibaba。Python 路线在 AI 生态里最成熟LangGraph 对图状态和 Agent 循环的原生支持非常契合「调度-执行-反馈」模型写原型速度快社区资料也最多。但问题在于多数做企业数据平台的公司后端主力是 JavaPython Agent 服务要独立部署、独立运维和现有权限体系、数据源管理平台的打通成本很高。Java 路线的优势是工程化能力强。Spring AI Alibaba 提供了 ChatModel、PromptTemplate、Tool Calling 的标准抽象配合 Spring Boot 的自动装配能力可以把 Agent 服务和现有的数据平台无缝集成。缺点是 AI 生态相对 Python 滞后很多新特性要等适配。实际选型时我做了个折中核心 Agent 编排用 Java 17 Spring AI Alibaba元数据管理和工具层也在 Java 体系内实现但模型的 Prompt 调试和效果验证阶段我会用 Python 脚本快速跑实验确定最优 Prompt 后再固化到 Java 的提示词模板里。这样既保证了工程稳定性又不牺牲调试效率。配套的核心组件选型如下大模型主用通义千问系列的 qwen-plus 和 qwen-max复杂 SQL 生成用 max意图识别用 plus兼顾效果与成本。向量库用 Redis Search一是因为现网已有 Redis二是问数场景的向量检索量不大单独引入 Milvus 有点重。SQL 解析与校验用 JSQLParser 做语法解析再叠加自研的只读校验器。会话存储Redis 存短期会话MySQL 存长期知识沉淀。3.2 工具层为什么选择 MCP 协议告别「每个数据源一套接入代码」工具层是问数项目架构里最容易被低估的部分。早期我接触过不少 Agent 项目工具调用基本是写死在代码里的定义几个 Java 方法通过 Tool 注解暴露给模型。这样做的确能跑通但一旦数据源从 MySQL 扩展到 ClickHouse、再扩展到 Elasticsearch每个源都要写一套工具方法、一套鉴权逻辑、一套结果格式化维护成本直线上升。MCPModel Context Protocol解决的就是这个问题。它把「工具提供方」和「Agent 运行时」解耦每个数据源封装成一个标准的 MCP Server对外暴露统一的工具列表和调用接口Agent 侧只需要实现一个 MCP Client就能动态发现和调用所有工具。这个过程很像 USB 接口以前每种设备一个专用接口现在统一成标准协议插上就能用。问数项目的工具层我做了两层 MCP 设计元数据 MCP Server暴露数据表列表、字段详情、表间关系、口径词典等工具供取数 Agent 探查环境。查询执行 MCP Server暴露 SQL 执行工具内置只读校验、超时控制、结果集大小限制。两个 Server 分开是为了在权限上做隔离不是所有 Agent 都有权执行 SQL元数据探查和实际执行必须分开控制。MCP 的另一个好处是协议标准化之后后续接入新的数据源只需要单独部署一个 MCP Server 并注册到 Agent 配置里编排层代码几乎不用改。3.3 Prompt 与模型配置同一模型在不同 Agent 中的差异化设置选好模型后真正决定效果的是 Prompt 工程和模型参数。同一个 qwen-max 在调度 Agent、取数 Agent、分析 Agent 里我做了完全不同的配置调度 Agent 的 Prompt 强调「不要抢活」它只做意图识别和任务分派不需要知道具体的表结构参数上 temperature 调到 0.1保持稳定。取数 Agent 的 Prompt 是所有 Agent 里最复杂的我把「查询步骤强制规范」写进 System Prompt必须先探查元数据、再对齐口径、再写 SQL、再执行校验禁止跳步这里的 temperature 设成 0因为是强规则任务任何创造性发挥都是灾难。分析 Agent 反而允许一定随机性temperature 设 0.4让它在解读结果时有一点多样化的表达避免每次输出完全雷同的废话。此外我还在模型配置层接入了「技能位」机制。所谓技能位就是一组预设的 Prompt 片段和工具集绑定当调度 Agent 识别出「取数」意图它会把取数技能位注入取数 Agent 的运行时当用户要求「用图表展示」分析 Agent 会加载图表配置技能位。这种机制对应了热词里提到的「AI Agent Skill」本质上是把常用的能力组合沉淀成可复用的配置单元让 Agent 不用每次从零推理。4. 项目目录结构与核心模块设计一个可落地的工程骨架4.1 工程目录结构按职责边界拆分的多模块项目架构设计最终要落到工程结构上。问数项目我采用 Maven 多模块结构每个模块的边界和前面的架构分层严格对应lcoder-ask-data/ ├── lcoder-ask-web/ # 接入层Web API、会话管理 │ └── src/main/java/com/lcoder/ask/ │ ├── controller/ # 对话接口、健康检查 │ ├── interceptor/ # 认证、权限、审计日志 │ └── vo/ # 请求响应对象 ├── lcoder-ask-agent/ # 编排层Agent 核心逻辑 │ └── src/main/java/com/lcoder/ask/ │ ├── dispatcher/ # 调度 Agent意图识别、任务分派 │ ├── query/ # 取数 AgentNL2SQL、SQL 校验 │ ├── analysis/ # 分析 Agent结果解读 │ ├── context/ # 会话上下文与状态管理 │ ├── prompt/ # Prompt 模板管理 │ └── skill/ # 技能位配置 ├── lcoder-ask-mcp/ # 工具层MCP Client 与 Server │ └── src/main/java/com/lcoder/ask/ │ ├── client/ # MCP Client 封装 │ ├── server/metadata/ # 元数据 MCP Server │ ├── server/query/ # 查询执行 MCP Server │ └── protocol/ # MCP 通信模型 ├── lcoder-ask-common/ # 公共模块 │ └── src/main/java/com/lcoder/ask/ │ ├── model/ # 领域模型查询任务、字段映射等 │ ├── util/ # 工具类 │ └── exception/ # 统一异常体系 └── lcoder-ask-docs/ # 架构文档、Prompt 调试记录这个结构我最满意的一点是接入层、编排层、工具层完全隔离你可以在不修改编排代码的情况下替换底层模型也可以在不影响接入层的情况下新增一个 MCP Server。各模块间的依赖关系是单向的web 依赖 agentagent 依赖 mcpcommon 被所有人依赖没有循环依赖。4.2 核心模块职责说明每个模块到底负责什么接入层的controller只做两件事接收对话请求、返回流式响应。问数场景里流式返回非常重要因为 SQL 生成和执行为耗时操作如果等全部完成再一次性返回用户会以为系统卡死了。所以我在接入层就集成了 SSE 流式输出让 Agent 的思考过程、工具调用过程、结果生成过程都能实时推给前端。编排层的context包是整个多 Agent 协作的中枢。我定义了一个QueryContext类它包含用户 ID、会话 ID、原始问题、澄清后的口径、选中的表、生成的 SQL、执行结果、错误历史等字段。调度 Agent、取数 Agent、分析 Agent 之间不直接通信所有信息都通过QueryContext传递这样可以非常方便地做日志审计和问题回溯。工具层的client包封装了 MCP Client 的标准化调用方式它对上层暴露的是几个简单的 Java 方法比如listTools()、callTool()底层通过 MCP 协议与各个 Server 通信。之所以不让上层直接调 Server 接口是为了保持编排层对工具层的无知将来 MCP 协议升级或替换成别的方式不会牵连 Agent 逻辑。4.3 配置管理与环境隔离本地、测试、生产怎么区分Agent 项目配置管理比普通后端项目更敏感因为里面含有模型 API Key、数据库只读账号、MCP Server 地址等关键信息。我在每个环境使用独立的配置文件和独立的账号体系本地环境模型用 mock 或沙箱 key数据库指向本地 Docker 起的测试库方便调试。测试环境用真实的模型 API但数据源是脱敏后的样本库SQL 执行结果不会污染真实数据。生产环境全部走配置中心模型 Key 和数据库账号加密存储MCP Server 地址通过服务发现获取。权限设计上问数项目的每个数据库账号都是只读账号并且通过 MySQL 的SET MAX_EXECUTION_TIME和 ClickHouse 的max_execution_time做了语句级超时控制。这部分我建议一定要在项目架构阶段设计好不要等上线了再补否则任何一次权限事故都可能是致命的。5. 核心调用链路与关键流程设计从自然语言到数据结论的完整旅程5.1 打通完整链路意图识别、元数据探查、SQL 生成、执行、解读问数项目最核心的运行链路我拆成六个环节来设计第一步用户输入问题进入调度 Agent。调度 Agent 先做意图识别区分这个问题是「查数」「闲聊」还是「需要澄清」。如果是查数它会检查QueryContext中是否已有会话级的口径信息如果之前聊过且上下文足够就直接进入取数环节否则先返回澄清问题。第二步取数 Agent 启动元数据探查。它会调用元数据 MCP Server把可能的表结构、字段列表拉到上下文中并和用户问题中的业务术语做一次初匹配。这一步非常关键因为直接在生成 SQL 时不探查元数据模型极大概率会编造不存在的字段名。第三步语义对齐与口径确认。取数 Agent 会根据元数据信息和用户问题生成候选的字段映射清单比如「华东区」映射到region east「销量」映射到SUM(order_quantity)。如果存在多个口径它会通过调度 Agent 向用户二次确认而不是自作主张。第四步SQL 生成与本地校验。取数 Agent 基于对齐后的语义生成 SQL先用 JSQLParser 做语法解析再通过自研校验器检查是否包含只读语句之外的操作最后把校验结果写回QueryContext。第五步执行查询。SQL 通过校验后取数 Agent 调用查询执行 MCP Server 执行并获取结果集。执行过程中如果报错错误信息会返回给调度 Agent调度 Agent 决定是换个思路重试还是向用户说明失败原因。第六步分析 Agent 生成结论。执行成功后分析 Agent 基于结果集生成自然语言解读包括总体描述、关键趋势、异常提醒并将结果格式化为 Markdown 表格返回给用户。如果用户接着追问整个流程可以继续基于QueryContext迭代。5.2 上下文管理与会话记忆多轮对话不「失忆」的关键问数项目最容易翻车的不是单轮查询而是多轮对话。用户第一轮问「华东区销量」第二轮问「那毛利呢」第三轮问「和华南比呢」如果 Agent 不记得前面的上下文第二轮直接变成无头问题。我处理多轮上下文的方式是分两层记忆短期记忆放在 Redis保存当前会话最近 N 轮的关键信息包括已经确认的口径、历史 SQL 模板、之前查询的结果摘要长期记忆沉淀到 MySQL保存每个用户的数据偏好比如某个用户习惯把「华东区」理解为包含山东、江苏、浙江、安徽、江西、福建六省下次他再问华东区就直接套用这个口径。还有一个非常实用的设计是「数据血缘记录」。每当一条 SQL 执行成功我会把它的特征提取出来放进一个 SQL 模板库输入问题的关键词、命中的表、使用的字段、生成的 SQL 骨架。下次遇到相似问题时取数 Agent 可以先匹配模板库命中就直接复用历史 SQL 的骨架只修改具体条件这样既快又稳。这个机制在热词中和「知识库 AI Agent」的场景很契合但本质是不同的知识库存的是文档术语模板库存的是成功执行的查询经验。5.3 错误处理与兜底机制Agent 系统不能用「报错」回应一切Agent 系统的错误处理比传统接口复杂得多因为错误来源横跨模型、工具、数据三层。我在架构里设计了三级兜底第一级是模型层面的兜底。当调度 Agent 判断用户问题超出问数能力范围时它会直接给出「这个问题我暂时无法处理可以尝试这样问……」的引导而不是硬着头皮调工具。第二级是执行层面的兜底。SQL 执行报错时取数 Agent 先获取错误信息区分是语法错误、字段不存在还是超时。语法错误和字段不存在会触发自动修正循环最多重试两次超时则直接让调度 Agent 向用户解释查询量太大建议缩小范围。第三级是系统层面的兜底。即使经过多轮重试仍然失败系统也必须保证进程不崩溃、上下文不丢失并生成一段详细的失败日志方便事后复盘。我在QueryContext里加了一个traceId每次请求的所有环节都带上这个 ID排查问题时凭 traceId 就能串起全链路日志。这套错误处理设计本质上是承认 Agent 系统的「不确定性」。传统软件追求确定性输出但 Agent 基于大模型一定会有随机失败架构必须为这种随机性设计好缓冲和恢复机制。6. 常见问题与排查技巧实录问数智能体最容易在哪里翻车6.1 高频问题排查表SQL 幻觉、死循环、口径冲突一次说清问数项目从开发到联调我踩过的坑基本都集中在下面这几个方向我整理成了排查速查表供你直接对照问题现象根本原因排查方向解决方案SQL 里出现不存在的字段名模型没有先查元数据凭训练记忆臆造查看取数 Agent 日志是否调用过元数据工具强制「先查表再写 SQL」步骤校验失败必须重查Agent 在选表和报错间死循环元数据返回的表太多模型反复选错观察调度 Agent 的任务重试次数设置最大迭代上限超限后交回调度 Agent 重新规划两个部门对同一指标口径不一致缺少口径词典模型自行解读检索口径词典命中情况构建业务口径词库冲突时向用户二次确认多轮对话后 Agent 遗忘前文短期记忆只依赖模型窗口未显式保存检查 Redis 会话缓存是否失效显式维护会话上下文每轮对话写入关键信息大表查询超时未设置语句级超时和结果集上限查看查询执行 Server 的超时配置统一加max_execution_time和 LIMIT 限制这里我想特别聊一下「SQL 幻觉」问题它是最隐蔽也最致命的。现象是模型生成的 SQL 语法完全正确但查出来的表或字段在数据库里根本不存在。根因在于取数 Agent 跳过了元数据探查步骤直接凭模型的训练记忆生成了 SQL。解决办法不是做更多提示词约束而是把「必须先调用元数据 MCP Server」变成一条无法跳过的强制步骤在代码层面校验工具调用顺序调用顺序不合法就直接拒绝进入下一步。6.2 前期踩坑记录三个让我重构架构的教训做问数项目期间有三次踩坑直接推动了我重构架构我觉得比任何成功经验都值得分享。第一个坑是「无限制的 Agent 循环」。早期设计里取数 Agent 可以在 SQL 报错后无限重试结果测试时有一次模型连续 7 次生成同样的错误 SQL白白消耗了大量 token 和时间。后来我加了重试上限和指数退避策略并把多次失败后的控制权交还给调度 Agent让它可以尝试换一个思路比如简化查询条件或换个表。第二个坑是「 Prompt 管理失控」。最开始 Prompt 全部散落在各个 Agent 类的代码里每次调试 Prompt 都要改代码、重新部署效率极低。后来我把 Prompt 全部外置成模板文件再结合热词里提到的「AI Agent Skill」思路把不同场景的 Prompt 片段做成可插拔的技能包调 Prompt 变成改配置、发布配置彻底和代码解耦。第三个坑是「把业务数据全部塞进向量库」。早期设计时我想着把各种业务日报、分析报告都灌进向量库让 Agent 查询时先检索相关资料。结果发现这些文档和结构化数据查询基本不相关检索出来的片段噪音很大还会把取数 Agent 的思路带偏。后来我把向量库的定位收缩为「仅存储元数据说明和口径词典」效果立刻好了很多这也印证了一个原则知识库服务于 Agent 的决策质量而不是服务于最终答案。6.3 监控与效果评估Agent 项目怎么衡量好坏最后说一个架构阶段容易被忽略、但上线后一定会被问的问题怎么评估 Agent 做得好不好。传统接口可以用响应时间、错误率来衡量但 Agent 系统还需要评估「任务成功率」和「结果可信度」。我在架构里设计了一套评估数据集包含 200 条覆盖不同难度的问数用例每天定时把线上真实请求和用例集灌到测试环境用大模型自动打分的方式评估每条回答的质量。评估维度有四个意图识别是否准确、生成的 SQL 是否合理、结果解读是否准确、多轮交互是否自然。每次上线模型或修改 Prompt都先跑一遍回归评估效果不降级才允许发布。这套评估体系是问数项目架构里投入产出比最高的部分它让优化工作从「感觉上变好了」变成了「指标上变好了」。如果你做 Agent 项目我强烈建议在一开始就把评估集建起来哪怕只有几十条用例也比上线后凭感觉找问题要强得多。回到架构本身如果让我重新设计一遍我最想优化的点是模块间的可观测性现在虽然每个环节都有日志但各模块日志分散在不同存储里跨模块链路追踪还需要手工拼凑 traceId。下一步我计划把全链路日志统一采集到一套追踪系统把每轮 Agent 的思考过程、工具调用、决策依据全部可视化出来这样不管是调 Prompt 还是排查线上问题效率都能再上一个台阶。这个系列后面几篇会从项目架构进入详细实现下一篇准备专门讲取数 Agent 的实现细节包括元数据探查怎么做、SQL 校验规则怎么定、多轮上下文怎么管理我们下一篇实战见。
返回列表