案例 / 主题 03

从一句话提单到医疗集团 AI 原生工单系统

17 天,从三个 Agent 的概念走到真实生产。我重新理解了 AI 原生企业软件:不是让模型接管一切,而是让自然语言、业务治理、可靠事务和组织学习形成闭环。

迭代中 AI 原生 医疗 IT 服务 Agent 工程
17 天
从概念验证到真实生产
4 类 Agent
分诊、分析、报告与自我记录
336 + 87 项
代码测试与候选环境 UAT
31 / 31
阶梯并发模型请求全部成功

这不是一个“给传统工单系统接上大模型”的项目。真正发生的事情,是我们把医院 IT 服务中最难表达、最容易失真的部分交给模型理解,再把权限、流程、数据和责任重新交还给确定性系统。

AI 原生企业软件的核心,不是把传统页面换成聊天框,而是重新划分人、模型和系统的职责。

整个过程从一个很朴素的问题开始:用户能不能只说一句话,系统就知道发生了什么、还缺什么、应该找谁,并且把处理过程完整留下来?

17 天后,系统已经从三个 Agent 的概念验证,走到移动端可用、附件可追踪、工单可转派、多医院隔离、提示词可配置、真实模型可测试、候选环境可回归、生产可以低中断切换。期间也走过不少弯路:做过后来删除的项目管理,产生过重复工单,遇到过 8.5 MB 文件上传失败、手机按钮点不动、模型请求超过 20 秒,以及“模型识别对了但页面仍显示未填写”这类最典型的端到端问题。

这些弯路比“上线成功”更值得记录。

AI 原生工单系统从原型、产品可用化、医院业务闭环、生产治理到医疗集团化的 17 天演进时间线
17 天的演进。每一次产品转向,都沉淀为新的系统边界、业务门禁或工程能力。

起点不是表单,而是三个 Agent

最初设想的核心能力很清楚:

  1. 工单分诊与分派 Agent:理解问题,选择工作组或处理人。
  2. 问题分析与解决方案 Agent:发现难点、共性问题,给出可复核建议。
  3. 运营报告 Agent:基于事实数据生成日报、周报和运营摘要。

后来又增加了第四个“问题自我记录 Agent”。它处理的是另一类很容易被混淆的输入:用户不是要别人帮忙,而是要记录今天自己已经处理的问题。两者都可以用自然语言描述,但业务含义完全不同。

这个起点到今天仍然成立:不同任务使用不同上下文、提示词、阈值和模型,而不是让一个“万能 Agent”承担所有责任。

但很快就发现,三个 Agent 只解决了产品最有特色的部分,并没有自动带来一个可用系统。真实工单系统仍然需要账号、权限、附件、提醒、搜索、状态、SLA、审计、移动端和后台配置。AI 是差异,不是豁免。

第一次产品收敛:用户先说明自己要什么

工作台最早有“自动判断、新建问题、更新任务”三个入口,概念太多,也与自然语言本身的意图识别重复。后来收敛成两个业务目的:

  • 自动派单:这是需要协作处理的问题,系统创建正式工单并执行分派。
  • 问题记录:这是我今天自行处理的问题,只记录在本人名下,不再打扰其他人。

这种简化不是减少能力,而是让用户先回答一个真正有意义的问题:我要找人协作,还是沉淀自己的工作? 查询、更新、转派、催办和帮助仍然可以直接告诉 AI。

AI 原生 IT 服务系统双模式工作台,提供自动派单和问题记录
双模式工作台。页面不要求用户先理解工单字段或流程状态,只需要表达业务目的和真实问题。

这里有一个重要体会:AI 产品的界面不能因为“自然语言什么都能说”而失去结构。好的结构不是要求用户填写更多,而是在关键决策点告诉用户自己正在做什么。

必填不等于必须填一张长表

医院 IT 服务现场最终明确了一份有效工单的最低信息:

  • 科室;
  • 现场联系人或报修人姓名;
  • 固话/分机或手机至少一个;
  • 能够理解的申报内容。

工号、诊室、详细地址、计算机名和 IP 可以选填。分机如果能唯一匹配目录,可以带出科室、诊室和地址;不能唯一确认时,系统必须继续询问,而不是猜。

所谓“必填”,不再意味着用户必须先看到一张表,而是意味着模型解析之后必须得到这些事实。缺什么,就每轮只问一个最关键的问题。完整之前不创建工单、不绑定附件、不执行分派;完整以后仍然要由用户确认。

手机端自然语言新建工单,在缺少姓名时进行单字段多轮追问
移动端多轮补问。AI 已经识别的内容继续保留,只补姓名这一个关键缺项。自然语言建单不能重新退化成一次性长表单。

这一流程后来稳定为:

自然语言输入
  → 模型提取严格 JSON
  → 服务端按医院当前配置校验
  → 缺失时单字段追问
  → 用户确认结构化预览
  → 幂等创建工单
  → Agent 分诊和分派

最重要的不是 JSON,而是模型只提供候选事实,代码决定能不能进入下一状态

自然语言工单从模型抽取、完整性门禁、幂等创建、候选选择到平台执行的完整闭环
受控业务流水线。模型调用不是终点,完整性门禁、幂等、候选约束、安全降级和审计共同构成产品。

分派的难点,不是让模型说出一个人名

真实业务需要两种工作组接单方式:

模式如何工作平台必须保证什么
轮转派单在当前可接单的成员之间轮流分配到个人休假、暂停接单和停用人员不参与;游标一致
工作组抢单先派到工作组,全组收到提醒,第一位接单者获得处理权并发只能成功一次;其他人的未读提醒自动撤销

员工还可以把工单直接转派给本人或其他可接单员工。业务后来决定放宽为:只要能够看到工单,就可以转派;但这并不意味着取消系统边界。目标员工必须属于同一医院、账号有效、处于可接单状态;完成或取消的工单不能继续转派;原处理人、新处理人、原因、操作者和时间全部留痕。

这里最容易犯的错误,是把所有分派规则写进提示词,然后期待模型“自觉遵守”。正确的分工应该是:

  • Agent 根据医院自己的提示词,理解业务系统并选择有限候选;
  • 平台校验医院、工作组、接单模式、员工状态和并发版本;
  • 无法确认或候选不合法时,进入人工分诊,而不是猜一个结果。

提示词表达可变的业务政策,代码执行不可违反的系统不变量。

工单分诊与分派 Agent 配置页面,包括提示词、真实模型测试、候选校验与执行日志
Agent 不是黑盒。提示词、真实模型单条测试、平台校验和分派执行日志在同一页面呈现,让管理员可以验证政策如何变成结果。

从单家医院走向医疗集团,真正需要改的是数据边界

系统后来升级为医疗集团版本。普通医院用户登录后仍然直接进入自己的工作台,只能看到本院用户、工作组、工单、附件、Agent、SLA、分机和报告。平台超级管理员通过同一个登录入口进入集团总览,查看跨院运行情况;需要执行写操作时,必须先进入明确的医院上下文。

医疗集团平台超级管理员查看多家医院工单、风险和运行情况的集团服务总览
集团治理,不是虚构一个“集团医院”。集团看汇总,各医院独立运行;普通用户的医院边界完全由服务端会话决定。

多租户不是在页面加一个医院筛选框。数据库记录、API 查询、附件对象、Agent 版本、导入导出、测试数据和日志都必须从设计阶段带有医院边界。普通用户即使伪造 hospitalId,服务端也必须忽略。

这一步让我重新认识了 AI 配置的归属:提示词不是全平台共享的一段文字,而是每家医院自己的运营政策。不同医院的系统名称、职责、工作组、第三方运维和服务语言都不同,Agent 也必须在租户边界内独立配置和发布。

AI 原生企业软件,是五层可信系统

做到这里以后,我逐渐形成了一个比“Agent 架构”更完整的认识。

AI 原生企业软件的表达层、语义层、治理层、事务层和学习层五层模型
五层模型。越靠上越接近人的表达,越靠下越接近组织责任和数据事实。

1. 表达层

让医生、护士、工程师用自然语言、附件和移动端表达真实处境。目标是降低使用门槛,而不是要求用户理解数据库字段和流程状态。

2. 语义层

Agent 负责识别意图、抽取 JSON、分类问题、生成分析和报告,把非结构化表达转成可校验的候选事实和建议。

3. 治理层

必填门禁、医院隔离、权限、候选资格、人工兜底和版本策略,把“模型认为”转换为“系统允许”。

4. 事务层

幂等、数据库事务、轮转游标、并发抢单、附件授权与审计,让每一次动作可执行、可追踪、可恢复、不可越权。

5. 学习层

日志、评测集、日报周报、共性问题、提示词迭代和运营复盘,让一次问题处理沉淀为下一次更好的组织能力。

最容易被忽略的是中间两层。没有治理层,模型会越权、跨院或误派;没有事务层,正确建议也可能因为重复点击、网络重试和并发变成错误数据。聊天体验只是入口,可信执行才是产品。

为什么模型一度需要 20 多秒

早期自动分派把几十个工作组和第三方系统全部塞进提示词,请模型从完整名单里选择。结果并不意外:请求越来越大,平均耗时一度超过 20 秒,模型还更容易在相似名称之间犹豫。

后来改为“先检索,再推理”:

  • 先用工单文字、工作组名称与职责、系统别名和提示词中的明确路由语句召回候选;
  • 工作组最多保留 14 个,第三方系统最多保留 8 个;
  • 候选只缩小决策空间,不直接执行派单;
  • 最终仍由模型做语义选择,再由平台做资格验证。

请求从约 20.8 KB 缩小到约 5.4 至 7.8 KB,自动分派平均回到约 4 秒。这件事的启发很直接:上下文工程和候选检索,往往比盲目更换更大模型更有效。

模型也不需要全部用最强版本。字段抽取、意图识别、分派和问题记录输出固定、上下文较短,可以使用更快模型;疑难问题分析和日报周报需要更强的综合能力,再使用更强模型。模型名称、提示词版本和实际耗时必须真实记录,不能让 UI 展示一个与生产不一致的品牌标签。

并发没有击穿服务器,尾延迟来自外部模型网关

在不写生产工单的 Agent 沙箱里,我做了一次 1、2、4、8、16 阶梯并发测试。31 次 HTTP 请求全部成功,没有 429、超时或首次模型调用失败。P50 大致保持在 4 至 5 秒,P95/最大值最高约 10.56 秒。

AI 工单分派在并发 1 到 16 下的 P50 和 P95 延迟基准
阶梯并发结果。应用服务器资源充足,尾延迟主要来自外部模型网关排队;这决定了下一步应该建设有界并发、短队列和熔断,而不是先扩机器。

这次测试也暴露了另一个事实:同一句偏模糊的“AI 助手”描述偶尔会进入人工分诊,而不是稳定命中目标组。HTTP 成功不等于业务正确。模型测试至少要同时看:结构化输出、明确路由、歧义兜底、人工分诊率、P50、P95、最大耗时和并发错误率。

移动端不是桌面端缩小版

这套系统最有价值的 bug 很多来自手机:

  • 隐藏文件输入框在部分微信和医院 WebView 中点不动;
  • 8.5 MB 附件在页面标注 10 MB 可上传时仍然失败;
  • 弹窗太长,底部保存按钮看不到;
  • 字体太小,筛选控件和固定底栏互相挤压;
  • 多列复选框把整个页面撑出横向滚动。

最终形成的原则很朴素:关键触控区域至少约 40 至 48 px;文件选择使用真实按钮显式触发;移动端用卡片和分段信息,不强行压缩桌面表格;弹窗正文独立滚动、操作区固定;至少验证 390 × 844,并补充 Android WebView 行为。

还有一条更通用的体验原则:用户必须看见系统正在做什么。

附件要显示本地预览、上传中、成功、失败、重试和删除;AI 要显示正在解析、缺少什么、识别了什么、是否等待确认、是否正在分派,以及失败后进入了什么安全状态。没有反馈时,用户会再次点击,重复提交和并发问题就随之而来。

自然语言流程必须以幂等为基础设施

系统曾出现过一个很典型的事故:用户补充问题时已经保存,最终确认后又创建,列表里出现多张几乎相同的工单。

根因不是一个按钮,而是前端对话状态、模型状态和数据库写入没有明确分开。后来形成的规则是:

  • 问询阶段只计算,不写正式工单;
  • 最终创建使用稳定的客户端请求 ID;
  • 服务端对请求 ID 和短时间内容重复进行保护;
  • 网络重试返回同一结果,而不是重复执行;
  • 写按钮进入忙碌状态,防止连续点击。

自然语言会让流程更灵活,也会带来更多重试、补充和状态恢复。幂等不是“后端优化”,而是 Agent 产品的基础设施。

另一个问题更值得警惕:“高端产科门诊”已经在用户原文中,也可能已经被模型正确抽取,但详情页仍然显示服务地点未填写。断点可能发生在模型、字段合并、落库、查询或 UI 任何一层。模型输出正确,不代表产品结果正确。 端到端测试必须从输入一直断言到移动端最终显示。

测试中心不是为了展示一个通过数字

测试体系后来逐渐分成八层:领域单元测试、API 冒烟、专项业务测试、角色 UAT、真实模型评测、响应式验证、候选发布验证和正式无破坏冒烟。

在一次阶段验证中,代码测试达到 336/336,隔离候选环境 UAT 达到 87/87。数字本身不是成绩。真正重要的是:每一项失败都能回答“模型错了、候选无效、配置不足、权限拒绝、数据前置条件变化,还是页面没有正确显示”。

测试中心统一管理测试用例、风险等级、测试数据、自动化覆盖和发布验证
质量资产产品化。用例、风险、数据、自动化覆盖和发布验证进入同一个视图,而不是散落在脚本、聊天和个人记忆里。

完整回归不能直接污染生产目录。早期测试产生过大量 UAT 工作组和测试用户,后来还要专门物理清理。成熟做法是复制正式状态到隔离候选目录,在独立端口完成完整测试,结束后整体销毁;生产只做健康、登录、静态资源、医院隔离和只读模型沙箱等无破坏验证。

测试最有价值的样本也不是理想输入,而是人们真的会做的事:10 MB 边界附件、连续点三次按钮、两个人同时抢单、用户停留页面后数据变化、休假人员成为候选、删除仍被工单引用的员工、普通用户伪造医院参数、模型返回 Markdown 或非法 JSON、模型网关 429、502 和断链。

正式系统的另一半,是部署与可观测性

项目最早依赖个人电脑和会变化的网络环境。真正迁移到云端后,我给发布过程定了几条底线:不能依赖开发电脑开机,不能影响同服务器的其他业务,完整测试不能写生产状态,正式切换尽可能短,而且必须能证明线上究竟运行的是哪一版。

AI 原生工单系统的用户端、Cloudflare、安全入口、应用、模型代理、数据库和附件存储架构
当前生产架构。图中的虚线 AI 任务队列是后续规划;当前系统仍由应用同步调用模型代理。公开图隐去了服务器、密钥和内部网络参数。

当前单机阶段采用“候选容器 + 状态副本 + 短切换”:源码和运行配置先构建为带版本的候选镜像,候选挂载正式状态副本完成回归,验证通过后只替换目标应用服务。健康接口同时返回发布版本、数据库和实际模型信息,前端静态资源也带版本指纹。

仅仅看到网站可以访问,不能证明它运行的是最新代码。完整证据链应该是:

本地 Git HEAD
  = GitHub main
  = 镜像构建提交
  = 健康接口 release
  = 前端资源版本
  = 部署记录中的容器与镜像摘要

可观测性也不是故障以后才补。关键链路需要统一 Request ID,并记录阶段、模型、提示词版本、候选数、请求字节、耗时、重试、结果和业务审计;但日志不能记录密码、令牌、API Key、附件正文或完整工单正文。详细日志与泄露敏感数据不是一回事。

那些看起来很小、实际很深的错误

表面现象真正暴露的问题
页面写支持 10 MB,8.5 MB 却上传失败限制分散在浏览器、multipart、代理和存储多层,不能只改前端文案
手机沟通附件按钮无效标准桌面浏览器通过,不代表 WebView 交互可用
一次补充生成三张相同工单多轮流程没有把计算状态与正式写入分开,也缺少幂等
科室已识别,服务地点仍为空模型、合并、落库、查询和 UI 之间缺少整链路断言
删除按钮长期灰色保护性设计没有解释原因,也没有提供管理员可执行的受控清理路径
密码页面出现巨大蓝框通用 CSS 选择器污染紧凑控件,组件尺寸没有被固定
同一句模糊问题偶发进入人工分诊模型非确定性需要候选约束、别名、平台验证和人工兜底
自动分派超过 20 秒提示词和候选无限增长;应该先检索再推理
本地、GitHub、生产难判断新旧版本不能靠 Release Note 或文件时间猜,必须有运行时指纹

这些问题有一个共同特点:截图通常只显示最后一层,而根因藏在整条链路里。真正有效的修复不能只改截图所在的组件。

从“把单关掉”到“组织下一次不再从零开始”

传统工单系统优化的是流转效率:谁接单、什么时候响应、何时关闭。AI 原生工单系统还应该多走一步:让每一次处理留下可复用的组织资产。

一张工单在关闭时,至少可以沉淀四类内容:

  1. 事实数据:发生了什么,影响了谁,在哪个系统和地点。
  2. 解决过程:尝试过什么,什么有效,什么无效。
  3. 责任边界:谁做了判断,谁执行了动作,何时发生转派和确认。
  4. 可复用知识:是否属于共性问题,能否形成标准方案、字典、提示词或预防措施。

因此,日报周报不能只是让模型把标题重新排列。它应该回答更重要的问题:哪些系统反复出错,哪些科室等待时间过长,哪些工作组持续超载,哪些问题应该形成标准解决方案,哪些基础目录或提示词需要修订。

从这个角度看:

  • Agent 提示词逐渐接近一份可执行的运营政策
  • 测试集是组织对“什么叫正确”的机器可读定义
  • 审计日志是组织责任和持续改进的事实基础
  • 工单不再只是待办事项,而是组织运行的数字痕迹

但系统不能自动替代责任。模型可以建议、归纳和排序,平台可以执行授权动作,最终责任仍然属于确认事实、配置政策和处理问题的人。在医疗场景中,这种责任分层比“模型更聪明”更重要。

最后留下十条判断

  1. AI 原生的价值是让用户用自然语言完成工作,不是让模型绕过业务规则。
  2. 模型负责语义,代码负责权限、一致性和可审计执行。
  3. 先结构化、再校验、再执行,是多轮 Agent 最稳妥的主流程。
  4. 候选检索和上下文压缩,往往比盲目更换大模型更有效。
  5. 移动端必须用真实触屏和 WebView 验证,桌面通过不代表手机可用。
  6. 用户反馈揭示的是端到端问题,不能只修截图所在的单一组件。
  7. 正式回归应该在隔离候选副本执行,生产只做无破坏验证。
  8. 低中断发布、版本指纹和可追踪日志,是正式系统的基本功能。
  9. 产品必须允许做减法;边界错误的模块应该拆开,而不是继续堆补丁。
  10. 文档的目的不是存档,而是让下一台电脑、下一种 AI 工具和下一位维护者能够安全接手。

这次开发最值得保留的,不是某一个页面、模型或提示词,而是一套逐渐成熟的方法:从真实业务出发,用模型降低表达成本,用代码守住系统边界,用测试证明端到端行为,用候选环境保护生产,再用文档和运行证据保证系统能够被继续维护。

AI 放大的从来不只是效率。职责越清楚、数据越准确、反馈越完整,系统才会越聪明。