チュートリアル

TwelveLabsとPerplexity Sonarを使用したビデオディープリサーチの構築

リシケシュ・ヤダフ

このチュートリアルでは、Twelve LabsのPegasus 1.2モデルを使用して動画コンテンツを分析し、Perplexity Sonarを使用してその分析結果から引用文献に裏付けられたリサーチインサイトを生成する、Video Deep Researchアプリケーションの構築手順を説明します。フロントエンドにはNext.js、バックエンドにはFlaskを採用し、事前にインデックス化された動画と直接アップロードの両方をサポートしています。

このチュートリアルでは、Twelve LabsのPegasus 1.2モデルを使用して動画コンテンツを分析し、Perplexity Sonarを使用してその分析結果から引用文献に裏付けられたリサーチインサイトを生成する、Video Deep Researchアプリケーションの構築手順を説明します。フロントエンドにはNext.js、バックエンドにはFlaskを採用し、事前にインデックス化された動画と直接アップロードの両方をサポートしています。

この記事の内容

No headings found on page

ニュースレターに登録する

ニュースレターに登録する

ビデオ理解に関する最新の技術進歩、チュートリアル、業界の動向をお届けします

ビデオ理解に関する最新の技術進歩、チュートリアル、業界の動向をお届けします

AIを活用してビデオを検索、分析、探索します。

2025/10/07

13分

記事へのリンクをコピー

u306fu3058u3081u306bu305b

u30a6u30a7u30d6u4e0au3067u30c6u30adu30b9u30c8u3092u691cu7d22u3059u308bu306eu3068u540cu3058u304fu3089u3044u7c21u5358u306bu52d5u753bu3092u691cu7d22u3067u304du3001u4fe1u983cu3067u304du308bu5f15u7528u5143u3068u3068u3082u306bあらゆるu30a4u30f3u30b5u30a4u30c8u3092u5f97u3089u308cu308bu3068u3057u305fu3089u3069u3046u3067u3057u30e7u30a6uff1f ud83cudfa5ud83dudd0d

u73feu5728u306eu3068u3053u308du3001u305du308cu306fu307eu3060u30a6u30a7u30d6u306bu6b20u3051u3066u3044u308bu30d4u30fcu30b9u306eu3072u3068u3064u3067u3059u3002u691cu7d22u30a8u30f3u30b8u30f3u306fu3001u7d50u679cu3092u5f97u308bu305fu3081u306eu5165u529bu3068u3057u3066u52d5u753bu3092u8003u616eu3057u3066u3044u307eu305bu3093u3002u3053u306eu305fu3081u3001u7814u7a76u8005u3001u30afu30eau30a8u30a4u30bfu30fcu3001u5c02u9580u5bb6u306fu3001u69cbu9020u5316u3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u62bdu51fau3057u305fu308au691cu8a3cu3057u305fu308au3059u308bu4fe1u983cu3067u304du308bu65b9u6cd5u304cu306au3044u307eu307eu3001u4f55u6642u9593u3082u306eu6620u50cfu3092u624bu52d5u3067u78bau8a8du305bu3056u308bu3092u5f97u306au3044u72b6u6cc1u306bu3042u308au307eu3059u3002

Video Deep Researchu306fu3001u7814u7a76u306eu305fu3081u306eu52d5u753bu306eu6349u3048u65b9u3092u5909u3048u307eu3059u3002u610fu5473u7684u306au52d5u753bu7406u89e3u3092u884cu3046 TwelveLabs Analyze pegasus-1.2 u3068u3001u5f15u7528u3092u88cfu4ed8u3051u305fu77e5u8b58u691cu7d22u3092u884cu3046 Sonar by Perplexity u3092u7d44u307fu5408u308fu305bu308bu3053u3068u3067u3001u52d5u753bu3092u691cu7d22u53efu80fdu3067u4fe1u983cu306eu304au3051u308bu7814u7a76u30eau30bdu30fcu30b9u3078u3068u5909u5faeu3055u305bu307eu3059u3002

u3053u306e Video Deep Research u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u304cu3069u306eu3088u3046u306bu52d5u4f5cu3059u308bu306eu304bu3001u305du3057u3066 TwelveLabs Python SDK u3068 Perplexity Sonar u3092u4f7fu7528u3057u305fu52d5u753bu7406u89e3u3068u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u306bu3088u3063u3066u3001u540cu69d8u306eu30bdu30eau30e5u30fcu30b7u30e7u30f3u3092u3069u306eu3088u3046u306bu69cbu7bc3u3067u304du308bu304bu3092u63a2u3063u3066u307fu307eu3057u30e7u3046u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30c7u30e2u306fu3053u3061u3089u304bu3089u4f53u9a13u3067u304du307eu3059uff1a Video Deep Research u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3


u524du63d0u6761u4ef6

  • TwelveLabs Playground u306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3066u3001API u30adu30fcu3092u767au884cu3057u307eu3059uff0e

  • Sonar u306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3001u30e2u30c7u30ebu306bu30a2u30afu30bbu30b9u3059u308bu305fu3081u306e API u30adu30fcu3092u767au884cu3057u307eu3059u3002 

  • u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30eau30ddu30b8u30c8u30eau306f Github u30eau30ddu30b8u30c8u30ea u306bu3042u308au307eu3059u3002

  • Pythonu3001Flasku3001Next.js u306eu77e5u8b58u304cu3042u308bu3053u3068u304cu671bu307eu3057u3044u3067u3059u3002


u30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3

u3053u306eu30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u52d5u753bu7406u89e3u3068u77e5u8b58u691cu7d22u304cu3001u3069u306eu3088u3046u306bu3057u3066u5168u304fu65b0u3057u3044u7814u7a76u624bu6cd5u3092u5207u308au958bu304fu3053u306eu3067u304du308bu304bu3092u5bb6u73feu3057u3066u3044u307eu305su3002

u30e2u30fcu30b6u30fcu306fu3001TwelveLabs API u30adu30fcu3092u63a5u7d9au3059u308bu3060u3051u3067u3001u52d5u753bu3092u30a2u30c3u30d7u30edu30fcu30c9u3059u308bu304bu3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu30aau30f3u30e9u30a4u30f3u304bu3089u9078u629eu3059u308bu3053u3068u304cu3067u304du307eu3059u3002u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du306eu5f8cu3001u30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u3066u69cbu9020u5316u3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u62bdu51fau3057u3001u305du308cu3089u3092u691cu8a3cu53efu80fdu306au53c2u7167u5148u306bu30eau30f3u30afu3055u305bu308bu3053u3068u3067u3001u52d5u753bu3068u4fe1u983cu3067u304du308bu7814u7a76u306eu67b6u3051u6a4bu3068u306au308au307eu3059u3002

u3053u3053u3067u306fu3001u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u6a5fu80fdu3092u642du8f09u3057u305fu72ecu81eau306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc3u30fbu62e1u5f35u3067u304du308bu3088u3046u3001u30b3u30fcu30c9u3068u30c7u30e2u306eu8a73u7d30u306au8acbu91c8u3092u884cu3044u307eu3059u3002


u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu52d5u4f5cu3057u304fu307f

u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f2u3064u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059u3002

  1. TwelveLabs API u30adu30fcu306eu4f7fu7528uff1au500bu4ebau306e TwelveLabs API u30adu30fcu3092u63a5u7d9au3057u3066u3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu81eau5206u306eu52d5u753bu306bu30a2u30afu30bbu30b9u3057u3001u64cdu4f5cu3057u307eu3059u3002u63a5u7d9au3059u308bu3068u3001u65e2u5b58u306eu30a4u30f3u30c7u30c3u30afu30b9 ID u3068u5bfeu5fdcu3059u308bu52d5u753bu3092u9078u629eu3067u304du307eu3059u3002

  2. u52d5u753bu306eu30a2u30c3u30d7u30edu30fcu30c9uff1au52d5u753bu304cu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu308bu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu30b7u30fcu30e0u30ecu30b9u306au30bbu30c3u30c8u30a2u30c3u30d7u306eu305fu3081u306bu30c7u30d5u30a9u30ebu30c8u306e TwelveLabs API u30adu30fcu3092u81eau52d5u7684u306bu4f7fu7528u3059u308bu3088u3046u306bu8a2du8a08u3055u308cu3066u3044u307eu3059u3002u30a2u30c3u30d7u30edu30fcu30c9u5f8cu3001u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u304cu3059u3050u306bu5f00u59cbu3055u308cu307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu5b8cu4e86u3059u308bu3068u3001u6700u8fd1u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu304cu6700u65b0u306eu5229u7528u53efu80fdu306au30b3u30f3u30c6u30f3u30c4u3068u3057u3066u8868u793au3055u308cu307eu3059u3002u3053u306eu6642u70b9u4ee5u964du306fu3001u4e21u65b9u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3067u3001u4ee5u4e0bu306bu8a18u8f09u3059u308bu624bu9806u306bu5f93u3063u3066u3001u30afu30a8u30eau3068u5f15u7528 u306eu30efu30fcu30afu30d5u30edu30fcu304cu307eu3063u305fu304fu540cu69d8u306bu9032u884cu3057u307eu3059u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu5b8cu5168u306au30efu30fcu30afu30d5u30edu30fcu306fu3001TwelveLabs u30afu30e9u30a4u30a2u30f3u30c8u306eu8a2du5b9au304bu308au59cbu307eu308au307eu3059u3002u3053u308cu306bu306fu3001u74b0u5883u5909u6570u3067u63d0u4f9bu3055u308cu305fu30adu30fcu3092u4f7fu7528u3059u308bu304bu3001u30e2u30fcu30b6u30fcu304cu30afu30e9u30a4u30a2u30f3u30c8u5074u304bu308fu81eau5206u306eu30adu30fcu3092u63a5u7d9au3057u3066u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu306bu30a2u30afu30bbu30b9u3067u304du308bu3088u3046u306bu3001TwelveLabs API u30adu30fcu3092u30bbu30c3u30c8u30a2u30c3u30d7u3059u308bu5fc5u8981u304cu3042u308au307eu3059u3002u30afu30e9u30a4u30a2u30f3u30c8u304cu8a2du5b9au3055u308cu308bu3068u3001u30d7u30edu30bbu30b9u306fu4ee5u4e0bu306bu793au3059u9806u6b21u306eu30d5u30edu30fcu306bu5f93u3044u307eu5ea6u3002 u2013

  1. u30a4u30f3u30c7u30c3u30afu30b9u306eu53d6u5f97 (Fetch Indexes) u2013 u63a5u7d9au3055u308cu305f TwelveLabs u30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u3082u305fu30a4u30f3u30c7u30c3u30afu30b9u306eu30eau30b9u30c8u3092u53d6u5f97u3057u307eu3059u3002

  2. u52d5u753bu306eu9078u629e (Select Video) u2013 u5206u6790u3057u305fu3044u30a4u30f3u30c7u30c3u30afu30b9u304bu3089u52d5u753bu3092u9078u629eu3057u307eu3059u3002

  3. u52d5u753bu306eu5206u6790 (Analyze Video) u2013 u6307u5b9au3055u308cu305fu30afu30a8u30eau3092u4f7fu7528u3057u3066u3001u9078u629eu3057u305fu52d5u753bu306eu30b3u30f3u30c6u30f3u30c4u5206u6790u3092u884cu3041u307eu3059u3002

  4. u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1 (Deep Research) u2013 u5206u6790u3055u308cu305fu56deu7b54u3001u69cbu9020u5316u3055u308cu305fu30d7u30edu30f3u30d7u30c8u3001u304au3088u3073u30e2u30fcu30b6u30fcu306eu30afu30a8u30eau3092u7d44u307fu5408u308fu305bu3001u305du306eu5185u5bb9u3092 Sonar u30eau30b5u30fcu30c1u30e2u30c7u30ebu306bu6e21u3057u3066u3001u3088u308au6df1u3044u63a8u8ad6u3068u5f15u7528u306eu88cfu4ed8u3051u306eu3042u308bu30a4u30f3u30b5u30a4u30c8u3092u5f97u307eu3059u3002

u3053u306eu69cbu9020u5316u3055u308cu305fu30efu30fcu30afu30d5u30edu30fcu306bu3088u308au3001u52d5u753bu306eu30a4u30f3u30c7u30c3u30afu30b9u5316u304bu3089u9ad8u5ea6u306au7814u7a76u307eu3067u30b9u30e0u30fcu30bau306bu9032u884cu3057u3001u30e2u30fcu30b6u30fcu306bu8a73u7d30u3067u30b3u30f3u30c6u30adu30b9u30c8u3092u5224u65adu3057u305fu51fau529bu3092u63d0u4f9bu3057u307eu3059u3002

u4e21u65b9u306eu30a2u30d7u30edu30fcu30c1u306fu3001u4ee5u4e0bu306eu30a2u30fcu30adu30c6u30afu30c1u30e3u56f3u306bu793au3055u308cu3066u3044u307eu3059u3002

u3053u306eu30d5u30edu30fcu306fu3001u30eau30b5u30fcu30c1u56deu7b54u304cu751fu6210u3055u308cu305fu5f8cu3001u30e2u30fcu30b6u30fcu304cu540cu3058u6587u8108u3067u3055u3089u306au308bu53c2u7167u5148u3084u6df1u3044u30a4u30f3u30b5u30a4u30c8u3092u6c42u3081u308bu8ffdu52a0u30afu30a8u30eau3092u884cu3048u308bu3088u3046u306bu8a2du8a08u3055u308cu3066u3044u307eu5ea6u3002u3053u308cu3089u306eu5f8cu7d9au30afu30a8u30eau306f Sonar u30eau30b5u30fcu30c1u30ebu30fcu30d7u306bu30d5u30a3u30fcu30c9u30d0u30c3u30afu3055u308cu3001u6587u8108u306eu7d99u7d9au6027u3092u7dadu6301u3057u306au304cu3089u65e2u5b58u306eu77e5u8b58u30d2u30fcu30d9u30fcu30b9u3092u62e1u5f35u3057u307eu3059u3002u3053u306eu53cdu5fa9u7684u306au8a2du8a08u306bu3088u308au3001u65b0u3057u3044u30afu30a8u30eau305au3064u304cu4e8bu524du306eu7d50u679cu306bu57fau3065u3044u3066u69cbu7bc3u3055u308cu3001u6bb5u968eu7684u306bu8c4au304bu3067u30b3u30f3u30c6u30adu30b9u30c8u3092u8003u616eu3057u305fu7814u7a76u51fau529bu3092u5f97u308bu3053u306eu304cu3067u304du307eu3059u3002


u6e96u5099u624bu9806

  1. TwelveLabs Playground u304bu3089u30a2u30afu30bbu30b9 API u30adu30fcu3092u53d6u5f97u3057u3001u74b0u5883u5909u6570u3092u8a2du5b9au3057u307eu3059u3002

  2. TwelveLabs Playground u3092u901au3058u3066 pegasus-1.2 u3092u9078u629eu3057u3001u30a4u30f3u30c7u30c3u30afu30b9u3092u4f5cu6210u3057u3001u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u7528u306e index_id u3092u53d6u5f97u3057u307eu3059u3002

  3. Github u304bu3089u30d7u30edu30b8u30a7u30afu30c8u3092u30afu30edu30fcu30f3u3057u307eu3059u3002

  4. Sonar by Perplexity u304bu3089 API KEY u3092u53d6u5f97u3057u307eu3059u3002

  5. TwelveLabs u3068 Sonar u306eu8a3cu660eu60c5u5831u3092u542bu3080 .env u30d5u30a1u30a4u30ebu3092u4f5cu6210u3057u307eu3059u3002u74b0u5883u8a2du5b9au306eu4ee5u4e0bu306fu3001u3053u3061u3089 u3067u78bau8a8du3067u304du307eu3059u3002

u3053u308cu3089u306eu624bu9806u304cu5b8cu4e86u3059u308bu3068u3001u958bu767au3092u590bu3081u308bu6e96u5099u304cu6574u3044u307eu3059uff01


u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30a2u30d7u30eau306eu30fcu30afu30b9u30ebu30fc

u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u306bu57fau3065u3044u3066u30a6u30a7u30d6u304bu3089u5f15u7528u60c5u5831u3084u95a2u9023u60c5u5831u3092u53d6u5f97u3067u304du308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu69cbu7bc3u65b9u6cd5u3092u5bb6u73feu3057u307eu3059u3002u3053u306eu30d7u30edu30b8u30a7u30afu30c8u3067u306fu3001u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306b Next.js u3092u3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u306bu306f Flask APIuff08CORSu6709u52b9u5316uff09u3092u4f7fu7528u3057u3066u307eu3059u3002u6211u3005u306eu4e3bu306eu30d5u30a9u30fcu30abu30b9u306fu3001u3053u306eu52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4e3bu8981u306au30d0u30c3u30afu30a8u30f3u30c3u30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu5b9fu88c5u3068u3001u5b8cu5168u306au74b0u5883u306eu30bbu30c3u30c8u30a2u30c3u30d7u3067u3059u3002

u8a73u7d30u306f u30bbu30c3u30c8u30a2u30c3u30d7u624bu9806u3068u5b8cu5168u306au30b3u30fcu30c9u69cbu9020u306bu3064u3044u3066u306fu3001GitHub u30eau30ddu30b8u30c8u30eau306e README.md u30d5u30a1u30a4u30ebu3092u53c2u7167u3057u3066u304fu3060u3055u3044u3002


1 - u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u5b9fu88c5u306eu30efu30fcu30afu30d5u30edu30fc

u30efu30fcu30afu30d5u30edu30fcu3067u3082u3063u3068u3082u91cdu8981u306au30b9u30c6u30actu306fu3001TwelveLabs API u30adu30fcu306eu521du671fu5316u3068u30cfu30f3u30c9u30eau30f3u30b0u3067u3059u3002u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u30c7u30d5u30a9u30ebu30c8u306eu4f7fu7528u306eu305fu3081u306bu74b0u5883u304bu3089u30adu30fcu3092u76f4u63a5u8aadu307fu8fbcu3080u304bu3001u30e2u30fcu30b6u30fcu304cu30afu30e9u30a4u30a2u30f3u30c8u3092u4ecbu3057u3066u72ecu81eau306e API u30adu30fcu3092u63d0u4f9bu3067u304du308bu3088u3046u306bu3057u307eu3059u3002

backend/service/twelvelabs_service.py (14-36u884cu76ee)

class TwelveLabsService:
    def __init__(self, api_key=None):
        # If no API key is provided, try to get it from environment variable
        if api_key is None:
            api_key = os.environ.get('TWELVELABS_API_KEY', '')
        self.api_key = api_key # Store API key in the instance
        self.client = TwelveLabs(api_key=api_key) # Intialize the TwelveLabs client


1.1 u30a4u30f3u30c7u30c3u30afu30b9u306eu53d6u5f97 (GET Indexes)

u30e2u30fcu30b6u30fcu304cu30ddu30fcu30bfu30ebu3092u901au3058u3066 TwelveLabs API u30adu30fcu3092u63a5u7d9au3059u308bu304bu3001u307eu305fu306fu74b0u5883u304bu3089u30adu30fcu304cu8decu307fu8fbcu307eu308cu308bu30c7u30d5u30a9u30ebu30c8u30e2u30fcu30c9u3092u4f7fu7528u3059u308bu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du306eu30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u3082u305fu3059u3079u3066u306eu30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3057u307eu3059u3002u53d6u5f97u3055u308cu305fu30c7u30fcu30bfu306fu69cbu9020u5316u3055u308cu3001u8868u793au306eu305fu3081u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu5c4au3051u3089u3082u307eu3059u00e3u3002

backend/service/twelvelabs_service.py (14-36u884cu76ee)

def get_indexes(self):
        try:
            print("Fetching indexes...")
            # Check if API key is available
            if not self.api_key:
                print("No API key available")
                return []
            
            # Use TwelveLabs client to get a list of indexes
            indexes = self.client.indexes.list()
            
            result = []
            for index in indexes:
                # Append a dictionary with relevant index details
                result.append({
                    "id": index.id,
                    "name": index.index_name
                })
                print(f"ID: {index.id}")
                print(f"  Name: {index.index_name}")
            
            return result
        except Exception as e:
            print(f"Error fetching indexes: {e}")
            return []


1.2 u5bfeu5fdcu3059u308bu30a4u30f3u30c7u30c3u30afu30b9 ID u306eu52d5u753bu30eau30b9u30c8u3092u53d6u5f97 (GET Videos)

u30e2u30fcu30b6u30fcu304cu30a4u30f3u30c7u30c3u30afu30b9u3092u9078u629eu3059u308bu306eu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu95a2u90a6 index_id u3092u8a18u9332u305eu3057u307eu3059u3002u3053u306e index_id u3092u4f7fu7528u3057u3066u3001u30b7u30b9u30c6u30e0u306fu305du306eu30a4u30f3u30c7u30c3u30afu30b9u306bu30eau30f3u30afu3055u308cu305fu3059u3079u3066u306eu52d5u753bu3092u53d6u5f97u3057u3066u8fd4u3059u95a2u9023u30e1u30bdu30c3u30c9u3092u547cu3073u51fau3057u307eu3059u3002

backend/service/twelvelabs_service.py (38-70u884cu76ee)

def get_videos(self, index_id, page=1):
        try:
            # Check if API key is available
            if not self.api_key:
                print("No API key available")
                return []
            
            # Use TwelveLabs client to get a list of videos
            videos_response = self.client.indexes.videos.list(index_id=index_id, page=page)
            
            result = []
            for video in videos_response.items:
                system_metadata = video.system_metadata
                hls_data = video.hls
                thumbnail_urls = hls_data.get('thumbnail_urls', []) if hls_data else []
                thumbnail_url = thumbnail_urls[0] if thumbnail_urls else None
                video_url = hls_data.get('video_url') if hls_data else None
                # Append a dictionary with relevant video details
                result.append({
                    "id": video.id,
                    "name": system_metadata.filename if system_metadata and system_metadata.filename else f'Video {video.id}',
                    "duration": system_metadata.duration if system_metadata else 0,
                    "thumbnail_url": thumbnail_url,
                    "video_url": video_url,
                    "width": system_metadata.width if system_metadata else 0,
                    "height": system_metadata.height if system_metadata else 0,
                    "fps": system_metadata.fps if system_metadata else 0,
                    "size": system_metadata.size if system_metadata else 0
                })
            
            return result
        except Exception as e:
            print(f"Error fetching videos for index {index_id}: {e}")
            return []


1.3 u52d5u753bu30b3u30f3u30c6u30f3u30c4u306eu5206u6790

u52d5u753bu304cu9078u629eu3055u308cu3001u30e2u30fcu30b6u30fcu304bu3089u30eau30b5u30fcu30c1u30afu30a8u30eau304cu63d0u4f9bu3055u308cu308bu3068u3001video_id u3068u30afu30a8u30eau306eu4e21u65b9u304cu52d5u753bu7406u89e3u306eu305fu3081u306b analyze u30e6u30fcu30c6u30a3u30eau30c6u30a3u306bu6e21u3055u308cu307eu3059u3002u30afu30a8u30eau306fu4e8bu524du306bu5b9au7fa9u3055u308cu305fu30d7u30edu30f3u30d7u30c8u306bu8ffdu52a0u3055u308cu3001u6587u8108u304cu5f37u5316u3055u308cu3001u6709u610fu7fa9u306au5206u6790u56deu7b54u304cu5f97u3089u308eu308bu3088u3046u306bu3057u307eu3059u3002u52d5u753bu5206u6790u306bu4f7fu7528u3055u308cu308bu30d7u30edu30f3u30d7u30c8u306f u3053u3061u3089 u306bu3042u308au307eu3059u3002

backend/service/twelvelabs_service.py (72-81u884cu76ee)

def analyze_video(self, video_id, prompt):
        try:
            # Call the TwelveLabs client to analyze the video
            analysis_response = self.client.analyze(
                video_id=video_id,
                prompt=prompt
            )
            return analysis_response.data
        except Exception as e:
            print(f"Error analyzing video {video_id}: {e}")
            raise e


1.4 u5206u6790u3053u307fu30b3u30f3u30c6u30f3u30c4u306eu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1

u521du671fu5206u6790u304fu304cu5b8cu4e86u3059u308bu306eu3068u3001u30efu30fcu30afu30d5u30edu30fcu306f Sonar u30e2u30c7u30ebu3092u4f7fu7528u3057u305fu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30d5u30a7u30fcu30bau306bu79fbu308au307eu3059u3002deep_research u547cu3073u51fau3057u306fu3001u30e2u30fcu30b6u30fcu306eu5143u306eu30afu30a8u30eau3001u30eau30b5u30fcu30c1u30d7u30edu30f3u30d7u30c8u3001u30eau30b5u30fcu30c1u7d50u679cu306e 3u3064u306eu8981u7d20u3092u7d44u307fu5408u308fu305bu305f1u3064u306e u30dau30a4u30edu30fcu30c9 u3092u69cbu7bc3u3057u3001u305du306eu69cbu9020u5316u3055u308cu305fu5165u529bu3092 Sonar u306bu9001u3063u3066u3055u3089u306au308bu51e6u7406u3092u884cu3044u307eu3059u3002Sonar u306fu3001u60c5u5831u6e90u306eu5f15u7528u3092u542bu3080u3001u30d6u30e9u30c3u30b7u30e5u30a2u30c3u30d7u3055u308cu305fu69cbu9020u5316u3055u308cu305fu56deu7b54u3092u8fd4u3057u307eu3059u3002u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u306eu30d7u30edu30f3u30d7u30c8u306f u3053u3061u3089 u306bu3042u308au307eu3059u3002

backend/service/sonar_service.py (13-52u884cu76ee)

def deep_research(self, query, timeout=180):
        try:
            # Ensure API key is available
            if not self.api_key:
                raise ValueError("API key is required")
            
            payload = {
                "model": "sonar",
                "messages": [
                    {"role": "user", "content": query}
                ]
            }
            
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json"
            }
            
            # POST request to the API endpoint with timeout
            response = requests.post(
                self.base_url, 
                json=payload, 
                headers=headers, 
                timeout=timeout
            )
            
            # Check if the response was successful
            if response.status_code == 200:
                return response.json()
            else:
                print(f"Error: {response.status_code} - {response.text}")
                return {"error": f"API request failed with status {response.status_code}"}
                
        except requests.exceptions.Timeout:
            print("Request timed out")
            return {"error": "Request timed out - Sonar research is taking too long"}
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")
            return {"error": f"Network error: {str(e)}"}
        except Exception as e:
            print(f"Error in deep_research: {e}")
            return {"error": str(e)}

u3053u3053u306bu306f sonaru3001sonar-reasoningu3001sonar-deep-research u306au3069u3001u8907u6570u306e Sonar u30d0u30eau30a2u30f3u30c8u304cu5229u7528u53efu80fdu3067u3059u3002sonar-deep-research u30e2u30c7u30ebu306f reasoning_effort u8a2du5b9auff08low, medium, highuff09u3092u30b5u30ddu30fcu30c8u3057u3066u304au308au3001u30c7u30d5u30a9u30ebu30c8u306fu5206u6790u3068u901fu5ea6u306eu30d0u30e9u30f3u30b9u3092u53d6u3063u305f medium u3067u3059u3002u63a8u8ad6u30d7u30edu30bbu30b9u3092 u201chighu201d u306bu5411u4e0au3055u305bu308bu3068u3001u3088u308au591au304fu306eu5f15u7528u3068u6df1u3044u30a4u30f3u30b5u30a4u30c8u304cu5f97u3089u308cu307eu3059u304cu3001u56deu7b54u6642u9593u3068u30c8u30fcu30afu30f3u306eu4f7fu7528u91cfu3082u5897u52a0u3059u308bu305fu3081u3001u5fc5u8981u306au5fb9u5e95u3055u3001u9045u5ef6u8a31u5bb9u5ea6u3001u30b3u30b9u30c8u306bu57fau3065u3044u3066u30e2u30c7u30ebu3068u52aau529bu30ecu30d9u30ebu3092u9078u629eu3057u3066u304fu3060u3055u3044u3002

u30a2u30d7u30eau306eu30e2u30c7u30ebu540du3092 sonar-deep-research u306bu5909u66f4u3059u308bu3060u3051u3062u3001u30b7u30b9u30c6u30e0u306fu3088u308au8a73u7d30u306au63a8u8ad6u3068u591au304fu306eu5f15u7528u3092u751fu6210u3057u307eu3059u3002u3053u306eu8a2du5b9au306bu3088u308au3001u30c7u30d5u30a9u30ebu30c8u306e sonar u30e2u30c7u30ebu3068u6bd4u8f03u3057u3066u3001u3088u308au6df1u3044u7814u7a76u3068u8c4au304bu306eu30a4u30f3u30b5u30a4u30c8u304cu5229u7528u3067u304du307eu3059u3002u4ee5u4e0bu306fu3001u751fu6210u3055u308cu305fu5f37u5316u3055u308cu305fu56deu7b54u306eu30c7u30e2u3067u3059 u2014


1.5 u30eau30b5u30fcu30c1u306eu305fu3081u306eu95a2u6570u547cu3073u51fau3057u30efu30fcu30afu30d5u30edu30fc

u30efu30fcu30afu30d5u30edu30fcu306f TwelveLabs u30afu30e9u30a4u30a2u30f3u30c8u306eu8a2du5b9au304bu308au59cbu307eu308au3001API u30adu30fcu3001u30a4u30f3u30c7u30c3u30afu30b9 IDu3001u52d5u753b ID u304cu9069u5207u306bu691cu8a3cu3055u308cu3066u3044u308bu3053u3068u3092u78bau306bu3057u307eu3059u3002u30bbu30c3u30c8u30a2u30c3u30d7u304fu3055u308cu308bu306eu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f TwelveLabs u30b5u30fcu30d3u30b9u304bu3081u52d5u753bu306eu8a73u7d30u3092u53d6u5f97u3057u307eu3059u3002u3053u308cu306bu3088u308au3001u3055u3089u306au308bu51e6u7406u306bu9032u3080u524du306bu3001u9078u629eu3057u305fu52d5u753bu306eu30b3u30f3u30c6u30adu30b9u30c8u304cu660eu78bau306bu8a2du5b9au3055u308cu307eu3059u3002u7d50u679cu306f yield u3092u4f7fu7528u3057u3066u30eau30a2u30ebu30bfu30a4u30e0u3067u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu3001u30d7u30edu30bbu30b9u5168u4f53u306eu5b8cu4e86u3092u5f85u3064u3053u3068u306au304fu3001UI u3092u6bb5u968eu7684u306bu66f4u65b0u3059u308bu3053u306eu3042u308au307eu3059u3002

u6b21u306bu3001u30b7u30b9u30c6u30e0u306fu5b9au7fa9u3055u308cu305f TwelveLabs u30b5u30fcu30d3u30b9 u30afu30e9u30b9u306e analyze_video u30e1u30bdu30c3u30c9u3092u547cu3073u51fau3057u3001u9078u629eu3057u305f video_id u3068u5206u6790u30d7u30edu30f3u30d7u30c8u3092u6e21u3057u307eu3059u3002u3053u306eu5206u6790u306eu51fau529bu306fu3001u4e8bu524du306bu5b9au7fa9u3055u308cu305fu30c6u30f3u30d7u30ecu30fcu30c8u3067u69cbu6210u3055u308cu305fu5f37u5316u3055u308cu305fu30eau30b5u30fcu30c1u30afu30a8u30eau306bu7d44u307fu8fbcu307eu308cu307eu3059u3002u3053u306eu30c6u30f3u30d7u30ecu30fcu30c8u306fu3001u6307u793au3068u3057u3066 Markdown u30d9u30fcu30b9u306eu56deu7b54u30d5u30a9u30fcu30deu30c3u30c8u3092u5f37u5236u3057u3001u5206u6790u7d50u679cu3068u30e2u30fcu30b6u30fcu306eu30afu30a8u30eau306eu4e21u65b9u304fu4e00u8cabu3057u305fu69cbu9020u306bu5408u308fu305bu3089u308cu308bu3088u3046u306bu3057u307eu3059u3002u305du306eu5f8cu3001u5f37u5316u3055u308cu305fu30afu30a8u30eau306f Sonar u30b5u30fcu30d3u30b9u306bu9001u3089u308cu3066 u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1 u304cu884cu308fu308cu3001u30d6u30e9u30cbu30e5u30a2u30c3u30d7u3055u308cu305fu5f15u302eu88cfu4ed8u3051u306eu3042u308bu56deu7b54u304cu751fu6210u3055u308cu307eu3059u3002

backend/routes/api_routes.py (31-162u884cu76ee)

def generate_workflow(twelvelabs_api_key, index_id, video_id, analysis_prompt, research_query, research_prompt_template):
    # Input validation
    if not twelvelabs_api_key:
        yield json.dumps({'type': 'error', 'message': 'TwelveLabs API key is required'}) + '\n'
        return
    if not index_id or not video_id:
        yield json.dumps({'type': 'error', 'message': 'Index ID and Video ID are required'}) + '\n'
        return
    if not research_query:
        yield json.dumps({'type': 'error', 'message': 'Research query is required'}) + '\n'
        return

    try:
        twelvelabs_service = TwelveLabsService(api_key=twelvelabs_api_key)
        
        # Step 1: Get video details
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'video_details',
            'message': 'Fetching video details...',
            'progress': 0
        }) + '\n'

        video_details = twelvelabs_service.get_video_details(index_id, video_id)
        if not video_details:
            yield safe_json_dumps({'type': 'error', 'message': 'Could not retrieve video details'}) + '\n'
            return

        yield safe_json_dumps({
            'type': 'data',
            'step': 'video_details',
            'data': {
                'id': video_details.get('_id', ''),
                'filename': video_details.get('system_metadata', {}).get('filename', ''),
                'duration': video_details.get('system_metadata', {}).get('duration', 0)
            },
            'progress': 33
        }) + '\n'

        # Step 2: Analyze video
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'analysis',
            'message': 'Analyzing video content...',
            'progress': 33
        }) + '\n'

        analysis_result = twelvelabs_service.analyze_video(video_id, analysis_prompt)
        yield safe_json_dumps({
            'type': 'data',
            'step': 'analysis',
            'data': analysis_result,
            'progress': 66
        }) + '\n'

        # Step 3: Research with context
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'research',
            'message': 'Conducting deep research...',
            'progress': 66
        }) + '\n'

        enhanced_query = research_prompt_template.format(
            analysis_result=analysis_result,
            research_query=research_query
        )
        
        sonar_service = SonarService()
        research_result = sonar_service.deep_research(enhanced_query, timeout=180)

        if 'error' in research_result:
            yield safe_json_dumps({'type': 'error', 'message': f'Research failed: {research_result["error"]}'}) + '\n'
            return

        # Extract research content
        research_content = ""
        if research_result and research_result.get('choices'):
            research_content = research_result['choices'][0].get('message', {}).get('content', '')
        
        # Send research content in chunks if large
        max_chunk_size = 10000
        if len(research_content) > max_chunk_size:
            for i in range(0, len(research_content), max_chunk_size):
                chunk = research_content[i:i + max_chunk_size]
                is_final = (i + max_chunk_size) >= len(research_content)
                
                yield safe_json_dumps({
                    'type': 'research_chunk',
                    'content': chunk,
                    'is_final': is_final,
                    'progress': 80 + (i / len(research_content)) * 20
                }) + '\n'
            
            # Send completion with chunked content indicator
            yield safe_json_dumps({
                'type': 'complete',
                'data': {
                    'research': {
                        'choices': [{
                            'message': {
                                'content': '[CHUNKED_CONTENT]'
                            }
                        }],
                        'citations': research_result.get('citations', [])[:10],
                        'usage': research_result.get('usage', {})
                    },
                    'sources': research_result.get('search_results', [])[:10]
                },
                'progress': 100
            }) + '\n'
        else:
            # Send completion with research data
            yield safe_json_dumps({
                'type': 'complete',
                'data': {
                    'research': {
                        'choices': [{
                            'message': {
                                'content': research_content
                            }
                        }],
                        'citations': research_result.get('citations', [])[:10],
                        'usage': research_result.get('usage', {})
                    },
                    'sources': research_result.get('search_results', [])[:10]
                },
                'progress': 100
            }) + '\n'

    except Exception as e:
        yield safe_json_dumps({'type': 'error', 'message': str(e)}) + '\n'

u5927u898fu6a21u306au30eau30b5u30fcu30c1u51fau529bu3092u51e6u7406u3059u308bu305fu3081u306bu3001u30efu30fcu30afu30d5u30edu30fcu306fu56deu7b54u306eu5206u5272uff08u30c1u30e3u30f3u30afu5316uff09u3092u5b9eu88c5u3057u3066u3044u307eu3059u3002Sonar u306fu8a73u7d30u306au63a8u8ad6u3068u591au304fu306eu5f15u7528u3092u542bu3080u5e83u7bc4u56f2u306au30b3u30f3u30c6u30f3u30c4u3092u8fd4u3059u3053u306eu304cu3042u308bu305fu3081u30011u3064u306eu5927u304du306a JSON u3068u3057u3066u9001u4fe1u3059u308bu306eu306f u30dau30a4u30edu30fcu30c9 u30b5u30a4u30bau5236u9650u3092u8d85u3048u3001u30b7u30eau30a2u30e9u30a4u30bcu30fcu30b7u30e7u30f3u30a8u30e9u30fcu3092u5f15u304du8d77u3053u3059u30eau30b9u30afu304cu3042u308au307eu3059u3002u3053u308cu3092u9632u3050u305fu3081u3001u56deu7b54u306fu7ba1u7406u53efu80fdu306au30c1u30e3u30f3u30afu306bu5206u5272u3055u308cu3001u9806u6b21u30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu307eu3059u3002u3053u306eu8a2du5b9au306fu30b9u30b1u30fcu30e9u30d3u30eau30c6u30a3u3092u78bau4fddu305fu3001u30cdu30c3u30c8u30efu30fcu30afu306eu30dcu30c8u30ebu30cdu30c3u30afu3092u56deu907fu3057u3001u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306eu5fdcu7b54u6027u3092u7dadu6301u3057u307eu3059u3002


2 - u52d5u753bu30a2u30c3u30d7u30edu30fcu30c9u30a4u30f3u30c7u30c3u30afu30b9u5316u30efu30fcu30afu30d5u30edu30fcu306eu8981u70b9

u3082u30461u3064u306eu30efu30fcu30afu30d5u30edu30fcu3067u306fu3001u4e8bu524du306eu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu306bu4f9du5b58u3059u308bu306eu3067u306fu306au304fu3001u30e2u30fcu30b6u30fcu304cu65b0u3057u3044u52d5u753bu30d5u30a1u30a4u30ebu3092u76f4u63a5u30a2u30c3u30d7u30edu30fcu30c9u3057u307eu3059u3002upload_video_file u30e1u30bdu30c3u30c9u306fu3001API u30adu30fcu3001u30a3u30f3u30c7u30c3u30afu30b9 IDu3001u30d5u30a1u30a4u30ebu30d1u30b9u306eu5fc5u8981u306au5165u529bu3092u691cu8a3cu3059u308bu3053u3068u3067u3001u3053u306eu30d7u30edu30bbu30b9u3092u51e6u7406u3057u307eu3059u3002u691cu8a3cu3055u308cu308bu306eu3068u3001TwelveLabs u306eu30bfu30b9u30afu30a8u30f3u30c3u30c9u30ddu30a4u30f3u30c3u30c8u306bu30bfu30b9u30af u30eau30afu30a8u30b9u30c8 u3092u958bu59cbu3057u3001u52d5u753bu30d5u30a1u30a4u30ebu304cu6dfbu4ed8u3055u308cu305fu30a2u30c3u30d7u30edu30fcu30c9 u30bfu30b9u30af u3092u4f5cu6210u3057u307eu3059u3002u30bfu30b9u30af u306eu4f5cu6210u304cu6210u529fu3059u308bu3068u3001u30bfu30b9u30af ID u304fu8fd4u3055u308cu3001u3053u308cu3092u4f7fu7528u3057u3066u30a4u30f3u30c7u30c3u30afu30b9u5316u306eu30b9u30bfu30fcu30bfu30b9u3092u76e3u8996u3057u307eu5ea6u3002

u305du306eu5f8cu3001u3053u306eu30e1u30bdu30c3u30c9u306fu30ddu30fcu30eau30f3u30b0 u30ebu30fcu30d7u306bu5165u308au3001u5b8cu4e86u3059u308bu304bu3001u5931u6557u3059u308bu304bu3001u307eu305fu306fu8a2du5b9au3055u308cu305fu30bfu30a4u30e0u30a2u30a6u30c8u306bu9054u3059u308bu307eu3067u3001u5b9au671fu7684u306bu30bfu30b9u30af u30b9u30bfu30fcu30bfu30b9u3092u78bau8a8du3057u307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304fu6210u529fu3059u308bu306eu3068u3001u56deu7b54u306bu306fu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu3092u4e00u610fu306bu8b58u5225u3059u308b video_id u304cu542bu307eu308cu3001u305du306eu52d5u753bu306fu3059u3050u306bu3055u3089u306au308bu5206u6790u306bu5229u7528u3067u304du308bu3088u3046u306bu306au308au307eu3059u3002u3053u308cu306bu3088u308eu3001u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu304cu30ddu30fcu30bfu30ebu4e0au3067u6700u65b0u306eu5229u7528u53efu80fdu306au52d5u753bu306bu306au308au307eu3059u3002u5931u6557u3084u30bfu30a4u30e0u30a2u30a6u30c8u306eu5830u5208u306fu3001u9069u5207u306au30a8u30e9u30fc u30e1u30c3u30bbu30fcu30b8u304fu8fd4u3055u308cu3001u30a2u30c3u30d7u30edu30fcu30c9u3068u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u306bu5b9fu8aadu306au30a8u30e9u30fc u30cfu30f3u30c9u30eau30f3u30b0u3092u63d0u4f9bu3057u307eu3059u3002

backend/service/twelvelabs_service.py (145-207u884cu76ee)

def upload_video_file(self, index_id: str, file_path: str, timeout_seconds: int = 900):
        import sys
        try:
            if not self.api_key:
                return {"error": "Missing TwelveLabs API key"}
            if not index_id:
                return {"error": "Missing index_id"}
            if not os.path.exists(file_path):
                return {"error": f"File not found: {file_path}"}
            
            print(f"Starting upload for file: {file_path}", file=sys.stderr)

            tasks_url = "https://api.twelvelabs.io/v1.3/tasks"
            headers = {
                "x-api-key": self.api_key
            }

            # Create upload task
            with open(file_path, "rb") as f:
                files = {
                    "video_file": (os.path.basename(file_path), f)
                }
                data = {
                    "index_id": index_id
                }
                resp = requests.post(tasks_url, headers=headers, files=files, data=data)

            if resp.status_code not in (200, 201):
                return {"error": f"Failed to create upload task: {resp.status_code} {resp.text}"}

            resp_json = resp.json() if resp.text else {}
            task_id = resp_json.get("id") or resp_json.get("task_id") or resp_json.get("_id")
            if not task_id:
                return {"error": f"No task id returned: {resp_json}"}

            # Poll task until ready
            import time
            start_time = time.time()
            print(f"Starting to poll task {task_id} for completion...", file=sys.stderr)
            
            while time.time() - start_time < timeout_seconds:
                r = requests.get(f"{tasks_url}/{task_id}", headers=headers)
                if r.status_code != 200:
                    time.sleep(2)
                    continue
                task = r.json() if r.text else {}
                status = task.get("status")
                print(f"Task {task_id} status: {status}", file=sys.stderr)
                
                if status in ("ready", "completed"):
                    video_id = task.get("video_id") or (task.get("data") or {}).get("video_id")
                    print(f"Indexing completed successfully! Video ID: {video_id}", file=sys.stderr)
                    return {"status": status, "video_id": video_id, "task": task}
                if status in ("failed", "error"):
                    print(f"Indexing failed with status: {status}", file=sys.stderr)
                    return {"error": f"Indexing failed with status {status}", "task": task}
                time.sleep(2)

            print(f"Upload timed out after {timeout_seconds} seconds", file=sys.stderr)
            return {"error": "Upload timed out"}

u5f8cu7d9au306eu30efu30fcu30afu30d5u30edu30fc u30d4u30d7u30e9u30a4u30f3u306fu3001u52d5u753bu304cu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu3066u30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu308du306eu3068u3001u751fu6210u3055u308cu305f video_id u304cu5206u6790u3001u30eau30b5u30fcu30c1u5f37u5316u3001u304au3088u3073u5f15u7528u306eu88cfu4ed8u3051u306eu3042u308bu56deu7b54u306eu30efu30fcu30afu30d5u30edu30fcu306bu6e21u3055u308cu3001u4e8bu524du306bu8aacu660eu3057u305fu306eu3068u540cu3058u30b7u30fcu30b1u30f3u30b9u306bu5f93u3044u307eu3059u3002u3053u308cu306bu3088u308au3001u7d71u4e00u3055u308cu305fu30efu30fcu30afu30d5u30edu30fcu3092u7dadu6301u3057u306au304cu3089u3001u30c7u30d5u30a9u30ebu30c8u30e2u30fcu30c9uff08u4e8bu524du306fu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753buff09u3068u9ec4u66ffu30e2u30fcu30c9uff08u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753buff09u306eu9593u306eu4e00u8cabu6027u304cu78bau4fddu3055u308cu307eu3059u3002u4ee5u4e0bu306fu3001u52d5u753bu306eu30a2u30c3u30d7u30edu30fcu30c9u3001u30a4u30f3u30c7u30c3u30afu30b9u5316u306eu5b9fu884cu3001u304au3088u3073u5b8cu5168u306au30d4u30d7u30e9u30a4u30f3u306eu5b9fu884cu30d7u30edu30bbu30b9u3092u5bb6u73feu3059u308bu30afu30a4u30c3u30afu30c7u30e2u3067u3059 u2014

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f TwelveLabs API u30adu30fcu3092u30afu30e9u30a4u30a2u30f3u30c8u5074u3067u76f4u63a5u51e6u7406u3059u308bu3053u306eu3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059u3002u3053u308cu306bu3088u308au3001u30e2u30fcu30b6u30fcu306fu72ecu81eau306e API u30adu30fcu3092u63a5u7d9au3059u308bu67d4u8edfu6027u304cu5f97u3089u308cu3001u30c7u30d5u30a9u30ebu30c8u306eu30adu30fcu306bu4f9du5b58u3059u308bu3053u306eu306au304fu3001u4e8bu524du306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu3092u5206u6790u3057u3001u7814u7a76u306fu305du306eu52d5u753bu3067u884cu3048u308bu3088u3046u306bu306au308au307eu3059u3002


u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u3055u3089u306bu5b9fu9a13u3059u308bu305fu3081u306eu30a2u30a4u30c7u30a2

u52d5u753bu7406u89e3u304cu3069u306eu3088u3046u306bu3057u3066u691cu8a3cu53efu80fdu306au7814u7a76u306bu63a5u7d9au3055u308cu308bu304bu3092u63a2u308bu3053u306eu306fu3001u3055u3089u306bu5f37u529bu306au30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3078u306eu6249u3092u958bu304du307eu3059u3002TwelveLabs Analyze u3068 Sonar by Perplexity u3092u4f7fu7528u3057u3066u3001u4ee5u4e0bu306eu3088u3046u306au5b9fu9a13u7684u306au65b9u5411u6027u3092u8a66u3059u3053u306eu3042u308au307eu3059 u2014

ud8d1udd0d u6df1u5c64u52d5u753bu30d5u30a1u30afu30c8u30c1u30a7u30c3u30af u2014 u62bdu51fau3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u4fe1u983cu3067u304du308bu60c5u5831u6e90u3084u5f15u7528u5143u306bu30eau30f3u30afu3055u305eu308bu3053u306eu3067u3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u5185u306eu767au8a00u3084u4e3bu5f35u3092u81eau52d5u7684u306bu691cu8a3cu3057u307eu3059u3002

ud83dudcc3 u610fu5473u7684u30eau30b5u30fcu30c1u30ecu30d3u30e5u30fc u2014 u52d5u753bu30b3u30f3u30c6u30f3u30c4u306eu69cbu9020u5316u3055u308cu305fu8981u7d04/u30ecu30dccu30e5u30fcu3092u751fu6210u3057u3001u4e3bu8981u306au30a2u30a4u30c7u30a2u3001u53c2u7167u5148u3001u305du3057u3066u5b9fu884cu53efu80fdu306au30a4u30f3u30b5u30a4u30c8u3092u5f37u8abfu3057u3066 u30eau30b5u30fcu30c1u3092u9ad8u901fu5316u3057u307eu3059u3002

ud83dudcda u5f37u5316u3055u308cu305fu5b66u7fd2u30efu30fcu30afu30d5u30edu30fc u2014 u52d5u753bu306eu30a4u30f3u30b5u30a4u30c8u3092u5916u90e8u306eu77e5u8b58u30eau30ddu30b8u30c8u30eau3068u7d44u307fu5408u308fu305bu308bu3053u306eu3067u3001u7814u7a76u8005u3001u5b66u751fu3001u30b3u30f3u30c6u30f3u30c4u30afu30eau30a8u30a4u30bfu30fcu5411u3051u306bu3001u53ccu65b9u5411u306au3001u307eu305fu306fu30acu30a4u30c9u4ed8u304du306eu5b66u7fd2u4f53u9a13u3092u4f5cu6210u3057u307eu3059u3002


u307eu3068u3081 

u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306fu3001u52d5u753bu7406u89e3u304cu6211u3005u306eu7814u7a76u624bu6cd5u3084u52d5u753bu30b3u30f3u30c6u30f3u30c4u3068u306eu95a2u308fu308au65b9u3092u3069u306eu3088u3046u306bu5909u9769u3067u304eu308bu304bu3092u5bb6u73feu3057u305fu3002 TwelveLabs Analyzeu3092u4f7fu7528u3057u305fu6df1u5c64u52d5u753bu5206u6790u3068u3001Sonar by Perplexity u3092u4f7fu7528u3057u305fu77e5u8b58u691cu7d22u30fbu5f15u7528u3092u7d44u307fu5408u308fu305bu308bu3053u306eu3067u3001u52d5u753bu3092u53d7u52d5u7684u306au30e1u30c7u30a3u30a2u304bu3089u3001u69cbu9020u5316u3055u308cu305fu5f15u7528u53efu80fdu306au7814u7a76u30c4u30fcu30ebu3078u3068u5909u5faeu3055u305bu308bu30b3u30b9u30c6u30e0u3092u69cbu7bc3u3057u307eu3057u305fu3002u3053u308cu306bu3088u308au3001u7814u7a76u8005u3001u30afu30eau30a8u30a4u30bfu30fcu3001u5c02u9580u5bb6u304cu6700u3082u6709u610fu7fa9u3067u4fe1u983cu3067u304du308bu65b9u6cd5u3067u52d5u753bu30b3u30f3u30c6u30f3u30c4u3092u63a2u7d22u3059u308bu3053u306eu3092u53efu80fdu306bu3057u307eu3059u3002


u8ffdu52a0u30eau30bdu30fcu30b9

u52d5u753bu5206u6790u30a8u30f3u30b8u30f3u306e u30fc Pegasus-1.2 u306bu3064u3044u3066u3055u3089u306eu8a73u7d30u3092u5b66u3076u3053u306eu3042u308au307eu3059u3002TwelveLabs u306bu3064u3044u3066u3055u3089u306au308bu63a2u7d22u3092u884cu3044u3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u5206u6790u306eu7406u89e3u3092u6df1u3081u308bu305fu3081u306bu3001u4ee5u4e0bu306eu30eau30bdu30fcu30b9u3092u30c1u30a7u30c3u30afu3057u3066u304fu3060u3055u3044uff1a

  • u4ed6u306eu30e1u30fcu30b9u30fcu30b1u30fcu30b9u3092'u30a8u30afu30b9u30d7u30edu30fcu30e9u30fcu3059u308b: Sonar by Perplexity u3092u8a2au306du3066u3001u305du306eu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u6a5fu80fdu306bu3064u3044u3066u5b66u3076u3053u306eu3042u308au307eu3059u3002u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306bu5c0fu3055u306au5909u66f4u3092u52a0u3048u308bu3060u3051u3067u3001u3055u3089u306bu591au304fu306eu30e1u30fcu30b9u30fcu30b1u30fcu30b9u3092u63a2u7d22u3067u304du308bu3088u3046u306bu306au308au307eu3059u3002

  • u30d5u30a3u30fcu30d1u30fcu30c6u30a3u30fcu306bu53c2u52a0u3059u308b: TwelveLabs Discord u3067u3001u3053u306eu7d71u5408u306bu95a2u3059u308bu30d5u30a3u30fcu30c9u30d0u30c3u30afu3092u5171u6709u3057u3066u304fu3060u3055u3044u3002

  • u30c1u30e5u30fcu30c8u30eau30a2u30ebu3092u30a8u30afu30b9u30d7u30edu30fcu30e9u30fcu3059u308b: u30c1u30e5u30fcu30c8u30eau30a2u30ebu3092u3055u3089u306bu30c1u30a7u30c3u30af u2014 u6211u3005u306eu30afu30f3u30d7u30eau30d8u30f3u30b7u30d6u306au30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u3001TwelveLabs u306eu6a5fu80fdu3092u3055u3089u306bu6df1u304fu63a2u3063u3066u307fu307eu3057u30e7u3046u3002

u3053u308cu3089u306eu30eau30bdu30fcu30b9u3092u4f7fu7528u3057u3066u00e3u77e5u8b58u3092u62e1u3052u3001TwelveLabsu306eu52d5u753bu7406u89e3u6280u8853u3092u4f7fu7528u3057u305fu9769u65b0u306au30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u4f5cu6210u3059u308bu3053u306eu3092 u304au52e7u3081u3057u307eu3059u3002

u306fu3058u3081u306bu305b

u30a6u30a7u30d6u4e0au3067u30c6u30adu30b9u30c8u3092u691cu7d22u3059u308bu306eu3068u540cu3058u304fu3089u3044u7c21u5358u306bu52d5u753bu3092u691cu7d22u3067u304du3001u4fe1u983cu3067u304du308bu5f15u7528u5143u3068u3068u3082u306bあらゆるu30a4u30f3u30b5u30a4u30c8u3092u5f97u3089u308cu308bu3068u3057u305fu3089u3069u3046u3067u3057u30e7u30a6uff1f ud83cudfa5ud83dudd0d

u73feu5728u306eu3068u3053u308du3001u305du308cu306fu307eu3060u30a6u30a7u30d6u306bu6b20u3051u3066u3044u308bu30d4u30fcu30b9u306eu3072u3068u3064u3067u3059u3002u691cu7d22u30a8u30f3u30b8u30f3u306fu3001u7d50u679cu3092u5f97u308bu305fu3081u306eu5165u529bu3068u3057u3066u52d5u753bu3092u8003u616eu3057u3066u3044u307eu305bu3093u3002u3053u306eu305fu3081u3001u7814u7a76u8005u3001u30afu30eau30a8u30a4u30bfu30fcu3001u5c02u9580u5bb6u306fu3001u69cbu9020u5316u3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u62bdu51fau3057u305fu308au691cu8a3cu3057u305fu308au3059u308bu4fe1u983cu3067u304du308bu65b9u6cd5u304cu306au3044u307eu307eu3001u4f55u6642u9593u3082u306eu6620u50cfu3092u624bu52d5u3067u78bau8a8du305bu3056u308bu3092u5f97u306au3044u72b6u6cc1u306bu3042u308au307eu3059u3002

Video Deep Researchu306fu3001u7814u7a76u306eu305fu3081u306eu52d5u753bu306eu6349u3048u65b9u3092u5909u3048u307eu3059u3002u610fu5473u7684u306au52d5u753bu7406u89e3u3092u884cu3046 TwelveLabs Analyze pegasus-1.2 u3068u3001u5f15u7528u3092u88cfu4ed8u3051u305fu77e5u8b58u691cu7d22u3092u884cu3046 Sonar by Perplexity u3092u7d44u307fu5408u308fu305bu308bu3053u3068u3067u3001u52d5u753bu3092u691cu7d22u53efu80fdu3067u4fe1u983cu306eu304au3051u308bu7814u7a76u30eau30bdu30fcu30b9u3078u3068u5909u5faeu3055u305bu307eu3059u3002

u3053u306e Video Deep Research u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u304cu3069u306eu3088u3046u306bu52d5u4f5cu3059u308bu306eu304bu3001u305du3057u3066 TwelveLabs Python SDK u3068 Perplexity Sonar u3092u4f7fu7528u3057u305fu52d5u753bu7406u89e3u3068u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u306bu3088u3063u3066u3001u540cu69d8u306eu30bdu30eau30e5u30fcu30b7u30e7u30f3u3092u3069u306eu3088u3046u306bu69cbu7bc3u3067u304du308bu304bu3092u63a2u3063u3066u307fu307eu3057u30e7u3046u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30c7u30e2u306fu3053u3061u3089u304bu3089u4f53u9a13u3067u304du307eu3059uff1a Video Deep Research u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3


u524du63d0u6761u4ef6

  • TwelveLabs Playground u306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3066u3001API u30adu30fcu3092u767au884cu3057u307eu3059uff0e

  • Sonar u306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3001u30e2u30c7u30ebu306bu30a2u30afu30bbu30b9u3059u308bu305fu3081u306e API u30adu30fcu3092u767au884cu3057u307eu3059u3002 

  • u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30eau30ddu30b8u30c8u30eau306f Github u30eau30ddu30b8u30c8u30ea u306bu3042u308au307eu3059u3002

  • Pythonu3001Flasku3001Next.js u306eu77e5u8b58u304cu3042u308bu3053u3068u304cu671bu307eu3057u3044u3067u3059u3002


u30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3

u3053u306eu30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u52d5u753bu7406u89e3u3068u77e5u8b58u691cu7d22u304cu3001u3069u306eu3088u3046u306bu3057u3066u5168u304fu65b0u3057u3044u7814u7a76u624bu6cd5u3092u5207u308au958bu304fu3053u306eu3067u304du308bu304bu3092u5bb6u73feu3057u3066u3044u307eu305su3002

u30e2u30fcu30b6u30fcu306fu3001TwelveLabs API u30adu30fcu3092u63a5u7d9au3059u308bu3060u3051u3067u3001u52d5u753bu3092u30a2u30c3u30d7u30edu30fcu30c9u3059u308bu304bu3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu30aau30f3u30e9u30a4u30f3u304bu3089u9078u629eu3059u308bu3053u3068u304cu3067u304du307eu3059u3002u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du306eu5f8cu3001u30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u3066u69cbu9020u5316u3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u62bdu51fau3057u3001u305du308cu3089u3092u691cu8a3cu53efu80fdu306au53c2u7167u5148u306bu30eau30f3u30afu3055u305bu308bu3053u3068u3067u3001u52d5u753bu3068u4fe1u983cu3067u304du308bu7814u7a76u306eu67b6u3051u6a4bu3068u306au308au307eu3059u3002

u3053u3053u3067u306fu3001u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u6a5fu80fdu3092u642du8f09u3057u305fu72ecu81eau306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc3u30fbu62e1u5f35u3067u304du308bu3088u3046u3001u30b3u30fcu30c9u3068u30c7u30e2u306eu8a73u7d30u306au8acbu91c8u3092u884cu3044u307eu3059u3002


u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu52d5u4f5cu3057u304fu307f

u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f2u3064u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059u3002

  1. TwelveLabs API u30adu30fcu306eu4f7fu7528uff1au500bu4ebau306e TwelveLabs API u30adu30fcu3092u63a5u7d9au3057u3066u3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu81eau5206u306eu52d5u753bu306bu30a2u30afu30bbu30b9u3057u3001u64cdu4f5cu3057u307eu3059u3002u63a5u7d9au3059u308bu3068u3001u65e2u5b58u306eu30a4u30f3u30c7u30c3u30afu30b9 ID u3068u5bfeu5fdcu3059u308bu52d5u753bu3092u9078u629eu3067u304du307eu3059u3002

  2. u52d5u753bu306eu30a2u30c3u30d7u30edu30fcu30c9uff1au52d5u753bu304cu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu308bu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu30b7u30fcu30e0u30ecu30b9u306au30bbu30c3u30c8u30a2u30c3u30d7u306eu305fu3081u306bu30c7u30d5u30a9u30ebu30c8u306e TwelveLabs API u30adu30fcu3092u81eau52d5u7684u306bu4f7fu7528u3059u308bu3088u3046u306bu8a2du8a08u3055u308cu3066u3044u307eu3059u3002u30a2u30c3u30d7u30edu30fcu30c9u5f8cu3001u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u304cu3059u3050u306bu5f00u59cbu3055u308cu307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu5b8cu4e86u3059u308bu3068u3001u6700u8fd1u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu304cu6700u65b0u306eu5229u7528u53efu80fdu306au30b3u30f3u30c6u30f3u30c4u3068u3057u3066u8868u793au3055u308cu307eu3059u3002u3053u306eu6642u70b9u4ee5u964du306fu3001u4e21u65b9u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3067u3001u4ee5u4e0bu306bu8a18u8f09u3059u308bu624bu9806u306bu5f93u3063u3066u3001u30afu30a8u30eau3068u5f15u7528 u306eu30efu30fcu30afu30d5u30edu30fcu304cu307eu3063u305fu304fu540cu69d8u306bu9032u884cu3057u307eu3059u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu5b8cu5168u306au30efu30fcu30afu30d5u30edu30fcu306fu3001TwelveLabs u30afu30e9u30a4u30a2u30f3u30c8u306eu8a2du5b9au304bu308au59cbu307eu308au307eu3059u3002u3053u308cu306bu306fu3001u74b0u5883u5909u6570u3067u63d0u4f9bu3055u308cu305fu30adu30fcu3092u4f7fu7528u3059u308bu304bu3001u30e2u30fcu30b6u30fcu304cu30afu30e9u30a4u30a2u30f3u30c8u5074u304bu308fu81eau5206u306eu30adu30fcu3092u63a5u7d9au3057u3066u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu306bu30a2u30afu30bbu30b9u3067u304du308bu3088u3046u306bu3001TwelveLabs API u30adu30fcu3092u30bbu30c3u30c8u30a2u30c3u30d7u3059u308bu5fc5u8981u304cu3042u308au307eu3059u3002u30afu30e9u30a4u30a2u30f3u30c8u304cu8a2du5b9au3055u308cu308bu3068u3001u30d7u30edu30bbu30b9u306fu4ee5u4e0bu306bu793au3059u9806u6b21u306eu30d5u30edu30fcu306bu5f93u3044u307eu5ea6u3002 u2013

  1. u30a4u30f3u30c7u30c3u30afu30b9u306eu53d6u5f97 (Fetch Indexes) u2013 u63a5u7d9au3055u308cu305f TwelveLabs u30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u3082u305fu30a4u30f3u30c7u30c3u30afu30b9u306eu30eau30b9u30c8u3092u53d6u5f97u3057u307eu3059u3002

  2. u52d5u753bu306eu9078u629e (Select Video) u2013 u5206u6790u3057u305fu3044u30a4u30f3u30c7u30c3u30afu30b9u304bu3089u52d5u753bu3092u9078u629eu3057u307eu3059u3002

  3. u52d5u753bu306eu5206u6790 (Analyze Video) u2013 u6307u5b9au3055u308cu305fu30afu30a8u30eau3092u4f7fu7528u3057u3066u3001u9078u629eu3057u305fu52d5u753bu306eu30b3u30f3u30c6u30f3u30c4u5206u6790u3092u884cu3041u307eu3059u3002

  4. u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1 (Deep Research) u2013 u5206u6790u3055u308cu305fu56deu7b54u3001u69cbu9020u5316u3055u308cu305fu30d7u30edu30f3u30d7u30c8u3001u304au3088u3073u30e2u30fcu30b6u30fcu306eu30afu30a8u30eau3092u7d44u307fu5408u308fu305bu3001u305du306eu5185u5bb9u3092 Sonar u30eau30b5u30fcu30c1u30e2u30c7u30ebu306bu6e21u3057u3066u3001u3088u308au6df1u3044u63a8u8ad6u3068u5f15u7528u306eu88cfu4ed8u3051u306eu3042u308bu30a4u30f3u30b5u30a4u30c8u3092u5f97u307eu3059u3002

u3053u306eu69cbu9020u5316u3055u308cu305fu30efu30fcu30afu30d5u30edu30fcu306bu3088u308au3001u52d5u753bu306eu30a4u30f3u30c7u30c3u30afu30b9u5316u304bu3089u9ad8u5ea6u306au7814u7a76u307eu3067u30b9u30e0u30fcu30bau306bu9032u884cu3057u3001u30e2u30fcu30b6u30fcu306bu8a73u7d30u3067u30b3u30f3u30c6u30adu30b9u30c8u3092u5224u65adu3057u305fu51fau529bu3092u63d0u4f9bu3057u307eu3059u3002

u4e21u65b9u306eu30a2u30d7u30edu30fcu30c1u306fu3001u4ee5u4e0bu306eu30a2u30fcu30adu30c6u30afu30c1u30e3u56f3u306bu793au3055u308cu3066u3044u307eu3059u3002

u3053u306eu30d5u30edu30fcu306fu3001u30eau30b5u30fcu30c1u56deu7b54u304cu751fu6210u3055u308cu305fu5f8cu3001u30e2u30fcu30b6u30fcu304cu540cu3058u6587u8108u3067u3055u3089u306au308bu53c2u7167u5148u3084u6df1u3044u30a4u30f3u30b5u30a4u30c8u3092u6c42u3081u308bu8ffdu52a0u30afu30a8u30eau3092u884cu3048u308bu3088u3046u306bu8a2du8a08u3055u308cu3066u3044u307eu5ea6u3002u3053u308cu3089u306eu5f8cu7d9au30afu30a8u30eau306f Sonar u30eau30b5u30fcu30c1u30ebu30fcu30d7u306bu30d5u30a3u30fcu30c9u30d0u30c3u30afu3055u308cu3001u6587u8108u306eu7d99u7d9au6027u3092u7dadu6301u3057u306au304cu3089u65e2u5b58u306eu77e5u8b58u30d2u30fcu30d9u30fcu30b9u3092u62e1u5f35u3057u307eu3059u3002u3053u306eu53cdu5fa9u7684u306au8a2du8a08u306bu3088u308au3001u65b0u3057u3044u30afu30a8u30eau305au3064u304cu4e8bu524du306eu7d50u679cu306bu57fau3065u3044u3066u69cbu7bc3u3055u308cu3001u6bb5u968eu7684u306bu8c4au304bu3067u30b3u30f3u30c6u30adu30b9u30c8u3092u8003u616eu3057u305fu7814u7a76u51fau529bu3092u5f97u308bu3053u306eu304cu3067u304du307eu3059u3002


u6e96u5099u624bu9806

  1. TwelveLabs Playground u304bu3089u30a2u30afu30bbu30b9 API u30adu30fcu3092u53d6u5f97u3057u3001u74b0u5883u5909u6570u3092u8a2du5b9au3057u307eu3059u3002

  2. TwelveLabs Playground u3092u901au3058u3066 pegasus-1.2 u3092u9078u629eu3057u3001u30a4u30f3u30c7u30c3u30afu30b9u3092u4f5cu6210u3057u3001u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u7528u306e index_id u3092u53d6u5f97u3057u307eu3059u3002

  3. Github u304bu3089u30d7u30edu30b8u30a7u30afu30c8u3092u30afu30edu30fcu30f3u3057u307eu3059u3002

  4. Sonar by Perplexity u304bu3089 API KEY u3092u53d6u5f97u3057u307eu3059u3002

  5. TwelveLabs u3068 Sonar u306eu8a3cu660eu60c5u5831u3092u542bu3080 .env u30d5u30a1u30a4u30ebu3092u4f5cu6210u3057u307eu3059u3002u74b0u5883u8a2du5b9au306eu4ee5u4e0bu306fu3001u3053u3061u3089 u3067u78bau8a8du3067u304du307eu3059u3002

u3053u308cu3089u306eu624bu9806u304cu5b8cu4e86u3059u308bu3068u3001u958bu767au3092u590bu3081u308bu6e96u5099u304cu6574u3044u307eu3059uff01


u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30a2u30d7u30eau306eu30fcu30afu30b9u30ebu30fc

u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u306bu57fau3065u3044u3066u30a6u30a7u30d6u304bu3089u5f15u7528u60c5u5831u3084u95a2u9023u60c5u5831u3092u53d6u5f97u3067u304du308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu69cbu7bc3u65b9u6cd5u3092u5bb6u73feu3057u307eu3059u3002u3053u306eu30d7u30edu30b8u30a7u30afu30c8u3067u306fu3001u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306b Next.js u3092u3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u306bu306f Flask APIuff08CORSu6709u52b9u5316uff09u3092u4f7fu7528u3057u3066u307eu3059u3002u6211u3005u306eu4e3bu306eu30d5u30a9u30fcu30abu30b9u306fu3001u3053u306eu52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4e3bu8981u306au30d0u30c3u30afu30a8u30f3u30c3u30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu5b9fu88c5u3068u3001u5b8cu5168u306au74b0u5883u306eu30bbu30c3u30c8u30a2u30c3u30d7u3067u3059u3002

u8a73u7d30u306f u30bbu30c3u30c8u30a2u30c3u30d7u624bu9806u3068u5b8cu5168u306au30b3u30fcu30c9u69cbu9020u306bu3064u3044u3066u306fu3001GitHub u30eau30ddu30b8u30c8u30eau306e README.md u30d5u30a1u30a4u30ebu3092u53c2u7167u3057u3066u304fu3060u3055u3044u3002


1 - u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u5b9fu88c5u306eu30efu30fcu30afu30d5u30edu30fc

u30efu30fcu30afu30d5u30edu30fcu3067u3082u3063u3068u3082u91cdu8981u306au30b9u30c6u30actu306fu3001TwelveLabs API u30adu30fcu306eu521du671fu5316u3068u30cfu30f3u30c9u30eau30f3u30b0u3067u3059u3002u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u30c7u30d5u30a9u30ebu30c8u306eu4f7fu7528u306eu305fu3081u306bu74b0u5883u304bu3089u30adu30fcu3092u76f4u63a5u8aadu307fu8fbcu3080u304bu3001u30e2u30fcu30b6u30fcu304cu30afu30e9u30a4u30a2u30f3u30c8u3092u4ecbu3057u3066u72ecu81eau306e API u30adu30fcu3092u63d0u4f9bu3067u304du308bu3088u3046u306bu3057u307eu3059u3002

backend/service/twelvelabs_service.py (14-36u884cu76ee)

class TwelveLabsService:
    def __init__(self, api_key=None):
        # If no API key is provided, try to get it from environment variable
        if api_key is None:
            api_key = os.environ.get('TWELVELABS_API_KEY', '')
        self.api_key = api_key # Store API key in the instance
        self.client = TwelveLabs(api_key=api_key) # Intialize the TwelveLabs client


1.1 u30a4u30f3u30c7u30c3u30afu30b9u306eu53d6u5f97 (GET Indexes)

u30e2u30fcu30b6u30fcu304cu30ddu30fcu30bfu30ebu3092u901au3058u3066 TwelveLabs API u30adu30fcu3092u63a5u7d9au3059u308bu304bu3001u307eu305fu306fu74b0u5883u304bu3089u30adu30fcu304cu8decu307fu8fbcu307eu308cu308bu30c7u30d5u30a9u30ebu30c8u30e2u30fcu30c9u3092u4f7fu7528u3059u308bu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du306eu30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u3082u305fu3059u3079u3066u306eu30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3057u307eu3059u3002u53d6u5f97u3055u308cu305fu30c7u30fcu30bfu306fu69cbu9020u5316u3055u308cu3001u8868u793au306eu305fu3081u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu5c4au3051u3089u3082u307eu3059u00e3u3002

backend/service/twelvelabs_service.py (14-36u884cu76ee)

def get_indexes(self):
        try:
            print("Fetching indexes...")
            # Check if API key is available
            if not self.api_key:
                print("No API key available")
                return []
            
            # Use TwelveLabs client to get a list of indexes
            indexes = self.client.indexes.list()
            
            result = []
            for index in indexes:
                # Append a dictionary with relevant index details
                result.append({
                    "id": index.id,
                    "name": index.index_name
                })
                print(f"ID: {index.id}")
                print(f"  Name: {index.index_name}")
            
            return result
        except Exception as e:
            print(f"Error fetching indexes: {e}")
            return []


1.2 u5bfeu5fdcu3059u308bu30a4u30f3u30c7u30c3u30afu30b9 ID u306eu52d5u753bu30eau30b9u30c8u3092u53d6u5f97 (GET Videos)

u30e2u30fcu30b6u30fcu304cu30a4u30f3u30c7u30c3u30afu30b9u3092u9078u629eu3059u308bu306eu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu95a2u90a6 index_id u3092u8a18u9332u305eu3057u307eu3059u3002u3053u306e index_id u3092u4f7fu7528u3057u3066u3001u30b7u30b9u30c6u30e0u306fu305du306eu30a4u30f3u30c7u30c3u30afu30b9u306bu30eau30f3u30afu3055u308cu305fu3059u3079u3066u306eu52d5u753bu3092u53d6u5f97u3057u3066u8fd4u3059u95a2u9023u30e1u30bdu30c3u30c9u3092u547cu3073u51fau3057u307eu3059u3002

backend/service/twelvelabs_service.py (38-70u884cu76ee)

def get_videos(self, index_id, page=1):
        try:
            # Check if API key is available
            if not self.api_key:
                print("No API key available")
                return []
            
            # Use TwelveLabs client to get a list of videos
            videos_response = self.client.indexes.videos.list(index_id=index_id, page=page)
            
            result = []
            for video in videos_response.items:
                system_metadata = video.system_metadata
                hls_data = video.hls
                thumbnail_urls = hls_data.get('thumbnail_urls', []) if hls_data else []
                thumbnail_url = thumbnail_urls[0] if thumbnail_urls else None
                video_url = hls_data.get('video_url') if hls_data else None
                # Append a dictionary with relevant video details
                result.append({
                    "id": video.id,
                    "name": system_metadata.filename if system_metadata and system_metadata.filename else f'Video {video.id}',
                    "duration": system_metadata.duration if system_metadata else 0,
                    "thumbnail_url": thumbnail_url,
                    "video_url": video_url,
                    "width": system_metadata.width if system_metadata else 0,
                    "height": system_metadata.height if system_metadata else 0,
                    "fps": system_metadata.fps if system_metadata else 0,
                    "size": system_metadata.size if system_metadata else 0
                })
            
            return result
        except Exception as e:
            print(f"Error fetching videos for index {index_id}: {e}")
            return []


1.3 u52d5u753bu30b3u30f3u30c6u30f3u30c4u306eu5206u6790

u52d5u753bu304cu9078u629eu3055u308cu3001u30e2u30fcu30b6u30fcu304bu3089u30eau30b5u30fcu30c1u30afu30a8u30eau304cu63d0u4f9bu3055u308cu308bu3068u3001video_id u3068u30afu30a8u30eau306eu4e21u65b9u304cu52d5u753bu7406u89e3u306eu305fu3081u306b analyze u30e6u30fcu30c6u30a3u30eau30c6u30a3u306bu6e21u3055u308cu307eu3059u3002u30afu30a8u30eau306fu4e8bu524du306bu5b9au7fa9u3055u308cu305fu30d7u30edu30f3u30d7u30c8u306bu8ffdu52a0u3055u308cu3001u6587u8108u304cu5f37u5316u3055u308cu3001u6709u610fu7fa9u306au5206u6790u56deu7b54u304cu5f97u3089u308eu308bu3088u3046u306bu3057u307eu3059u3002u52d5u753bu5206u6790u306bu4f7fu7528u3055u308cu308bu30d7u30edu30f3u30d7u30c8u306f u3053u3061u3089 u306bu3042u308au307eu3059u3002

backend/service/twelvelabs_service.py (72-81u884cu76ee)

def analyze_video(self, video_id, prompt):
        try:
            # Call the TwelveLabs client to analyze the video
            analysis_response = self.client.analyze(
                video_id=video_id,
                prompt=prompt
            )
            return analysis_response.data
        except Exception as e:
            print(f"Error analyzing video {video_id}: {e}")
            raise e


1.4 u5206u6790u3053u307fu30b3u30f3u30c6u30f3u30c4u306eu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1

u521du671fu5206u6790u304fu304cu5b8cu4e86u3059u308bu306eu3068u3001u30efu30fcu30afu30d5u30edu30fcu306f Sonar u30e2u30c7u30ebu3092u4f7fu7528u3057u305fu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30d5u30a7u30fcu30bau306bu79fbu308au307eu3059u3002deep_research u547cu3073u51fau3057u306fu3001u30e2u30fcu30b6u30fcu306eu5143u306eu30afu30a8u30eau3001u30eau30b5u30fcu30c1u30d7u30edu30f3u30d7u30c8u3001u30eau30b5u30fcu30c1u7d50u679cu306e 3u3064u306eu8981u7d20u3092u7d44u307fu5408u308fu305bu305f1u3064u306e u30dau30a4u30edu30fcu30c9 u3092u69cbu7bc3u3057u3001u305du306eu69cbu9020u5316u3055u308cu305fu5165u529bu3092 Sonar u306bu9001u3063u3066u3055u3089u306au308bu51e6u7406u3092u884cu3044u307eu3059u3002Sonar u306fu3001u60c5u5831u6e90u306eu5f15u7528u3092u542bu3080u3001u30d6u30e9u30c3u30b7u30e5u30a2u30c3u30d7u3055u308cu305fu69cbu9020u5316u3055u308cu305fu56deu7b54u3092u8fd4u3057u307eu3059u3002u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u306eu30d7u30edu30f3u30d7u30c8u306f u3053u3061u3089 u306bu3042u308au307eu3059u3002

backend/service/sonar_service.py (13-52u884cu76ee)

def deep_research(self, query, timeout=180):
        try:
            # Ensure API key is available
            if not self.api_key:
                raise ValueError("API key is required")
            
            payload = {
                "model": "sonar",
                "messages": [
                    {"role": "user", "content": query}
                ]
            }
            
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json"
            }
            
            # POST request to the API endpoint with timeout
            response = requests.post(
                self.base_url, 
                json=payload, 
                headers=headers, 
                timeout=timeout
            )
            
            # Check if the response was successful
            if response.status_code == 200:
                return response.json()
            else:
                print(f"Error: {response.status_code} - {response.text}")
                return {"error": f"API request failed with status {response.status_code}"}
                
        except requests.exceptions.Timeout:
            print("Request timed out")
            return {"error": "Request timed out - Sonar research is taking too long"}
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")
            return {"error": f"Network error: {str(e)}"}
        except Exception as e:
            print(f"Error in deep_research: {e}")
            return {"error": str(e)}

u3053u3053u306bu306f sonaru3001sonar-reasoningu3001sonar-deep-research u306au3069u3001u8907u6570u306e Sonar u30d0u30eau30a2u30f3u30c8u304cu5229u7528u53efu80fdu3067u3059u3002sonar-deep-research u30e2u30c7u30ebu306f reasoning_effort u8a2du5b9auff08low, medium, highuff09u3092u30b5u30ddu30fcu30c8u3057u3066u304au308au3001u30c7u30d5u30a9u30ebu30c8u306fu5206u6790u3068u901fu5ea6u306eu30d0u30e9u30f3u30b9u3092u53d6u3063u305f medium u3067u3059u3002u63a8u8ad6u30d7u30edu30bbu30b9u3092 u201chighu201d u306bu5411u4e0au3055u305bu308bu3068u3001u3088u308au591au304fu306eu5f15u7528u3068u6df1u3044u30a4u30f3u30b5u30a4u30c8u304cu5f97u3089u308cu307eu3059u304cu3001u56deu7b54u6642u9593u3068u30c8u30fcu30afu30f3u306eu4f7fu7528u91cfu3082u5897u52a0u3059u308bu305fu3081u3001u5fc5u8981u306au5fb9u5e95u3055u3001u9045u5ef6u8a31u5bb9u5ea6u3001u30b3u30b9u30c8u306bu57fau3065u3044u3066u30e2u30c7u30ebu3068u52aau529bu30ecu30d9u30ebu3092u9078u629eu3057u3066u304fu3060u3055u3044u3002

u30a2u30d7u30eau306eu30e2u30c7u30ebu540du3092 sonar-deep-research u306bu5909u66f4u3059u308bu3060u3051u3062u3001u30b7u30b9u30c6u30e0u306fu3088u308au8a73u7d30u306au63a8u8ad6u3068u591au304fu306eu5f15u7528u3092u751fu6210u3057u307eu3059u3002u3053u306eu8a2du5b9au306bu3088u308au3001u30c7u30d5u30a9u30ebu30c8u306e sonar u30e2u30c7u30ebu3068u6bd4u8f03u3057u3066u3001u3088u308au6df1u3044u7814u7a76u3068u8c4au304bu306eu30a4u30f3u30b5u30a4u30c8u304cu5229u7528u3067u304du307eu3059u3002u4ee5u4e0bu306fu3001u751fu6210u3055u308cu305fu5f37u5316u3055u308cu305fu56deu7b54u306eu30c7u30e2u3067u3059 u2014


1.5 u30eau30b5u30fcu30c1u306eu305fu3081u306eu95a2u6570u547cu3073u51fau3057u30efu30fcu30afu30d5u30edu30fc

u30efu30fcu30afu30d5u30edu30fcu306f TwelveLabs u30afu30e9u30a4u30a2u30f3u30c8u306eu8a2du5b9au304bu308au59cbu307eu308au3001API u30adu30fcu3001u30a4u30f3u30c7u30c3u30afu30b9 IDu3001u52d5u753b ID u304cu9069u5207u306bu691cu8a3cu3055u308cu3066u3044u308bu3053u3068u3092u78bau306bu3057u307eu3059u3002u30bbu30c3u30c8u30a2u30c3u30d7u304fu3055u308cu308bu306eu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f TwelveLabs u30b5u30fcu30d3u30b9u304bu3081u52d5u753bu306eu8a73u7d30u3092u53d6u5f97u3057u307eu3059u3002u3053u308cu306bu3088u308au3001u3055u3089u306au308bu51e6u7406u306bu9032u3080u524du306bu3001u9078u629eu3057u305fu52d5u753bu306eu30b3u30f3u30c6u30adu30b9u30c8u304cu660eu78bau306bu8a2du5b9au3055u308cu307eu3059u3002u7d50u679cu306f yield u3092u4f7fu7528u3057u3066u30eau30a2u30ebu30bfu30a4u30e0u3067u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu3001u30d7u30edu30bbu30b9u5168u4f53u306eu5b8cu4e86u3092u5f85u3064u3053u3068u306au304fu3001UI u3092u6bb5u968eu7684u306bu66f4u65b0u3059u308bu3053u306eu3042u308au307eu3059u3002

u6b21u306bu3001u30b7u30b9u30c6u30e0u306fu5b9au7fa9u3055u308cu305f TwelveLabs u30b5u30fcu30d3u30b9 u30afu30e9u30b9u306e analyze_video u30e1u30bdu30c3u30c9u3092u547cu3073u51fau3057u3001u9078u629eu3057u305f video_id u3068u5206u6790u30d7u30edu30f3u30d7u30c8u3092u6e21u3057u307eu3059u3002u3053u306eu5206u6790u306eu51fau529bu306fu3001u4e8bu524du306bu5b9au7fa9u3055u308cu305fu30c6u30f3u30d7u30ecu30fcu30c8u3067u69cbu6210u3055u308cu305fu5f37u5316u3055u308cu305fu30eau30b5u30fcu30c1u30afu30a8u30eau306bu7d44u307fu8fbcu307eu308cu307eu3059u3002u3053u306eu30c6u30f3u30d7u30ecu30fcu30c8u306fu3001u6307u793au3068u3057u3066 Markdown u30d9u30fcu30b9u306eu56deu7b54u30d5u30a9u30fcu30deu30c3u30c8u3092u5f37u5236u3057u3001u5206u6790u7d50u679cu3068u30e2u30fcu30b6u30fcu306eu30afu30a8u30eau306eu4e21u65b9u304fu4e00u8cabu3057u305fu69cbu9020u306bu5408u308fu305bu3089u308cu308bu3088u3046u306bu3057u307eu3059u3002u305du306eu5f8cu3001u5f37u5316u3055u308cu305fu30afu30a8u30eau306f Sonar u30b5u30fcu30d3u30b9u306bu9001u3089u308cu3066 u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1 u304cu884cu308fu308cu3001u30d6u30e9u30cbu30e5u30a2u30c3u30d7u3055u308cu305fu5f15u302eu88cfu4ed8u3051u306eu3042u308bu56deu7b54u304cu751fu6210u3055u308cu307eu3059u3002

backend/routes/api_routes.py (31-162u884cu76ee)

def generate_workflow(twelvelabs_api_key, index_id, video_id, analysis_prompt, research_query, research_prompt_template):
    # Input validation
    if not twelvelabs_api_key:
        yield json.dumps({'type': 'error', 'message': 'TwelveLabs API key is required'}) + '\n'
        return
    if not index_id or not video_id:
        yield json.dumps({'type': 'error', 'message': 'Index ID and Video ID are required'}) + '\n'
        return
    if not research_query:
        yield json.dumps({'type': 'error', 'message': 'Research query is required'}) + '\n'
        return

    try:
        twelvelabs_service = TwelveLabsService(api_key=twelvelabs_api_key)
        
        # Step 1: Get video details
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'video_details',
            'message': 'Fetching video details...',
            'progress': 0
        }) + '\n'

        video_details = twelvelabs_service.get_video_details(index_id, video_id)
        if not video_details:
            yield safe_json_dumps({'type': 'error', 'message': 'Could not retrieve video details'}) + '\n'
            return

        yield safe_json_dumps({
            'type': 'data',
            'step': 'video_details',
            'data': {
                'id': video_details.get('_id', ''),
                'filename': video_details.get('system_metadata', {}).get('filename', ''),
                'duration': video_details.get('system_metadata', {}).get('duration', 0)
            },
            'progress': 33
        }) + '\n'

        # Step 2: Analyze video
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'analysis',
            'message': 'Analyzing video content...',
            'progress': 33
        }) + '\n'

        analysis_result = twelvelabs_service.analyze_video(video_id, analysis_prompt)
        yield safe_json_dumps({
            'type': 'data',
            'step': 'analysis',
            'data': analysis_result,
            'progress': 66
        }) + '\n'

        # Step 3: Research with context
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'research',
            'message': 'Conducting deep research...',
            'progress': 66
        }) + '\n'

        enhanced_query = research_prompt_template.format(
            analysis_result=analysis_result,
            research_query=research_query
        )
        
        sonar_service = SonarService()
        research_result = sonar_service.deep_research(enhanced_query, timeout=180)

        if 'error' in research_result:
            yield safe_json_dumps({'type': 'error', 'message': f'Research failed: {research_result["error"]}'}) + '\n'
            return

        # Extract research content
        research_content = ""
        if research_result and research_result.get('choices'):
            research_content = research_result['choices'][0].get('message', {}).get('content', '')
        
        # Send research content in chunks if large
        max_chunk_size = 10000
        if len(research_content) > max_chunk_size:
            for i in range(0, len(research_content), max_chunk_size):
                chunk = research_content[i:i + max_chunk_size]
                is_final = (i + max_chunk_size) >= len(research_content)
                
                yield safe_json_dumps({
                    'type': 'research_chunk',
                    'content': chunk,
                    'is_final': is_final,
                    'progress': 80 + (i / len(research_content)) * 20
                }) + '\n'
            
            # Send completion with chunked content indicator
            yield safe_json_dumps({
                'type': 'complete',
                'data': {
                    'research': {
                        'choices': [{
                            'message': {
                                'content': '[CHUNKED_CONTENT]'
                            }
                        }],
                        'citations': research_result.get('citations', [])[:10],
                        'usage': research_result.get('usage', {})
                    },
                    'sources': research_result.get('search_results', [])[:10]
                },
                'progress': 100
            }) + '\n'
        else:
            # Send completion with research data
            yield safe_json_dumps({
                'type': 'complete',
                'data': {
                    'research': {
                        'choices': [{
                            'message': {
                                'content': research_content
                            }
                        }],
                        'citations': research_result.get('citations', [])[:10],
                        'usage': research_result.get('usage', {})
                    },
                    'sources': research_result.get('search_results', [])[:10]
                },
                'progress': 100
            }) + '\n'

    except Exception as e:
        yield safe_json_dumps({'type': 'error', 'message': str(e)}) + '\n'

u5927u898fu6a21u306au30eau30b5u30fcu30c1u51fau529bu3092u51e6u7406u3059u308bu305fu3081u306bu3001u30efu30fcu30afu30d5u30edu30fcu306fu56deu7b54u306eu5206u5272uff08u30c1u30e3u30f3u30afu5316uff09u3092u5b9eu88c5u3057u3066u3044u307eu3059u3002Sonar u306fu8a73u7d30u306au63a8u8ad6u3068u591au304fu306eu5f15u7528u3092u542bu3080u5e83u7bc4u56f2u306au30b3u30f3u30c6u30f3u30c4u3092u8fd4u3059u3053u306eu304cu3042u308bu305fu3081u30011u3064u306eu5927u304du306a JSON u3068u3057u3066u9001u4fe1u3059u308bu306eu306f u30dau30a4u30edu30fcu30c9 u30b5u30a4u30bau5236u9650u3092u8d85u3048u3001u30b7u30eau30a2u30e9u30a4u30bcu30fcu30b7u30e7u30f3u30a8u30e9u30fcu3092u5f15u304du8d77u3053u3059u30eau30b9u30afu304cu3042u308au307eu3059u3002u3053u308cu3092u9632u3050u305fu3081u3001u56deu7b54u306fu7ba1u7406u53efu80fdu306au30c1u30e3u30f3u30afu306bu5206u5272u3055u308cu3001u9806u6b21u30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu307eu3059u3002u3053u306eu8a2du5b9au306fu30b9u30b1u30fcu30e9u30d3u30eau30c6u30a3u3092u78bau4fddu305fu3001u30cdu30c3u30c8u30efu30fcu30afu306eu30dcu30c8u30ebu30cdu30c3u30afu3092u56deu907fu3057u3001u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306eu5fdcu7b54u6027u3092u7dadu6301u3057u307eu3059u3002


2 - u52d5u753bu30a2u30c3u30d7u30edu30fcu30c9u30a4u30f3u30c7u30c3u30afu30b9u5316u30efu30fcu30afu30d5u30edu30fcu306eu8981u70b9

u3082u30461u3064u306eu30efu30fcu30afu30d5u30edu30fcu3067u306fu3001u4e8bu524du306eu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu306bu4f9du5b58u3059u308bu306eu3067u306fu306au304fu3001u30e2u30fcu30b6u30fcu304cu65b0u3057u3044u52d5u753bu30d5u30a1u30a4u30ebu3092u76f4u63a5u30a2u30c3u30d7u30edu30fcu30c9u3057u307eu3059u3002upload_video_file u30e1u30bdu30c3u30c9u306fu3001API u30adu30fcu3001u30a3u30f3u30c7u30c3u30afu30b9 IDu3001u30d5u30a1u30a4u30ebu30d1u30b9u306eu5fc5u8981u306au5165u529bu3092u691cu8a3cu3059u308bu3053u3068u3067u3001u3053u306eu30d7u30edu30bbu30b9u3092u51e6u7406u3057u307eu3059u3002u691cu8a3cu3055u308cu308bu306eu3068u3001TwelveLabs u306eu30bfu30b9u30afu30a8u30f3u30c3u30c9u30ddu30a4u30f3u30c3u30c8u306bu30bfu30b9u30af u30eau30afu30a8u30b9u30c8 u3092u958bu59cbu3057u3001u52d5u753bu30d5u30a1u30a4u30ebu304cu6dfbu4ed8u3055u308cu305fu30a2u30c3u30d7u30edu30fcu30c9 u30bfu30b9u30af u3092u4f5cu6210u3057u307eu3059u3002u30bfu30b9u30af u306eu4f5cu6210u304cu6210u529fu3059u308bu3068u3001u30bfu30b9u30af ID u304fu8fd4u3055u308cu3001u3053u308cu3092u4f7fu7528u3057u3066u30a4u30f3u30c7u30c3u30afu30b9u5316u306eu30b9u30bfu30fcu30bfu30b9u3092u76e3u8996u3057u307eu5ea6u3002

u305du306eu5f8cu3001u3053u306eu30e1u30bdu30c3u30c9u306fu30ddu30fcu30eau30f3u30b0 u30ebu30fcu30d7u306bu5165u308au3001u5b8cu4e86u3059u308bu304bu3001u5931u6557u3059u308bu304bu3001u307eu305fu306fu8a2du5b9au3055u308cu305fu30bfu30a4u30e0u30a2u30a6u30c8u306bu9054u3059u308bu307eu3067u3001u5b9au671fu7684u306bu30bfu30b9u30af u30b9u30bfu30fcu30bfu30b9u3092u78bau8a8du3057u307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304fu6210u529fu3059u308bu306eu3068u3001u56deu7b54u306bu306fu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu3092u4e00u610fu306bu8b58u5225u3059u308b video_id u304cu542bu307eu308cu3001u305du306eu52d5u753bu306fu3059u3050u306bu3055u3089u306au308bu5206u6790u306bu5229u7528u3067u304du308bu3088u3046u306bu306au308au307eu3059u3002u3053u308cu306bu3088u308eu3001u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu304cu30ddu30fcu30bfu30ebu4e0au3067u6700u65b0u306eu5229u7528u53efu80fdu306au52d5u753bu306bu306au308au307eu3059u3002u5931u6557u3084u30bfu30a4u30e0u30a2u30a6u30c8u306eu5830u5208u306fu3001u9069u5207u306au30a8u30e9u30fc u30e1u30c3u30bbu30fcu30b8u304fu8fd4u3055u308cu3001u30a2u30c3u30d7u30edu30fcu30c9u3068u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u306bu5b9fu8aadu306au30a8u30e9u30fc u30cfu30f3u30c9u30eau30f3u30b0u3092u63d0u4f9bu3057u307eu3059u3002

backend/service/twelvelabs_service.py (145-207u884cu76ee)

def upload_video_file(self, index_id: str, file_path: str, timeout_seconds: int = 900):
        import sys
        try:
            if not self.api_key:
                return {"error": "Missing TwelveLabs API key"}
            if not index_id:
                return {"error": "Missing index_id"}
            if not os.path.exists(file_path):
                return {"error": f"File not found: {file_path}"}
            
            print(f"Starting upload for file: {file_path}", file=sys.stderr)

            tasks_url = "https://api.twelvelabs.io/v1.3/tasks"
            headers = {
                "x-api-key": self.api_key
            }

            # Create upload task
            with open(file_path, "rb") as f:
                files = {
                    "video_file": (os.path.basename(file_path), f)
                }
                data = {
                    "index_id": index_id
                }
                resp = requests.post(tasks_url, headers=headers, files=files, data=data)

            if resp.status_code not in (200, 201):
                return {"error": f"Failed to create upload task: {resp.status_code} {resp.text}"}

            resp_json = resp.json() if resp.text else {}
            task_id = resp_json.get("id") or resp_json.get("task_id") or resp_json.get("_id")
            if not task_id:
                return {"error": f"No task id returned: {resp_json}"}

            # Poll task until ready
            import time
            start_time = time.time()
            print(f"Starting to poll task {task_id} for completion...", file=sys.stderr)
            
            while time.time() - start_time < timeout_seconds:
                r = requests.get(f"{tasks_url}/{task_id}", headers=headers)
                if r.status_code != 200:
                    time.sleep(2)
                    continue
                task = r.json() if r.text else {}
                status = task.get("status")
                print(f"Task {task_id} status: {status}", file=sys.stderr)
                
                if status in ("ready", "completed"):
                    video_id = task.get("video_id") or (task.get("data") or {}).get("video_id")
                    print(f"Indexing completed successfully! Video ID: {video_id}", file=sys.stderr)
                    return {"status": status, "video_id": video_id, "task": task}
                if status in ("failed", "error"):
                    print(f"Indexing failed with status: {status}", file=sys.stderr)
                    return {"error": f"Indexing failed with status {status}", "task": task}
                time.sleep(2)

            print(f"Upload timed out after {timeout_seconds} seconds", file=sys.stderr)
            return {"error": "Upload timed out"}

u5f8cu7d9au306eu30efu30fcu30afu30d5u30edu30fc u30d4u30d7u30e9u30a4u30f3u306fu3001u52d5u753bu304cu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu3066u30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu308du306eu3068u3001u751fu6210u3055u308cu305f video_id u304cu5206u6790u3001u30eau30b5u30fcu30c1u5f37u5316u3001u304au3088u3073u5f15u7528u306eu88cfu4ed8u3051u306eu3042u308bu56deu7b54u306eu30efu30fcu30afu30d5u30edu30fcu306bu6e21u3055u308cu3001u4e8bu524du306bu8aacu660eu3057u305fu306eu3068u540cu3058u30b7u30fcu30b1u30f3u30b9u306bu5f93u3044u307eu3059u3002u3053u308cu306bu3088u308au3001u7d71u4e00u3055u308cu305fu30efu30fcu30afu30d5u30edu30fcu3092u7dadu6301u3057u306au304cu3089u3001u30c7u30d5u30a9u30ebu30c8u30e2u30fcu30c9uff08u4e8bu524du306fu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753buff09u3068u9ec4u66ffu30e2u30fcu30c9uff08u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753buff09u306eu9593u306eu4e00u8cabu6027u304cu78bau4fddu3055u308cu307eu3059u3002u4ee5u4e0bu306fu3001u52d5u753bu306eu30a2u30c3u30d7u30edu30fcu30c9u3001u30a4u30f3u30c7u30c3u30afu30b9u5316u306eu5b9fu884cu3001u304au3088u3073u5b8cu5168u306au30d4u30d7u30e9u30a4u30f3u306eu5b9fu884cu30d7u30edu30bbu30b9u3092u5bb6u73feu3059u308bu30afu30a4u30c3u30afu30c7u30e2u3067u3059 u2014

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f TwelveLabs API u30adu30fcu3092u30afu30e9u30a4u30a2u30f3u30c8u5074u3067u76f4u63a5u51e6u7406u3059u308bu3053u306eu3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059u3002u3053u308cu306bu3088u308au3001u30e2u30fcu30b6u30fcu306fu72ecu81eau306e API u30adu30fcu3092u63a5u7d9au3059u308bu67d4u8edfu6027u304cu5f97u3089u308cu3001u30c7u30d5u30a9u30ebu30c8u306eu30adu30fcu306bu4f9du5b58u3059u308bu3053u306eu306au304fu3001u4e8bu524du306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu3092u5206u6790u3057u3001u7814u7a76u306fu305du306eu52d5u753bu3067u884cu3048u308bu3088u3046u306bu306au308au307eu3059u3002


u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u3055u3089u306bu5b9fu9a13u3059u308bu305fu3081u306eu30a2u30a4u30c7u30a2

u52d5u753bu7406u89e3u304cu3069u306eu3088u3046u306bu3057u3066u691cu8a3cu53efu80fdu306au7814u7a76u306bu63a5u7d9au3055u308cu308bu304bu3092u63a2u308bu3053u306eu306fu3001u3055u3089u306bu5f37u529bu306au30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3078u306eu6249u3092u958bu304du307eu3059u3002TwelveLabs Analyze u3068 Sonar by Perplexity u3092u4f7fu7528u3057u3066u3001u4ee5u4e0bu306eu3088u3046u306au5b9fu9a13u7684u306au65b9u5411u6027u3092u8a66u3059u3053u306eu3042u308au307eu3059 u2014

ud8d1udd0d u6df1u5c64u52d5u753bu30d5u30a1u30afu30c8u30c1u30a7u30c3u30af u2014 u62bdu51fau3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u4fe1u983cu3067u304du308bu60c5u5831u6e90u3084u5f15u7528u5143u306bu30eau30f3u30afu3055u305eu308bu3053u306eu3067u3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u5185u306eu767au8a00u3084u4e3bu5f35u3092u81eau52d5u7684u306bu691cu8a3cu3057u307eu3059u3002

ud83dudcc3 u610fu5473u7684u30eau30b5u30fcu30c1u30ecu30d3u30e5u30fc u2014 u52d5u753bu30b3u30f3u30c6u30f3u30c4u306eu69cbu9020u5316u3055u308cu305fu8981u7d04/u30ecu30dccu30e5u30fcu3092u751fu6210u3057u3001u4e3bu8981u306au30a2u30a4u30c7u30a2u3001u53c2u7167u5148u3001u305du3057u3066u5b9fu884cu53efu80fdu306au30a4u30f3u30b5u30a4u30c8u3092u5f37u8abfu3057u3066 u30eau30b5u30fcu30c1u3092u9ad8u901fu5316u3057u307eu3059u3002

ud83dudcda u5f37u5316u3055u308cu305fu5b66u7fd2u30efu30fcu30afu30d5u30edu30fc u2014 u52d5u753bu306eu30a4u30f3u30b5u30a4u30c8u3092u5916u90e8u306eu77e5u8b58u30eau30ddu30b8u30c8u30eau3068u7d44u307fu5408u308fu305bu308bu3053u306eu3067u3001u7814u7a76u8005u3001u5b66u751fu3001u30b3u30f3u30c6u30f3u30c4u30afu30eau30a8u30a4u30bfu30fcu5411u3051u306bu3001u53ccu65b9u5411u306au3001u307eu305fu306fu30acu30a4u30c9u4ed8u304du306eu5b66u7fd2u4f53u9a13u3092u4f5cu6210u3057u307eu3059u3002


u307eu3068u3081 

u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306fu3001u52d5u753bu7406u89e3u304cu6211u3005u306eu7814u7a76u624bu6cd5u3084u52d5u753bu30b3u30f3u30c6u30f3u30c4u3068u306eu95a2u308fu308au65b9u3092u3069u306eu3088u3046u306bu5909u9769u3067u304eu308bu304bu3092u5bb6u73feu3057u305fu3002 TwelveLabs Analyzeu3092u4f7fu7528u3057u305fu6df1u5c64u52d5u753bu5206u6790u3068u3001Sonar by Perplexity u3092u4f7fu7528u3057u305fu77e5u8b58u691cu7d22u30fbu5f15u7528u3092u7d44u307fu5408u308fu305bu308bu3053u306eu3067u3001u52d5u753bu3092u53d7u52d5u7684u306au30e1u30c7u30a3u30a2u304bu3089u3001u69cbu9020u5316u3055u308cu305fu5f15u7528u53efu80fdu306au7814u7a76u30c4u30fcu30ebu3078u3068u5909u5faeu3055u305bu308bu30b3u30b9u30c6u30e0u3092u69cbu7bc3u3057u307eu3057u305fu3002u3053u308cu306bu3088u308au3001u7814u7a76u8005u3001u30afu30eau30a8u30a4u30bfu30fcu3001u5c02u9580u5bb6u304cu6700u3082u6709u610fu7fa9u3067u4fe1u983cu3067u304du308bu65b9u6cd5u3067u52d5u753bu30b3u30f3u30c6u30f3u30c4u3092u63a2u7d22u3059u308bu3053u306eu3092u53efu80fdu306bu3057u307eu3059u3002


u8ffdu52a0u30eau30bdu30fcu30b9

u52d5u753bu5206u6790u30a8u30f3u30b8u30f3u306e u30fc Pegasus-1.2 u306bu3064u3044u3066u3055u3089u306eu8a73u7d30u3092u5b66u3076u3053u306eu3042u308au307eu3059u3002TwelveLabs u306bu3064u3044u3066u3055u3089u306au308bu63a2u7d22u3092u884cu3044u3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u5206u6790u306eu7406u89e3u3092u6df1u3081u308bu305fu3081u306bu3001u4ee5u4e0bu306eu30eau30bdu30fcu30b9u3092u30c1u30a7u30c3u30afu3057u3066u304fu3060u3055u3044uff1a

  • u4ed6u306eu30e1u30fcu30b9u30fcu30b1u30fcu30b9u3092'u30a8u30afu30b9u30d7u30edu30fcu30e9u30fcu3059u308b: Sonar by Perplexity u3092u8a2au306du3066u3001u305du306eu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u6a5fu80fdu306bu3064u3044u3066u5b66u3076u3053u306eu3042u308au307eu3059u3002u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306bu5c0fu3055u306au5909u66f4u3092u52a0u3048u308bu3060u3051u3067u3001u3055u3089u306bu591au304fu306eu30e1u30fcu30b9u30fcu30b1u30fcu30b9u3092u63a2u7d22u3067u304du308bu3088u3046u306bu306au308au307eu3059u3002

  • u30d5u30a3u30fcu30d1u30fcu30c6u30a3u30fcu306bu53c2u52a0u3059u308b: TwelveLabs Discord u3067u3001u3053u306eu7d71u5408u306bu95a2u3059u308bu30d5u30a3u30fcu30c9u30d0u30c3u30afu3092u5171u6709u3057u3066u304fu3060u3055u3044u3002

  • u30c1u30e5u30fcu30c8u30eau30a2u30ebu3092u30a8u30afu30b9u30d7u30edu30fcu30e9u30fcu3059u308b: u30c1u30e5u30fcu30c8u30eau30a2u30ebu3092u3055u3089u306bu30c1u30a7u30c3u30af u2014 u6211u3005u306eu30afu30f3u30d7u30eau30d8u30f3u30b7u30d6u306au30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u3001TwelveLabs u306eu6a5fu80fdu3092u3055u3089u306bu6df1u304fu63a2u3063u3066u307fu307eu3057u30e7u3046u3002

u3053u308cu3089u306eu30eau30bdu30fcu30b9u3092u4f7fu7528u3057u3066u00e3u77e5u8b58u3092u62e1u3052u3001TwelveLabsu306eu52d5u753bu7406u89e3u6280u8853u3092u4f7fu7528u3057u305fu9769u65b0u306au30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u4f5cu6210u3059u308bu3053u306eu3092 u304au52e7u3081u3057u307eu3059u3002

u306fu3058u3081u306bu305b

u30a6u30a7u30d6u4e0au3067u30c6u30adu30b9u30c8u3092u691cu7d22u3059u308bu306eu3068u540cu3058u304fu3089u3044u7c21u5358u306bu52d5u753bu3092u691cu7d22u3067u304du3001u4fe1u983cu3067u304du308bu5f15u7528u5143u3068u3068u3082u306bあらゆるu30a4u30f3u30b5u30a4u30c8u3092u5f97u3089u308cu308bu3068u3057u305fu3089u3069u3046u3067u3057u30e7u30a6uff1f ud83cudfa5ud83dudd0d

u73feu5728u306eu3068u3053u308du3001u305du308cu306fu307eu3060u30a6u30a7u30d6u306bu6b20u3051u3066u3044u308bu30d4u30fcu30b9u306eu3072u3068u3064u3067u3059u3002u691cu7d22u30a8u30f3u30b8u30f3u306fu3001u7d50u679cu3092u5f97u308bu305fu3081u306eu5165u529bu3068u3057u3066u52d5u753bu3092u8003u616eu3057u3066u3044u307eu305bu3093u3002u3053u306eu305fu3081u3001u7814u7a76u8005u3001u30afu30eau30a8u30a4u30bfu30fcu3001u5c02u9580u5bb6u306fu3001u69cbu9020u5316u3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u62bdu51fau3057u305fu308au691cu8a3cu3057u305fu308au3059u308bu4fe1u983cu3067u304du308bu65b9u6cd5u304cu306au3044u307eu307eu3001u4f55u6642u9593u3082u306eu6620u50cfu3092u624bu52d5u3067u78bau8a8du305bu3056u308bu3092u5f97u306au3044u72b6u6cc1u306bu3042u308au307eu3059u3002

Video Deep Researchu306fu3001u7814u7a76u306eu305fu3081u306eu52d5u753bu306eu6349u3048u65b9u3092u5909u3048u307eu3059u3002u610fu5473u7684u306au52d5u753bu7406u89e3u3092u884cu3046 TwelveLabs Analyze pegasus-1.2 u3068u3001u5f15u7528u3092u88cfu4ed8u3051u305fu77e5u8b58u691cu7d22u3092u884cu3046 Sonar by Perplexity u3092u7d44u307fu5408u308fu305bu308bu3053u3068u3067u3001u52d5u753bu3092u691cu7d22u53efu80fdu3067u4fe1u983cu306eu304au3051u308bu7814u7a76u30eau30bdu30fcu30b9u3078u3068u5909u5faeu3055u305bu307eu3059u3002

u3053u306e Video Deep Research u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u304cu3069u306eu3088u3046u306bu52d5u4f5cu3059u308bu306eu304bu3001u305du3057u3066 TwelveLabs Python SDK u3068 Perplexity Sonar u3092u4f7fu7528u3057u305fu52d5u753bu7406u89e3u3068u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u306bu3088u3063u3066u3001u540cu69d8u306eu30bdu30eau30e5u30fcu30b7u30e7u30f3u3092u3069u306eu3088u3046u306bu69cbu7bc3u3067u304du308bu304bu3092u63a2u3063u3066u307fu307eu3057u30e7u3046u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30c7u30e2u306fu3053u3061u3089u304bu3089u4f53u9a13u3067u304du307eu3059uff1a Video Deep Research u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3


u524du63d0u6761u4ef6

  • TwelveLabs Playground u306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3066u3001API u30adu30fcu3092u767au884cu3057u307eu3059uff0e

  • Sonar u306bu30b5u30a4u30f3u30a2u30c3u30d7u3057u3001u30e2u30c7u30ebu306bu30a2u30afu30bbu30b9u3059u308bu305fu3081u306e API u30adu30fcu3092u767au884cu3057u307eu3059u3002 

  • u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu30eau30ddu30b8u30c8u30eau306f Github u30eau30ddu30b8u30c8u30ea u306bu3042u308au307eu3059u3002

  • Pythonu3001Flasku3001Next.js u306eu77e5u8b58u304cu3042u308bu3053u3068u304cu671bu307eu3057u3044u3067u3059u3002


u30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3

u3053u306eu30c7u30e2u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u52d5u753bu7406u89e3u3068u77e5u8b58u691cu7d22u304cu3001u3069u306eu3088u3046u306bu3057u3066u5168u304fu65b0u3057u3044u7814u7a76u624bu6cd5u3092u5207u308au958bu304fu3053u306eu3067u304du308bu304bu3092u5bb6u73feu3057u3066u3044u307eu305su3002

u30e2u30fcu30b6u30fcu306fu3001TwelveLabs API u30adu30fcu3092u63a5u7d9au3059u308bu3060u3051u3067u3001u52d5u753bu3092u30a2u30c3u30d7u30edu30fcu30c9u3059u308bu304bu3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu30aau30f3u30e9u30a4u30f3u304bu3089u9078u629eu3059u308bu3053u3068u304cu3067u304du307eu3059u3002u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du306eu5f8cu3001u30b3u30f3u30c6u30f3u30c4u3092u51e6u7406u3057u3066u69cbu9020u5316u3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u62bdu51fau3057u3001u305du308cu3089u3092u691cu8a3cu53efu80fdu306au53c2u7167u5148u306bu30eau30f3u30afu3055u305bu308bu3053u3068u3067u3001u52d5u753bu3068u4fe1u983cu3067u304du308bu7814u7a76u306eu67b6u3051u6a4bu3068u306au308au307eu3059u3002

u3053u3053u3067u306fu3001u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u6a5fu80fdu3092u642du8f09u3057u305fu72ecu81eau306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u69cbu7bc3u30fbu62e1u5f35u3067u304du308bu3088u3046u3001u30b3u30fcu30c9u3068u30c7u30e2u306eu8a73u7d30u306au8acbu91c8u3092u884cu3044u307eu3059u3002


u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu52d5u4f5cu3057u304fu307f

u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f2u3064u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059u3002

  1. TwelveLabs API u30adu30fcu306eu4f7fu7528uff1au500bu4ebau306e TwelveLabs API u30adu30fcu3092u63a5u7d9au3057u3066u3001u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu81eau5206u306eu52d5u753bu306bu30a2u30afu30bbu30b9u3057u3001u64cdu4f5cu3057u307eu3059u3002u63a5u7d9au3059u308bu3068u3001u65e2u5b58u306eu30a4u30f3u30c7u30c3u30afu30b9 ID u3068u5bfeu5fdcu3059u308bu52d5u753bu3092u9078u629eu3067u304du307eu3059u3002

  2. u52d5u753bu306eu30a2u30c3u30d7u30edu30fcu30c9uff1au52d5u753bu304cu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu308bu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu30b7u30fcu30e0u30ecu30b9u306au30bbu30c3u30c8u30a2u30c3u30d7u306eu305fu3081u306bu30c7u30d5u30a9u30ebu30c8u306e TwelveLabs API u30adu30fcu3092u81eau52d5u7684u306bu4f7fu7528u3059u308bu3088u3046u306bu8a2du8a08u3055u308cu3066u3044u307eu3059u3002u30a2u30c3u30d7u30edu30fcu30c9u5f8cu3001u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u304cu3059u3050u306bu5f00u59cbu3055u308cu307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304cu5b8cu4e86u3059u308bu3068u3001u6700u8fd1u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu304cu6700u65b0u306eu5229u7528u53efu80fdu306au30b3u30f3u30c6u30f3u30c4u3068u3057u3066u8868u793au3055u308cu307eu3059u3002u3053u306eu6642u70b9u4ee5u964du306fu3001u4e21u65b9u306eu30a4u30f3u30bfu30e9u30afu30b7u30e7u30f3u30e2u30fcu30c9u3067u3001u4ee5u4e0bu306bu8a18u8f09u3059u308bu624bu9806u306bu5f93u3063u3066u3001u30afu30a8u30eau3068u5f15u7528 u306eu30efu30fcu30afu30d5u30edu30fcu304cu307eu3063u305fu304fu540cu69d8u306bu9032u884cu3057u307eu3059u3002

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu5b8cu5168u306au30efu30fcu30afu30d5u30edu30fcu306fu3001TwelveLabs u30afu30e9u30a4u30a2u30f3u30c8u306eu8a2du5b9au304bu308au59cbu307eu308au307eu3059u3002u3053u308cu306bu306fu3001u74b0u5883u5909u6570u3067u63d0u4f9bu3055u308cu305fu30adu30fcu3092u4f7fu7528u3059u308bu304bu3001u30e2u30fcu30b6u30fcu304cu30afu30e9u30a4u30a2u30f3u30c8u5074u304bu308fu81eau5206u306eu30adu30fcu3092u63a5u7d9au3057u3066u3059u3067u306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu306bu30a2u30afu30bbu30b9u3067u304du308bu3088u3046u306bu3001TwelveLabs API u30adu30fcu3092u30bbu30c3u30c8u30a2u30c3u30d7u3059u308bu5fc5u8981u304cu3042u308au307eu3059u3002u30afu30e9u30a4u30a2u30f3u30c8u304cu8a2du5b9au3055u308cu308bu3068u3001u30d7u30edu30bbu30b9u306fu4ee5u4e0bu306bu793au3059u9806u6b21u306eu30d5u30edu30fcu306bu5f93u3044u307eu5ea6u3002 u2013

  1. u30a4u30f3u30c7u30c3u30afu30b9u306eu53d6u5f97 (Fetch Indexes) u2013 u63a5u7d9au3055u308cu305f TwelveLabs u30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u3082u305fu30a4u30f3u30c7u30c3u30afu30b9u306eu30eau30b9u30c8u3092u53d6u5f97u3057u307eu3059u3002

  2. u52d5u753bu306eu9078u629e (Select Video) u2013 u5206u6790u3057u305fu3044u30a4u30f3u30c7u30c3u30afu30b9u304bu3089u52d5u753bu3092u9078u629eu3057u307eu3059u3002

  3. u52d5u753bu306eu5206u6790 (Analyze Video) u2013 u6307u5b9au3055u308cu305fu30afu30a8u30eau3092u4f7fu7528u3057u3066u3001u9078u629eu3057u305fu52d5u753bu306eu30b3u30f3u30c6u30f3u30c4u5206u6790u3092u884cu3041u307eu3059u3002

  4. u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1 (Deep Research) u2013 u5206u6790u3055u308cu305fu56deu7b54u3001u69cbu9020u5316u3055u308cu305fu30d7u30edu30f3u30d7u30c8u3001u304au3088u3073u30e2u30fcu30b6u30fcu306eu30afu30a8u30eau3092u7d44u307fu5408u308fu305bu3001u305du306eu5185u5bb9u3092 Sonar u30eau30b5u30fcu30c1u30e2u30c7u30ebu306bu6e21u3057u3066u3001u3088u308au6df1u3044u63a8u8ad6u3068u5f15u7528u306eu88cfu4ed8u3051u306eu3042u308bu30a4u30f3u30b5u30a4u30c8u3092u5f97u307eu3059u3002

u3053u306eu69cbu9020u5316u3055u308cu305fu30efu30fcu30afu30d5u30edu30fcu306bu3088u308au3001u52d5u753bu306eu30a4u30f3u30c7u30c3u30afu30b9u5316u304bu3089u9ad8u5ea6u306au7814u7a76u307eu3067u30b9u30e0u30fcu30bau306bu9032u884cu3057u3001u30e2u30fcu30b6u30fcu306bu8a73u7d30u3067u30b3u30f3u30c6u30adu30b9u30c8u3092u5224u65adu3057u305fu51fau529bu3092u63d0u4f9bu3057u307eu3059u3002

u4e21u65b9u306eu30a2u30d7u30edu30fcu30c1u306fu3001u4ee5u4e0bu306eu30a2u30fcu30adu30c6u30afu30c1u30e3u56f3u306bu793au3055u308cu3066u3044u307eu3059u3002

u3053u306eu30d5u30edu30fcu306fu3001u30eau30b5u30fcu30c1u56deu7b54u304cu751fu6210u3055u308cu305fu5f8cu3001u30e2u30fcu30b6u30fcu304cu540cu3058u6587u8108u3067u3055u3089u306au308bu53c2u7167u5148u3084u6df1u3044u30a4u30f3u30b5u30a4u30c8u3092u6c42u3081u308bu8ffdu52a0u30afu30a8u30eau3092u884cu3048u308bu3088u3046u306bu8a2du8a08u3055u308cu3066u3044u307eu5ea6u3002u3053u308cu3089u306eu5f8cu7d9au30afu30a8u30eau306f Sonar u30eau30b5u30fcu30c1u30ebu30fcu30d7u306bu30d5u30a3u30fcu30c9u30d0u30c3u30afu3055u308cu3001u6587u8108u306eu7d99u7d9au6027u3092u7dadu6301u3057u306au304cu3089u65e2u5b58u306eu77e5u8b58u30d2u30fcu30d9u30fcu30b9u3092u62e1u5f35u3057u307eu3059u3002u3053u306eu53cdu5fa9u7684u306au8a2du8a08u306bu3088u308au3001u65b0u3057u3044u30afu30a8u30eau305au3064u304cu4e8bu524du306eu7d50u679cu306bu57fau3065u3044u3066u69cbu7bc3u3055u308cu3001u6bb5u968eu7684u306bu8c4au304bu3067u30b3u30f3u30c6u30adu30b9u30c8u3092u8003u616eu3057u305fu7814u7a76u51fau529bu3092u5f97u308bu3053u306eu304cu3067u304du307eu3059u3002


u6e96u5099u624bu9806

  1. TwelveLabs Playground u304bu3089u30a2u30afu30bbu30b9 API u30adu30fcu3092u53d6u5f97u3057u3001u74b0u5883u5909u6570u3092u8a2du5b9au3057u307eu3059u3002

  2. TwelveLabs Playground u3092u901au3058u3066 pegasus-1.2 u3092u9078u629eu3057u3001u30a4u30f3u30c7u30c3u30afu30b9u3092u4f5cu6210u3057u3001u3053u306eu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u7528u306e index_id u3092u53d6u5f97u3057u307eu3059u3002

  3. Github u304bu3089u30d7u30edu30b8u30a7u30afu30c8u3092u30afu30edu30fcu30f3u3057u307eu3059u3002

  4. Sonar by Perplexity u304bu3089 API KEY u3092u53d6u5f97u3057u307eu3059u3002

  5. TwelveLabs u3068 Sonar u306eu8a3cu660eu60c5u5831u3092u542bu3080 .env u30d5u30a1u30a4u30ebu3092u4f5cu6210u3057u307eu3059u3002u74b0u5883u8a2du5b9au306eu4ee5u4e0bu306fu3001u3053u3061u3089 u3067u78bau8a8du3067u304du307eu3059u3002

u3053u308cu3089u306eu624bu9806u304cu5b8cu4e86u3059u308bu3068u3001u958bu767au3092u590bu3081u308bu6e96u5099u304cu6574u3044u307eu3059uff01


u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30a2u30d7u30eau306eu30fcu30afu30b9u30ebu30fc

u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u306fu3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u306bu57fau3065u3044u3066u30a6u30a7u30d6u304bu3089u5f15u7528u60c5u5831u3084u95a2u9023u60c5u5831u3092u53d6u5f97u3067u304du308bu30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu69cbu7bc3u65b9u6cd5u3092u5bb6u73feu3057u307eu3059u3002u3053u306eu30d7u30edu30b8u30a7u30afu30c8u3067u306fu3001u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306b Next.js u3092u3001u30d0u30c3u30afu30a8u30f3u30c3u30c9u306bu306f Flask APIuff08CORSu6709u52b9u5316uff09u3092u4f7fu7528u3057u3066u307eu3059u3002u6211u3005u306eu4e3bu306eu30d5u30a9u30fcu30abu30b9u306fu3001u3053u306eu52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306eu4e3bu8981u306au30d0u30c3u30afu30a8u30f3u30c3u30c9u30e6u30fcu30c6u30a3u30eau30c6u30a3u306eu5b9fu88c5u3068u3001u5b8cu5168u306au74b0u5883u306eu30bbu30c3u30c8u30a2u30c3u30d7u3067u3059u3002

u8a73u7d30u306f u30bbu30c3u30c8u30a2u30c3u30d7u624bu9806u3068u5b8cu5168u306au30b3u30fcu30c9u69cbu9020u306bu3064u3044u3066u306fu3001GitHub u30eau30ddu30b8u30c8u30eau306e README.md u30d5u30a1u30a4u30ebu3092u53c2u7167u3057u3066u304fu3060u3055u3044u3002


1 - u52d5u753bu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u5b9fu88c5u306eu30efu30fcu30afu30d5u30edu30fc

u30efu30fcu30afu30d5u30edu30fcu3067u3082u3063u3068u3082u91cdu8981u306au30b9u30c6u30actu306fu3001TwelveLabs API u30adu30fcu306eu521du671fu5316u3068u30cfu30f3u30c9u30eau30f3u30b0u3067u3059u3002u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu3001u30c7u30d5u30a9u30ebu30c8u306eu4f7fu7528u306eu305fu3081u306bu74b0u5883u304bu3089u30adu30fcu3092u76f4u63a5u8aadu307fu8fbcu3080u304bu3001u30e2u30fcu30b6u30fcu304cu30afu30e9u30a4u30a2u30f3u30c8u3092u4ecbu3057u3066u72ecu81eau306e API u30adu30fcu3092u63d0u4f9bu3067u304du308bu3088u3046u306bu3057u307eu3059u3002

backend/service/twelvelabs_service.py (14-36u884cu76ee)

class TwelveLabsService:
    def __init__(self, api_key=None):
        # If no API key is provided, try to get it from environment variable
        if api_key is None:
            api_key = os.environ.get('TWELVELABS_API_KEY', '')
        self.api_key = api_key # Store API key in the instance
        self.client = TwelveLabs(api_key=api_key) # Intialize the TwelveLabs client


1.1 u30a4u30f3u30c7u30c3u30afu30b9u306eu53d6u5f97 (GET Indexes)

u30e2u30fcu30b6u30fcu304cu30ddu30fcu30bfu30ebu3092u901au3058u3066 TwelveLabs API u30adu30fcu3092u63a5u7d9au3059u308bu304bu3001u307eu305fu306fu74b0u5883u304bu3089u30adu30fcu304cu8decu307fu8fbcu307eu308cu308bu30c7u30d5u30a9u30ebu30c8u30e2u30fcu30c9u3092u4f7fu7528u3059u308bu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu305du306eu30a2u30abu30a6u30f3u30c8u306bu95a2u9023u4ed8u3051u3089u3082u305fu3059u3079u3066u306eu30a4u30f3u30c7u30c3u30afu30b9u3092u53d6u5f97u3057u307eu3059u3002u53d6u5f97u3055u308cu305fu30c7u30fcu30bfu306fu69cbu9020u5316u3055u308cu3001u8868u793au306eu305fu3081u306bu30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu5c4au3051u3089u3082u307eu3059u00e3u3002

backend/service/twelvelabs_service.py (14-36u884cu76ee)

def get_indexes(self):
        try:
            print("Fetching indexes...")
            # Check if API key is available
            if not self.api_key:
                print("No API key available")
                return []
            
            # Use TwelveLabs client to get a list of indexes
            indexes = self.client.indexes.list()
            
            result = []
            for index in indexes:
                # Append a dictionary with relevant index details
                result.append({
                    "id": index.id,
                    "name": index.index_name
                })
                print(f"ID: {index.id}")
                print(f"  Name: {index.index_name}")
            
            return result
        except Exception as e:
            print(f"Error fetching indexes: {e}")
            return []


1.2 u5bfeu5fdcu3059u308bu30a4u30f3u30c7u30c3u30afu30b9 ID u306eu52d5u753bu30eau30b9u30c8u3092u53d6u5f97 (GET Videos)

u30e2u30fcu30b6u30fcu304cu30a4u30f3u30c7u30c3u30afu30b9u3092u9078u629eu3059u308bu306eu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306fu95a2u90a6 index_id u3092u8a18u9332u305eu3057u307eu3059u3002u3053u306e index_id u3092u4f7fu7528u3057u3066u3001u30b7u30b9u30c6u30e0u306fu305du306eu30a4u30f3u30c7u30c3u30afu30b9u306bu30eau30f3u30afu3055u308cu305fu3059u3079u3066u306eu52d5u753bu3092u53d6u5f97u3057u3066u8fd4u3059u95a2u9023u30e1u30bdu30c3u30c9u3092u547cu3073u51fau3057u307eu3059u3002

backend/service/twelvelabs_service.py (38-70u884cu76ee)

def get_videos(self, index_id, page=1):
        try:
            # Check if API key is available
            if not self.api_key:
                print("No API key available")
                return []
            
            # Use TwelveLabs client to get a list of videos
            videos_response = self.client.indexes.videos.list(index_id=index_id, page=page)
            
            result = []
            for video in videos_response.items:
                system_metadata = video.system_metadata
                hls_data = video.hls
                thumbnail_urls = hls_data.get('thumbnail_urls', []) if hls_data else []
                thumbnail_url = thumbnail_urls[0] if thumbnail_urls else None
                video_url = hls_data.get('video_url') if hls_data else None
                # Append a dictionary with relevant video details
                result.append({
                    "id": video.id,
                    "name": system_metadata.filename if system_metadata and system_metadata.filename else f'Video {video.id}',
                    "duration": system_metadata.duration if system_metadata else 0,
                    "thumbnail_url": thumbnail_url,
                    "video_url": video_url,
                    "width": system_metadata.width if system_metadata else 0,
                    "height": system_metadata.height if system_metadata else 0,
                    "fps": system_metadata.fps if system_metadata else 0,
                    "size": system_metadata.size if system_metadata else 0
                })
            
            return result
        except Exception as e:
            print(f"Error fetching videos for index {index_id}: {e}")
            return []


1.3 u52d5u753bu30b3u30f3u30c6u30f3u30c4u306eu5206u6790

u52d5u753bu304cu9078u629eu3055u308cu3001u30e2u30fcu30b6u30fcu304bu3089u30eau30b5u30fcu30c1u30afu30a8u30eau304cu63d0u4f9bu3055u308cu308bu3068u3001video_id u3068u30afu30a8u30eau306eu4e21u65b9u304cu52d5u753bu7406u89e3u306eu305fu3081u306b analyze u30e6u30fcu30c6u30a3u30eau30c6u30a3u306bu6e21u3055u308cu307eu3059u3002u30afu30a8u30eau306fu4e8bu524du306bu5b9au7fa9u3055u308cu305fu30d7u30edu30f3u30d7u30c8u306bu8ffdu52a0u3055u308cu3001u6587u8108u304cu5f37u5316u3055u308cu3001u6709u610fu7fa9u306au5206u6790u56deu7b54u304cu5f97u3089u308eu308bu3088u3046u306bu3057u307eu3059u3002u52d5u753bu5206u6790u306bu4f7fu7528u3055u308cu308bu30d7u30edu30f3u30d7u30c8u306f u3053u3061u3089 u306bu3042u308au307eu3059u3002

backend/service/twelvelabs_service.py (72-81u884cu76ee)

def analyze_video(self, video_id, prompt):
        try:
            # Call the TwelveLabs client to analyze the video
            analysis_response = self.client.analyze(
                video_id=video_id,
                prompt=prompt
            )
            return analysis_response.data
        except Exception as e:
            print(f"Error analyzing video {video_id}: {e}")
            raise e


1.4 u5206u6790u3053u307fu30b3u30f3u30c6u30f3u30c4u306eu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1

u521du671fu5206u6790u304fu304cu5b8cu4e86u3059u308bu306eu3068u3001u30efu30fcu30afu30d5u30edu30fcu306f Sonar u30e2u30c7u30ebu3092u4f7fu7528u3057u305fu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u30d5u30a7u30fcu30bau306bu79fbu308au307eu3059u3002deep_research u547cu3073u51fau3057u306fu3001u30e2u30fcu30b6u30fcu306eu5143u306eu30afu30a8u30eau3001u30eau30b5u30fcu30c1u30d7u30edu30f3u30d7u30c8u3001u30eau30b5u30fcu30c1u7d50u679cu306e 3u3064u306eu8981u7d20u3092u7d44u307fu5408u308fu305bu305f1u3064u306e u30dau30a4u30edu30fcu30c9 u3092u69cbu7bc3u3057u3001u305du306eu69cbu9020u5316u3055u308cu305fu5165u529bu3092 Sonar u306bu9001u3063u3066u3055u3089u306au308bu51e6u7406u3092u884cu3044u307eu3059u3002Sonar u306fu3001u60c5u5831u6e90u306eu5f15u7528u3092u542bu3080u3001u30d6u30e9u30c3u30b7u30e5u30a2u30c3u30d7u3055u308cu305fu69cbu9020u5316u3055u308cu305fu56deu7b54u3092u8fd4u3057u307eu3059u3002u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u306eu30d7u30edu30f3u30d7u30c8u306f u3053u3061u3089 u306bu3042u308au307eu3059u3002

backend/service/sonar_service.py (13-52u884cu76ee)

def deep_research(self, query, timeout=180):
        try:
            # Ensure API key is available
            if not self.api_key:
                raise ValueError("API key is required")
            
            payload = {
                "model": "sonar",
                "messages": [
                    {"role": "user", "content": query}
                ]
            }
            
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json"
            }
            
            # POST request to the API endpoint with timeout
            response = requests.post(
                self.base_url, 
                json=payload, 
                headers=headers, 
                timeout=timeout
            )
            
            # Check if the response was successful
            if response.status_code == 200:
                return response.json()
            else:
                print(f"Error: {response.status_code} - {response.text}")
                return {"error": f"API request failed with status {response.status_code}"}
                
        except requests.exceptions.Timeout:
            print("Request timed out")
            return {"error": "Request timed out - Sonar research is taking too long"}
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")
            return {"error": f"Network error: {str(e)}"}
        except Exception as e:
            print(f"Error in deep_research: {e}")
            return {"error": str(e)}

u3053u3053u306bu306f sonaru3001sonar-reasoningu3001sonar-deep-research u306au3069u3001u8907u6570u306e Sonar u30d0u30eau30a2u30f3u30c8u304cu5229u7528u53efu80fdu3067u3059u3002sonar-deep-research u30e2u30c7u30ebu306f reasoning_effort u8a2du5b9auff08low, medium, highuff09u3092u30b5u30ddu30fcu30c8u3057u3066u304au308au3001u30c7u30d5u30a9u30ebu30c8u306fu5206u6790u3068u901fu5ea6u306eu30d0u30e9u30f3u30b9u3092u53d6u3063u305f medium u3067u3059u3002u63a8u8ad6u30d7u30edu30bbu30b9u3092 u201chighu201d u306bu5411u4e0au3055u305bu308bu3068u3001u3088u308au591au304fu306eu5f15u7528u3068u6df1u3044u30a4u30f3u30b5u30a4u30c8u304cu5f97u3089u308cu307eu3059u304cu3001u56deu7b54u6642u9593u3068u30c8u30fcu30afu30f3u306eu4f7fu7528u91cfu3082u5897u52a0u3059u308bu305fu3081u3001u5fc5u8981u306au5fb9u5e95u3055u3001u9045u5ef6u8a31u5bb9u5ea6u3001u30b3u30b9u30c8u306bu57fau3065u3044u3066u30e2u30c7u30ebu3068u52aau529bu30ecu30d9u30ebu3092u9078u629eu3057u3066u304fu3060u3055u3044u3002

u30a2u30d7u30eau306eu30e2u30c7u30ebu540du3092 sonar-deep-research u306bu5909u66f4u3059u308bu3060u3051u3062u3001u30b7u30b9u30c6u30e0u306fu3088u308au8a73u7d30u306au63a8u8ad6u3068u591au304fu306eu5f15u7528u3092u751fu6210u3057u307eu3059u3002u3053u306eu8a2du5b9au306bu3088u308au3001u30c7u30d5u30a9u30ebu30c8u306e sonar u30e2u30c7u30ebu3068u6bd4u8f03u3057u3066u3001u3088u308au6df1u3044u7814u7a76u3068u8c4au304bu306eu30a4u30f3u30b5u30a4u30c8u304cu5229u7528u3067u304du307eu3059u3002u4ee5u4e0bu306fu3001u751fu6210u3055u308cu305fu5f37u5316u3055u308cu305fu56deu7b54u306eu30c7u30e2u3067u3059 u2014


1.5 u30eau30b5u30fcu30c1u306eu305fu3081u306eu95a2u6570u547cu3073u51fau3057u30efu30fcu30afu30d5u30edu30fc

u30efu30fcu30afu30d5u30edu30fcu306f TwelveLabs u30afu30e9u30a4u30a2u30f3u30c8u306eu8a2du5b9au304bu308au59cbu307eu308au3001API u30adu30fcu3001u30a4u30f3u30c7u30c3u30afu30b9 IDu3001u52d5u753b ID u304cu9069u5207u306bu691cu8a3cu3055u308cu3066u3044u308bu3053u3068u3092u78bau306bu3057u307eu3059u3002u30bbu30c3u30c8u30a2u30c3u30d7u304fu3055u308cu308bu306eu3068u3001u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f TwelveLabs u30b5u30fcu30d3u30b9u304bu3081u52d5u753bu306eu8a73u7d30u3092u53d6u5f97u3057u307eu3059u3002u3053u308cu306bu3088u308au3001u3055u3089u306au308bu51e6u7406u306bu9032u3080u524du306bu3001u9078u629eu3057u305fu52d5u753bu306eu30b3u30f3u30c6u30adu30b9u30c8u304cu660eu78bau306bu8a2du5b9au3055u308cu307eu3059u3002u7d50u679cu306f yield u3092u4f7fu7528u3057u3066u30eau30a2u30ebu30bfu30a4u30e0u3067u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306bu30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu3001u30d7u30edu30bbu30b9u5168u4f53u306eu5b8cu4e86u3092u5f85u3064u3053u3068u306au304fu3001UI u3092u6bb5u968eu7684u306bu66f4u65b0u3059u308bu3053u306eu3042u308au307eu3059u3002

u6b21u306bu3001u30b7u30b9u30c6u30e0u306fu5b9au7fa9u3055u308cu305f TwelveLabs u30b5u30fcu30d3u30b9 u30afu30e9u30b9u306e analyze_video u30e1u30bdu30c3u30c9u3092u547cu3073u51fau3057u3001u9078u629eu3057u305f video_id u3068u5206u6790u30d7u30edu30f3u30d7u30c8u3092u6e21u3057u307eu3059u3002u3053u306eu5206u6790u306eu51fau529bu306fu3001u4e8bu524du306bu5b9au7fa9u3055u308cu305fu30c6u30f3u30d7u30ecu30fcu30c8u3067u69cbu6210u3055u308cu305fu5f37u5316u3055u308cu305fu30eau30b5u30fcu30c1u30afu30a8u30eau306bu7d44u307fu8fbcu307eu308cu307eu3059u3002u3053u306eu30c6u30f3u30d7u30ecu30fcu30c8u306fu3001u6307u793au3068u3057u3066 Markdown u30d9u30fcu30b9u306eu56deu7b54u30d5u30a9u30fcu30deu30c3u30c8u3092u5f37u5236u3057u3001u5206u6790u7d50u679cu3068u30e2u30fcu30b6u30fcu306eu30afu30a8u30eau306eu4e21u65b9u304fu4e00u8cabu3057u305fu69cbu9020u306bu5408u308fu305bu3089u308cu308bu3088u3046u306bu3057u307eu3059u3002u305du306eu5f8cu3001u5f37u5316u3055u308cu305fu30afu30a8u30eau306f Sonar u30b5u30fcu30d3u30b9u306bu9001u3089u308cu3066 u30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1 u304cu884cu308fu308cu3001u30d6u30e9u30cbu30e5u30a2u30c3u30d7u3055u308cu305fu5f15u302eu88cfu4ed8u3051u306eu3042u308bu56deu7b54u304cu751fu6210u3055u308cu307eu3059u3002

backend/routes/api_routes.py (31-162u884cu76ee)

def generate_workflow(twelvelabs_api_key, index_id, video_id, analysis_prompt, research_query, research_prompt_template):
    # Input validation
    if not twelvelabs_api_key:
        yield json.dumps({'type': 'error', 'message': 'TwelveLabs API key is required'}) + '\n'
        return
    if not index_id or not video_id:
        yield json.dumps({'type': 'error', 'message': 'Index ID and Video ID are required'}) + '\n'
        return
    if not research_query:
        yield json.dumps({'type': 'error', 'message': 'Research query is required'}) + '\n'
        return

    try:
        twelvelabs_service = TwelveLabsService(api_key=twelvelabs_api_key)
        
        # Step 1: Get video details
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'video_details',
            'message': 'Fetching video details...',
            'progress': 0
        }) + '\n'

        video_details = twelvelabs_service.get_video_details(index_id, video_id)
        if not video_details:
            yield safe_json_dumps({'type': 'error', 'message': 'Could not retrieve video details'}) + '\n'
            return

        yield safe_json_dumps({
            'type': 'data',
            'step': 'video_details',
            'data': {
                'id': video_details.get('_id', ''),
                'filename': video_details.get('system_metadata', {}).get('filename', ''),
                'duration': video_details.get('system_metadata', {}).get('duration', 0)
            },
            'progress': 33
        }) + '\n'

        # Step 2: Analyze video
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'analysis',
            'message': 'Analyzing video content...',
            'progress': 33
        }) + '\n'

        analysis_result = twelvelabs_service.analyze_video(video_id, analysis_prompt)
        yield safe_json_dumps({
            'type': 'data',
            'step': 'analysis',
            'data': analysis_result,
            'progress': 66
        }) + '\n'

        # Step 3: Research with context
        yield safe_json_dumps({
            'type': 'progress',
            'step': 'research',
            'message': 'Conducting deep research...',
            'progress': 66
        }) + '\n'

        enhanced_query = research_prompt_template.format(
            analysis_result=analysis_result,
            research_query=research_query
        )
        
        sonar_service = SonarService()
        research_result = sonar_service.deep_research(enhanced_query, timeout=180)

        if 'error' in research_result:
            yield safe_json_dumps({'type': 'error', 'message': f'Research failed: {research_result["error"]}'}) + '\n'
            return

        # Extract research content
        research_content = ""
        if research_result and research_result.get('choices'):
            research_content = research_result['choices'][0].get('message', {}).get('content', '')
        
        # Send research content in chunks if large
        max_chunk_size = 10000
        if len(research_content) > max_chunk_size:
            for i in range(0, len(research_content), max_chunk_size):
                chunk = research_content[i:i + max_chunk_size]
                is_final = (i + max_chunk_size) >= len(research_content)
                
                yield safe_json_dumps({
                    'type': 'research_chunk',
                    'content': chunk,
                    'is_final': is_final,
                    'progress': 80 + (i / len(research_content)) * 20
                }) + '\n'
            
            # Send completion with chunked content indicator
            yield safe_json_dumps({
                'type': 'complete',
                'data': {
                    'research': {
                        'choices': [{
                            'message': {
                                'content': '[CHUNKED_CONTENT]'
                            }
                        }],
                        'citations': research_result.get('citations', [])[:10],
                        'usage': research_result.get('usage', {})
                    },
                    'sources': research_result.get('search_results', [])[:10]
                },
                'progress': 100
            }) + '\n'
        else:
            # Send completion with research data
            yield safe_json_dumps({
                'type': 'complete',
                'data': {
                    'research': {
                        'choices': [{
                            'message': {
                                'content': research_content
                            }
                        }],
                        'citations': research_result.get('citations', [])[:10],
                        'usage': research_result.get('usage', {})
                    },
                    'sources': research_result.get('search_results', [])[:10]
                },
                'progress': 100
            }) + '\n'

    except Exception as e:
        yield safe_json_dumps({'type': 'error', 'message': str(e)}) + '\n'

u5927u898fu6a21u306au30eau30b5u30fcu30c1u51fau529bu3092u51e6u7406u3059u308bu305fu3081u306bu3001u30efu30fcu30afu30d5u30edu30fcu306fu56deu7b54u306eu5206u5272uff08u30c1u30e3u30f3u30afu5316uff09u3092u5b9eu88c5u3057u3066u3044u307eu3059u3002Sonar u306fu8a73u7d30u306au63a8u8ad6u3068u591au304fu306eu5f15u7528u3092u542bu3080u5e83u7bc4u56f2u306au30b3u30f3u30c6u30f3u30c4u3092u8fd4u3059u3053u306eu304cu3042u308bu305fu3081u30011u3064u306eu5927u304du306a JSON u3068u3057u3066u9001u4fe1u3059u308bu306eu306f u30dau30a4u30edu30fcu30c9 u30b5u30a4u30bau5236u9650u3092u8d85u3048u3001u30b7u30eau30a2u30e9u30a4u30bcu30fcu30b7u30e7u30f3u30a8u30e9u30fcu3092u5f15u304du8d77u3053u3059u30eau30b9u30afu304cu3042u308au307eu3059u3002u3053u308cu3092u9632u3050u305fu3081u3001u56deu7b54u306fu7ba1u7406u53efu80fdu306au30c1u30e3u30f3u30afu306bu5206u5272u3055u308cu3001u9806u6b21u30b9u30c8u30eau30fcu30dfu30f3u30b0u3055u308cu307eu3059u3002u3053u306eu8a2du5b9au306fu30b9u30b1u30fcu30e9u30d3u30eau30c6u30a3u3092u78bau4fddu305fu3001u30cdu30c3u30c8u30efu30fcu30afu306eu30dcu30c8u30ebu30cdu30c3u30afu3092u56deu907fu3057u3001u30d5u30edu30f3u30c8u30a8u30f3u30c3u30c9u306eu5fdcu7b54u6027u3092u7dadu6301u3057u307eu3059u3002


2 - u52d5u753bu30a2u30c3u30d7u30edu30fcu30c9u30a4u30f3u30c7u30c3u30afu30b9u5316u30efu30fcu30afu30d5u30edu30fcu306eu8981u70b9

u3082u30461u3064u306eu30efu30fcu30afu30d5u30edu30fcu3067u306fu3001u4e8bu524du306eu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu306bu4f9du5b58u3059u308bu306eu3067u306fu306au304fu3001u30e2u30fcu30b6u30fcu304cu65b0u3057u3044u52d5u753bu30d5u30a1u30a4u30ebu3092u76f4u63a5u30a2u30c3u30d7u30edu30fcu30c9u3057u307eu3059u3002upload_video_file u30e1u30bdu30c3u30c9u306fu3001API u30adu30fcu3001u30a3u30f3u30c7u30c3u30afu30b9 IDu3001u30d5u30a1u30a4u30ebu30d1u30b9u306eu5fc5u8981u306au5165u529bu3092u691cu8a3cu3059u308bu3053u3068u3067u3001u3053u306eu30d7u30edu30bbu30b9u3092u51e6u7406u3057u307eu3059u3002u691cu8a3cu3055u308cu308bu306eu3068u3001TwelveLabs u306eu30bfu30b9u30afu30a8u30f3u30c3u30c9u30ddu30a4u30f3u30c3u30c8u306bu30bfu30b9u30af u30eau30afu30a8u30b9u30c8 u3092u958bu59cbu3057u3001u52d5u753bu30d5u30a1u30a4u30ebu304cu6dfbu4ed8u3055u308cu305fu30a2u30c3u30d7u30edu30fcu30c9 u30bfu30b9u30af u3092u4f5cu6210u3057u307eu3059u3002u30bfu30b9u30af u306eu4f5cu6210u304cu6210u529fu3059u308bu3068u3001u30bfu30b9u30af ID u304fu8fd4u3055u308cu3001u3053u308cu3092u4f7fu7528u3057u3066u30a4u30f3u30c7u30c3u30afu30b9u5316u306eu30b9u30bfu30fcu30bfu30b9u3092u76e3u8996u3057u307eu5ea6u3002

u305du306eu5f8cu3001u3053u306eu30e1u30bdu30c3u30c9u306fu30ddu30fcu30eau30f3u30b0 u30ebu30fcu30d7u306bu5165u308au3001u5b8cu4e86u3059u308bu304bu3001u5931u6557u3059u308bu304bu3001u307eu305fu306fu8a2du5b9au3055u308cu305fu30bfu30a4u30e0u30a2u30a6u30c8u306bu9054u3059u308bu307eu3067u3001u5b9au671fu7684u306bu30bfu30b9u30af u30b9u30bfu30fcu30bfu30b9u3092u78bau8a8du3057u307eu3059u3002u30a4u30f3u30c7u30c3u30afu30b9u5316u304fu6210u529fu3059u308bu306eu3068u3001u56deu7b54u306bu306fu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu3092u4e00u610fu306bu8b58u5225u3059u308b video_id u304cu542bu307eu308cu3001u305du306eu52d5u753bu306fu3059u3050u306bu3055u3089u306au308bu5206u6790u306bu5229u7528u3067u304du308bu3088u3046u306bu306au308au307eu3059u3002u3053u308cu306bu3088u308eu3001u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753bu304cu30ddu30fcu30bfu30ebu4e0au3067u6700u65b0u306eu5229u7528u53efu80fdu306au52d5u753bu306bu306au308au307eu3059u3002u5931u6557u3084u30bfu30a4u30e0u30a2u30a6u30c8u306eu5830u5208u306fu3001u9069u5207u306au30a8u30e9u30fc u30e1u30c3u30bbu30fcu30b8u304fu8fd4u3055u308cu3001u30a2u30c3u30d7u30edu30fcu30c9u3068u30a4u30f3u30c7u30c3u30afu30b9u5316u30d7u30edu30bbu30b9u306bu5b9fu8aadu306au30a8u30e9u30fc u30cfu30f3u30c9u30eau30f3u30b0u3092u63d0u4f9bu3057u307eu3059u3002

backend/service/twelvelabs_service.py (145-207u884cu76ee)

def upload_video_file(self, index_id: str, file_path: str, timeout_seconds: int = 900):
        import sys
        try:
            if not self.api_key:
                return {"error": "Missing TwelveLabs API key"}
            if not index_id:
                return {"error": "Missing index_id"}
            if not os.path.exists(file_path):
                return {"error": f"File not found: {file_path}"}
            
            print(f"Starting upload for file: {file_path}", file=sys.stderr)

            tasks_url = "https://api.twelvelabs.io/v1.3/tasks"
            headers = {
                "x-api-key": self.api_key
            }

            # Create upload task
            with open(file_path, "rb") as f:
                files = {
                    "video_file": (os.path.basename(file_path), f)
                }
                data = {
                    "index_id": index_id
                }
                resp = requests.post(tasks_url, headers=headers, files=files, data=data)

            if resp.status_code not in (200, 201):
                return {"error": f"Failed to create upload task: {resp.status_code} {resp.text}"}

            resp_json = resp.json() if resp.text else {}
            task_id = resp_json.get("id") or resp_json.get("task_id") or resp_json.get("_id")
            if not task_id:
                return {"error": f"No task id returned: {resp_json}"}

            # Poll task until ready
            import time
            start_time = time.time()
            print(f"Starting to poll task {task_id} for completion...", file=sys.stderr)
            
            while time.time() - start_time < timeout_seconds:
                r = requests.get(f"{tasks_url}/{task_id}", headers=headers)
                if r.status_code != 200:
                    time.sleep(2)
                    continue
                task = r.json() if r.text else {}
                status = task.get("status")
                print(f"Task {task_id} status: {status}", file=sys.stderr)
                
                if status in ("ready", "completed"):
                    video_id = task.get("video_id") or (task.get("data") or {}).get("video_id")
                    print(f"Indexing completed successfully! Video ID: {video_id}", file=sys.stderr)
                    return {"status": status, "video_id": video_id, "task": task}
                if status in ("failed", "error"):
                    print(f"Indexing failed with status: {status}", file=sys.stderr)
                    return {"error": f"Indexing failed with status {status}", "task": task}
                time.sleep(2)

            print(f"Upload timed out after {timeout_seconds} seconds", file=sys.stderr)
            return {"error": "Upload timed out"}

u5f8cu7d9au306eu30efu30fcu30afu30d5u30edu30fc u30d4u30d7u30e9u30a4u30f3u306fu3001u52d5u753bu304cu30a2u30c3u30d7u30edu30fcu30c9u3055u308cu3066u30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu308du306eu3068u3001u751fu6210u3055u308cu305f video_id u304cu5206u6790u3001u30eau30b5u30fcu30c1u5f37u5316u3001u304au3088u3073u5f15u7528u306eu88cfu4ed8u3051u306eu3042u308bu56deu7b54u306eu30efu30fcu30afu30d5u30edu30fcu306bu6e21u3055u308cu3001u4e8bu524du306bu8aacu660eu3057u305fu306eu3068u540cu3058u30b7u30fcu30b1u30f3u30b9u306bu5f93u3044u307eu3059u3002u3053u308cu306bu3088u308au3001u7d71u4e00u3055u308cu305fu30efu30fcu30afu30d5u30edu30fcu3092u7dadu6301u3057u306au304cu3089u3001u30c7u30d5u30a9u30ebu30c8u30e2u30fcu30c9uff08u4e8bu524du306fu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753buff09u3068u9ec4u66ffu30e2u30fcu30c9uff08u30a2u30c3u30d7u30edu30fcu30c9u3055u308cu305fu52d5u753buff09u306eu9593u306eu4e00u8cabu6027u304cu78bau4fddu3055u308cu307eu3059u3002u4ee5u4e0bu306fu3001u52d5u753bu306eu30a2u30c3u30d7u30edu30fcu30c9u3001u30a4u30f3u30c7u30c3u30afu30b9u5316u306eu5b9fu884cu3001u304au3088u3073u5b8cu5168u306au30d4u30d7u30e9u30a4u30f3u306eu5b9fu884cu30d7u30edu30bbu30b9u3092u5bb6u73feu3059u308bu30afu30a4u30c3u30afu30c7u30e2u3067u3059 u2014

u30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u306f TwelveLabs API u30adu30fcu3092u30afu30e9u30a4u30a2u30f3u30c8u5074u3067u76f4u63a5u51e6u7406u3059u308bu3053u306eu3092u30b5u30ddu30fcu30c8u3057u3066u3044u307eu3059u3002u3053u308cu306bu3088u308au3001u30e2u30fcu30b6u30fcu306fu72ecu81eau306e API u30adu30fcu3092u63a5u7d9au3059u308bu67d4u8edfu6027u304cu5f97u3089u308cu3001u30c7u30d5u30a9u30ebu30c8u306eu30adu30fcu306bu4f9du5b58u3059u308bu3053u306eu306au304fu3001u4e8bu524du306bu30a4u30f3u30c7u30c3u30afu30b9u5316u3055u308cu305fu52d5u753bu3092u5206u6790u3057u3001u7814u7a76u306fu305du306eu52d5u753bu3067u884cu3048u308bu3088u3046u306bu306au308au307eu3059u3002


u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u3055u3089u306bu5b9fu9a13u3059u308bu305fu3081u306eu30a2u30a4u30c7u30a2

u52d5u753bu7406u89e3u304cu3069u306eu3088u3046u306bu3057u3066u691cu8a3cu53efu80fdu306au7814u7a76u306bu63a5u7d9au3055u308cu308bu304bu3092u63a2u308bu3053u306eu306fu3001u3055u3089u306bu5f37u529bu306au30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3078u306eu6249u3092u958bu304du307eu3059u3002TwelveLabs Analyze u3068 Sonar by Perplexity u3092u4f7fu7528u3057u3066u3001u4ee5u4e0bu306eu3088u3046u306au5b9fu9a13u7684u306au65b9u5411u6027u3092u8a66u3059u3053u306eu3042u308au307eu3059 u2014

ud8d1udd0d u6df1u5c64u52d5u753bu30d5u30a1u30afu30c8u30c1u30a7u30c3u30af u2014 u62bdu51fau3055u308cu305fu30a4u30f3u30b5u30a4u30c8u3092u4fe1u983cu3067u304du308bu60c5u5831u6e90u3084u5f15u7528u5143u306bu30eau30f3u30afu3055u305eu308bu3053u306eu3067u3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u5185u306eu767au8a00u3084u4e3bu5f35u3092u81eau52d5u7684u306bu691cu8a3cu3057u307eu3059u3002

ud83dudcc3 u610fu5473u7684u30eau30b5u30fcu30c1u30ecu30d3u30e5u30fc u2014 u52d5u753bu30b3u30f3u30c6u30f3u30c4u306eu69cbu9020u5316u3055u308cu305fu8981u7d04/u30ecu30dccu30e5u30fcu3092u751fu6210u3057u3001u4e3bu8981u306au30a2u30a4u30c7u30a2u3001u53c2u7167u5148u3001u305du3057u3066u5b9fu884cu53efu80fdu306au30a4u30f3u30b5u30a4u30c8u3092u5f37u8abfu3057u3066 u30eau30b5u30fcu30c1u3092u9ad8u901fu5316u3057u307eu3059u3002

ud83dudcda u5f37u5316u3055u308cu305fu5b66u7fd2u30efu30fcu30afu30d5u30edu30fc u2014 u52d5u753bu306eu30a4u30f3u30b5u30a4u30c8u3092u5916u90e8u306eu77e5u8b58u30eau30ddu30b8u30c8u30eau3068u7d44u307fu5408u308fu305bu308bu3053u306eu3067u3001u7814u7a76u8005u3001u5b66u751fu3001u30b3u30f3u30c6u30f3u30c4u30afu30eau30a8u30a4u30bfu30fcu5411u3051u306bu3001u53ccu65b9u5411u306au3001u307eu305fu306fu30acu30a4u30c9u4ed8u304du306eu5b66u7fd2u4f53u9a13u3092u4f5cu6210u3057u307eu3059u3002


u307eu3068u3081 

u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306fu3001u52d5u753bu7406u89e3u304cu6211u3005u306eu7814u7a76u624bu6cd5u3084u52d5u753bu30b3u30f3u30c6u30f3u30c4u3068u306eu95a2u308fu308au65b9u3092u3069u306eu3088u3046u306bu5909u9769u3067u304eu308bu304bu3092u5bb6u73feu3057u305fu3002 TwelveLabs Analyzeu3092u4f7fu7528u3057u305fu6df1u5c64u52d5u753bu5206u6790u3068u3001Sonar by Perplexity u3092u4f7fu7528u3057u305fu77e5u8b58u691cu7d22u30fbu5f15u7528u3092u7d44u307fu5408u308fu305bu308bu3053u306eu3067u3001u52d5u753bu3092u53d7u52d5u7684u306au30e1u30c7u30a3u30a2u304bu3089u3001u69cbu9020u5316u3055u308cu305fu5f15u7528u53efu80fdu306au7814u7a76u30c4u30fcu30ebu3078u3068u5909u5faeu3055u305bu308bu30b3u30b9u30c6u30e0u3092u69cbu7bc3u3057u307eu3057u305fu3002u3053u308cu306bu3088u308au3001u7814u7a76u8005u3001u30afu30eau30a8u30a4u30bfu30fcu3001u5c02u9580u5bb6u304cu6700u3082u6709u610fu7fa9u3067u4fe1u983cu3067u304du308bu65b9u6cd5u3067u52d5u753bu30b3u30f3u30c6u30f3u30c4u3092u63a2u7d22u3059u308bu3053u306eu3092u53efu80fdu306bu3057u307eu3059u3002


u8ffdu52a0u30eau30bdu30fcu30b9

u52d5u753bu5206u6790u30a8u30f3u30b8u30f3u306e u30fc Pegasus-1.2 u306bu3064u3044u3066u3055u3089u306eu8a73u7d30u3092u5b66u3076u3053u306eu3042u308au307eu3059u3002TwelveLabs u306bu3064u3044u3066u3055u3089u306au308bu63a2u7d22u3092u884cu3044u3001u52d5u753bu30b3u30f3u30c6u30f3u30c4u5206u6790u306eu7406u89e3u3092u6df1u3081u308bu305fu3081u306bu3001u4ee5u4e0bu306eu30eau30bdu30fcu30b9u3092u30c1u30a7u30c3u30afu3057u3066u304fu3060u3055u3044uff1a

  • u4ed6u306eu30e1u30fcu30b9u30fcu30b1u30fcu30b9u3092'u30a8u30afu30b9u30d7u30edu30fcu30e9u30fcu3059u308b: Sonar by Perplexity u3092u8a2au306du3066u3001u305du306eu30c7u30a3u30fcu30d7u30eau30b5u30fcu30c1u6a5fu80fdu306bu3064u3044u3066u5b66u3076u3053u306eu3042u308au307eu3059u3002u3053u306eu30c1u30e5u30fcu30c8u30eau30a2u30ebu306bu5c0fu3055u306au5909u66f4u3092u52a0u3048u308bu3060u3051u3067u3001u3055u3089u306bu591au304fu306eu30e1u30fcu30b9u30fcu30b1u30fcu30b9u3092u63a2u7d22u3067u304du308bu3088u3046u306bu306au308au307eu3059u3002

  • u30d5u30a3u30fcu30d1u30fcu30c6u30a3u30fcu306bu53c2u52a0u3059u308b: TwelveLabs Discord u3067u3001u3053u306eu7d71u5408u306bu95a2u3059u308bu30d5u30a3u30fcu30c9u30d0u30c3u30afu3092u5171u6709u3057u3066u304fu3060u3055u3044u3002

  • u30c1u30e5u30fcu30c8u30eau30a2u30ebu3092u30a8u30afu30b9u30d7u30edu30fcu30e9u30fcu3059u308b: u30c1u30e5u30fcu30c8u30eau30a2u30ebu3092u3055u3089u306bu30c1u30a7u30c3u30af u2014 u6211u3005u306eu30afu30f3u30d7u30eau30d8u30f3u30b7u30d6u306au30c1u30e5u30fcu30c8u30eau30a2u30ebu3067u3001TwelveLabs u306eu6a5fu80fdu3092u3055u3089u306bu6df1u304fu63a2u3063u3066u307fu307eu3057u30e7u3046u3002

u3053u308cu3089u306eu30eau30bdu30fcu30b9u3092u4f7fu7528u3057u3066u00e3u77e5u8b58u3092u62e1u3052u3001TwelveLabsu306eu52d5u753bu7406u89e3u6280u8853u3092u4f7fu7528u3057u305fu9769u65b0u306au30a2u30d7u30eau30b1u30fcu30b7u30e7u30f3u3092u4f5cu6210u3059u308bu3053u306eu3092 u304au52e7u3081u3057u307eu3059u3002