Qoder开发智能体实战:FED 进厂第一天
FED 进厂第一天:数据在 PLC 里、在纸上、在老师傅脑子里——一次真实感拉满的故障排查实录
关键词:FED、数据孤岛、PLC、DCS、点检表、知识图谱、RAG、Qoder、工业智能体、pymodbus、OPC UA
适用人群:工业 AI 工程师、FED/FDE、MES 实施顾问、数字化转型从业者
⚠️ 免责声明:本文案例为典型工业场景综合改编,非特定企业真实事件;文中技术方案需结合实际工况评估;涉及工控操作须遵守 LOTO 规范。

一、周一早上 8:07,车间主任把我堵在门口
“你就是总部派来的那个 AI 工程师?”
我还没来得及掏工牌,车间主任老张已经把手机怼到我面前——屏幕上是一张照片,一台卧式加工中心的操作面板,闪烁着红色报警灯。
“这台 HMC-80 上周三跳了一次主轴过载,我们自己复位了,后来又好了。今天早上又跳了,复位不了。”
“报警代码多少?”
“AL-72,主轴驱动器过载。”
“之前有过类似报警吗?”
“去年 11 月有过一次,换了接触器就好了。”
“那这次呢?”
老张摇摇头:“不知道。维修班说可能是轴承,也可能是变频器,也可能是程序问题。你那个 AI 不是能查吗?”
我掏出笔记本,写下第一行:AL-72,主轴过载,间歇性 → 持续性,HMC-80。
然后我意识到一个问题——我手里什么数据都没有。
二、数据在 PLC 里,但我不认识它
第一步当然是拿数据。我问设备管理员要 PLC 的通讯地址表。
他给了我一份 PDF,文件名是 HMC-80_IO_List_V2.3_最终版.pdf。
打开一看:
| 地址 | 信号名 | 备注 |
|---|---|---|
| DB12.DBX0.0 | SPINDLE_RUN | 主轴运行 |
| DB12.DBW4 | SPINDLE_SPEED | 主轴转速(rpm) |
| DB12.DBW6 | SPINDLE_LOAD | 主轴负载(0-100%) |
| DB12.DBW8 | SPINDLE_CURRENT | 主轴电流(0.1A) |
| DB12.DBW10 | SPINDLE_TEMP | 主轴温度(0.1℃) |
看起来很规整。但当我用 pymodbus 连上去读的时候——
# pymodbus v3.x 正确写法
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('192.168.1.50', port=502)
client.connect()
# 读主轴负载(地址 6,保持寄存器,1 个字)
result = client.read_holding_registers(address=6, count=1, slave=1)
if result.isError():
print(f"读取失败: {result}")
else:
raw = result.registers[0]
print(f"主轴负载原始值: {raw}") # 输出 847
847 是什么意思?0-100% 的范围里怎么会有 847?
我翻回那份 PDF,在角落里找到一行小字:“注:SPINDLE_LOAD 为 0-16384 对应 0-100%”。
所以真实负载是 847 / 16384 × 100% ≈ 5.17%,或者工程中更常用的算法:847 / 163.84 ≈ 5.17%。
数据在 PLC 里,但它不讲人话。 你得知道它的缩放比例、偏移量、字节序、是否要 swap word。这些在 IO 表里可能写、可能不写、可能写错了。
FED 经验 #1:PLC 数据永远需要"翻译层"。不要相信任何一份 IO 表是 100% 准确的,现场验证每个地址至少三次。建议建立
address_map.yaml配置文件,将原始值、缩放因子、工程单位、数据类型统一管理。
三、数据在 DCS 里,但它和 PLC 说的是两套语言
这台 HMC-80 的主轴冷却系统接的是车间 DCS(分布式控制系统),不是设备本身的 PLC。冷却水的流量、压力、温度都走 DCS。
我问仪表工要 DCS 数据。他给了我一个 OPC UA 的 endpoint 地址和一个标签列表:
ns=2;s=HMC80.CW.Flow # 冷却水流量 m³/h
ns=2;s=HMC80.CW.Press # 冷却水压力 bar
ns=2;s=HMC80.CW.Temp_Ret # 冷却水回水温度 ℃
ns=2;s=HMC80.CW.Temp_Sup # 冷却水供水温度 ℃
⚠️ 技术注记:
opcua库已归档,新项目建议使用asyncua(异步)或python-opcua的 fork 版本。以下示例展示同步读取模式。
# 同步读取示例(实际生产建议用 asyncua)
from opcua import Client
client = Client("opc.tcp://192.168.2.10:4840")
client.connect()
flow_node = client.get_node("ns=2;s=HMC80.CW.Flow")
flow = flow_node.get_value()
print(f"冷却水流量: {flow}") # 输出 12.3
client.disconnect()
拿到数据了。但问题来了——PLC 的时间戳和 DCS 的时间戳对不上。
PLC 用的是设备内部时钟,DCS 用的是车间 NTP 服务器。两者差了 47 秒。
这意味着你没法直接把 PLC 的主轴电流和 DCS 的冷却水流量做关联分析,因为时间轴没对齐。
FED 经验 #2:多数据源融合的第一步不是算法,是时间对齐。要么统一 NTP,要么在数据处理层做插值对齐。没有对齐的时间轴,所有关联分析都是假象。
# pandas 2.0+ 兼容的时间对齐方案
import pandas as pd
def align_to_plc(plc_df, dcs_df, tolerance='30s'):
"""
plc_df: PLC 数据,index 为 DatetimeIndex
dcs_df: DCS 数据,index 为 DatetimeIndex
返回:合并后的 DataFrame,DCS 数据按 PLC 时间轴插值
"""
# 方法1:merge_asof(推荐,按最近时间匹配)
plc_reset = plc_df.reset_index()
dcs_reset = dcs_df.reset_index()
merged = pd.merge_asof(
plc_reset.sort_values('timestamp'),
dcs_reset.sort_values('timestamp'),
on='timestamp', direction='nearest', tolerance=pd.Timedelta(tolerance)
)
merged.set_index('timestamp', inplace=True)
return merged
四、数据在点检表里,而点检表在柜子里
我去找设备档案。老张带我到资料室,从一个铁皮柜最底层抽出一个文件夹,里面是厚厚一叠纸质点检表。
"这是去年全年的。"他拍了拍灰。
我翻开看:
| 日期 | 设备 | 点检人 | 主轴异响 | 润滑正常 | 冷却正常 | 备注 |
|---|---|---|---|---|---|---|
| 2025-03-12 | HMC-80 | 王师傅 | ✓ | ✓ | ✓ | 无 |
| 2025-03-19 | HMC-80 | 王师傅 | ✓ | ✓ | ✓ | 无 |
| 2025-03-26 | HMC-80 | 李师傅 | ⚠ 轻微 | ✓ | ✓ | 主轴加速时有异响 |
| 2025-04-02 | HMC-80 | 王师傅 | ✓ | ✓ | ✓ | 无 |
| 2025-04-09 | HMC-80 | 王师傅 | ⚠ 比上周明显 | ✓ | ✓ | 异响持续,建议检查 |
3 月 26 日就有记录了。
但维修班不知道这件事——因为点检表填完就塞回柜子里了,没有人录入系统,没有告警,没有流转。
💡 OCR 实践建议:纸质表数字化可用 PaddleOCR(中文识别率高)或 Tesseract(开源),但表格结构识别建议配合
pdfplumber或camelot。关键字段必须人工校验,尤其数字和日期。
我把这些表逐页拍照,OCR 提取 + 人工校验后结构化:
# 点检记录结构化(OCR 后人工校验结果)
inspection_log = [
{"date": "2025-03-26", "inspector": "李师傅", "anomaly": "主轴加速时有异响", "severity": "minor"},
{"date": "2025-04-09", "inspector": "王师傅", "anomaly": "异响持续,比上周明显", "severity": "moderate"},
{"date": "2025-05-14", "inspector": "王师傅", "anomaly": "异响加重,伴随振动", "severity": "severe"},
{"date": "2025-06-18", "inspector": "李师傅", "anomaly": "主轴过载报警 AL-72", "severity": "critical"},
{"date": "2025-11-03", "inspector": "王师傅", "anomaly": "AL-72 报警,复位后正常", "severity": "critical"},
{"date": "2026-01-07", "inspector": "王师傅", "anomaly": "AL-72 再次报警,无法复位", "severity": "critical"},
]
把时间线拉出来一看,故障的演进轨迹清清楚楚:
3/26 异响(轻微)→ 4/9 异响加重 → 5/14 异响+振动 → 6/18 首次过载报警
↓
11/3 再次报警(复位后正常)→ 1/7 持续报警(今天)
从第一次记录异响到今天彻底停机,历时 7 个月。如果 3 月份的数据能流动到维修班,这就是一次标准的预测性维护窗口。
FED 经验 #3:纸质数据不是"没有数据",是没有进入数据流的数据。FED 的现场工作之一就是把纸质记录数字化,哪怕只是拍照+OCR+人工校验,也比让它躺在柜子里强 100 倍。中小工厂可先用 Excel 模板 + 定期导入,不必一步到位上扫码系统。
五、还有一大半在老师傅脑子里
点检表只能告诉我"什么时候发现了什么",但不知道为什么。
我找到王师傅。他在车间干了 22 年,HMC-80 装上去那天他就在。
“王师傅,这台设备 3 月份开始有异响,您当时怎么判断的?”
他靠在机床旁边,想了想:“主轴加速的时候有’嘶嘶’声,像是什么东西缺油了。我那会儿跟维修班说了,他们说没报警就先跑着。”
“您觉得是什么问题?”
“八成是主轴轴承。这台设备 2019 年装的,轴承从来没换过。正常五年一换,已经超了。”
“为什么没换?”
“备件要 3 万 6,申请了两次没批下来。”
3 万 6 的轴承 vs 今天停机一天损失 8 万产能。
🔊 声音特征补充:轴承缺油初期确实可能发出高频"嘶嘶"或"吱吱"声(类似金属摩擦的尖细声),随着磨损加剧转为低频"嗡嗡"或周期性"咔咔"声。不同轴承类型(角接触、圆锥滚子、圆柱滚子)声音特征有差异,需结合频谱分析确认。
我接着问:“您怎么判断是轴承不是别的?”
“你听声音。轴承缺油是高频嘶嘶,变频器问题是低频嗡嗡,程序问题是间歇性的不跟着转速走。它跟着转速走,加速就有,所以机械问题。”
这段对话里有多少信息量?
- 故障模式分类(机械 vs 电气 vs 程序)
- 声音特征与故障的映射关系
- 设备服役年限与 MTBF 经验
- 决策链条(报修 → 未批 → 延期)
这些全在王师傅脑子里,没有一行被记录过。
六、FED 怎么把这些数据拼起来
回到办公室,我把四个来源的数据摆在桌面上:
| 数据源 | 格式 | 内容 | 状态 |
|---|---|---|---|
| PLC | Modbus TCP | 实时电流、负载、转速 | ✅ 已接入,需校准 |
| DCS | OPC UA | 冷却水流量、温度 | ✅ 已接入,需时间对齐 |
| 点检表 | 纸质 → OCR → JSON | 异响记录、趋势 | ✅ 已数字化 |
| 王师傅 | 口述 → 笔记 | 故障判断逻辑、经验 | ⏳ 需结构化 |
6.1 用 Qoder 构建知识沉淀 Agent
# .qoder/agents/knowledge-capture-agent.md
---
name: knowledge-capture-agent
description: 将老师傅经验、点检记录、故障案例结构化沉淀为知识库
tools: Read, Write, Bash, Grep, Glob
model: auto
---
你是一名工业知识工程师,负责将非结构化经验转化为结构化知识:
1. 接收输入:口述记录、点检表 OCR 文本、维修日志、故障报告
2. 提取实体:设备、部件、故障模式、症状、原因、措施
3. 建立关系:部件 → 故障模式 → 症状映射 → 根因 → 处置措施
4. 输出格式:JSON(供知识图谱导入)+ Markdown(供 RAG 检索)
5. 每条知识标注:来源、置信度、适用条件
置信度等级定义:
- high:多次验证、多人确认、与数据吻合
- medium:单次记录、经验判断、部分数据支持
- low:推测性、无直接数据支持
约束:
- 每条知识必须标注来源(人/文档/系统)
- 经验类知识标注"老师傅经验",与数据类知识区分
- 不确定信息标注置信度等级
6.2 结构化知识输出
// knowledge_hmc80_bearing.json
[
{
"entity": "HMC-80 主轴轴承",
"fault_mode": "轴承缺油/磨损",
"symptoms": [
{"description": "主轴加速时高频嘶嘶声", "source": "王师傅口述", "confidence": "high"},
{"description": "异响随时间加重", "source": "点检表 2025-03~06", "confidence": "high"},
{"description": "伴随振动增大", "source": "点检表 2025-05-14", "confidence": "medium"},
{"description": "AL-72 主轴过载报警", "source": "报警记录", "confidence": "high"}
],
"root_cause": "轴承润滑不足 → 磨损加剧 → 阻力增大 → 过载",
"action": "停机更换主轴轴承总成,检查润滑脂管路",
"prevention": "每 5 年或 20000 小时更换轴承,每月检查润滑脂存量",
"context": {
"install_date": "2019-06",
"last_bearing_change": "从未更换",
"design_life_years": 5,
"current_age_years": 6.5
}
}
]
6.3 故障演进时间轴(ECharts)
// 故障演进时间轴
var timelineOption = {
title: { text: 'HMC-80 主轴故障演进时间线', textStyle: { color: '#e0e6ed' } },
tooltip: { trigger: 'item' },
timeline: {
axisType: 'category',
data: ['2025-03', '2025-04', '2025-05', '2025-06', '2025-11', '2026-01'],
label: { color: '#8fa8c0' }
},
series: [{
type: 'scatter',
data: [
{ name: '异响(轻微)', value: ['2025-03', 1], itemStyle: { color: '#f0a500' } },
{ name: '异响加重', value: ['2025-04', 2], itemStyle: { color: '#f0a500' } },
{ name: '异响+振动', value: ['2025-05', 3], itemStyle: { color: '#ef232a' } },
{ name: '首次过载报警', value: ['2025-06', 4], itemStyle: { color: '#ef232a' } },
{ name: '再次报警', value: ['2025-11', 5], itemStyle: { color: '#ef232a' } },
{ name: '持续报警(停机)', value: ['2026-01', 6], itemStyle: { color: '#ef232a' } }
],
symbolSize: function (val) { return val[1] * 15; }
}]
};
七、诊断结论
把四层数据拼起来之后,结论非常清晰:
| 证据层 | 说了什么 |
|---|---|
| PLC 电流 | 主轴启动电流从 12A 逐步爬升到 18A(正常 11A) |
| DCS 冷却水 | 回水温度从 38℃ 升到 52℃,流量正常;需结合供水温度判断温差(若温差 >8℃ 则散热不足) |
| 点检表 | 3 月起有异响记录,6 次递进式恶化 |
| 王师傅经验 | 加速嘶嘶声 = 轴承缺油,服役 6.5 年超期 |
诊断结论:主轴轴承润滑失效 → 磨损 → 阻力增大 → 过载保护动作。
处置建议:停机更换主轴轴承总成(备件号 xxx),同步更换润滑脂管路滤芯。
根因追溯:3 月 26 日点检已发现异常,但信息未流转至维修决策链,备件申请未获批,导致小问题拖成大故障。
八、FED 的收获
这次排查之后,车间做了三件事:
- 点检表电子化:中小工厂先用 Excel 模板 + 每周导入,条件成熟后升级为企业微信/钉钉扫码填报
- 异常自动流转:点检发现异常 → 自动生成维修申请 → 推送给车间主任审批(可用低代码平台实现)
- 老师傅经验库:王师傅的 22 年经验,用 Qoder Knowledge-Agent 结构化沉淀,新人也能查
而对我来说,这次排查验证了 FED 的核心方法论:
数据不在某一个地方,数据在每一个地方。FED 的工作不是"建一个大数据平台",而是把散落在 PLC、DCS、纸质表、人脑子里的信息,用最低成本串成一条能用的证据链。
九、技术要点总结
| 问题 | 解法 | 工具/技术 |
|---|---|---|
| PLC 数据需翻译 | 地址表 + 现场校准 + 缩放公式 | pymodbus v3.x + address_map.yaml |
| 多源时间不对齐 | NTP 统一或 merge_asof 插值 | pandas merge_asof |
| 纸质数据不流动 | OCR + 结构化 + 电子化流程 | PaddleOCR/camelot + Excel/DB |
| 经验不可传承 | 口述记录 → 结构化知识 → 知识库 | Qoder Agent + JSON + RAG |
| 异常不触发动作 | 规则引擎 + 自动工单流转 | 低代码平台 / 工单系统 API |
十、结语
FED 进厂第一天,你不会拿到一份干净的数据集。你拿到的是:
- 一份可能写错的 IO 表
- 一个你不知道密码的 OPC UA 服务器
- 一柜子纸质点检表
- 一个愿意跟你聊但下午要接孙子的老师傅
这就是现场。这就是真实。
能把这四样东西拼成一条能用的诊断链,你就是合格的 FED。能把它变成系统自动跑起来,你就是优秀的 FED。
⚠️ 本文案例为典型工业场景综合改编,技术方案需结合实际工况评估;涉及工控操作须遵守 LOTO 规范。
下一篇预告:《FED 实战:从点检表到知识图谱——老师傅退休前,把他脑子里的东西留下来》
更多推荐

所有评论(0)