多模态感知:AI 操作系统如何看、听、读

一个只能接收文字的 Agent 就像一个只会阅读的人 — 它错过了图像、声音、文档和网络的丰富信息。OctopusOS 多模态感知赋予内核五种感官:图片、音频、视频、文档和链接 — 每种模态都流经从上传到 LLM 推理的受治理、类型安全的完整管线。


1. 为什么 AI 操作系统需要多模态

传统聊天界面只接受文字输入。但现实任务涉及错误截图、会议录音、PDF 合同、视频演示和网页链接。没有多模态感知,用户必须手动描述视觉内容或复制粘贴文档文字 — 丢失上下文,浪费时间。

OctopusOS 构建了一个全栈多模态管线,端到端处理五种模态:从浏览器文件选择、服务端处理,到 LLM 原生视觉和音频推理能力。


2. 五种模态总览

图片
PNG, JPEG, GIF, WebP 格式Base64 编码为 OpenAI vision content blocks自动模型升级: gpt-4.1-nano → gpt-4.1-miniLLMVisionPort 独立图像分析
音频
MP3, WAV, OGG, WebM 音频格式OpenAI Whisper API 转录转录文本注入 LLM promptWhisperAudioPort 优雅降级
视频
MP4, WebM, QuickTime 格式ffmpeg 关键帧提取(5秒间隔,最多10帧)VisionPort 帧分析 + AudioPort 音轨转录无 ffmpeg 时优雅降级
文档
PDF, DOCX, XLSX, PPTX, CSV, TXT 格式内核域 parse_file() + 扫描PDF OCR提取文本(最多5000字符)注入 promptDocumentProcessor 封装内核解析管线
链接
正则自动检测消息中的 URL(每消息最多3条)httpx 抓取 + SSRF 防护(拦截内网IP)OG 标签提取:标题、描述、正文50KB 内容限制,5秒超时

3. 上传管线:9 个阶段

每次多模态交互都遵循相同的受治理管线,不论模态类型。

多模态上传管线
1
1. 选择文件
用户通过回形针按钮选择文件或拖放到聊天区域。带 MIME accept 过滤器的隐藏 <input type='file'>。
2
2. 上传
POST /api/upload,multipart/form-data 格式。服务端接收 UploadFile + session_id。25MB 大小限制。
3
3. MIME 检测
服务端校验文件 MIME 类型是否在允许列表中(5种模态17种类型)。未知类型返回 415 状态码。
4
4. 存储
文件保存到 workspace/uploads/{session_id}/{attachment_id}.{ext},配套 .meta.json 元数据文件。
5
5. 处理
按模态分发处理: 图片→base64, 音频→Whisper, 视频→ffmpeg+ports, 文档→解析器, 链接→展开。
6
6. 内容块构建
构建 OpenAI 多模态消息: 图片使用 image_url blocks,其他模态的处理文本追加到 text block。
7
7. LLM 调用
自动模型选择: 有图片时用 gpt-4.1-mini(支持视觉),纯文本用 gpt-4.1-nano。视觉请求超时延长至30秒。
8
8. 响应
LLM 基于完整的多模态上下文生成回复 — 可以描述图片、回答文档问题、总结音频内容。
9
9. 渲染
AttachmentPreview 组件内联渲染媒体: 图片用 <img>,音频/视频用播放器,文档显示文件图标。

4. 四层架构

多模态处理分层
L4: LLM 推理层
OpenAI Chat Completions API多模态 content blocks (text + image_url)自动模型选择 (nano→mini)视觉请求超时延长 (30s vs 10s)
L3: Port 处理层
LLMVisionPort — GPT-4 Vision 图像分析WhisperAudioPort — OpenAI Whisper 转录VideoProcessor — ffmpeg 帧提取 + Port 融合DocumentProcessor — 内核 parse_file() + OCRLinkUnfurler — httpx 抓取 + SSRF 防护
L2: HTTP API 层
POST /api/upload — 文件上传GET /api/upload/{id}/content — 文件服务MessageIn.attachments — 附件引用IntentIn.attachments — Console 链路传递
L1: 前端层
React 文件选择 + 拖放上传uploadFile() — FormData 上传AttachmentPreview — 按模态渲染待发送附件预览条 + 移除按钮

5. Port 模式:协议 + 实现 + 降级

OctopusOS 遵循严格的 Port 模式处理多模态。内核定义 Protocol 接口(零 I/O),服务层提供真实实现并优雅降级到 Stub。

Port 装配架构
VisionPort 协议
analyze_image(), describe_frame(), is_available()
AudioPort 协议
transcribe(), analyze_audio(), is_available()
Bootstrap 装配
条件判断: 有 API Key → 真实 Port, 无 → Stub
LLMVisionPort
OpenAI GPT-4.1-mini Vision API
WhisperAudioPort
OpenAI Whisper 转录
Stub Ports
返回'不可用'优雅降级

Bootstrap 装配逻辑

# bootstrap.py — 条件 Port 装配
if llm_provider_port and llm_provider_port.is_available():
    vision_port = LLMVisionPort(llm_provider=llm_provider_port)
else:
    vision_port = StubVisionPort()

audio_port = WhisperAudioPort.from_config(config) \
    if config.get("OPENAI_API_KEY") else StubAudioPort()

这种模式确保内核永远不会因缺少 API Key 而崩溃 — 只是优雅降级。


6. LLM 多模态 Content Blocks

核心创新是将用户消息从纯字符串转换为 OpenAI 的多模态 content block 格式。

Content Block 构建状态机
纯文本
图片附件
含图片
+ 音频/文档
混合模态
发送
LLM 调用

消息格式转换

# 纯文本消息(多模态之前)
{"role": "user", "content": "这是什么?"}

# 多模态消息(多模态之后)
{"role": "user", "content": [
    {"type": "text", "text": "这是什么?\n\n[音频转录]: Q1 业绩会议内容..."},
    {"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBOR..."}}
]}

7. 视频处理管线

视频是最复杂的模态,通过多阶段管线组合视觉和音频分析。

视频处理管线
1
输入
视频文件 (MP4, WebM, QuickTime) 上传后存储在磁盘
2
关键帧提取
ffmpeg -vf fps=1/5 — 每5秒提取1帧, 最多10帧 PNG 图片
3
帧分析
每个 PNG 帧发送到 VisionPort.describe_frame() → 帧描述文本
4
音轨提取
ffmpeg -vn -acodec pcm_s16le -ar 16000 — 提取单声道 WAV 音轨
5
音频转录
WAV 字节发送到 AudioPort.transcribe() → 完整转录文本
6
融合输出
帧描述 + 音频转录合并为 processed_text 提供给 LLM 上下文

8. 链接自动检测与展开

与其他需要显式上传的模态不同,链接从消息文本中自动检测。

链接处理管线
1
URL 检测
正则 https?://\S+ 扫描消息文本,每消息最多3个 URL,去除尾部标点
2
SSRF 防护
validate_url_no_ssrf() 拦截内网 IP、回环地址、链路本地地址、元数据端点 (169.254.169.254)
3
抓取
httpx.get() 5秒超时, follow_redirects=True, 50KB 内容限制, 自定义 User-Agent
4
元数据提取
解析 <title>, <meta og:title>, <meta og:description>, 去除 HTML 标签提取纯文本
5
LinkPreview
冻结内核合约: url, title, description, extracted_text, content_type, metadata
6
注入
LinkPreview 内容作为虚拟附件(modality='link')加入消息,提供 LLM 上下文

9. 内核合约

所有多模态数据都流经冻结的、不可变的内核合约 — 确保类型安全和可审计性。

# ModalityType — 从 4 种扩展到 6 种
ModalityType = Literal["text", "image", "audio", "video", "document", "link"]

# 文档和链接模态的新合约
@dataclass(frozen=True)
class DocumentAnalysisResult:
    analysis_id: str
    extracted_text: str
    page_count: int = 0
    doc_type: str = ""
    confidence: float = 0.0

@dataclass(frozen=True)
class LinkPreview:
    url: str
    title: str = ""
    description: str = ""
    extracted_text: str = ""
    content_type: str = ""

# ChatMessage — 向后兼容的附件扩展
@dataclass(frozen=True)
class ChatMessage:
    message_id: str
    role: MessageRole
    content: str
    timestamp_ms: int
    metadata: dict[str, Any] = field(default_factory=dict)
    attachments: list[dict[str, Any]] = field(default_factory=list)  # 新增

10. 安全架构

多模态处理引入了新的攻击面。OctopusOS 逐一解决。

上传安全
MIME 允许列表 — 仅接受 17 种已知类型25MB 大小限制(可通过 UPLOAD_MAX_SIZE_MB 配置)文件名净化 — 过滤 ../, 限制 255 字符路径穿越防护: validate_path_within_workspace()
SSRF 防护
拦截 169.254.169.254(AWS/GCP 元数据)拦截内网 IP(10.x, 172.16-31.x, 192.168.x)拦截回环地址 (127.0.0.1) 和链路本地地址仅允许 http:// 和 https:// 协议
内容限制
链接抓取: 50KB 正文限制, 5秒超时文档文本: 截取前 5000 字符链接文本: 截取前 2000 字符视频: 最多 10 帧, ffmpeg 60秒超时
Port 隔离
内核合约: 冻结 dataclass, 零 I/OPort 协议: 内核定义, 服务层实现Gate 检查: 禁止词防止内核层出现 I/OStub 降级: 缺少 API Key 不会崩溃

11. 前端集成

React 前端提供无缝的多模态体验,包含三种交互模式。

文件选择

隐藏的 <input type="file"> 由消息输入框旁的回形针按钮触发。accept 属性过滤支持的 MIME 类型。支持同时选择多个文件。

拖放上传

聊天区域通过 onDrop / onDragOver 处理器接受文件拖放,为桌面用户提供自然的交互方式。

附件预览

AttachmentPreview 组件按模态渲染上传的文件:

模态渲染方式紧凑模式
图片<img> 点击放大120x90 缩略图
音频<audio controls> 播放器180px 宽度
视频<video controls> 播放器160x120
文档文件图标 + 文件名 + 大小仅图标
链接URL 卡片含标题紧凑卡片

12. 实施指标

指标数量
支持的 MIME 类型17
新增冻结合约2 (DocumentAnalysisResult, LinkPreview)
ModalityType 字面量6 (text, image, audio, video, document, link)
Port 实现5 (Vision, Audio, Video, Document, Link)
管线阶段9
新建文件6
修改文件10
新增测试13
安全控制层4 (上传、SSRF、内容限制、Port 隔离)
引入的 Gate 违规0

13. 设计哲学

1. 每种模态都是一等公民。 无论用户发送图片、音频还是 PDF,都经过相同的管线处理:上传、存储、处理、注入 LLM 上下文、渲染到聊天。没有任何模态是二等公民。

2. 优雅降级优于硬失败。 缺少 OpenAI API Key?Vision 降级到 Stub。没有 ffmpeg?视频返回文件信息。链接抓取失败?记录错误,消息照常发送。系统永远不会因缺少依赖而崩溃。

3. 每个边界都有安全防护。 上传检查 MIME 类型和路径。链接展开拦截 SSRF。内容有大小限制。内核合约是冻结的且无 I/O。每一层独立执行自己的安全不变量。

4. 复用内核基础设施。 DocumentProcessor 封装现有的 parse_file() 域。VideoProcessor 复用 VisionPort 和 AudioPort。ModalityType 扩展现有的 Literal。ChatMessage 添加一个带默认值的字段 — 零破坏性变更。

LinkedIn X
OctopusOS
有什么可以帮您?