给中小企业做 AI 落地,我踩的第一个坑:把 AI 做成了"助手"
这个系列记录我给中小企业做 AI 落地的过程。我现在的身份有点别扭:白天在一家公司当项目负责人,做的就是中小企业管理系统的 AI 化;晚上回学校,这些项目又变成我的毕设素材。所以这里写的东西,一半是踩坑,一半是补课。
一、第一个项目,我做了个"AI 助手"
第一家客户是家八十来人的制造企业,做五金件的。
他们的日常是这样的:采购在微信上跟供应商聊,谈好了截个图,转发给仓库;仓库照着截图手敲进 Excel;月底财务再对着 Excel 和纸质单核一遍。一张采购单,从谈完到进系统,最快也要十几分钟,慢的时候第二天才录。
于是我做了个聊天入口,接了大模型,用户可以直接问"这个月哪种螺栓出库最多"“上次给XX五金那批货多少钱”。演示的时候老板坐旁边看,问了三个问题,答案都在三秒内出来了,他挺高兴,说"这个好,这个智能"。
那一刻我以为成了。
二、上线不到一个月,没人点了
不是用得少,是没人点。
我去现场待了半天,看他们怎么干活,才慢慢明白问题在哪:
第一,他们的问题不需要"问"。仓库管理员要知道某商品还有多少库存,他会直接打开库存列表按商品名搜一下——三秒。让他打字问一句"六角螺栓M8*30现在还有多少",再等模型想五秒,还要担心它答错,这不是提效,是添乱。
第二,答错了没人知道。有一次它把"近三个月采购额"算成了"近三个月入库金额",差了退货那部分。采购看了没发现,直接拿去跟供应商对账,被对方指出来。这件事之后,那个采购再没用过这个功能。
第三,它和流程是两张皮。他查完数据,该录的单还是得手敲。AI 帮他"知道"了一件事,但没帮他"做完"任何一件事。
我后来在复盘文档里写了一句话:我们交付了一个"更聪明的旁观者",而客户需要的是一个"能动手的同事"。
三、问题不在模型,在位置
冷静下来想,那个项目里模型的表现其实不差——抽取、理解、组织语言,都在及格线以上。真正的问题是:我把它放在了一个流程之外的位置。
旁挂的入口,无论多聪明,都只是"多了一个可以问的地方"。它不改变任何一条业务的流转路径,也就不会改变任何一个人的工作方式。而中小企业老板花钱,买的从来不是"能问",是"少干"。
后来我把这件事想成一句话,也是这个系列的基本立场:
别做 AI 助手,做 AI 节点。
四、“助手"和"节点”,差在哪
| AI 助手 | AI 节点 | |
|---|---|---|
| 位置 | 挂在系统旁边,独立入口 | 嵌在业务流程里,是某一步的实现方式 |
| 输入 | 用户随口一句话 | 结构化的上下文(单据、字段定义、权限) |
| 输出 | 一段自然语言 | 符合 Schema 的结构化数据 |
| 出错 | 用户自己发现 | 校验层拦截,转人工 |
| 失败 | 功能不可用 | 降级到手工流程,业务不停 |
| 价值 | 让人"查得更快" | 让人"少干一步" |
这个表是我后来做每个功能前都要过一遍的。凡是只能落在左列的,我一律砍掉——不是因为它不好,是因为它撑不起一个卖点。
五、一个很小的例子
同样是"从一张采购单里拿到数据",两种做法的差别很具体:
助手式做法:用户上传图片,模型输出一段话——“这张单子是向深圳市XX五金采购六角螺栓,数量 1200,单价 0.42,合计 504 元。” 用户看完,自己往系统里敲。
节点式做法:模型必须吐出这个东西——
fromdecimalimportDecimalfromtypingimportOptionalfrompydanticimportBaseModelclassLineItem(BaseModel):product_name:Optional[str]=Noneqty:Optional[Decimal]=Noneprice:Optional[Decimal]=Nonesource_span:Optional[str]=None# 原文依据片段confidence:float=0.0classCandidateDoc(BaseModel):partner_name:Optional[str]=Noneitems:list[LineItem]=[]然后必须过校验:
defvalidate(doc:CandidateDoc)->list[str]:errs=[]fori,itinenumerate(doc.items):ifit.qtyisNoneorit.qty<=0:errs.append(f"第{i+1}行:数量缺失或非正数")ifit.qtyandit.price:calc=(it.qty*it.price).quantize(Decimal("0.01"))errs.append(f"第{i+1}行:请确认金额口径(计算值{calc})")returnerrs过了校验,进确认页;没过,退回手工录入。
差别不在模型,在那两段 Python。前者产出的是"一段话",后者产出的是"一个可以继续往下走的数据结构"。有契约,后面的校验、确认、入库才接得上。
六、这个系列打算写什么
我不打算一口气把整套系统讲完——那既不像真实过程,也不好看。按我实际推进的顺序,大概是:
- 别做助手,做节点(本篇,立论)
- 让大模型稳定地"吐"结构化数据:输出契约怎么写
- 校验层:模型错了,系统得知道
- 主数据对齐:为什么这一步我不敢全自动
- 受限 NL2SQL:让 AI 能查库,但查不穿
- 补货建议:哪些数必须由程序算,模型碰都不能碰
- 算笔账:一次单据抽取到底烧多少钱
- 交付:怎么向老板和客户证明它真的有用
顺序也可能中途改——真做项目的人都知道,计划往往是干到一半才看清的。中间还会插几篇"学校学的"和"公司用的"对不上的地方,毕竟我两边都得交差。
七、下一篇
讲第 2 条:怎么让大模型稳定输出结构化数据。
这事听起来简单,写个"请返回 JSON"就完了。实际做起来,你会遇到模型给你加解释、给你套 markdown 代码块、字段名改一个字、数量返回成字符串、长单据直接截断——每一种都能让你的解析器崩掉。
下一篇我把这些坑和对应写法都列出来。