从一句话提单到医疗集团 AI 原生工单系统
17 天,从三个 Agent 的概念走到真实生产。我重新理解了 AI 原生企业软件:不是让模型接管一切,而是让自然语言、业务治理、可靠事务和组织学习形成闭环。
这不是一个“给传统工单系统接上大模型”的项目。真正发生的事情,是我们把医院 IT 服务中最难表达、最容易失真的部分交给模型理解,再把权限、流程、数据和责任重新交还给确定性系统。
AI 原生企业软件的核心,不是把传统页面换成聊天框,而是重新划分人、模型和系统的职责。
整个过程从一个很朴素的问题开始:用户能不能只说一句话,系统就知道发生了什么、还缺什么、应该找谁,并且把处理过程完整留下来?
17 天后,系统已经从三个 Agent 的概念验证,走到移动端可用、附件可追踪、工单可转派、多医院隔离、提示词可配置、真实模型可测试、候选环境可回归、生产可以低中断切换。期间也走过不少弯路:做过后来删除的项目管理,产生过重复工单,遇到过 8.5 MB 文件上传失败、手机按钮点不动、模型请求超过 20 秒,以及“模型识别对了但页面仍显示未填写”这类最典型的端到端问题。
这些弯路比“上线成功”更值得记录。
起点不是表单,而是三个 Agent
最初设想的核心能力很清楚:
- 工单分诊与分派 Agent:理解问题,选择工作组或处理人。
- 问题分析与解决方案 Agent:发现难点、共性问题,给出可复核建议。
- 运营报告 Agent:基于事实数据生成日报、周报和运营摘要。
后来又增加了第四个“问题自我记录 Agent”。它处理的是另一类很容易被混淆的输入:用户不是要别人帮忙,而是要记录今天自己已经处理的问题。两者都可以用自然语言描述,但业务含义完全不同。
这个起点到今天仍然成立:不同任务使用不同上下文、提示词、阈值和模型,而不是让一个“万能 Agent”承担所有责任。
但很快就发现,三个 Agent 只解决了产品最有特色的部分,并没有自动带来一个可用系统。真实工单系统仍然需要账号、权限、附件、提醒、搜索、状态、SLA、审计、移动端和后台配置。AI 是差异,不是豁免。
第一次产品收敛:用户先说明自己要什么
工作台最早有“自动判断、新建问题、更新任务”三个入口,概念太多,也与自然语言本身的意图识别重复。后来收敛成两个业务目的:
- 自动派单:这是需要协作处理的问题,系统创建正式工单并执行分派。
- 问题记录:这是我今天自行处理的问题,只记录在本人名下,不再打扰其他人。
这种简化不是减少能力,而是让用户先回答一个真正有意义的问题:我要找人协作,还是沉淀自己的工作? 查询、更新、转派、催办和帮助仍然可以直接告诉 AI。
这里有一个重要体会:AI 产品的界面不能因为“自然语言什么都能说”而失去结构。好的结构不是要求用户填写更多,而是在关键决策点告诉用户自己正在做什么。
必填不等于必须填一张长表
医院 IT 服务现场最终明确了一份有效工单的最低信息:
- 科室;
- 现场联系人或报修人姓名;
- 固话/分机或手机至少一个;
- 能够理解的申报内容。
工号、诊室、详细地址、计算机名和 IP 可以选填。分机如果能唯一匹配目录,可以带出科室、诊室和地址;不能唯一确认时,系统必须继续询问,而不是猜。
所谓“必填”,不再意味着用户必须先看到一张表,而是意味着模型解析之后必须得到这些事实。缺什么,就每轮只问一个最关键的问题。完整之前不创建工单、不绑定附件、不执行分派;完整以后仍然要由用户确认。
这一流程后来稳定为:
自然语言输入
→ 模型提取严格 JSON
→ 服务端按医院当前配置校验
→ 缺失时单字段追问
→ 用户确认结构化预览
→ 幂等创建工单
→ Agent 分诊和分派
最重要的不是 JSON,而是模型只提供候选事实,代码决定能不能进入下一状态。
分派的难点,不是让模型说出一个人名
真实业务需要两种工作组接单方式:
| 模式 | 如何工作 | 平台必须保证什么 |
|---|---|---|
| 轮转派单 | 在当前可接单的成员之间轮流分配到个人 | 休假、暂停接单和停用人员不参与;游标一致 |
| 工作组抢单 | 先派到工作组,全组收到提醒,第一位接单者获得处理权 | 并发只能成功一次;其他人的未读提醒自动撤销 |
员工还可以把工单直接转派给本人或其他可接单员工。业务后来决定放宽为:只要能够看到工单,就可以转派;但这并不意味着取消系统边界。目标员工必须属于同一医院、账号有效、处于可接单状态;完成或取消的工单不能继续转派;原处理人、新处理人、原因、操作者和时间全部留痕。
这里最容易犯的错误,是把所有分派规则写进提示词,然后期待模型“自觉遵守”。正确的分工应该是:
- Agent 根据医院自己的提示词,理解业务系统并选择有限候选;
- 平台校验医院、工作组、接单模式、员工状态和并发版本;
- 无法确认或候选不合法时,进入人工分诊,而不是猜一个结果。
提示词表达可变的业务政策,代码执行不可违反的系统不变量。
从单家医院走向医疗集团,真正需要改的是数据边界
系统后来升级为医疗集团版本。普通医院用户登录后仍然直接进入自己的工作台,只能看到本院用户、工作组、工单、附件、Agent、SLA、分机和报告。平台超级管理员通过同一个登录入口进入集团总览,查看跨院运行情况;需要执行写操作时,必须先进入明确的医院上下文。
多租户不是在页面加一个医院筛选框。数据库记录、API 查询、附件对象、Agent 版本、导入导出、测试数据和日志都必须从设计阶段带有医院边界。普通用户即使伪造 hospitalId,服务端也必须忽略。
这一步让我重新认识了 AI 配置的归属:提示词不是全平台共享的一段文字,而是每家医院自己的运营政策。不同医院的系统名称、职责、工作组、第三方运维和服务语言都不同,Agent 也必须在租户边界内独立配置和发布。
AI 原生企业软件,是五层可信系统
做到这里以后,我逐渐形成了一个比“Agent 架构”更完整的认识。
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 助手”描述偶尔会进入人工分诊,而不是稳定命中目标组。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 和断链。
正式系统的另一半,是部署与可观测性
项目最早依赖个人电脑和会变化的网络环境。真正迁移到云端后,我给发布过程定了几条底线:不能依赖开发电脑开机,不能影响同服务器的其他业务,完整测试不能写生产状态,正式切换尽可能短,而且必须能证明线上究竟运行的是哪一版。
当前单机阶段采用“候选容器 + 状态副本 + 短切换”:源码和运行配置先构建为带版本的候选镜像,候选挂载正式状态副本完成回归,验证通过后只替换目标应用服务。健康接口同时返回发布版本、数据库和实际模型信息,前端静态资源也带版本指纹。
仅仅看到网站可以访问,不能证明它运行的是最新代码。完整证据链应该是:
本地 Git HEAD
= GitHub main
= 镜像构建提交
= 健康接口 release
= 前端资源版本
= 部署记录中的容器与镜像摘要
可观测性也不是故障以后才补。关键链路需要统一 Request ID,并记录阶段、模型、提示词版本、候选数、请求字节、耗时、重试、结果和业务审计;但日志不能记录密码、令牌、API Key、附件正文或完整工单正文。详细日志与泄露敏感数据不是一回事。
那些看起来很小、实际很深的错误
| 表面现象 | 真正暴露的问题 |
|---|---|
| 页面写支持 10 MB,8.5 MB 却上传失败 | 限制分散在浏览器、multipart、代理和存储多层,不能只改前端文案 |
| 手机沟通附件按钮无效 | 标准桌面浏览器通过,不代表 WebView 交互可用 |
| 一次补充生成三张相同工单 | 多轮流程没有把计算状态与正式写入分开,也缺少幂等 |
| 科室已识别,服务地点仍为空 | 模型、合并、落库、查询和 UI 之间缺少整链路断言 |
| 删除按钮长期灰色 | 保护性设计没有解释原因,也没有提供管理员可执行的受控清理路径 |
| 密码页面出现巨大蓝框 | 通用 CSS 选择器污染紧凑控件,组件尺寸没有被固定 |
| 同一句模糊问题偶发进入人工分诊 | 模型非确定性需要候选约束、别名、平台验证和人工兜底 |
| 自动分派超过 20 秒 | 提示词和候选无限增长;应该先检索再推理 |
| 本地、GitHub、生产难判断新旧 | 版本不能靠 Release Note 或文件时间猜,必须有运行时指纹 |
这些问题有一个共同特点:截图通常只显示最后一层,而根因藏在整条链路里。真正有效的修复不能只改截图所在的组件。
从“把单关掉”到“组织下一次不再从零开始”
传统工单系统优化的是流转效率:谁接单、什么时候响应、何时关闭。AI 原生工单系统还应该多走一步:让每一次处理留下可复用的组织资产。
一张工单在关闭时,至少可以沉淀四类内容:
- 事实数据:发生了什么,影响了谁,在哪个系统和地点。
- 解决过程:尝试过什么,什么有效,什么无效。
- 责任边界:谁做了判断,谁执行了动作,何时发生转派和确认。
- 可复用知识:是否属于共性问题,能否形成标准方案、字典、提示词或预防措施。
因此,日报周报不能只是让模型把标题重新排列。它应该回答更重要的问题:哪些系统反复出错,哪些科室等待时间过长,哪些工作组持续超载,哪些问题应该形成标准解决方案,哪些基础目录或提示词需要修订。
从这个角度看:
- Agent 提示词逐渐接近一份可执行的运营政策;
- 测试集是组织对“什么叫正确”的机器可读定义;
- 审计日志是组织责任和持续改进的事实基础;
- 工单不再只是待办事项,而是组织运行的数字痕迹。
但系统不能自动替代责任。模型可以建议、归纳和排序,平台可以执行授权动作,最终责任仍然属于确认事实、配置政策和处理问题的人。在医疗场景中,这种责任分层比“模型更聪明”更重要。
最后留下十条判断
- AI 原生的价值是让用户用自然语言完成工作,不是让模型绕过业务规则。
- 模型负责语义,代码负责权限、一致性和可审计执行。
- 先结构化、再校验、再执行,是多轮 Agent 最稳妥的主流程。
- 候选检索和上下文压缩,往往比盲目更换大模型更有效。
- 移动端必须用真实触屏和 WebView 验证,桌面通过不代表手机可用。
- 用户反馈揭示的是端到端问题,不能只修截图所在的单一组件。
- 正式回归应该在隔离候选副本执行,生产只做无破坏验证。
- 低中断发布、版本指纹和可追踪日志,是正式系统的基本功能。
- 产品必须允许做减法;边界错误的模块应该拆开,而不是继续堆补丁。
- 文档的目的不是存档,而是让下一台电脑、下一种 AI 工具和下一位维护者能够安全接手。
这次开发最值得保留的,不是某一个页面、模型或提示词,而是一套逐渐成熟的方法:从真实业务出发,用模型降低表达成本,用代码守住系统边界,用测试证明端到端行为,用候选环境保护生产,再用文档和运行证据保证系统能够被继续维护。
AI 放大的从来不只是效率。职责越清楚、数据越准确、反馈越完整,系统才会越聪明。