# 简历 · 大模型应用开发工程师(制造业版)
> 由中医知识图谱项目迁移。同一套架构(采集 → LLM 抽取 → 图谱 → Agent → 服务 → 前端 → 微调),
> 换成设备故障诊断与工艺知识检索场景。带 `<>` 的请按实际情况替换。
---
## 基本信息
| | |
|---|---|
| 姓名 | `<姓名>` |
| 岗位 | 大模型应用开发工程师 / 工业 AI |
| 经验 | 4 年(其中大模型应用方向 2 年) |
| 电话 / 邮箱 | `<电话>` / `<邮箱>` |
| 学历 | `<学校>` `<专业>` `<本科/硕士>` |
---
## 技能栏
**大模型应用**
- LangGraph 有状态编排:多节点条件路由、带上限的重试环、多轮排障记忆、流式增量产出
- LangChain 链式调用与结构化输出,OpenAI 兼容端点(DeepSeek / vLLM 厂内部署)
- Prompt 工程:schema 注入、否定式约束、多级降级解析;维修方案的强制溯源约束
**知识图谱与检索**
- Neo4j:Cypher 读写、批量事务导入、唯一约束、`EXPLAIN` 静态校验、schema 元数据导出
- FAISS + bge-large-zh-v1.5 向量召回,按实体类型过滤
- 工业术语标准化:一线口语到标准故障码的映射("机器嗡嗡响" → "主轴异常振动")
**模型微调**:Alpaca 数据集构建、LoRA 微调、vLLM multi-LoRA 部署
**工程能力**:Python 3.10、FastAPI(异步 / 流式 / 线程池)、Streamlit、并发采集、
`asyncio.Queue` 跨线程反压、Git / Black;产线内网离线部署
---
## 项目经验
### 设备故障诊断与工艺知识图谱问答系统 `<公司/独立项目>`
**角色**:技术负责人,负责整体方案与全链路实现,与设备科 `<N>` 名工程师协作做知识校验
**背景**:产线设备的排障知识分散在设备手册、历史工单、老师傅的经验里。新人遇到报警只能
翻纸质手册或打电话问人,停机每分钟都是钱。通用大模型的问题是会编造不存在的故障码和
维修步骤 —— 按错误步骤操作可能造成设备二次损坏或人身伤害。目标是把手册和历史工单变成
可查询的知识图谱,让排障建议可回溯到具体手册章节或历史工单编号。
**技术栈**:Python 3.10 / LangGraph / LangChain / Neo4j / FAISS / sentence-transformers /
FastAPI / Streamlit / vLLM
**七阶段流水线:**
**1. 数据采集**(设备手册 + 历史维修工单 + 工艺规程 + 备件台账)
- 按**文档顺序**遍历文档结构而非按已知字段名查找 —— 不同厂商设备手册的章节命名和层级
完全不统一(故障排除/异常处理/Troubleshooting 混用),按顺序走开新章节才能完整保留。
漏掉"安全注意事项"章节直接对应作业风险
- 历史工单是半结构化的:现象描述是自由文本,处理措施常带方言和简写,
这部分交给 LLM 抽取而非规则解析
- 断点续传做在文件系统层:目标文件存在即完成;写入走 `.part` 再原子替换。
新设备入场或手册改版后重采,续传让增量更新只做缺失部分
- 并发采集 + Session 按线程隔离
**2. 故障知识抽取**(LLM 结构化输出)
- Pydantic 定义 schema 作为全链路契约:实体为**设备 / 部件 / 故障现象 / 故障原因 /
处理措施 / 备件**;关系为**由...引起 / 表现为 / 处置方式 / 需更换备件 / 属于 / 前置检查**
- 属性挂在实体上:设备带型号、产线、投产日期;备件带图号、库位、更换周期、供应商;
措施带工时、所需资质、停机需求
- **安全前置条件必须单独抽取**:断电挂牌、泄压、上锁等前置动作绝不能与处理步骤混在一起,
它们的执行顺序不可颠倒。这是本项目定义的 P0 约束
- Prompt 显式要求"现象与原因无明确关联时返回空结果" —— 模型最危险的行为是为了填满格式
而虚构因果链,把无关的故障原因关联到现象上,空结果是正确输出
- **参数数值逐字保留,禁止换算**:扭矩、压力、温度的数值和单位原样搬运,换算在下游显式处理
- 成本约束:耗时取决于**输出**规模,长手册章节显著更慢;失败不写文件因此留在待办列表,
重跑即重试;空结果要写,否则重跑在重复付费
**3. 图谱构建**
- **先在内存聚合再写库**:常见现象(如"异响")出现在数千份工单里,
逐条 MERGE 等于把同样的工作重做数千遍
- **节点主键是 `(类型, 名称)` 而非名称**:制造业跨类型同名极其常见 ——
"轴承过热"既是故障现象也是另一个故障的原因,"液压泵"既是部件也是备件。
只按名称去重会把它们错误合并,让"现象"查询召回备件节点
- 型号是必须入主键的维度:同名部件在不同设备型号上的规格和更换方式完全不同,
只按部件名去重会给出错误的备件图号
- 标签、关系类型、属性键先过白名单再拼接;值一律参数化
- 属性用 `MERGE ... SET n += $attrs`:手册改版或备件替代后属性变化,写进 MERGE 模式
会匹配失败并创建重复节点,`ON CREATE SET` 又永远不会回填已有节点
- **工单频次入图**:关系上带历史出现次数,排障时按频次排序候选原因 ——
这是知识图谱比纯手册检索更有价值的地方,手册不会告诉你哪个原因最常见
**4. 检索层**
- Neo4j schema 元数据导出后注入 Cypher 生成 prompt;关系描述人工补齐
(含适用型号、频次说明),由设备工程师复核
- FAISS 索引覆盖全部实体类型,**索引本身不带类型**,召回后必须按类型过滤 ——
否则"漏油"可能召回一个备件名并落进"现象"槽位,生成出错误的 Cypher。
超额取 `top_k * N` 再过滤
- 分级健康检查守住索引与图谱一致性:自检索(已知实体以距离≈0 返回 top-1)证明
向量与映射未错位;与 Neo4j 对账防止工单增量导入后索引陈旧
**5. LangGraph Agent**(9 节点、2 条件边、1 个环、3 个出口)
```
START → 语义转写 → 排障意图识别
├─ 非排障 ─→ 直接回答 ──────────────────────→ END
└─ 排障 ─→ 实体抽取 → 术语匹配 → cypher生成 ←──┐
→ cypher检查 │
├─ 全部合法 ─→ 执行 → 处置方案 → END
├─ 不合法且未超 3 次 ────────┘
└─ 额度用尽 ─→ 直接回答 → END
```
- **语义转写排在最前**:排障天然多轮 —— 先问"3 号线冲床报 E05",再问"换了还是不行"。
后一句单看没有任何信息,意图识别会判成无关。转写节点结合历史补全成完整问题,
下游才有东西可用。全图只有转写节点读原始输入,其余节点读转写结果
- **重试环的刹车靠状态计数**:路由函数只能读 state 不能记账,重试次数由生成节点自增,
上限 3 次。重试时回喂上一轮不合法的语句,否则模型输入不变会原样再生成
- **生成的 Cypher 直连生产库,两个独立位置设闸**:① 关键词词边界扫描 + 必须有 RETURN
且以 MATCH/WITH 开头;② `EXPLAIN` 逐条静态校验。生产环境的图谱库绝不能被
生成的语句写坏
- **绝不把用户原话放进 WHERE**:一线说"机器嗡嗡响",图里存的是"主轴异常振动"。
术语匹配节点弥合这个差距 —— 这在制造业尤其重要,一线口语和手册术语几乎没有交集
- **答案生成节点的硬约束**:处置步骤必须携带来源(手册章节号 / 工单编号),
来源只能来自图谱查询结果;安全前置条件必须置顶输出;检索不到时明确告知,
绝不由模型编造维修步骤
- JSON 解析多级降级;Cypher 逐条执行而非批量事务,出错补空列表保持下标对齐
**6. 服务化**
- FastAPI 三接口:健康检查、同步问答、流式问答
- 图是懒加载的模块级单例,`lifespan` 启动预热(FAISS 索引 + embedding 模型约 50 秒);
预热失败只记日志不阻止启动 —— 产线工具不能因为预热失败就整体不可用
- `graph.invoke` 同步阻塞,走 `run_in_threadpool`,否则事件循环被占死、服务退化成单并发。
多个班组同时排障是常态
- 流式接口用生产者-消费者:节点在工作线程产出,有界 `asyncio.Queue`(32,形成反压)
跨回事件循环。停机场景下等待成本极高,流式让"正在检索历史工单"的进度可见
- **产线内网离线部署**:vLLM 自托管模型 + 本地 embedding + 厂内 Neo4j,不依赖外网
**7. 前端与微调**
- Streamlit 多页:常规问答 + 流式页。流式页展示检索过程(命中的设备型号、候选原因及频次、
引用的工单号),设备工程师需要看到判断依据。移动端适配以便车间现场使用
- 抽取结果顺带产出 Alpaca 数据集用于微调;两条写入路径 —— 抽取时追加 JSONL
(并发追加整行不会破坏性交错),另有不调 LLM 的幂等重建脚本覆盖续传跳过的历史条目
- LoRA 微调后 vLLM 厂内部署,multi-LoRA 单服务挂多个产线/设备类型适配器按需切换
**成果**
- 覆盖 `<N>` 类设备、`<M>` 份手册、`<K>` 万条历史工单,schema 6 类实体 6 类关系
- 候选故障原因按历史频次排序,把老师傅的经验沉淀成可查询的数据
- **零编造维修步骤**:所有处置方案带手册章节或工单编号,检索不到时明确告知
- 安全前置条件强制置顶,不与操作步骤混排
- 接口层 27 条离线用例(替换假图,不触达 LLM/Neo4j/FAISS,2 秒内跑完)+ 15 条 live;
前端 49 条离线 + 11 条 live
- 全链路产线内网离线运行
---
## 行业适配要点(面试可展开)
1. **型号入主键**:同名部件在不同型号上规格不同,只按名称去重会给出错误备件图号
2. **安全前置条件独立抽取**:断电挂牌、泄压不能与处理步骤混排,顺序不可颠倒
3. **工单频次入图**:候选原因按历史频次排序,这是图谱相比手册检索的增量价值
4. **口语到故障码的映射**:"嗡嗡响" → "主轴异常振动",一线用语和手册术语几乎无交集
5. **跨类型同名**:轴承过热既是现象也是原因,主键必须是 `(类型, 名称)`
6. **内网离线部署**:工业数据不出厂,模型与向量库全部本地自托管
7. 定位为排障辅助工具,高风险操作须持证人员按规程执行