1. 为什么“大模型”和“流程管理”总是两张皮
我做过好几个企业内部的AI流程项目,从需求评审到上线运维全程跟下来,最大的感受就是:大模型Demo跑通只要一天,但让它真正嵌进业务流程里跑稳,三个月都算快的。很多团队卡在同一个地方——模型能力很强,业务系统却接不住。你让大模型写一段文案、抽一份合同,它干得漂亮;但你让它去驱动一个审批流、触发一次工单、回写一条数据库记录,它就开始“胡言乱语”了。
这个问题的根子不在模型本身,而在于流程管理系统和大模型之间缺少一层“翻译层”。传统流程引擎(比如各类BPM、工作流平台)是按确定性规则设计的:条件分支、会签、回退、超时提醒,每一步都有明确的输入输出。而大模型是概率性的,同一个问题问两次可能给出不同答案。把这两个东西直接对接,就像让一个诗人去操作数控机床——不是诗人不行,是接口不对。
所以这篇内容我想聊的,就是AI流程管理系统从大模型到业务执行这条链路上,到底要拆成哪几段、每段用什么技术、踩过哪些坑。适合正在做企业AI落地的大模型开发工程师、流程平台负责人,以及想搞清楚“大模型到底怎么跟业务系统结合”的技术管理者。我不会只讲概念,会把参数怎么选、接口怎么设计、异常怎么兜底这些实操层面的东西都摊开说。
2. 整体架构拆解:从模型输出到业务动作的四层结构
2.1 为什么不能“模型直连业务库”
先说一个我见过的最常见错误:有人为了图省事,让大模型直接生成SQL去操作业务数据库。这个方案在演示环境里跑得通,一上生产就出事。原因有三:第一,大模型的输出不稳定,今天生成的SQL语法对,明天可能就多一个字段名;第二,权限没法控制,模型一旦被诱导就能读写任意表;第三,没有审计链路,出了问题根本追溯不到是哪次推理导致的。
正确的做法是在中间加结构化的中间层。我总结下来,一个能落地的AI流程管理系统,至少需要四层:
| 层级 | 职责 | 关键技术 | 常见选型 |
|---|---|---|---|
| 模型层 | 理解意图、生成结构化输出 | LLM推理、Function Calling | 本地部署或API调用 |
| 编排层 | 任务拆解、流程调度 | Agent框架、状态机 | 主流Agent框架 |
| 执行层 | 调用业务接口、操作数据 | RPA、API网关、消息队列 | 企业现有中间件 |
| 治理层 | 权限、审计、兜底 | 规则引擎、日志系统 | 自研或开源方案 |
这四层里,编排层是最容易被低估的。很多人以为大模型输出一个JSON就完事了,实际上从“模型说要做A”到“系统真的做了A”,中间要经过意图校验、参数补全、权限检查、执行确认、结果回写这一整套动作。编排层就是干这个的。
2.2 模型层选型:本地部署还是调API
这是被问得最多的问题。我的判断标准很简单:看你的数据敏感度和调用频次。
如果流程涉及企业内部合同、财务数据、客户隐私,那基本只能走本地部署。本地部署大模型现在的门槛比两年前低了很多,一台带4张显卡的机器就能跑起来中等规模的模型。部署工具方面,Ollama是比较省心的选择,安装完之后模型就是一个文件,管理起来跟Docker镜像类似。Windows 11上跑Ollama加Llama3的完整流程,网上教程很多,核心就是装好运行环境、拉模型、配好端口。
如果数据敏感度不高、调用量波动大,那用API更划算。免费大模型API现在有不少公益站点可以用,但生产环境我不建议依赖免费额度,稳定性和数据安全都没保障。企业级场景还是走私有化部署或者商业API。
这里有个经验数据:流程管理场景下,模型响应时间超过3秒,用户体验就会明显下降。所以如果你选本地部署,要关注TPOT(Time Per Output Token)这个指标,它直接决定用户等多久。4张显卡的配置下,7B级别的模型TPOT可以做到50ms以内,13B大概在80-120ms,再大就得上更多卡了。
2.3 编排层:Agent框架怎么选
目前主流的Agent框架有好几个,选哪个取决于你的流程复杂度。我的建议是:
- 流程步骤固定、分支少:用轻量级的状态机就够了,不需要上重型Agent框架。杀鸡不用牛刀。
- 需要动态规划、多步推理:选支持工具调用(Tool Use)的Agent框架,让模型自己决定下一步调什么。
- 需要多Agent协作:比如一个负责理解需求、一个负责查数据、一个负责生成报告,那就需要支持Agent间通信的框架。
不管选哪个框架,有一条铁律:所有模型输出的动作,必须先转成结构化格式再执行。我通常要求模型输出严格的JSON Schema,包含action、params、confidence三个字段。confidence低于阈值的,直接转人工处理,不自动执行。
2.4 执行层:怎么让模型“动手”
执行层的关键是把业务能力封装成模型可调用的工具。比如“发起审批”是一个工具,“查询库存”是一个工具,“发送通知”是一个工具。模型不需要知道这些工具背后是REST API还是数据库存储过程,它只需要知道工具的名字、入参格式和返回值含义。
这里有个设计技巧:工具的描述要写得像给新人看的操作手册。我见过很多团队工具描述写得太技术化,模型理解不了。比如“调用SAP RFC接口”这种描述,模型根本不知道什么时候该用。改成“当需要查询物料库存数量时使用此工具,输入物料编码,返回当前库存”,模型就能正确调用了。
3. 核心细节:让大模型输出“能执行”的结果
3.1 结构化输出:从“说人话”到“说机器话”
大模型天然输出的是自然语言,但流程系统需要的是结构化数据。这个转换过程叫结构化输出约束。目前主流做法有三种:
第一种是Prompt约束,在提示词里明确要求“只输出JSON,不要任何解释”。这种方法最简单,但可靠性一般,模型偶尔会加一句“好的,以下是结果”。
第二种是Function Calling,利用模型原生的工具调用能力,直接返回结构化参数。这是目前最可靠的方式,主流大模型都支持。
第三种是输出解析器,在模型输出之后用规则或小模型做一次格式清洗。这是兜底方案,前两种都失败的时候用。
我的实操建议是:Function Calling为主,输出解析器兜底。在提示词里同时写清楚“优先使用工具调用,如果无法调用则输出JSON格式”。
3.2 参数校验:模型说的“数量”到底是几个
这是踩过坑的地方。模型从用户那句话里抽取出“帮我订5箱A4纸”,它可能输出{"item": "A4纸", "quantity": 5},看起来没问题。但如果用户说的是“订几箱A4纸”,模型可能输出{"item": "A4纸", "quantity": null},也可能自作主张填个1。
所以参数校验层必须独立于模型存在。我的做法是维护一份参数规则表:
| 参数类型 | 校验规则 | 缺失时处理 |
|---|---|---|
| 数量 | 必须为正整数,范围1-999 | 追问用户 |
| 日期 | 必须为未来日期,格式YYYY-MM-DD | 默认取明天 |
| 枚举值 | 必须在预定义列表中 | 取默认值并记录日志 |
| 文本 | 长度限制、敏感词过滤 | 截断或拒绝 |
这张表用规则引擎实现,不依赖模型。模型只负责抽取,校验和补全由规则层完成。
3.3 置信度阈值:什么时候该让模型“闭嘴”
不是所有模型输出都值得信任。我通常会给每个动作设一个置信度阈值,低于阈值的转人工。阈值怎么定?看业务容错率。
- 高容错场景(比如推荐话术、生成摘要):阈值可以设0.6,让模型多干活。
- 中容错场景(比如创建工单、分配任务):阈值设0.8,宁可多问一句。
- 低容错场景(比如资金操作、合同审批):阈值设0.95,基本等于必须人工确认。
置信度从哪来?如果模型API返回logprobs,可以直接算;如果不返回,就用一致性采样——同一个问题问三次,看输出是否一致,一致率高则置信度高。
3.4 上下文管理:多轮对话怎么不“失忆”
流程管理往往是多轮的:用户说“帮我请假”,系统问“请几天”,用户说“三天”,系统问“从哪天开始”,用户说“下周一”。这中间模型需要记住前面的信息。
上下文管理有两个坑:一是上下文窗口有限,聊太久会丢信息;二是信息污染,前面轮次的错误理解会一直影响后面。
我的做法是每轮对话都做一次状态快照,把已经确认的参数存到流程实例的变量里,而不是依赖模型的对话历史。模型每轮只需要看当前状态和最新输入,不需要看完整历史。这样既省token,又避免污染。
4. 实操过程:一个请假流程的完整实现
4.1 场景定义与工具封装
拿一个最简化的请假流程举例。业务需求是:员工用自然语言申请请假,系统自动判断假期类型、计算天数、检查余额、发起审批。
首先封装工具。我定义了四个工具:
{ "name": "check_leave_balance", "description": "查询员工年假余额,输入员工ID,返回剩余天数", "parameters": { "employee_id": {"type": "string", "required": true} } }{ "name": "calculate_leave_days", "description": "计算请假天数,输入开始日期和结束日期,返回工作日天数", "parameters": { "start_date": {"type": "string", "format": "date"}, "end_date": {"type": "string", "format": "date"} } }{ "name": "create_approval", "description": "发起审批流程,输入申请人、假期类型、天数、起止日期", "parameters": { "applicant": {"type": "string"}, "leave_type": {"type": "string", "enum": ["annual", "sick", "personal"]}, "days": {"type": "number"}, "start_date": {"type": "string"}, "end_date": {"type": "string"} } }{ "name": "notify_manager", "description": "通知直属上级,输入上级ID和审批单号", "parameters": { "manager_id": {"type": "string"}, "approval_id": {"type": "string"} } }工具描述我刻意写得像操作手册,而不是技术文档。实测下来,模型对“查询员工年假余额”这种描述的理解准确率,比“调用HR系统API”高出不少。
4.2 编排逻辑:状态机怎么设计
这个流程我用了一个简单的状态机,状态流转如下:
- 意图识别:判断用户是否在申请请假
- 参数收集:抽取假期类型、起止日期
- 参数校验:检查日期格式、是否过去日期
- 余额检查:调用
check_leave_balance - 天数计算:调用
calculate_leave_days - 确认环节:向用户展示计算结果,等待确认
- 发起审批:调用
create_approval - 通知上级:调用
notify_manager - 完成
每个状态都有明确的进入条件和退出条件。模型只在“意图识别”和“参数收集”两个状态参与,后面的状态都是确定性逻辑。这样设计的好处是模型出错的影响面被限制在前两步,后面即使模型抽错了参数,校验层也能拦住。
4.3 关键代码:模型调用与结果解析
模型调用部分我用的是Function Calling模式。核心逻辑是:
def process_user_input(user_input, context): messages = build_messages(user_input, context) response = llm.chat(messages, tools=available_tools) if response.tool_calls: for tool_call in response.tool_calls: result = execute_tool(tool_call.name, tool_call.arguments) context.update(result) return continue_flow(context) else: return ask_for_clarification(response.content)这里有个细节:每次工具调用之后,要把结果回传给模型,让模型知道上一步执行成功了。否则模型可能重复调用同一个工具。
4.4 异常处理:模型“发疯”了怎么办
我遇到过几种典型的模型异常:
第一种是幻觉调用,模型调用了一个不存在的工具。处理方式是维护一个工具白名单,不在白名单里的调用直接拒绝并记录日志。
第二种是参数类型错误,比如把日期写成了“下周一”而不是“2025-06-02”。处理方式是在工具执行前做一次参数规范化,用日期解析库把自然语言日期转成标准格式。
第三种是死循环,模型反复调用同一个工具。处理方式是设置最大调用次数,超过3次就中断流程转人工。
第四种是越权操作,模型试图调用超出当前用户权限的工具。处理方式是在工具执行层做权限校验,跟模型无关。
这些异常处理逻辑加起来大概占了整个系统代码量的40%。模型本身可能只占20%,剩下80%都是工程化的东西。
5. 常见问题与排查技巧实录
5.1 模型输出不稳定怎么排查
这是最高频的问题。同一个输入,模型今天输出A,明天输出B。排查思路分三步:
第一步,检查temperature参数。流程管理场景建议设0.1-0.3,不要用默认的0.7。temperature越低,输出越稳定。
第二步,检查提示词是否有歧义。我见过一个案例,提示词里写“根据用户输入判断意图”,但没定义意图有哪些类别,模型就自由发挥了。改成“从以下类别中选择:请假、报销、采购、其他”,稳定性立刻提升。
第三步,检查上下文是否被污染。如果多轮对话中有一轮模型理解错了,后面可能一直错。解决办法是每轮都重置关键状态,不依赖模型记忆。
5.2 工具调用失败怎么定位
工具调用失败通常有三种原因:模型没调、调错了、调了但执行失败。
区分方法很简单:看日志。如果日志里没有工具调用记录,说明模型没调,问题在提示词或模型能力;如果有调用记录但参数不对,问题在参数抽取;如果参数对但执行报错,问题在工具实现。
我通常会在工具执行层加一个装饰器,记录每次调用的入参、出参、耗时、结果状态。排查的时候一目了然。
5.3 性能瓶颈在哪里
AI流程管理系统的性能瓶颈通常不在模型推理,而在工具调用的网络延迟。模型推理可能只要500ms,但调用一个外部API可能要2秒。如果流程里有5个工具调用,总耗时就是10秒以上。
优化方向有两个:一是并行调用,没有依赖关系的工具同时调;二是缓存,查询类工具的结果缓存一段时间。比如员工信息、组织架构这类变化不频繁的数据,缓存5分钟没问题。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查动作 | 解决方案 |
|---|---|---|---|
| 模型不调用工具 | 提示词未说明工具用途 | 检查工具描述 | 补充使用场景说明 |
| 参数抽取错误 | 输入有歧义 | 查看原始输入 | 增加追问环节 |
| 流程卡住 | 状态机死锁 | 检查状态流转日志 | 增加超时中断 |
| 重复执行 | 未回传工具结果 | 检查消息历史 | 每步回传执行结果 |
| 响应太慢 | 工具串行调用 | 分析调用链耗时 | 改并行或加缓存 |
| 权限越界 | 未做执行层校验 | 检查权限配置 | 工具层加权限检查 |
5.5 几个踩坑心得
第一个坑:不要试图让模型做所有事。我一开始想让模型自己判断该调哪个工具、该传什么参数、该不该确认,结果模型经常“想太多”。后来改成模型只负责意图识别和参数抽取,后面的逻辑全部用代码写死,稳定性大幅提升。
第二个坑:工具数量不要太多。有次一个流程里放了20多个工具,模型选择困难,经常调错。后来按场景分组,每个流程只暴露相关的5-8个工具,准确率明显改善。
第三个坑:一定要有“人工兜底”入口。不管模型多准,总会有它处理不了的情况。在流程的每个关键节点都留一个“转人工”按钮,用户点一下就能接管。这个功能看起来简单,但极大提升了用户信任度。
第四个坑:日志要记全。模型输入、模型输出、工具调用、执行结果、用户反馈,这些都要记。出问题的时候,没有日志就是盲人摸象。我习惯用结构化日志,每条记录带trace_id,方便串联。
6. 从单点流程到平台化:后续扩展方向
单个流程跑通之后,下一步通常是平台化。平台化的核心是把工具、提示词、流程定义都变成可配置的资产,而不是写死在代码里。
我目前的实践是维护三个库:工具库(所有可调用的业务能力)、提示词库(各场景的提示词模板)、流程库(状态机定义)。新流程上线时,从三个库里组合配置,不需要改代码。这样业务人员经过简单培训也能自己搭流程。
另一个扩展方向是多模态输入。现在很多流程的入口不只是文字,还有图片、PDF、Excel。比如报销流程,用户直接拍发票照片上传,系统自动识别金额、日期、发票号。这需要多模态大模型的支持,目前技术已经比较成熟了。
还有一个方向是流程挖掘。系统跑一段时间后,积累了大量执行日志,可以用这些数据反过来优化流程设计。比如发现某个审批环节经常被跳过,说明这个环节可能没必要;某个参数经常需要人工修正,说明模型抽取能力需要加强。
我个人在实际操作中的体会是,AI流程管理系统的落地难点从来不在模型本身,而在模型和业务之间的那层“胶水”。这层胶水写得好不好,直接决定系统能不能用、好不好用。把80%的精力花在工程化上,20%花在模型调优上,这个比例是比较合理的。