首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Harness 工程——用户附件处理策略深度解析

Harness 工程——用户附件处理策略深度解析

原创
作者头像
OneCode
发布2026-07-27 20:04:37
发布2026-07-27 20:04:37
2620
举报
文章被收录于专栏:ooderAgentooderAgent

目录

  1. 引言:为什么附件处理是 Harness 的核心命题
  2. 架构全景:Workflow-Harness-LLM 三层协同
  3. 附件推送机制:SSE human_confirm 与 FILE_UPLOAD 子类型
  4. 上传全链路:前端 XHR → 后端 VFS → 流程恢复
  5. 格式检测与解析策略:7 种格式 × 5 种设计源
  6. VFS 归一:从临时目录到版本化虚拟文件系统
  7. 场景消费:附件如何注入 4 大编排场景
  8. 超时与容错:HUMAN 节点的归一化超时策略
  9. 去重与版本:基于 SHA-256 的附件版本管理
  10. 审计与合规:SSE 事件链完整性校验
  11. 演进路线:从当前到理想的归一化蓝图

1. 引言:为什么附件处理是 Harness 的核心命题

在企业级 AI 应用中,用户附件是最一手的业务资料。一份专利审查文档、一张 Excel 员工花名册、一份 Figma 设计稿——这些文件的格式之广泛、内容之丰富,远超纯文本对话所能承载的信息密度。

传统聊天式 LLM 交互将附件视为"附属品":先上传,再提取文本,最后拼接到 prompt 中。这种简单策略在面对以下场景时迅速失效:

  • 设计源文件(Figma/Axure/Lanhu):不是文本而是结构化视觉语义,需要专用解析器提取组件树
  • 多格式混合(专利 PDF + 审查 Excel + 法律 Word):每种格式的解析策略、字段提取逻辑完全不同
  • 大文件(100+ 页 PDF):全量解析文本动辄数百万字符,不可能直接塞入 prompt
  • 流程编排需求:附件不是一次性消费,而是贯穿"上传→解析→甄别→确认→构建→审查"多阶段

OODER 的解决方案是:将附件提升为一等公民,通过 Workflow 驱动 Harness 工程实现其完整生命周期管理。本文将深入剖析这一机制的设计哲学与工程实现。

核心设计原则

附件不是对话的"附加信息",而是驱动流程编排的语义源头。每一个附件的上传都是一个 HUMAN 节点的暂停事件,每一次解析都是一个 Skill 的执行活动,每一次甄别都是一次人机协同确认。

2. 架构全景:Workflow-Harness-LLM 三层协同

附件处理不是孤立的"上传→解析"管道,而是嵌入在 Workflow-Harness-LLM 三层架构中的完整闭环:

图 1:Workflow-Harness-LLM 三层架构 — 附件处理贯穿全层

在这三层架构中,附件的旅程是:

  1. L1:HUMAN 节点暂停流程,发射 human_confirm 事件,等待用户上传
  2. L2:AttachmentParseSkill 解析附件,FieldExtractorSkill 提取字段,发布 ATTACHMENT_ANALYZED 事件
  3. L3:解析结果注入 ContextLayer,LLM 基于附件语义生成组件/视图/API

3. 附件推送机制:SSE human_confirm 与 FILE_UPLOAD 子类型

OODER 不会为附件创建独立的"上传事件"——附件推送复用 SSE human_confirm 事件体系,通过 confirmType 字段区分交互类型。这是一个关键的设计决策:

设计哲学:统一交互模型

图 2:附件推送机制 — human_confirm 事件驱动前端渲染上传区域

SSE 事件通过 SseEventEmitter.emitHumanConfirmRequiredEvent() 发射,经由 ContextEventBus → SseEventPushListener 桥接转发到前端。前端有两条渲染路径,通过 _renderHumanConfirm 主入口自动选择:流程面板活跃时注入到 activity-body 层内,否则渲染到主窗体。

4. 上传全链路:前端 XHR → 后端 VFS → 流程恢复

附件上传的完整链路涉及前端、后端、VFS 和流程引擎四个维度,下图展示了从用户拖拽文件到流程恢复的完整数据流:

图 3:附件上传全链路 — 从前端 XHR 到 VFS 存储再到流程恢复

关键设计:signalConfirm 原子操作

GenericAttachmentController.uploadBatch() 在完成所有文件处理后,一次性调用 signalConfirm 唤醒阻塞线程。前端无需二次发送 confirm 请求,避免了上传完成与流程恢复之间的竞态条件。

5. 格式检测与解析策略:7 种格式 × 5 种设计源

用户附件场景之广泛,要求解析层必须具备格式感知的多策略分派能力。当前系统支持 7 种基础格式和 5 种设计源格式:

格式类型

扩展名

解析策略

输出数据

典型场景

Word

.docx .doc

Apache POI → 纯文本

字段列表 + 段落结构

法律文档、合同模板

Excel

.xlsx .xls

Apache POI → 行列结构

字段列表 + TREEGRID 建议

员工花名册、财务报表

PDF

.pdf

PDFBox → 纯文本提取

全文 + 页码结构

专利文档、学术论文

HTML

.html .htm

Jsoup → Axure/通用解析

组件树 + 布局 + 样式

Axure/Mockplus 原型

CSV

.csv

OpenCSV → 表格结构

字段列表 + TREEGRID 建议

数据导入、批量配置

Figma JSON

.json

FigmaDesignReader → 组件映射

组件树 + 样式 Token

Figma 设计稿导出

纯文本

.txt .md

直接读取

全文

配置文件、说明文档

设计源格式扩展

设计源

输入形式

解析器

输出

Figma URL

https://figma.com/...

FigmaDesignReader

组件树 + 样式 Token

Lanhu URL

https://lanhuapp.com/...

LanhuDesignReader

页面结构 + 样式

Axure 导出

.html (含 Axure 标记)

AxureWidgetParser → AxureComponentMapper

组件映射 + 样式转换

格式检测通过 AttachmentParseSkill.detectFormat() 实现,采用三级检测策略

  1. URL 检测:Figma/Lanhu 在线设计源 URL
  2. 扩展名检测:通过 AttachmentRuleConfig 配置的扩展名→格式映射
  3. 内容特征检测:遍历配置的 contentFeatures 列表(contains/startsWith/custom 模式)

6. VFS 归一:从临时目录到版本化虚拟文件系统

这是本次改造的核心命题。在改造前,附件保存使用 java.io.tmpdir/ooder-attachments 本地临时目录,存在三个严重问题:

改造前的三大风险

1. 重启丢失:临时目录在 JVM 重启后可能被清理,导致附件引用失效 2. 部署不兼容:绝对路径 e:\xxx 在 Linux 部署环境无效 3. 违反 VFS 约束:项目硬约束要求"所有文件读取必须使用 VFS 路径"

图 4:VFS 归一改造 — 从临时目录到版本化虚拟文件系统

改造后的 GenericAttachmentController 在文件保存后立即执行三步 VFS 归一操作:

  1. 计算文件内容 SHA-256 哈希,用于去重判定
  2. 通过 UnifiedVFSManager.writeFileString() 写入 VFS,路径包含 conversationId + hash + 原始文件名
  3. 大文件(>100KB)的 parsedText 额外写入 VFS 中间文件,下游按需读取

7. 场景消费:附件如何注入 4 大编排场景

附件不是一次性消费——它是场景编排的语义源头。系统中 4 大编排场景以不同方式消费附件数据:

图 5:附件场景消费 — 4 大编排场景的数据流与 SSE 事件链

8. 超时与容错:HUMAN 节点的归一化超时策略

HUMAN 节点暂停后,系统需要处理"用户不响应"的容错场景。改造后的超时策略已从三选一扩展为四选一:

策略

代码

行为

适用场景

优先级

P0跳过

SKIP

跳过当前活动,路由到下一活动

附件可选的场景

默认

P1重试

RETRY

重新触发 human_confirm 事件

网络不稳定场景

P1失败

FAIL

流程失败终止

附件必填的场景

P1部分成功继续

AUTO_ACCEPT_PARTIAL

部分上传成功则继续流程

多文件批量上传场景

新增

FILE_UPLOAD 独立超时配置

改造前,FILE_UPLOAD 复用 CONFIRM 的 confirmTimeoutMs(默认 300s),但附件上传耗时远超普通确认。改造后在 HumanOperationConfig 中新增独立配置:

代码语言:javascript
复制
// HumanOperationConfig — FILE_UPLOAD 子配置
fileUploadTimeoutMs   = 600000  // 10分钟(vs 确认的5分钟)
fileUploadMaxCount    = 20      // 最大文件数
fileUploadAcceptTypes = ".xlsx,.docx,.pdf,.csv,.json,.html"
fileUploadMaxFileSize = 10485760 // 10MB

这些配置通过 @BpmField 注解驱动,BPM Designer 属性面板自动渲染配置表单,无需额外前端开发。

9. 去重与版本:基于 SHA-256 的附件版本管理

同一个文件可能被多次上传(不同对话、不同时间),VFS 版本管理通过内容哈希去重实现:

图 6:附件去重与版本管理 — SHA-256 内容哈希 + VFS 版本历史

10. 审计与合规:SSE 事件链完整性校验

附件处理涉及多个 SSE 事件的前后端交互,事件链完整性是系统可靠性的关键保证。以下是对现有实现的审计结果:

检查项

状态

说明

human_confirm 有独立监听器

PASS

NlpChatInlineNetwork.js L2828: addEventListener('human_confirm')

attachment_analysis 有独立监听器

PASS

NlpChatInlineNetwork.js L2793: addEventListener('attachment_analysis')

field_suggestion 有独立监听器

PASS

NlpChatInlineNetwork.js L2807: addEventListener('field_suggestion')

事件无消费者冗余

PASS

每个事件仅一处消费

事件命名符合六层分类

WARN

attachment_analysis/field_suggestion 未用 FLOW_ 前缀

事件时序正确

PASS

ATTACHMENT_ANALYZED → FIELD_SUGGESTION → human_confirm

场景与主流程交互合规

PASS

通过 extensions 传递数据,不直接修改主流程 context

VFS 路径归一

PASS

改造后所有附件通过 VFS 路径引用

signalConfirm 残留清理

PASS

Loop修复#15: 超时/错误时清理残留

11. 演进路线:从当前到理想的归一化蓝图

图 7:附件处理演进路线 — 从 VFS 归一到智能预处理

总结

附件在 OODER 系统中不是对话的附属品,而是驱动 Workflow 编排的语义源头。通过 VFS 归一、SHA-256 去重、独立超时策略和 SSE 事件链审计,我们构建了一个完整、可靠、可审计的附件生命周期管理体系。这个体系的核心是:每一个附件都有确定的 VFS 身份(vfsPath)、可追溯的内容指纹(contentHash)、与流程绑定的生命周期(human_confirm → signalConfirm → resumeActivity),以及面向未来的版本管理能力。

OODER Architecture Series — Workflow 驱动 Harness 工程实现

Copyright © 2026 ooder.ai — All rights reserved

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 目录
  • 1. 引言:为什么附件处理是 Harness 的核心命题
  • 2. 架构全景:Workflow-Harness-LLM 三层协同
  • 3. 附件推送机制:SSE human_confirm 与 FILE_UPLOAD 子类型
  • 4. 上传全链路:前端 XHR → 后端 VFS → 流程恢复
  • 5. 格式检测与解析策略:7 种格式 × 5 种设计源
  • 设计源格式扩展
  • 6. VFS 归一:从临时目录到版本化虚拟文件系统
  • 7. 场景消费:附件如何注入 4 大编排场景
  • 8. 超时与容错:HUMAN 节点的归一化超时策略
  • FILE_UPLOAD 独立超时配置
  • 9. 去重与版本:基于 SHA-256 的附件版本管理
  • 10. 审计与合规:SSE 事件链完整性校验
  • 11. 演进路线:从当前到理想的归一化蓝图
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档