Skip to content

从自然语言到正确数据:认知澄清 ​

2026-08-13。回答:步骤是什么、为何禁止 Text-to-SQL、要不要 MCP、要不要训练模型、评测话术干什么、为什么感觉很难。


0. 先纠正最常见的三处偏差 ​

你原来的图景大致是:

系统先提供 MCP
  → 把自然语言翻译成 LLM 能听懂的话
  → LLM 把拿到的数据整理成报告

更接近事实的图景是:

用户原话直接进 LLM(LLM 自己就是「理解自然语言」的那一层)
  → LLM 只输出结构化意图 / 选哪个工具 / 填什么参数
  → Java Tool 按白名单去查库、算指标(数据真相在这里)
  → 把「已经算好的表」再交给 LLM 写人话 / 做报告

三处偏差:

你的理解更准确的说法
先要有 MCP,AI 才能知道怎么取数MCP 只是工具的一种对外协议。对内更常见的是 Function Calling / Tool,本质就是调你已经写好的 Java 方法
先有一层 NLU,把人话翻译给 LLM没有单独的翻译层。LLM 读的就是用户原话;你要约束的是它的输出格式(JSON Intent),不是再发明一种「LLM 语言」
数据交给 LLM 去整理、分析、出数LLM 不负责出数。转化率、退款率必须 Java/SQL 算完,LLM 只解释和润色。否则它会编数字

医院挂号 / 营养餐如果看起来像「自己训练了一个模型」,多数其实是:固定流程 + 业务工具 + 提示词(偶尔再加领域微调)。你现在做数据分析助手,不需要训练模型。


1. 一次请求到底走几步 ​

以 B 端这句话为例:

帮我分析五一活动的订单转化情况,重点看退款率异常的产品,最后生成一份运营报告。

步骤 1:接入与鉴权(你的系统,不是 LLM) ​

用户已登录 Admin。请求带上 userId、角色。后面每个 Tool 都带着这个身份,不能换成超级管理员。

步骤 2:LLM 做「理解」,只输出结构,不碰库 ​

把用户原话 + System Prompt(角色、只允许的意图、JSON Schema、禁止编造)发给模型。期望得到类似:

json
{
  "intent": "CAMPAIGN_EFFECT_ANALYSIS",
  "campaignHint": "五一活动",
  "period": { "preset": "MAY_DAY_2026" },
  "focus": ["CONVERSION", "REFUND_RATE_ANOMALY"],
  "deliverable": "OPS_REPORT_MARKDOWN"
}

这一步没有访问数据库。模型不知道五一对应哪些 activityId,也不知道退款率是多少。

评测话术(C001、C009…)测的主要就是这一层:意图对不对、槽位抽得对不对、该拒的有没有拒。

步骤 3:Java 补全与校验(确定性代码) ​

  • 「五一活动」可能对应 1 个或 N 个活动 → 不够就追问,或按运营配置的活动集合解析
  • 时间窗写成具体日期
  • 当前用户有没有权限看这些活动的订单
  • 意图若是「取消活动并退款」→ 直接拒绝,不进后续 Tool

步骤 4:按固定工作流调 Tool(仍然是你的代码) ​

不是让模型即兴写 SQL,而是走已经写死的步骤:

get_campaign
  → query_campaign_orders
  → query_refund_statistics
  → calculate_campaign_metrics   // 转化率、退款率在这里算

每个 Tool ≈ 一个受约束的 ApplicationService 方法:入参 Schema、权限、超时、审计。

数据正确性的保证在这一层,不在 LLM。 工具返回什么,库里就是什么。LLM 看不到连接串,也拼不出 SELECT * FROM users。

步骤 5:异常用规则标,不用模型「感觉」 ​

例如:退款率 > 20% 或同比 +50% → 标 SEVERE。阈值写在代码或配置里。

步骤 6:LLM 第二次出场——只看表,写报告 ​

把 已经算好的 JSON/表格 塞进 Prompt:

以下数据由系统计算,禁止改数字、禁止补充表中没有的活动。
[metrics table]
请用中文写运营报告:结论、异常产品、可能原因(仅基于表内字段)、建议。

模型可以写「A 活动退款率 28%,高于阈值」,不能把 28% 改成 12%,也不能发明一个不存在的产品。

步骤 7:人确认后保存 ​

报告预览 → 运营点确认 → 落库。这是企业助手能上线的关键,不是可选装饰。


2. 为什么反复说「不要 Text-to-SQL」 ​

Text-to-SQL = 让模型根据人话直接生成 SELECT ... 打生产库。

问题:

  • SQL 很容易错:JOIN 漏了、时间区切错、把「转化率」写成订单数/UV 的错误分母
  • 不安全:提示注入可以诱导出 DROP / 扫全表 / 读手机号(你评测里的 C012)
  • 口径漂移:今天一种 SQL,明天另一种,报表对不上
  • 权限难做:模型生成的 SQL 很难按「这个运营只能看自己负责的活动」过滤

正确替代:

人话 → Intent JSON → 白名单 Tool → 你写好的查询/聚合

模型选的是 query_campaign_orders(campaignId, start, end) 这种函数,不是任意 SQL。
这和你平时写 Controller 调 ApplicationService 是同一件事,只是触发方式从「点按钮」变成「说话」。

C 端同理:不是「帮我写一段查活动的 SQL」,而是填 ActivitySearchCriteria 再调已经存在的 searchActivitiesAdvanced。


3. MCP 是什么、要不要「全部 MCP」 ​

Tool / Function Calling(你真正要用的) ​

模型 API 支持:你声明一批函数(名字、描述、参数 JSON Schema),模型返回「我要调哪个、参数是什么」,你的服务器执行后再把结果喂回模型。

对接 TourMate:

AssistantApplicationService
  → ILlmPort(Spring AI)
  → SearchActivitiesTool / GetCampaignTool
  → 现有 IActivityQueryApplicationService 等

这就是嵌入当前系统的默认方式。不是 MCP。

MCP(可选外壳) ​

MCP 是一套开放协议:让 Claude Desktop、Cursor 等客户端,用统一方式发现和调用你的工具。

Tool Use  = 业务能力(查活动、查订单)
MCP       = 把这些能力暴露给「别的 AI 客户端」的插头

类比:你已经有 REST API;OpenAPI 是说明书;MCP 有点像「给 Agent 用的说明书 + 调用约定」。

阶段用什么
C 端 / B 端助手嵌在 TourMate 里主站内 Function Calling + Java Tool
想让 Cursor / Claude 也能查旅搭订单再包一层 tour-mate-mcp-server
一上来全部 MCP不建议:多一层鉴权、部署、排障,对内聊天框没有收益

「计划去新疆的出游」不是「做一个 MCP 就完了」。MCP 最多暴露 search_activities、get_weather 这类工具;真正难的是:槽位是否抽对、无结果怎么问、卡片是否真实、用户会不会点进去。工具只是零件。


4. 医院挂号 / 营养餐:多半不是「从零训练了一个大模型」 ​

你看到的产品,常见组合是:

能力通常怎么做
听懂「7 天营养餐」「嗓子痛」Prompt + 结构化输出;有的会做小规模微调(分类/抽槽)
列出真实餐品 / 可挂医生Tool 查库存/号源,和是否微调无关
合计金额、支付、按日派单原订单系统,模型不碰钱
独立服务器上的 Qwen / DeepSeek多数是 部署开源权重做推理(自托管),不等于「用你们业务数据训练出一个新模型」

三种容易混的词:

说法含义你现需要吗
调用模型HTTP 调 Qwen/DeepSeek/OpenAI✅ 要
自托管开源模型GPU 上跑 vLLM 等,数据不出机房可选,后期成本/合规再考虑
训练 / 微调改模型权重(SFT、LoRA)❌ 第一期不要

判断是否微调:Prompt → 结构化输出 → RAG → Tool → 工作流,都解决不了再评估。
数据分析、活动检索都属于「知识在库里、口径在代码里」——微调帮不上忙,还引入数据集和评测地狱。


5. 怎么保证 LLM 拿到的是正确数据? ​

不靠「相信模型」,靠 管道设计:

  1. 模型拿不到库。 它只能调用你声明过的 Tool。
  2. Tool 返回的就是查询结果。 正确性 = 你现有 searchActivitiesAdvanced / 订单聚合对不对(跟有没有 AI 无关)。
  3. 第二次调用时只喂表,并写死「禁止改数字、禁止补行」。
  4. 报告里带出处。 「转化率 12.3%(订单 32 / 曝光 260,来源 query_campaign_orders)」——人可以点开对账。
  5. 对账抽检。 同一活动用助手出的数 vs Admin 报表页,必须一致。不一致就是 Tool/口径 bug,不是「模型不够聪明」。

C 端更硬:活动卡片的 activityId/title/price 必须来自 Tool 返回值 原样拷贝,禁止模型重写标题或编一个 id。


6. 怎么保证每次结果差不多一致?评测话术是不是在测这个? ​

LLM 默认 非确定性(温度、措辞都会变)。企业做法是分层:

层要稳定的东西怎么保证
意图 / 槽位「五一 + 转化 + 退款异常 + 要报告」结构化输出 + 低温度 + 评测话术
工具选择调了该调的 Tool、没调禁止的评测:是否 call tool、参数对不对
数字转化率、退款率代码计算,与 LLM 无关;同一输入同一输出
报告文案可以略有出入不要求逐字相同;要求不改数、不编活动、结构完整
拒答 / 安全C009 写游记、C012 要手机号评测集必须覆盖

所以:

  • 评测话术 = AI 应用的测试集(测理解、抽槽、拒答、是否乱调工具)
  • 它不测「报告是否每个字一样」,也 不测「数据库算得对不对」(那是单测/对账)
  • 数字一致性靠 Java;理解一致性靠评测 + 固定 Schema;文案允许轻微波动

同一句话跑 10 次:Intent JSON 应几乎一样;报告用词可以不同,但表中的 28% 必须还是 28%。


7. 为什么感觉很难?难的不是 MCP ​

难的是 约束一个会胡说的模型,去驱动一个已经正确的业务系统:

  • 边界:什么能查、什么必须拒、什么要人点确认
  • 槽位:用户说半句时追问,而不是猜错时间去查
  • 口径:转化率分母是曝光还是报名,必须唯一
  • 评测:50 句话里越权 0、虚构 0
  • 体验:慢、贵、用户以为万能

容易的部分你已经有了:活动搜索、订单、退款、权限、DDD Port。
助手只是新开一扇「用说话触发这些 Port」的门。

C 端 MVP 甚至更窄:

人话 → Intent → ActivitySearchCriteria → searchActivitiesAdvanced → 卡片 + deep link

这里连「第二次让 LLM 写长报告」都可以极短(一句话复述条件即可)。
B 端「五一分析」才需要工作流 + 二次生成;仍然 不是 先上 MCP、也 不是 先训练模型。


8. 嵌进当前系统:推荐对接图(不是全部 MCP) ​

App / Admin 对话 UI
    → POST /api/assistant/chat  (Trigger)
    → AssistantApplicationService
         ├─ ILlmPort.structured(用户原话) → Intent
         ├─ 校验权限、补默认时间
         ├─ ToolDispatcher
         │     search_activities → IActivityQueryApplicationService
         │     get_campaign / query_orders / query_refunds → 现有查询
         │     calculate_metrics → 纯 Java
         └─ (可选)ILlmPort.report(指标表) → Markdown
    → 卡片 / 报告预览
  • 第一期:零 MCP、零微调、零 Text-to-SQL
  • 模型:先云端 API(通义/DeepSeek 等);自托管是运维选项
  • MCP:仅当需要被 Cursor 等外部 Agent 复用同一批 Tool 时再做

9. 一句话对照表 ​

问题答案
自然语言怎么变成数据?LLM 抽 Intent → Java Tool 查数/算数 → (可选)LLM 写人话
要 MCP 吗?对内不要;Tool Calling 就够
要训练模型吗?不要;要的是正确 Tool + 评测
数据对不对?看 Tool 是否复用现网查询;报告禁止改数
结果稳不稳?数字靠代码;理解靠评测话术;文案允许略变
出游计划是不是就是 MCP?不是。MCP 只是插头;计划能力是流程 + 工具 + 产品边界

Powered by VitePress