用 Strands Agents 在 AWS 上构建可对话的视频理解系统

2026-09-24 26 预计阅读时间: 1 分钟
来源: aws.amazon.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

传统视频分析通常要求用户先选择“语音转写”“人物识别”或“物体检测”,再分别查看各服务的结果。Agentic 架构改变的是这一层交互:用户直接提问,单个 Strands Agents SDK Agent 根据问题决定调用 Amazon Transcribe、Amazon Rekognition,或同时调用两者,最后交给 Amazon Bedrock 组织答案。

这种方案的重点不是让大模型直接“观看”整段视频,而是让 Agent 成为调度器,把专用服务产生的结构化证据组合起来。

一条问题如何变成答案

可以把处理链路拆成四层:

  1. 视频上传到 Amazon S3。
  2. Agent 接收自然语言问题,例如“视频里什么时候出现了汽车?”
  3. Agent 根据问题选择工具:
  4. 对话、演讲内容、关键词:调用 Amazon Transcribe。
  5. 人物、物体、场景及出现时间:调用 Amazon Rekognition。
  6. “演讲者提到汽车时,画面里真的有汽车吗?”:同时调用两项服务。
  7. Amazon Bedrock 根据工具返回的转写文本、标签和时间戳生成自然语言答案。

关键设计是让工具返回可验证的证据,而不是只返回一个模糊结论。例如,Rekognition 工具应保留标签、置信度和毫秒时间戳;Transcribe 工具则应保留完整文本,生产环境中还可以进一步保留词级时间戳。

用户问题
   │
   ▼
Strands Agent ─────► Amazon Bedrock:理解问题、规划调用、整理答案
   │
   ├───────────────► Amazon Transcribe:语音与对白
   │
   └───────────────► Amazon Rekognition:物体、人物、场景与时间点
                           │
                           ▼
                      Amazon S3 视频

为什么要由 Agent 动态选服务

如果每个问题都无条件运行全部分析,系统虽然容易实现,却会增加延迟、费用和上下文长度。基于意图的工具路由更合适:

用户问题 建议调用
“主持人总结了哪三点?” Transcribe
“第一个人什么时候出现?” Rekognition
“画面出现产品时,旁白说了什么?” Rekognition + Transcribe
“这段视频的文件名是什么?” S3 元数据工具即可

Agent 的价值在于运行时决策,但它不应该拥有无限权限。每个工具应只暴露完成任务所需的参数和 AWS 权限,并限制可访问的 S3 Bucket、最长视频时长、轮询时间和返回数据量。

还要注意,Transcribe 和 Rekognition 的视频任务通常是异步任务。“数秒内回答”更适合已经预处理、短视频或命中缓存的场景。对较长视频,建议在上传后提前生成分析结果,提问时只让 Agent 查询结果;若坚持按问题实时启动任务,就需要向用户明确展示处理中状态。

可改造的最小 Python 示例

下面的示例让 Strands Agent 自行选择两个工具:一个启动 Amazon Transcribe 转写,另一个运行 Amazon Rekognition 标签检测。代码假设视频已经放在 S3,AWS 凭证也已配置。

安装依赖:

python -m venv .venv
source .venv/bin/activate
pip install strands-agents boto3

export AWS_REGION=us-east-1
export VIDEO_BUCKET=my-video-bucket
export VIDEO_KEY=uploads/demo.mp4

运行前需要在目标区域启用可供 Strands 使用的 Amazon Bedrock 模型,并为当前身份授予最小权限。至少会涉及读取目标 S3 对象、启动和查询 Transcribe 任务、启动和查询 Rekognition 视频任务,以及调用选定 Bedrock 模型。

将以下内容保存为 video_agent.py

import json
import os
import time
import urllib.request
import uuid

import boto3
from strands import Agent, tool

REGION = os.getenv("AWS_REGION", "us-east-1")
BUCKET = os.environ["VIDEO_BUCKET"]
KEY = os.environ["VIDEO_KEY"]

transcribe = boto3.client("transcribe", region_name=REGION)
rekognition = boto3.client("rekognition", region_name=REGION)


def wait(seconds: int = 5) -> None:
    time.sleep(seconds)


@tool
def transcribe_video() -> str:
    """Transcribe the speech in the configured S3 video and return its text."""
    job_name = f"video-agent-{uuid.uuid4().hex}"
    transcribe.start_transcription_job(
        TranscriptionJobName=job_name,
        Media={"MediaFileUri": f"s3://{BUCKET}/{KEY}"},
        IdentifyLanguage=True,
    )

    while True:
        response = transcribe.get_transcription_job(
            TranscriptionJobName=job_name
        )
        job = response["TranscriptionJob"]
        status = job["TranscriptionJobStatus"]

        if status == "COMPLETED":
            transcript_uri = job["Transcript"]["TranscriptFileUri"]
            with urllib.request.urlopen(transcript_uri, timeout=30) as result:
                payload = json.load(result)
            return payload["results"]["transcripts"][0]["transcript"]

        if status == "FAILED":
            return f"Transcription failed: {job.get('FailureReason', 'unknown')}"

        wait()


@tool
def detect_video_labels() -> str:
    """Detect objects and scenes in the configured video, including timestamps."""
    started = rekognition.start_label_detection(
        Video={"S3Object": {"Bucket": BUCKET, "Name": KEY}},
        MinConfidence=75,
    )
    job_id = started["JobId"]

    while True:
        page = rekognition.get_label_detection(
            JobId=job_id,
            MaxResults=1000,
            SortBy="TIMESTAMP",
        )
        status = page["JobStatus"]

        if status == "FAILED":
            return f"Label detection failed: {page.get('StatusMessage', 'unknown')}"
        if status == "SUCCEEDED":
            break
        wait()

    detections = []
    while True:
        for item in page.get("Labels", []):
            label = item["Label"]
            detections.append(
                {
                    "time_seconds": round(item["Timestamp"] / 1000, 2),
                    "label": label["Name"],
                    "confidence": round(label["Confidence"], 1),
                }
            )

        token = page.get("NextToken")
        if not token or len(detections) >= 300:
            break

        page = rekognition.get_label_detection(
            JobId=job_id,
            MaxResults=1000,
            SortBy="TIMESTAMP",
            NextToken=token,
        )

    return json.dumps(detections[:300], ensure_ascii=False)


SYSTEM_PROMPT = """
你是视频分析助手。根据问题只调用必要的工具:
- 涉及说话内容、主题、关键词时,调用 transcribe_video。
- 涉及画面中的物体、人物、场景或出现时间时,调用 detect_video_labels。
- 需要对齐画面与对白时,同时调用两个工具。
只能依据工具返回的证据回答。证据不足时明确说明,不要猜测。
涉及时间时使用 mm:ss 格式,并简要说明依据。
"""

agent = Agent(
    system_prompt=SYSTEM_PROMPT,
    tools=[transcribe_video, detect_video_labels],
)

question = input("请输入关于视频的问题:")
print(agent(question))

运行:

python video_agent.py

可以尝试这些问题:

视频中什么时候出现了汽车?
演讲者主要讨论了什么?
画面出现电脑时,旁白正在说什么?

不同版本的 Strands Agents SDK 可能采用不同的 Bedrock 模型初始化方式。如果默认模型不适合所在区域,应按照所安装版本的模型配置接口,为 Agent 显式传入可用的 Bedrock 模型。

从演示走向生产环境

上面的脚本适合说明工具路由,但不适合直接承担高并发生产流量。实际系统可以做几项改造。

预处理并缓存结果

视频上传后通过事件触发工作流,提前生成转写、标签和时间轴,并把结果写入 S3、DynamoDB 或搜索索引。Agent 提问时查询现有结果,能显著缩短响应时间,也能避免同一视频被重复分析。

缓存键至少应包含:

bucket + object_key + object_version + analysis_type + model_or_api_version

控制上下文大小

长视频的完整转写可能超出模型上下文,也会增加推理费用。可以按时间窗口切分转写,为每一段生成摘要和向量,只把与问题最相关的片段交给 Bedrock。Rekognition 结果也应聚合连续重复标签,例如把 01:10 到 01:18 连续出现的 Car 合并为一个时间区间。

把证据带进答案

生产答案最好包含时间戳、置信度和证据类型,例如:

汽车约在 01:12 首次出现。
依据:Rekognition 标签 Car,置信度 96.4%。
相关旁白:转写片段 01:09–01:16。

这比只输出“视频里有汽车”更便于用户复核,也有助于定位识别错误。

设置安全与成本边界

上线前应检查:

  • Agent 使用独立 IAM Role,并限定 S3 前缀和允许调用的 AWS API。
  • 上传入口校验文件类型、大小、时长和租户归属。
  • 转写和检测任务设置超时、重试上限及并发配额。
  • 日志避免记录未经脱敏的完整转写和敏感画面信息。
  • 对人脸、身份、医疗、会议和监控视频建立额外的数据治理规则。
  • 记录 Agent 调用了哪些工具、参数是什么、最终答案引用了哪些证据。

采用建议

适合从一个受控场景开始,例如培训视频检索、媒体素材搜索或内部会议回顾。先定义十到二十个真实问题,检查 Agent 是否选对工具、时间戳是否准确、答案是否能追溯到证据,再逐步加入人物识别、章节摘要或企业知识库检索。

Agentic 视频智能的核心并不是堆叠更多模型,而是把路由、异步任务、缓存、证据和权限边界设计清楚。Bedrock 负责理解与表达,Rekognition 和 Transcribe 提供专用信号,Strands Agent 则把这些能力组合成一个自然语言入口。


相关推荐