前阵子在某制造企业的Java技术栈系统里做AI落地推进对方技术负责人提了个很直接的要求希望AI能把设备故障、质量异常、物料追溯这类问题“直接处理掉”而不是只给一段看起来合理的回答。这句话基本概括了制造业Java系统AgentRAG落地要解决的核心问题——让AI从“会回答”走向“会落地”。很多团队在做内部知识库问答时RAG效果已经能看了觉得离“数字员工”不远了。真放到制造业环境里跑一圈就会发现能让AI把历史工单查出来、把维修记录调出来是一回事能让它根据检索结果替人发起工单流转、回写处理状态完全是另一回事。这篇内容按一个偏实战的项目复盘来写在Java技术栈占主导、系统又老又杂的制造业现场Agent层和RAG层到底怎么配合才不至于让AI停留在“聊天机器人”阶段。适合正在做制造业知识库升级、想把AI接进已有业务系统的人参考也适合被老板一句“别人家AI都能自动干活了”追着跑的团队看完可以少走几段弯路。1. 纯RAG问答在制造业为什么“看着能跑实际没法用”1.1 制造业知识问答的三个典型困境制造业做RAG起步时多半和我遇到的情况一样把设备手册、工艺规范、故障案例、SOP文档导进向量库接上大模型一个看着还挺像样的问答系统就出来了。演示时很惊艳——“这台设备的额定转速是多少”“换油周期的标准是什么”都能对答如流。但一放到班组长和维修工手里系统很快就失宠了。第一个困境是知识时效。设备点检表、工艺卡、安全规范经常改版老版本会被新版本替代但向量库里老文档还在检索系统偶尔会把作废标准捞出来当成依据回答。制造业现场讲究“文实相符”一份过期规范引起的误判比AI答不上来还让人头疼。第二个困境是文档形态差。很多车间里的知识不是干净的可编辑文本而是扫描件、带红章的照片、手写维修记录、Excel台账。扫描件不做OCR向量化基本是空转手写记录的错别字和简写会让检索质量大打折扣。没有前处理流程RAG直接从文档夹里起飞大概率半路摔机。第三个困境最要命制造业的大量提问不是单纯“求信息”而是“求动作”。员工问“这个设备有问题该怎么办”潜台词是“帮我查一下现在什么状态最好能生成一个维修工单”。RAG只能从静态文档里组织一段文字回答它不知道这台设备昨天刚换过一个轴承不知道当前系统里它已经处于离线状态更不可能替你点一个“创建工单”的按钮。1.2 “会回答”和“会干活”之间隔着一整个系统层想明白一个道理之后很多设计就顺了RAG本质上解决的是“模型不知道企业内部知识”的问题通过检索外部资料来增强上下文但它的输出边界始终停在“生成回答”。而制造业真正需要的是从“生成回答”跨到“执行动作”——写工单、查台账、改状态、通知下一环节人员。这一步跨不出去AI就始终是个高级搜索引擎。从技术实现角度看跨出去靠的就是Agent层。Agent拿到用户问题后先判断该不该调用知识库该不该调用某个Java系统接口然后按流程把工具串起来最后把结果返回给用户。RAG是它的一个知识来源工具Java老系统的接口被包装后是它的另一个行动工具。整套架构在设计时我的核心原则是不要重写业务系统让业务系统以“工具”的形式被Agent调用。这个原则特别适合制造企业。制造业的Java技术栈系统可能积累了十年以上表结构复杂、接口文档缺失、关键逻辑散落在老代码里。动手术式改造谁都不敢签这个责任能用一层适配层把它们封装成可调用的工具API不动原系统的逻辑是最稳妥的打开方式。2. 目标架构Agent当调度、RAG当记忆、Java系统被“工具化”2.1 业务系统不推倒重写的落地原则我当时给团队画的落地原则就三条。第一条读取优先写入谨慎。先通过工具接口把设备状态、库存余量、工单记录这些实时数据暴露给Agent解决“AI回答过于静态”的问题写入操作默认不直接执行只生成草稿给人工复核后面会专门讲这个设计。第二条黑盒封装老系统。所有对老系统的访问都不直接拼SQL、不直接改库而是走一层独立的工具适配服务把数据查询、状态更新、工单创建封装成明确语义的“工具”。这样即使老系统某个接口重试超时或者返回怪异影响范围也能控制在这一层不会污染整个Agent链路。第三条知识库和业务库分离。RAG管知识类检索比如故障处理手册、操作规范、历史案例分析Java业务系统管实时数据比如当前设备状态、库存批次、工单进度。Agent先判断用户要的是哪类信息再决定走哪条路。最怕的是把业务库的数据全同步到向量库里那只能得到一个“永远过期”的知识库。2.2 Java侧技术栈怎么选这是个不能回避的问题。我见过不少团队本来Java系统一堆结果做AI又开一个Python服务两边来回调部署链路拉得很长。其实Java生态现在做AgentRAG已经有相当成熟的路子可以在Java技术栈内闭环。我们当时的选择是Agent编排层用Java侧的框架RAG链路也统一用Java实现来自持久化层直接用普遍都有的PostgreSQL加向量插件避免引入一套全新存储中间件。选型时参考这几个维度维度推荐方向理由Agent编排Java生态的Agent/RAG框架和Spring技术栈衔接顺团队不必维持两套语言向量存储现有PostgreSQL加向量插件不引入重组件运维成本低数据量在千万级以内够用Embedding中文效果好的开源嵌入模型制造业术语多通用英文嵌入模型命中率很差对话模型私有化部署的开源中文底座模型数据不出厂满足制造企业对工艺数据的安全要求工具暴露Spring Boot封装OpenAPI风格接口老系统接口做适配统一鉴权和审计有人会问为什么不直接用Python理由很简单项目维护是长期的Java团队里能维护Python的人往往只有一两个一旦骨干走了整个链路就瘫了一半。Java侧生态这两年已经跟进得很快了选择它们至少要JVM工程师上手的门槛低我也少花很多时间去解释“为什么要再维护一个Python服务”。2.3 一条请求从输入到落地的完整链路选型定了之后我在项目文档里写下了这条链路后来也成了所有开发对齐的基准用户提问进Agent编排层之后先做意图识别判断这是“知识查询型”问题还是“业务操作型”问题。如果是前者Agent带着检索条件调用RAG服务从知识库里捞切片再把切片组装成上下文交给模型生成回答。如果是后者Agent需要先从RAG知识库补足该业务的操作规范再从Java工具适配层获取实时数据必要时执行草稿创建类的操作最终把结果按约定格式返回给用户。举个例子现场说“二号粉碎机震动手感异常”Agent第一步检索知识库拿到振动类故障排查手册第二步调用设备状态工具发现这台设备当前负载确实偏高第三步检索历史维修记录发现两周前更换过一次轴承第四步生成工单草稿并注明依据等待确认。整个过程中RAG负责“我知道该怎么办”工具层负责“我知道现在是什么状态”Agent负责把两者串成一个可执行结论。单纯RAG做不到后半段这就是整篇文章想表达的核心差异。3. 让历史Java系统“张口说话”数据加工与RAG检索改造3.1 制造业知识源的清洗与结构化很多团队做RAG失败说“模型效果不行”其实问题出在源头数据上。制造业知识文档有自己的一套脾气设备手册通常是PDF分章节工艺文件可能是老式Word排版点检表是Excel嵌套合并单元格还有大量胶片式的扫描件。不把这些形态统一后面检索一定会出问题。我的处理流程分成四步扫描件先走OCR识别转成文本后再人工抽检PDF和Word解析成段落级文本保留章节目录信息Excel表格按“每行一个知识单元”或者“每块区域一个主题”转成自然语言记录最后把清洗结果按业务域重组比如设备类、工艺类、质量类、安全类。清洗完毕后统一入库该版本管理就版本管理该标注来源就标注来源。这里有一条操作经验制造企业的SOP文档经常有“本页作废”“以盖章版为准”这类标注清洗阶段要果断把作废版本排除出向量库而不是全都塞进去。否则AI会频繁引用过期内容现场人员用一次就会对系统失去信任。在我们项目里专门安排了一个质量专员维护知识库的“有效文档清单”新文档上线时同步下线旧版本。3.2 切片要按语义走不要按固定字数走技术文档切块这件事看起来是最没有含金量的环节实际上对最终效果影响极大。一开始我们图省事按固定512字切结果经常把“故障现象”和“处置步骤”切成上下两篇检索出来的上下文缺胳膊少腿模型回答自然也不靠谱。后来改成按“语义单元”切章节标题开始到下一个同级标题作为一个大块再按段落和操作步骤拆成可检索块。设备故障这类知识最好把“故障现象—可能原因—处置动作—注意事项”整理成结构化的问答对比如“粉碎机振动异常-原因A/B/C-处置S1/S2/S3-禁止在运转中直接伸手检查”。这样模型拿到切片时几乎不用费力拼凑信息回答质量明显上升。切完后要做重叠切片吗需要。我习惯让相邻切片有大概10%到20%的重叠区防止检索时把属于上文的语义边界切掉。你可以理解成安全边际成本不高但对召回率的改善很实在。3.3 纯向量检索不够要做混合检索和重排制造业的数据有个天然特点用户习惯用设备编号、型号、批次号、简称作为关键词比如“HMC630”“三号空压机”“RT-112”。这类字符串对向量检索很不友好嵌入模型经常把它们当成语义相近的噪声处理导致Top5里全是看似相关实则无关的结果。我们后来把检索改成混合模式向量检索负责找回语义相近的段落BM25基于关键词负责找回精确编码匹配的段落两路结果合并后再做重排序和去重。别小看这个改动实测在历史故障库上的召回率提升非常明显。我还加了一路“结构化前置查询”如果用户在问设备状态、库存数量这类问题直接走Java工具的SQL查询压根不进向量库既准确又实时。在挑选重排序模型时建议选对中文长文本不太吃内存的那种因为制造现场文档段落偏长模型输入长度不够会把检索结果截断。重排后的Top3切片才是最终交给大模型的内容宁少勿杂上下文越干净生成质量越稳定。4. 核心代码走读Java系统里的AgentRAG落地方案4.1 知识检索服务的具体实现RAG部分我用一个Spring Boot服务简单展示。核心有两个向量库检索以及把检索结果拼接成模型上下文。代码可以长这样Service public class RagAnswerService { private final VectorStore vectorStore; private final ChatModel chatModel; public RagAnswerService(VectorStore vectorStore, ChatModel chatModel) { this.vectorStore vectorStore; this.chatModel chatModel; } public String answer(String question) { // 1. 从向量库召回Top K相关切片 ListDocument docs vectorStore.similaritySearch(question, 5); // 2. 加上关键词检索结果混合去重 ListDocument keywordDocs keywordSearch(question); ListDocument merged mergeAndRerank(docs, keywordDocs); // 3. 拼装上下文限定模型“只依据资料回答不编造” String context merged.stream() .map(Document::text) .collect(Collectors.joining(\n---\n)); String prompt 你是制造业现场知识助手。请只依据如下资料回答问题。 若资料不相关或不足明确说无法回答。\n资料:\n context \n问题: question; return chatModel.call(prompt); } }这里有一个容易被忽略的点向量库检索出的切片如果跟问题无关模型强行作答就会产生幻觉。所以Prompt里必须写清楚“资料不足就承认不足”而不是硬凑。另外向量库连接、Embedding模型加载这些初始化工作最好在启动阶段完成并缓存住别让每次请求都重新初加载否则并发一上来系统就卡死。4.2 把Java老接口包装成Agent可调用的工具Java侧的工具化封装我习惯用注解方式定义“工具元数据”Agent框架会自动为每个方法生成调用描述。核心要点是一个工具方法只做一件清晰的小事描述里讲清楚什么时候该用它、参数什么含义、返回结果什么结构。模糊描述会导致Agent乱用比如把“查询工单状态”的工具拿去回答“怎么申请工单”。Component public class EquipmentTools { private final EquipmentService equipmentService; public EquipmentTools(EquipmentService equipmentService) { this.equipmentService equipmentService; } Tool(查询设备当前运行状态入参为设备编号) public String queryStatus(String equipmentId) { EquipmentStatus status equipmentService.getStatus(equipmentId); if (status null) { return 设备编号不存在禁止编造状态; } return 设备[ equipmentId ]当前状态 status.getState() , 负载 status.getLoadRate() , 最近保养时间 status.getLastMaintainTime(); } Tool(根据设备编号和故障描述生成维修工单草稿不能直接提交执行) public String createWorkOrderDraft(String equipmentId, String faultDesc) { String draftId workOrderService.createDraft(equipmentId, faultDesc); return 工单草稿已生成编号 draftId 请用户确认后提交; } }注意上面这两个工具的设计差异查询类工具可以直接返回结果写操作类工具一律生成“草稿”返回内容里带上“请用户确认后提交”这样的提示。这是制造现场的底线逻辑后面专门展开讲。工具太多时建议每个工具用两句以内的自然语言描述让模型容易区分。4.3 Agent的决策链路检索先于行动行动前必须校验Agent收到用户问题后我不会让它直接拿着对话模板就回答。决策链路固定如下先判断意图涉及专业知识的强制先做RAG检索而不是靠参数记忆硬答判断需要写数据的必须先获取相关设备信息确认用户意图足够明确才生成草稿。这条链路里有两个校验点很关键。校验点是工具入参校验。比如用户说“查一下粉碎机状态”但没说编号Agent不能瞎猜一个设备编号去调工具。正确的做法是继续询问确切的设备编号或者调用设备列表查询工具让用户选择。制造现场有很多重复编号、类似名称的设备猜错一次可能查出别人车间的数据出问题就是责任事故。校验点是结果可追溯。每一次工具调用我都在代码里打了审计日志谁问的、调了什么工具、入参出参是什么、耗时多少、最终返回给用户什么。这个日志不光是排查问题用的更是给现场安全部门看的“AI操作留痕”。别等出事后再补一开始就设计进去。5. 一个典型场景实测设备故障工单从咨询到自动派单5.1 为什么拿“设备故障工单”做首个落地场景选第一个场景时我建议团队不要贪大不要一上来就做“质量异常自动判责”“全流程排产优化”这种复杂目标。设备故障工单是最理想的试点原因有三点。这类知识高度密集维修手册、历史检修记录、备件更换档案都是现成的RAG养料效果容易做出来。它的动作链很短查状态、查历史、建工单草稿不需要跨多个系统做长流程协调初版实现难度低。最关键的是它可量化原来维修工要打电话问、翻手册查、再手动建单现在可以对比前后耗时老板看得懂。试点目标就定成一条现场班组长在聊天界面用自然语言描述故障AI给出排查依据并且在得到确认后生成结构化维修工单草稿维修工无需手动填写工单信息。5.2 实测数据对比我们在某车间跑了一个月取了五十条真实故障咨询样本对比人工处理链路和AI辅助链路的情况。下面的数字只代表本项目样本但趋势有共性指标纯人工操作普通RAG问答AgentRAG链路查询历史维修记录平均耗时5到8分钟30秒20秒故障排查建议与手册吻合度依赖维修工经验凭检索结果生成综合知识库加实时状态生成维修工单平均耗时10到15分钟无法生成1分钟内生成草稿工单信息缺失率10%左右无法计算3%以内草稿阶段普通RAG问答能把“查手册”这一步变快但没法把工单建起来。AgentRAG真正改变的是最后两行信息完整率提升了建单时间大幅缩短。维修工现在最常说的评价是“它至少把编号、设备状态、上次检修时间都给我填好了我只要核对一下”这就是把AI从“回答者”变成“助手”的直观感受。5.3 权限、风控与人工兜底能写系统之后的责任边界让AI碰生产系统安全设计优先于功能迭代。我们当时在权限和风控上做了三层设计这里建议所有做同类项目的人直接抄作业。第一层按角色控制工具可见性。普通操作工只能看到查询类工具和本部门设备范围班组长能看到工单草稿创建工具维修主管能看到备件领用草稿工具。工具层根据用户身份动态决定暴露哪些方法模型压根看不到不该用的工具最大程度防止误调用。第二层写操作默认不自动执行。所有更新状态、创建工单、变更数据的动作只生成草稿必须由用户明确的二次确认或者由人工复审后在下游系统执行。Agent返回“已生成草稿请确认”而不返回“已完成”这一字之差责任归属完全不同。第三层异常场景必须“认怂”。工具调用失败、设备编号不存在、数据查不到时Agent必须如实报告“查询失败”不能顺着用户的话茬编一个结果。制造现场最怕AI一本正经地给错误设备维修建议一个错误可能直接造成产线停机。6. 制造业特别容易踩的六个坑以及我填坑的过程6.1 术语歧义同类词汇在知识库里指代不同事物“工单”这个看似简单的词在不同车间意思完全不同维修工单、生产工单、质检工单结构千差万别。Agent第一次上线时用户说“帮我查一下工单”模型随机从向量库捞了三种类型的结果回答得牛头不对马嘴。后来我们用两个方法解决一是在知识切片阶段按知识域给每个块打标签维修、生产、质检单独拆分存储二是在系统提示词里明确说明“询问工单时必须确认工单类型”。这算知识域管理的必修课不做好后面所有准召率数据都白搭。我还顺手做了一份“制造业术语别名表”把口径不一样的词显式维护进去比如“换型”和“换产”、“停机”和“宕机”。别名表本身就是工程资产团队维护久了会发现它对知识库检索质量的提升比换大模型明显得多。6.2 老系统接口的质量不可控超时、缺字段、返回语义模糊Java老系统的接口一言难尽。有的接口遇到非法参数直接抛异常有的返回200但字段全空有的在不该超时的场景里卡三十秒。Agent调用这些工具一旦失败整条链路就像断了线的木偶。我对工具适配层立了几条规矩所有外部访问设置硬超时默认三秒失败即返回“服务暂不可用”而不是无限重试对返回结果做字段校验核心字段为空时视同失败每个工具定义“失败话术”让Agent知道怎么向用户解释而不是自己脑补结果。这些规矩写起来容易难的是坚持。有一次某个老接口偶发超时Agent连续三天被现场反馈“不好用”我们排查后发现问题就出在重试逻辑上。把超时改短、增加熔断后体验立刻稳了。老系统不会一夜之间变好但工具层的“防御性设计”能把它对用户体验的影响压到最低。6.3 向量召回不准时先检查切片别急着换模型团队里有个常见惯性思维效果不行就觉得是“模型不行”于是换更强的底座模型。我承认模型档次有影响但实际项目里最先影响效果的大概率是切片质量。有一次用户反复反馈“查不到某条工艺规范”我们去看切块发现那条规范恰好落在章节末尾语义被前面一大段概述稀释了向量表示完全不聚焦。把这条规范拆出来单独成块后检索立刻命中。所以排查召回问题时我建议遵循这个顺序先看切片是否聚焦再看检索方式是否覆盖了关键词精确匹配然后检查重排是否把准确切片挤掉了最后才考虑换Embedding模型或对话模型。这个排查次序能省很多冤枉钱和时间。6.4 多工具调用时的一致性问题不能把写链路全部交出去Agent在回答一个问题时有时会连续调用多个工具比如先查库存再创建备件领用草稿再通知库管。这在技术上很自然但工程上非常危险如果第二步成功、第三步失败用户会拿到一个“草稿已建但通知未发送”的中间态。如果第二步和第三步分别改了两个系统的数据还涉及跨系统事务问题更复杂。我的处理方式是把一个长动作拆成“草稿生成、人工审批、执行提交”三个环节所有写操作都落在可控的业务流里而不是让模型在一次推理里自己跑完整链条。真要跑多个工具也会给每个工具专门设计补偿逻辑比如“创建草稿失败”就回滚前一步的临时状态。制造环境里AI可以追求“效率高”但不能以“一致性崩坏”为代价。6.5 现场用户说话太“方言化”简称、口头语、口语化描述车间里用户提问很随性比如“三号机好像不太对劲”“那个磨又响了”。这类描述在向量检索里命中率很低因为知识库里写的是“HMC630型卧式加工中心主轴异常”。不做好文本归一化AI会连用户想问哪台设备都搞不清楚。我在Agent前面加了一个轻量归一化层把“三号机”按上下文映射到具体设备编号把“那个磨”“那边那个床子”这种指代通过追问澄清。同时把口语词汇和正式术语建立映射关系比如“响了”对应“异响”“过热”对应“温度超限”。这一步的价值一开始看不出上线两周后用户留存率明显上升。因为现场工人发现AI能听懂他们的话了才愿意继续用。别小看这种体验层面的东西制造业工具最怕的就是“学起来比手工还累”。6.6 上线初期的信任建立比模型精度更紧迫最后说一个经常被忽视的坑。AI系统的首次用户几乎都带着挑剔眼光测试只要回答错一次后面就很难扭转印象。尤其是Agent能写草稿之后用户对它的信任要求更高。我们当时做了一件很笨但很有用的事在最初两周所有Agent给出的答案都强制附带“依据来源”比如“依据《粉碎机维护手册》第三节”或“依据历史工单WX-2024-0876号”。用户可以点开来源核对哪怕AI说错了只要能快速看清依据信任还不至于崩塌。等用户慢慢习惯了“AI会给我链路完整的依据”之后再放开自动草稿的戏份整体推进就顺了。这也算一个经验吧制造业系统里AI再聪明都不如“让用户看得见聪明”来得重要。