拓冰建站拓冰建站
首页 / 资讯中心 / 正文

AI再工业化实践:用Python搭建设备维修知识问答Agent

黄仁勋在一系列公开场合表达过一个判断AI 正在推动再工业化。这里所说的再工业化不是简单地把传统生产线搬回来而是用大模型、机器视觉、AI Agent 和边缘推理重构制造业的研发、生产、运维方式。放在技术语境里这背后的核心变化是工业知识第一次可以被大规模抽取、检索、推理和复用设备操作、维修保养、工艺参数这些原本依赖老师傅经验的环节正在变成可编程、可调用的 AI 能力。这篇文章会落在一个可复现的工程案例上用 Python 技术栈实现一个“设备维修知识问答 Agent”。它的输入是工业设备手册输出是一个通过接口就能提问的 AI 助手。读者可以把它理解成 AI 再工业化场景里最常见、也最有实际价值的一种应用形态——知识密集型任务的智能化。文章会从概念讲到环境从代码讲到验证再从排错讲到生产化建议尽量做到每一步都能直接执行。1. 先理解 AI 推动再工业化背后的技术逻辑1.1 再工业化在技术语境下指的是什么再工业化这个概念在不同语境下有不同含义但从工程角度看它其实指向一个很现实的问题制造业能不能用更少的人、更短的时间、更稳定的质量完成更复杂的生产任务。传统自动化解决的是“按固定流程重复动作”它的前提是流程完全可控。但工业现场的实际情况要复杂得多设备状态会漂移原材料批次有差异同样的故障在不同环境下的表现不一样。这些不确定性问题以前的处理方式高度依赖人的经验。AI 提供了另一种处理不确定性的方式。大模型可以理解维修手册、工艺文档、设备日志里的自然语言机器视觉可以识别产品表面的微小缺陷AI Agent 可以在故障发生时自动检索历史案例并调用设备接口获取实时状态。这些能力叠加起来就形成了“用 AI 重构生产知识”的新模式。再工业化在技术语境下指的就是这种基于数据和模型的生产力重构。1.2 大模型在工业场景中不是直接可用需要工程化很多人在第一次接触大模型时会以为只要把问题发给模型它就能给出工业级答案。实际项目里这个想法会很快撞上三堵墙。第一堵墙是知识隔离。通用大模型训练时不会包含某家工厂的设备手册、维修记录和工艺配方所以它对具体设备往往是“知道概念不知道实际”。第二堵墙是幻觉。模型在不知道答案时可能用通顺但错误的文本“补全”一个答案在设备维修场景里这种幻觉可能直接导致错误操作。第三堵墙是集成成本。工业系统需要的是接口、权限、日志、监控和可回滚的发布流程而不是一个随时可聊天的对话框。所以要真正落地不能直接把大模型当作最终答案来源。工程上常用两条路线解决一是给模型外挂知识库也就是 RAG二是把模型放进一个有约束的流程里让它可以调用工具也就是 Agent。这篇文章后面的实践会同时用上这两条路线。1.3 AI Agent 是再工业化里最值得先落地的形态AI Agent 的本质是让大模型不再只做“文本生成”而是能够调用外部工具、访问数据源、按流程完成任务。工业场景非常适合这种形态。比如一个设备维修 Agent用户问“伺服电机过热跳闸是什么原因”Agent 先从维修手册知识库中检索相关段落再调用设备监测接口拿到当前电压、电流、温度数据最后把检索结果和实时数据一起组织成回答。整个过程中模型负责理解、组织和推理知识库负责提供事实工具接口负责提供最新状态。每一层都有明确边界出现问题时也容易定位。从工程实践角度看先做这种“知识检索 状态查询 文本生成”的问答 Agent比直接训练一个工业大模型要务实得多。它不需要昂贵的训练资源不需要先处理海量标注数据只需要一台能跑本地模型的机器、一个向量数据库和一套业务接口。下面就从环境准备开始演示一个最小可运行版本。2. 环境准备用最小技术栈跑通一个 AI 应用2.1 技术选型Python Ollama Chroma FastAPI学习环境和生产环境的技术选型可以不同但第一版建议尽量简单。这里采用一套可以完全本地运行的技术栈组件选型作用编程语言Python 3.10 及以上生态最完整适合快速搭建 AI 应用大模型服务Ollama qwen2.5:7b本地运行模型避免数据出域向量数据库Chroma轻量、文件持久化适合学习和验证Embedding 模型nomic-embed-text把文档和查询转成向量Web 框架FastAPI Uvicorn提供 HTTP 接口HTTP 客户端requests / openai SDK调用本地模型接口这套组合的好处是依赖少单机可跑任何一个环节都能单独调试。生产环境可以把 Ollama 换成 vLLM 部署的集群服务把 Chroma 换成 Milvus但接口设计可以基本保持一致。2.2 本地模型服务安装 Ollama 并拉取模型Ollama 是一个可以在本地运行大模型的工具它提供 OpenAI 兼容接口方便我们写统一的调用代码。安装完成后先拉取两个模型一个用于对话生成一个用于文本向量化。# 安装后启动服务默认监听 11434 端口 ollama serve # 拉取对话模型和向量模型 ollama pull qwen2.5:7b ollama pull nomic-embed-text # 确认模型已经就绪 ollama list如果机器 GPU 显存不足可以选择更小的模型例如qwen2.5:3b。对话模型和向量模型必须分开不能共用一个模型因为二者承担的任务完全不同。向量模型负责把文本映射成高维向量对话模型负责理解和生成自然语言。注意ollama pull会从模型仓库下载文件下载过程需要网络连接。如果内网环境不能直接下载需要提前准备离线模型包或者在部署机上配置好代理仓库。2.3 项目依赖与目录结构创建一个独立项目目录建议使用虚拟环境隔离依赖mkdir industrial-agent cd industrial-agent python3 -m venv .venv source .venv/bin/activate安装依赖pip install fastapi uvicorn chromadb openai requests python-dotenv项目目录规划如下industrial-agent/ ├── main.py # FastAPI 入口提供 /ask 接口 ├── agent.py # 核心 Agent 逻辑RAG 工具调用 ├── knowledge/ # 存放设备手册、维修文档 │ └── servo_motor_manual.md ├── chroma_data/ # Chroma 向量数据持久化目录 └── .env # 本地环境变量建议把知识库文档和代码分开。这样后续更新文档时不需要改代码只要重新触发索引即可。2.4 关键配置与参数速查在.env文件中保存模型服务地址和参数OLLAMA_BASE_URLhttp://localhost:11434 CHAT_MODELqwen2.5:7b EMBED_MODELnomic-embed-text CHUNK_SIZE500 CHUNK_OVERLAP50 TOP_K4这些参数会在后面的核心代码里用到。需要特别说明的是CHUNK_SIZE和CHUNK_OVERLAP。它们决定知识库文档被切分成多大的片段后向量化直接影响检索效果。片段太小语义不完整片段太大检索精度下降而且可能超过模型上下文窗口。500 到 800 之间的切分大小在多数工业文档场景里可以作为一个起步值。3. 实现一个工业知识问答 Agent3.1 核心链路RAG 的四个环节这个 Agent 的基础是 RAG全称是 Retrieval-Augmented Generation也就是“先检索再生成”。它解决了通用大模型不知道企业私域知识的问题。完整链路分成四个环节环节输入输出作用文档切分原始文档文本块让检索粒度可控向量化文本块向量把文本变成可计算相似度的数字召回用户问题相关文本块从知识库找出最相关内容增强生成问题 召回内容最终回答让模型基于资料而不是凭空生成下面从文档切分开始逐步实现。3.2 文档加载与切分先决定检索粒度先用一个简单函数把 Markdown 文档切分成固定大小的文本块。实际项目中可能还需要处理 PDF、Word、表格但核心思路一致先把长文档变成多个语义相对完整的小段。def load_document(path): with open(path, r, encodingutf-8) as f: return f.read() def split_text(text, chunk_size500, overlap50): chunks [] start 0 while start len(text): end start chunk_size chunks.append(text[start:end]) if end len(text): break start end - overlap return chunks这里有两个关键点。第一overlap是相邻片段之间的重叠字符数。它避免一个完整句子被一刀切开后检索时只看到半句话。第二切分粒度要和后续模型能力匹配。如果片段里包含多个无关主题检索召回后会把噪音一起送进提示词回答质量会明显下降。对于设备手册推荐先按“章节标题 段落”做结构化切分再对过大的段落做二次切分。固定字符切分只是兜底方案不能替代结构化解析。3.3 向量化与检索用相似度而不是关键词向量化的目标是把一段文本变成一个数字数组。相似问题在向量空间中距离更近。Chroma 负责存储向量和执行相似度检索。先自定义一个 Embedding 函数调用 Ollama 的向量接口import requests import chromadb from chromadb.api.types import Documents, EmbeddingFunction, Embeddings class OllamaEmbeddingFunction(EmbeddingFunction): def __init__(self, base_url, model_name): self.base_url base_url self.model_name model_name def __call__(self, input: Documents) - Embeddings: embeddings [] for doc in input: resp requests.post( f{self.base_url}/api/embeddings, json{model: self.model_name, prompt: doc}, timeout30, ) resp.raise_for_status() embeddings.append(resp.json()[embedding]) return embeddings然后创建 Chroma 集合并写入文档块client chromadb.PersistentClient(path./chroma_data) embed_func OllamaEmbeddingFunction( base_urlhttp://localhost:11434, model_namenomic-embed-text, ) collection client.get_or_create_collection( namemaintenance, embedding_functionembed_func, metadata{hnsw:space: cosine}, ) chunks split_text(load_document(knowledge/servo_motor_manual.md)) for i, chunk in enumerate(chunks): collection.add( ids[fchunk-{i}], documents[chunk], metadatas[{source: servo_motor_manual.md, chunk_index: i}], )查询时使用query_textsChroma 会先对用户问题做向量化再计算相似度返回最相近的片段def retrieve(question, top_k4): results collection.query( query_texts[question], n_resultstop_k, ) return results[documents][0]这里有个容易忽略的点查询用的 Embedding 模型必须和写入文档时用的模型完全一致。如果写入时用nomic-embed-text查询时换了另一个模型向量空间不兼容检索结果会不可用。3.4 增强提示词与生成把检索结果交给大模型召回完成后把相关文本块拼接到一个提示词模板里再调用对话模型生成答案。提示词必须明确告诉模型只能依据给定资料回答不要编造。from openai import OpenAI client OpenAI( base_urlhttp://localhost:11434/v1, api_keyollama, ) def generate_answer(question, contexts): context_text \n---\n.join(contexts) prompt f你是工业设备维修助手。请只依据下面的资料回答问题。 如果资料中没有足够信息就回答“资料中未找到相关内容”不要编造。 资料 {context_text} 问题 {question} 回答 resp client.chat.completions.create( modelqwen2.5:7b, messages[ {role: system, content: 你是严谨的工业设备维修助手。}, {role: user, content: prompt}, ], temperature0.1, ) return resp.choices[0].message.contenttemperature参数控制随机性。工业场景的回答需要稳定、可复现所以建议调低到 0.1 或 0。生产环境还可以在系统提示词中加入“如果上下文为空请直接拒绝回答”等约束。3.5 Agent 工具调用让 AI 能查询实时设备状态只做 RAG 还称不上 Agent。Agent 的典型特征是能调用外部工具。这里用一个设备状态查询函数演示当用户询问设备当前状态时先调用工具拿到实时数据再让模型组织回答。DEVICE_STATUS { P-01: {status: running, temperature: 65.0, current: 12.5}, M-02: {status: alarm, temperature: 92.0, current: 18.2}, } def get_device_status(device_id: str): 模拟从设备管理系统查询实时状态。 return DEVICE_STATUS.get(device_id, {status: unknown})接下来需要判断用户是否在询问设备状态。可以先用规则做意图路由后续再换成模型分类def detect_intent(question): if 状态 in question or 是否运行 in question or 实时 in question: return device_status return rag def run_agent(question): intent detect_intent(question) if intent device_status: # 实际项目中可以从问题中抽取设备ID这里简化处理 device_id P-01 if P-01 in question else M-02 device_data get_device_status(device_id) prompt f用户询问设备状态请把数据整理成自然语言回答。 设备ID{device_id} 设备状态{device_data} 回答 resp client.chat.completions.create( modelqwen2.5:7b, messages[{role: user, content: prompt}], temperature0.1, ) return resp.choices[0].message.content, [] contexts retrieve(question) answer generate_answer(question, contexts) return answer, contexts真正的生产级 Agent 可以更进一步让大模型自己决定是否调用工具、调用哪个工具、传什么参数然后循环执行直到得到最终答案。这个机制在 OpenAI 协议里叫 function calling。Ollama 也支持部分模型输出工具调用参数但由于不同模型实现差异较大第一版用“规则路由 工具函数”的方式更稳定也更容易定位问题。4. 运行验证从启动到回答的完整检查4.1 启动 API 服务并确认模型可用把所有逻辑串到 FastAPI 入口文件main.py中from fastapi import FastAPI from pydantic import BaseModel from agent import run_agent app FastAPI() class AskRequest(BaseModel): question: str class AskResponse(BaseModel): answer: str sources: list[str] app.post(/ask, response_modelAskResponse) def ask(req: AskRequest): answer, sources run_agent(req.question) return AskResponse(answeranswer, sourcessources)先确认 Ollama 模型服务正常curl http://localhost:11434/v1/models返回 JSON 中包含模型列表即可。然后启动 FastAPIuvicorn main:app --host 0.0.0.0 --port 8000 --reload看到Application startup complete.说明服务已经准备好。4.2 用真实问题验证 RAG 链路使用 curl 发送一个设备维修问题curl -X POST http://localhost:8000/ask \ -H Content-Type: application/json \ -d {question: 伺服电机过热跳闸常见原因有哪些}可能返回{ answer: 根据维修手册伺服电机过热跳闸的常见原因包括负载过大、散热风扇故障、环境温度过高、编码器信号干扰等。, sources: [ 伺服电机有过热保护机制当绕组温度超过设定值时驱动器会触发报警并停止输出。, 排查时应先检查负载转矩是否超过额定值再确认散热风道是否有积尘。 ] }此时验证的重点是sources是否来自知识库而不是模型临时编造。如果sources为空或者答案与手册明显无关说明检索链路存在问题需要回到第 5 章排查。4.3 验证 AI 幻觉治理后的结果再测试一个知识库中不存在的设备curl -X POST http://localhost:8000/ask \ -H Content-Type: application/json \ -d {question: 如何维修注塑机螺杆卡死}如果知识库中没有注塑机相关内容理想输出应该是{ answer: 资料中未找到相关内容。, sources: [] }这个测试非常重要。它验证的是“模型是否具备克制能力”也就是没有依据时不会强行回答。如果模型仍然给出了一套看起来合理的维修步骤说明提示词约束不够强或者检索环节把无关内容误判为相关需要调整top_k或相似度阈值。4.4 运行验证检查清单检查项预期结果失败时排查方向ollama list存在两个模型重新执行 pull/v1/models接口返回模型列表检查 Ollama 是否启动、端口是否监听知识库检索sources非空且相关检查切分大小、Embedding 模型、文档内容知识库检索无关问题sources为空或很少调整 top_k 和相似度阈值回答质量答案有依据、不编造增强提示词约束降低 temperature工具调用设备状态问题返回实时数据检查意图路由和设备 ID 解析规则注意不要只验证程序能启动还要分别验证“有知识库”“无知识库”“需要工具调用”三种请求这样才能确认整条链路是完整可用的。5. 常见问题排查RAG 与 Agent 最容易卡住的环节5.1 模型服务连不上或者拉取失败现象调用 Ollama 接口时超时日志出现Connection refused。可能原因有三种Ollama 服务没有启动监听了其他端口客户端base_url写错。检查方式# 查看进程 ps aux | grep ollama # 测试端口 curl http://localhost:11434/v1/models解决方案是按顺序确认启动服务、核对.env中的地址、确认防火墙放行。如果服务在其他机器要把localhost换成目标机器 IP并确保网络互通。5.2 检索不到相关内容现象用户问一个明确在文档里的问题但sources为空或者召回的是不相关段落。排查优先级文档是否真的写入到了 Chroma重新执行写入代码观察是否新增 id。写入和查询是否用了同一个 Embedding 模型这是最常见的错误。chunk_size是否过大导致语义被稀释或者过小导致句子被切断。文档语言是否统一中文文档最好使用支持中文的 Embedding 模型nomic-embed-text对中文效果一般生产环境可以换成更合适的中文向量模型。解决方法是先打印出注入知识库的文本块人工确认内容无损再逐条调整切分参数。5.3 回答出现幻觉或引用不存在的文档现象模型给出了知识库中不存在的维修步骤或者生成了看起来合理但没有出处的结论。原因通常是提示词中没有严格限制“只能依据资料回答”召回结果太杂temperature过高检索到的多个段落互相矛盾模型自己做了“合理融合”。解决方案prompt f请只依据下面的资料回答不要使用资料之外的知识。 如果资料不足请直接回答“资料中未找到相关内容”。 不要推测不要编造。 资料 {context_text} 问题 {question} 回答同时把temperature降到 0并在返回结果中带上sources让使用者能看到依据。生产环境还可以在回答后附加“引用来源”字段便于审计。5.4 Agent 工具调用返回格式错误现象用户问设备状态模型返回的是通用文本而不是结构化设备数据或者工具返回的数据没有成功参与回答。这个案例里的 Agent 用的是规则路由所以问题多数出在设备 ID 解析上。比如用户说“1号泵现在什么状态”规则里如果是靠P-01精确匹配就会解析失败。解决方法是先把设备别名和标准 ID 做映射再用模型抽取实体。实际项目中建议给工具函数定义清晰的参数 schema并记录工具调用日志。排查时优先看日志中的intent和设备 ID 是什么而不是直接看最终回答。5.5 性能与资源问题现象第一个问题响应很慢后续稍微好一点但并发请求时服务不可用。原因通常是大模型在 CPU 上运行推理速度慢或者多个请求同时到达排队时间过长。学习环境单用户使用没关系但生产环境必须考虑性能和资源预算。解决方向问题建议CPU 推理慢使用 GPU 实例选择量化模型单机并发不足使用 vLLM、TensorRT-LLM 等推理框架向量库查询慢降低 top_k增加索引升级到 Milvus日志缺失记录每个请求的耗时、召回内容和模型输出6. 生产化落地的工程建议6.1 学习环境到生产环境的差异上面这套实现最大的价值是快速验证业务效果但它离生产还有一段距离。学习环境可以容忍“本地模型 文件向量库 启动即用”生产环境则需要额外补齐很多能力。关注点学习环境生产环境模型部署Ollama 单机vLLM 集群、多副本、自动扩容向量数据库Chroma 本地文件Milvus、Qdrant具备备份和高可用配置管理.env 文件配置中心、环境变量注入、敏感信息加密权限控制无接口鉴权、用户隔离、操作审计日志监控print 输出结构化链路日志、Prometheus Grafana回滚方案重启进程模型版本管理、知识库版本管理、灰度发布数据安全本地可访问私有化部署、脱敏、合规审批如果所在的工业环境不允许数据出域生产环境的第一原则就是模型全流程私有化。不仅对话模型要私有化Embedding 模型也要私有化。很多项目只注意大模型却忽略向量化接口可能把文本发送到外部服务造成数据泄露。6.2 发布前检查清单每次发布新版本前可以按下面这份清单逐项确认知识库文档是否有版本号是否能随时回滚到上一版。文档切分脚本是否可重复执行写入向量库前是否清空旧数据。Embedding 模型是否和已有向量库保持一致升级模型时是否重建索引。检索结果是否有相关性阈值低于阈值的片段是否被过滤。提示词是否包含“只依据资料回答”的约束。temperature是否已经调低。接口是否有鉴权是否限制了请求频率。是否记录了完整请求日志包括检索到的片段和模型输出。是否准备了模型不可用时的降级方案比如返回错误提示而不是空转。6.3 扩展方向视觉质检、预测性维护、多 Agent 协作设备维修问答 Agent 只是第一个闭环。它在技术上验证了“知识检索 工具调用 自然语言生成”这条路径可行往后可以朝三个方向扩展。第一个方向是视觉质检。把设备知识问答延伸成“图片输入 缺陷识别 维修建议”。例如拍摄设备表面照片通过视觉模型判断是否存在漏油、裂纹再结合知识库给出处理措施。第二个方向是预测性维护。把设备传感器的时序数据接入时间序列模型预测剩余寿命或故障概率由 Agent 在故障发生前自动生成工单。第三个方向是多 Agent 协作。一个 Agent 负责知识检索一个 Agent 负责设备状态监控一个 Agent 负责生成维修工单通过一个调度 Agent 把多个结果汇总到最终报告。这个架构更接近工业场景中的完整智能体系统但基础仍然是单 Agent 的可靠落地。如果团队以 Java 为主也可以考虑在后续版本中用 Spring AI 重构服务层。Spring AI 提供了ChatClient、EmbeddingModel、VectorStore等抽象能够把模型调用和向量检索封装成 Spring 风格的组件便于与现有 Java 微服务体系集成。但要注意Spring AI 版本演进很快落地前必须先确认依赖版本和目标模型服务的兼容性不要直接照抄旧配置。AI 推动再工业化真正落到工程上靠的不是一个更聪明的模型而是一套能把模型、知识、工具和业务流程接起来的系统。先从一个最小的设备维修问答 Agent 开始跑通检索、生成、调用工具这条链路再去逐步加生产环境需要的各种保障。对新手来说最有价值的练习不是反复调 prompt而是把“文档切分、向量检索、提示词约束、结果验证”这四件事从头到尾做扎实。这个闭环一旦建立后续无论是换模型、换场景还是换部署形态都不会觉得无从下手。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门