当业务逻辑变成“文本→结构化数据”,if/else 就不再是工具,而是债务
一句话概览
最近在做一些开发项目的时候,越来越觉得现在的软件开发不够AI NAIVE,就想着构思一个框架:接收自然语言,按照你定义的规则,输出可被下游消费的结构化数据。它不是要替代 Function Call、MCP 或现有组件,而是成为它们前面的“语义理解层”。
一、背景:真实到令人头疼的三个场景
场景一:那个凌晨两点的紧急需求
产品经理发来消息:“用户反馈说,能不能把我们客服聊天记录里的差评自动分类一下?就是那种‘物流慢’、‘质量差’、‘态度不好’……大概分个五六类就行,明天能用上吗?”
你心里清楚:写正则?维度太多。训练分类模型?时间不够。最终你选择了大模型。
第二天你交了代码:一个 Python 脚本,调 OpenAI API,prompt 写在三引号字符串里,输出用正则硬拆。能用,但你知道这是一颗定时炸弹。
一个月后,分类维度变成 12 类,prompt 被改了 20 多次,那段正则已经没人敢动了。每次改一个词都要重新测全量样本。组里新来的同事问:“这段逻辑为什么要这么写?”你沉默了几秒,说:“因为当时只有两天。”
场景二:那个被 if/else 淹没的“智能客服”
你们做了一个 AI 客服,用户可以问各种问题:“订单到哪了?”“我要退货”“你们公司几点下班”“帮我查一下积分”“机器人你好可爱”……
你用了大模型做意图识别。最初 5 个意图,代码很优雅。后来变成 12 个。再后来变成 30 个。现在的代码长这样:
if "订单" in text or "物流" in text or "快递" in text:
if "在哪" in text or "进度" in text:
return intent_order_tracking
elif "退货" in text or "退款" in text:
return intent_return
...这段代码已经改不动了。不是因为逻辑复杂,而是因为没有人能确定改一行会不会影响另一个意图。
你想把 prompt 抽出来做成配置,但 prompt 里有很多 case,互相依赖,抽出来反而更乱。
场景三:那个永远对不上的“输出格式”
你接了一个需求:从用户评价里提取“产品名”、“评价维度”、“情感倾向”,然后传给一个 Dashboard 组件展示。
大模型每次输出都不一样。有时候输出 JSON,有时候在 JSON 前后加一句解释。有时候把“情感倾向”写成“sentiment”,有时候写成“emotion”。你加了各种后处理代码:正则提取 JSON、字段映射、默认值填充。代码量比业务逻辑还多。
更崩溃的是,上个月模型升级了,输出风格又变了。你的后处理代码又得改一遍。
你问自己:为什么每次改模型都要改代码?为什么不能定义一个输出契约,让模型严格遵守?
二、这些场景暴露了同一个问题
上面的三个场景,表面问题不同,根因是一样的:
我们在用“面向确定性执行”的编程模型,去应对一个“语义不确定”的世界
传统编程的假设是:
• 输入格式是固定的 • 输出结构是确定的 • 分支逻辑可以穷举
但大模型应用的现实是:
• 输入是任意的自然语言 • 输出每次可能不一样 • 分支无法提前穷举
所以你会看到:
• Prompt 散落在代码字符串里 → 改需求要改代码 • 路由靠 if/else 堆砌 → 每加一个意图就加一个分支 • 输出格式用正则硬修 → 模型一升级就崩
这不是你的代码写得不够好,是范式不匹配。
三、目的:把“文本→结构化”这个环节标准化
我们想做一件事:把“自然语言 → 结构化数据”这个环节,从业务代码里抽离出来,变成一个独立的框架层。
这个框架的核心主张是:
当你的业务逻辑本质上是对“文本”的处理和转换,你应该用声明式的方式定义规则,而不是用 if/else 硬编码。
框架的定位:
• 不做:Function Call、MCP、UI 组件、执行层 • 只做:接收自然语言,输出结构化契约
四、四个核心概念
1. DocModel:输出契约
定义“我希望输出什么样子的数据”。可以理解为一种轻量本体——某个实物或虚拟概念的属性、能力、关联关系,以 Markdown 或 JSON Schema 为载体。
2. Skill:最小的转换单元
每个 Skill 包含:
• name:唯一标识 • describe:这个 Skill 做什么 • 触发条件:什么情况下该用这个 Skill(必须写清楚,框架不负责猜) • 输出绑定:对应哪个 DocModel
Skill 之间的互斥性由开发者设计时保证,框架提供检测告警。
3. 软路由:匹配与分发
接收用户输入,根据 Skill 的触发条件进行匹配,选择最合适的 Skill,调用大模型执行转换。这是显式规则匹配,不是黑盒。
4. 适配器:对接现有生态
框架输出的是结构化数据(如 JSON)。适配器负责把它转成下游需要的格式:Function Call 参数、MCP 请求、UI 组件的 props 等。
五、完整流转示例:处理个人群聊数据
假设你是一个重度社群用户,每天有几十个群的几千条消息。你想让框架帮你自动处理这些数据。
场景设定
你有几个微信群:
• 行业资讯群:每天有人丢链接和文章 • 项目协作群:讨论需求和 bug • 闲聊群:各种段子和日常
你想做的事:
• 行业资讯群:提取链接 → 自动生成摘要 • 项目协作群:识别待办事项 → 生成任务列表 • 闲聊群:不需要处理
流转过程
第一步:定义 DocModel
定义两个输出契约:
• ArticleSummary:标题、来源、核心观点、链接• TaskItem:任务描述、负责人(如果提到)、截止时间(如果提到)
第二步:注册 Skill
注册两个 Skill:
• extract_links:触发条件包含“链接”、“文章”、“分享”等,输出绑定ArticleSummary• extract_todo:触发条件包含“待办”、“需要”、“麻烦谁”等,输出绑定TaskItem
第三步:软路由处理
群聊消息流入框架。软路由逐条匹配:
• “有人分享了一篇关于 RAG 的文章” → 匹配 extract_links• “@张三 需要在下周前完成方案” → 匹配 extract_todo• “今天天气不错” → 无匹配,静默丢弃
第四步:适配器输出
匹配到的消息:
• extract_links的输出通过适配器 → 存入“待读列表”或推送到笔记工具• extract_todo的输出通过适配器 → 同步到项目管理工具(如 Notion、Trello)
这个例子说明了什么?
• 框架处理的是大量松散文本 → 高密度结构化数据 • 开发者只需要定义“什么样的文本对应什么样的输出” • 下游可以接任何现有工具,框架不关心
六、与现有生态的关系
一句话:框架是执行层前面的语义理解层。
七、边界:不是什么?
这个框架不适合:
• 毫秒级实时响应 • 纯数值计算 • 确定性逻辑(直接写 if/else 就好)
它适合:
• 非结构化文本 → 结构化数据 • 多源文档 → 统一格式 • 自然语言意图 → 精确参数提取
八、当前状态与讨论邀请
目前这是一个概念构思,还没有代码实现。
核心待讨论的问题:
• Skill 的互斥设计是否可行? • 适配器的抽象层级是否合理? • 是否有同类项目已经在做类似的事?
如果你也在思考大模型应用的工程化问题,欢迎留言或私信讨论。
现在需要的是反馈,不是赞美。
九、最后
如果你有建议,或者觉得某个概念不合理,欢迎大家的讨论。
夜雨聆风