多模态感知:AI 操作系统如何看、听、读
一个只能接收文字的 Agent 就像一个只会阅读的人 — 它错过了图像、声音、文档和网络的丰富信息。OctopusOS 多模态感知赋予内核五种感官:图片、音频、视频、文档和链接 — 每种模态都流经从上传到 LLM 推理的受治理、类型安全的完整管线。
1. 为什么 AI 操作系统需要多模态
传统聊天界面只接受文字输入。但现实任务涉及错误截图、会议录音、PDF 合同、视频演示和网页链接。没有多模态感知,用户必须手动描述视觉内容或复制粘贴文档文字 — 丢失上下文,浪费时间。
OctopusOS 构建了一个全栈多模态管线,端到端处理五种模态:从浏览器文件选择、服务端处理,到 LLM 原生视觉和音频推理能力。
2. 五种模态总览
3. 上传管线:9 个阶段
每次多模态交互都遵循相同的受治理管线,不论模态类型。
4. 四层架构
5. Port 模式:协议 + 实现 + 降级
OctopusOS 遵循严格的 Port 模式处理多模态。内核定义 Protocol 接口(零 I/O),服务层提供真实实现并优雅降级到 Stub。
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 格式。
消息格式转换
# 纯文本消息(多模态之前)
{"role": "user", "content": "这是什么?"}
# 多模态消息(多模态之后)
{"role": "user", "content": [
{"type": "text", "text": "这是什么?\n\n[音频转录]: Q1 业绩会议内容..."},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBOR..."}}
]}
7. 视频处理管线
视频是最复杂的模态,通过多阶段管线组合视觉和音频分析。
8. 链接自动检测与展开
与其他需要显式上传的模态不同,链接从消息文本中自动检测。
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 逐一解决。
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 添加一个带默认值的字段 — 零破坏性变更。