视频流相关基础概念;Human-in-the-Loop Interrupt 支持在rag链路中的实现;

视频流相关基础概念

网络传输只有 byte

网络的物理层本质是比特流(bit stream),协议栈向上封装后,应用层看到的就是 byte[]。
所以不管传的是图像、视频还是字符串,到了网络上都变成 bytes,接收方再根据约定的格式还原。

byte[] 与数据格式

byte[] 只是数据在内存或网络中的存储形式,真正决定数据类型的是其中遵循的格式:

byte[] 内部数据 类型 说明
RGB / YUV 原始帧 未压缩,体积大,1080p 每帧 ~6MB
JPEG 图片编码 单帧压缩,帧间无依赖
H.264 / VP9 视频编码(裸流) 压缩率高,但需要解码上下文
MP4 / MKV 容器格式 封装了编码数据 + 时间戳 + 音频轨等

补充:编码(Codec) 和 容器(Container) 是不同层的概念:

  • 编码(H.264、VP9):决定数据怎么压缩
  • 容器(MP4、MKV):决定数据怎么打包和组织

实时图像传输的典型流程

[摄像头]
   ↓ 原始帧 (RGB/YUV,未压缩)
[编码器]           ← 这步决定传输效率
   ↓ 压缩后的 bytes (JPEG / H.264 / VP9...)
[网络传输]         ← 全程都是 bytes
   ↓
[接收方解码]
   ↓ 还原为原始帧
[显示]

不同传输方案对比

方案 传输的 bytes 内容 特点
直接传 RGB 原始像素数据 体积极大,延迟低
MJPEG 每帧独立 JPEG 体积小,延迟低,帧间无依赖
H.264 裸流 I/P/B 帧混合 压缩率高,但需要解码上下文
WebRTC H.264/VP8 + RTP 封包 专为实时设计,有丢包恢复
RTSP/HLS 容器封装后的 bytes 适合监控/直播,延迟较高

Human-in-the-Loop Interrupt在异步队列rag链路中的实现

流程

客户端                          服务端
  │                               │
  ├─ POST /rag/chat ──────────→   任务入队,worker 开始执行
  ├─ GET  /tasks/{id} ────────→   status=INTERRUPTED,返回 tool_calls
  │   (用户确认工具调用)
  ├─ POST /tasks/{id}/resume ─→   唤醒 worker,图继续执行
  ├─ GET  /tasks/{id} ────────→   status=SUCCESS
  └─ GET  /tasks/{id}/result ─→   answer + citations

图结构变化

# llm_call 后插入 interrupt 节点
llm_call → interrupt → tools_condition → tools → llm_call → ... → finalize

interrupt_node 检测到 tool_calls 时调用 interrupt() 暂停图,调用方 approve 后图从断点继续,cancel 则直接写入 answer 终止。

核心改动

TaskRecord 新增三个字段

interrupt_payload: dict | None  # 存 tool_calls,供调用方 GET 查看
resume_event: asyncio.Event     # pipeline 挂上,resume 时 set 唤醒 worker
resume_value: Any               # 存调用方原始 payload,由 pipeline 校验

on_interrupt 回调(pipeline 层)

async def on_interrupt(interrupt_payload) -> str:
    await dispatcher._mark_interrupted(task_id, interrupt_payload)  # 状态 → INTERRUPTED
    event = asyncio.Event()
    task_record.resume_event = event
    try:
        await asyncio.wait_for(event.wait(), timeout=...)           # 阻塞等调用方唤醒
    except asyncio.TimeoutError:
        return "cancel"
    return ResumeRequest.model_validate(task_record.resume_value).decision  # 校验在这里

校验层次

层次 职责
router 透传原始 dict,不做校验
dispatcher 检查任务存在且状态为 INTERRUPTED,存入 resume_value 并唤醒
pipeline ResumeRequest.model_validate 校验 decision 字段
posted @ 2026-06-26 17:51  asphyxiasea  阅读(16)  评论(0)    收藏  举报