# 市民请集合智能助手 Agent 设计复盘与改造方案
日期:2026-06-05
## 结论摘要
当前版本已经不是纯聊天窗口,而是一个“桌面端 + MCP + DeepSeek + 只读数据库工具”的 Agent 原型。它的优点是边界清楚、安全意识强、MCP 已经接管了 DeepSeek 和数据库配置;但它仍然更像“AI 帮忙挑固定任务”,还不是成熟的业务智能体。
更成熟的 Agent 应该是:模型根据用户目标自主规划,按需调用工具,拿到结果后继续判断是否还需要查数据库、查外部页面、生成表格或进入人工确认,直到给出可执行、可审计、可下载的结果。工具和安全边界由系统控制,决策和编排尽量交给模型。
一句话方向:从“前端/代码规则驱动的任务助手”升级为“模型驱动、工具受控、可追踪的业务 Agent”。
## 当前设计
当前项目分成两部分:
- `smqjh-admin-agent`:Electron 桌面端,负责窗口、对话 UI、后台登录会话、IPC、表格渲染、导出和本地任务执行。
- `smqjh-mcp-server`:Java MCP 服务,负责本机配置读取、DeepSeek 调用、只读数据库查询、业务工具注册和工具结果返回。
当前链路大致如下:
```mermaid
flowchart LR
User["管理员自然语言输入"] --> UI["Electron 对话界面"]
UI --> Orchestrator["AssistantOrchestrator"]
Orchestrator --> Plan["MCP DeepSeek 工具规划"]
Plan --> Tools["MCP 工具或本地任务"]
Tools --> DB["MySQL 只读查询"]
Tools --> Cloud["smqjh 网关接口"]
Tools --> Market["慢慢买/苏宁公开价格线索"]
Tools --> Summary["MCP DeepSeek 总结"]
Summary --> UIResult["回答 + 表格 + 导出"]
```
已经具备的能力:
| 能力 | 当前状态 |
| --- | --- |
| 桌面端 EXE 原型 | 已有 Electron 框架和界面 |
| 后台登录会话 | 已支持,并持久化 token |
| DeepSeek | 已迁移到 MCP 侧托管 |
| 数据库查询 | 已支持只读 SELECT、白名单表、默认 LIMIT、超时和只读事务 |
| 商品查询 | 已有 `smqjh.product.lookup.summary` |
| 订单统计 | 已有 `smqjh.order.count.query` |
| 通用 SQL 查询 | 已有 `smqjh.database.readonly.query` |
| 商品比价 | 已支持系统价 + 慢慢买/苏宁线索 |
| 月结需求 | 已有 `smqjh.settlement.monthly.plan` 规划工具 |
## 当前主要问题
### 1. 编排仍然偏一次性
现在的主流程基本是:
1. DeepSeek 判断一次要不要用工具。
2. 最多执行 3 个工具。
3. 再让 DeepSeek 总结结果。
这个流程缺少成熟 Agent 常见的循环能力:如果工具结果为空、SQL 字段不对、查到多个候选、需要再查明细,模型应该基于观察结果继续调用下一步工具,而不是直接结束或让用户自己查。
这解释了之前出现的体验问题:模型能识别意图,也能生成 SQL,但系统没有把 SQL 自动执行并回填结果。
### 2. 工具分布有点混乱
一部分能力在 MCP:数据库、DeepSeek、配置、订单统计、商品查询。
另一部分还在桌面端本地任务:商品比价、部分导出、市场页面抓取。
这样会导致模型眼里的工具不完整,桌面端还承担了太多业务逻辑。更好的做法是 MCP 统一暴露业务工具,桌面端只负责展示、会话和文件下载。
### 3. 表结构上下文不足
现在 DeepSeek 主要靠提示词里的“常用表、常用字段、SQL 示例”来生成查询。这个方式能跑起来,但不够稳。真正要让它智能查询数据库,需要把表结构、字段说明、业务口径、逻辑删除规则、金额单位等作为 MCP resources 或专门的 schema 工具提供。
否则模型会出现:
- 表名猜错。
- 字段单位搞错。
- 商品关键词提取不准。
- 同一个需求在不同问法下表现不一致。
### 4. 业务结果还没有完全“产物化”
用户要的是结果,不是过程。比如:
- “帮我做表格”应该直接生成 Excel,并给出下载/打开入口。
- “查订单物流状态”应该直接给表格。
- “生成月结报告”应该输出结算表、核对表、异常清单。
- “有差异”应该自动标记“需人工确认”。
当前已经能渲染一些表格,但文件产物、任务状态、异常清单和后续复核动作还需要变成一等能力。
### 5. UI 需要表达 Agent 的过程
现在用户看到“思考中”“处理中”时,不知道系统到底在做什么。成熟的 Agent UI 应该能显示:
- 正在理解意图。
- 正在调用哪个工具。
- 正在查询哪类数据。
- 已拿到多少条结果。
- 是否生成文件。
- 哪些地方需要人工确认。
这不是花哨交互,而是让管理员信任结果。
## 市场上主流 Agent 的正确制作步骤
下面不是某一家产品的唯一标准,而是目前 OpenAI、LangChain、Anthropic、MCP 等主流 Agent 体系共同体现出的落地路径。
### 标准步骤
| 阶段 | 应该做什么 | 关键产物 |
| --- | --- | --- |
| 1. 定义业务目标 | 先明确 Agent 要替谁完成什么工作,不是先做聊天框 | 场景清单、成功标准、风险分级 |
| 2. 设计工具边界 | 把系统能力封装成工具,模型只能通过工具读写业务系统 | Tool schema、权限、输入输出规范 |
| 3. 提供上下文 | 给模型表结构、接口说明、业务口径、示例和历史上下文 | MCP resources、业务知识库、字段字典 |
| 4. 建立 Agent 循环 | 模型规划、调用工具、观察结果、继续规划、最终回答 | 多轮工具调用循环、最大步数、失败重试 |
| 5. 加安全护栏 | 对写操作、敏感数据、金额、发券、结算确认加人工审批 | 只读限制、审批流、审计日志、脱敏 |
| 6. 结构化输出 | 让模型输出表格、JSON、Excel、任务状态,而不是长文本 | 表格 schema、artifact 文件、下载入口 |
| 7. 做评测集 | 用真实管理员问题持续测试准确率 | eval 用例、回归测试、工具调用追踪 |
| 8. 上线监控 | 记录调用链、失败原因、耗时、SQL、工具结果 | tracing、日志、告警、成本统计 |
### 官方资料参考
- [OpenAI: A Practical Guide to Building Agents](https://cdn.openai.com/business-guides-and-resources/a-practical-guide-to-building-agents.pdf)
- [OpenAI Agents SDK 文档](https://platform.openai.com/docs/guides/agents)
- [LangChain Agents 文档](https://docs.langchain.com/oss/javascript/langchain/agents)
- [Anthropic: Building Effective Agents](https://www.anthropic.com/engineering/building-effective-agents)
- [Model Context Protocol 官方文档](https://modelcontextprotocol.io/docs)
## 当前方案与主流做法对比
| 对比项 | 当前 smqjh-agent | 主流成熟 Agent | 建议 |
| --- | --- | --- | --- |
| 决策方式 | DeepSeek 一次性选择工具 | 模型循环规划,按观察结果继续行动 | 改成多步 agent loop |
| 工具来源 | MCP + 本地任务混合 | 工具集中注册,schema 清晰 | 统一迁移到 MCP |
| 数据库能力 | 有只读 SQL 工具,但表结构靠提示词 | schema/resource + SQL 执行 + 校验 | 增加 schema 查询工具 |
| 结果展示 | 文本和部分表格 | 文本、表格、文件、状态、依据分离 | 增加 artifact 层 |
| 人工确认 | 主要靠 dryRun 和文案 | 写操作前强制审批,差异自动标记 | 做审批/复核队列 |
| 业务知识 | 写在 prompt 和代码里 | 可维护的业务知识库和字段字典 | 建立 `business-schema` 文档/资源 |
| 可观测性 | 有日志,但链路不完整 | 每次工具调用、SQL、耗时、错误可追踪 | 增加 trace 面板 |
| 评测 | 暂无固定问题集 | 用真实问题做回归评测 | 建管理员问题 eval 集 |
## 推荐目标架构
```mermaid
flowchart TB
UI["Electron 桌面端
只负责展示、登录、文件入口"] --> Agent["Agent Runtime
多步规划和工具循环"]
Agent --> MCP["Java MCP Server
统一工具和资源"]
MCP --> LLM["DeepSeek
意图判断、SQL 草拟、总结"]
MCP --> Schema["业务 Schema Resource
表结构、字段、业务口径"]
MCP --> DB["MySQL 只读连接池
SELECT 校验、限流、审计"]
MCP --> API["smqjh-cloud API
登录态、导出、业务接口"]
MCP --> Market["外部价格工具
慢慢买、苏宁、后续授权平台"]
MCP --> Artifact["文件产物服务
Excel、报告、异常清单"]
```
核心原则:
1. 桌面端少做业务判断,只做展示和用户交互。
2. MCP 统一提供工具、资源、提示词和安全边界。
3. DeepSeek 负责判断“下一步查什么”,系统负责“能不能查、怎么安全查”。
4. 数据库查询默认只读,写操作必须进入人工确认。
5. 所有结果都要有依据:SQL、接口地址、外部请求地址、文件来源。
## 需要优先调整的点
### 第一阶段:让它真正像 Agent
目标:解决“识别到了但不执行”“问法变化就不会查”“回答不连贯”。
建议改动:
1. 把 `AssistantOrchestrator` 改为多步循环:
- 第一步让 DeepSeek 判断下一步动作。
- 执行工具。
- 把观察结果再喂给 DeepSeek。
- 如果还需要查,就继续。
- 最多 5 到 8 步,避免无限循环。
2. 增加一个 MCP 工具:`smqjh.database.smart.query`。
- 输入:管理员自然语言问题。
- 内部:DeepSeek 根据 schema 生成 SELECT。
- 校验:只读 SQL、安全表、LIMIT、逻辑删除。
- 输出:执行 SQL、表格 rows、依据、口径说明。
3. 增加 schema 工具或资源:
- `smqjh.schema.search`
- `smqjh.schema.getTable`
- `smqjh.schema.businessRules`
4. 明确规则:只要用户问的是业务系统事实,Agent 不应该回复“你可以去后台查”或“你可以执行 SQL”,而是自己调用工具。
### 第二阶段:把业务产物做完整
目标:让“查询、比价、月结、订单、物流、商品描述”都能输出表格和文件。
建议改动:
1. 增加通用表格输出 schema:
- `title`
- `columns`
- `rows`
- `summary`
- `evidence`
- `warnings`
2. 增加文件产物工具:
- `smqjh.artifact.excel.create`
- `smqjh.artifact.open`
- `smqjh.artifact.list`
3. 月结功能拆成工具链:
- `smqjh.settlement.enterprise.list`
- `smqjh.settlement.export.inputs`
- `smqjh.settlement.reconcile`
- `smqjh.settlement.report.create`
- `smqjh.settlement.confirmation.mark`
4. 商品价格对比工具继续保留,但迁移到 MCP:
- 系统商品价先查数据库。
- 外部价格优先查慢慢买和苏宁。
- 结果必须包含平台、商品名、总价、折算单价、规格匹配度、依据地址。
- 规格不一致时标记“需人工确认”。
### 第三阶段:上线治理
目标:支持多个客户端使用,降低对业务系统影响,并可审计。
建议改动:
1. MCP 从“每台客户端本机服务”逐步演进为“内网中心 MCP 服务”。
- 10 个客户端都各连 MySQL,短期可以接受。
- 但长期更建议集中 MCP,统一连接池、限流、审计和权限。
2. 数据库只读连接池:
- 每个查询短连接也能用,但不利于限流。
- 中心 MCP 可以用 HikariCP 之类连接池。
- 限制最大连接数、查询超时、默认 LIMIT。
3. 权限分级:
- 只读查询:自动执行。
- 导出文件:自动生成,但记录日志。
- 发券、充值、结算确认、修改订单:必须人工确认。
4. 追踪和评测:
- 每次记录用户问题、选用工具、SQL、耗时、结果行数、失败原因。
- 建一批真实问题作为回归评测,例如:
- 当前百事可乐 500ml 的商品描述是什么?
- 某手机号下了多少单?
- 某订单物流状态是什么?
- 铜仁移动 2026 年 5 月月结报告生成。
- 某商品和慢慢买/苏宁做价格对比并导出 Excel。
## 针对当前痛点的具体调整
| 痛点 | 原因 | 调整方式 |
| --- | --- | --- |
| SQL 生成了但不执行 | 编排把 SQL 当成回复内容,没有进入工具执行 | `smart.query` 内部生成并执行 SQL |
| 问“商品描述”白屏 | 前端或工具结果异常没有兜底 | 加 ErrorBoundary、IPC 异常兜底、结果 schema 校验 |
| 问订单物流状态不会查 | 没有专门工具时编排不敢走通用数据库查询 | 通用业务事实统一走 `database.smart.query` |
| 商品比价像固定规则 | 前端/本地任务承担了太多判断 | 迁移到 MCP,由 DeepSeek 决定搜索词和筛选口径 |
| 表格显示不稳定 | 文本 Markdown 和表格混在一起 | 回答文本和 `tables` 分离渲染 |
| 需要 Excel 但没有文件 | 文件不是一等产物 | 增加 artifact 工具,结果直接给文件入口 |
| 多客户端怕影响数据库 | 每客户端直连无法统一治理 | 中期改中心 MCP,连接池和限流 |
## 是否需要改成 Python + LangChain
不建议现在为了“更智能”直接大换语言。
原因:
- 当前真正的问题不是 Java、TypeScript 或 Python,而是 Agent loop、工具 schema、schema 上下文、结果产物和评测没有完善。
- Java MCP 很适合贴近现有 Spring/Java 业务系统,也方便后续做内网服务、权限和审计。
- Electron + TypeScript 做桌面端合适,MCP 侧 Java 做业务工具也合适。
可以考虑的折中:
- 短期:继续 Java MCP + Electron,把 Agent loop 和工具体系补完整。
- 中期:如果要做复杂多 Agent 编排、长期记忆、评测平台,可以单独增加 Python/LangGraph 服务,但不替换现有 MCP。
- 长期:MCP 保持为业务工具网关,Agent runtime 可以是 Java、TypeScript 或 Python,按团队维护成本选。
## 推荐下一步开发清单
优先级 P0:
1. 新增 `smqjh.database.smart.query`。
2. 桌面端编排改成多步工具循环。
3. 工具结果和表格结果分离,前端稳定渲染。
4. 加 ErrorBoundary,避免单次异常白屏。
5. 输出内容必须包含依据。
优先级 P1:
1. 商品比价迁移到 MCP。
2. 增加 Excel artifact 工具。
3. 增加 schema resource 或 schema 查询工具。
4. 月结结算报告工具链落地。
5. 增加工具调用日志和 trace 面板。
优先级 P2:
1. 中心 MCP 部署方案。
2. 数据库连接池、限流、慢 SQL 告警。
3. 人工确认和审批队列。
4. 管理员问题评测集。
## 最终目标体验
管理员输入:
> 当前百事可乐 500ml 的商品描述是什么?
Agent 应该自动:
1. 判断这是业务系统事实查询。
2. 查 schema,定位商品表和 SKU 表。
3. 生成只读 SQL。
4. 通过 MCP 执行。
5. 返回商品描述、商品状态、价格、规格、依据 SQL。
管理员输入:
> 帮我生成铜仁移动 2026 年 5 月月结报告。
Agent 应该自动:
1. 识别企业和月份。
2. 调用导出接口或读取上传表。
3. 读取订单、运费、员工积分表。
4. 按规则计算商品总额、运费、积分抵扣、现金支付、差异。
5. 标记需人工确认项。
6. 生成 Excel。
7. 给出下载入口和核对摘要。
管理员输入:
> 查一下这个订单的物流状态。
Agent 应该自动:
1. 从输入中提取订单号。
2. 查询订单表、配送字段、快递单号。
3. 如果需要,调用物流接口或提示暂无物流接口。
4. 用表格给出订单状态、配送状态、快递公司、运单号、更新时间和依据。
这才是我们要做的“智能体”,而不是让管理员根据按钮或固定任务项自己拼流程。