maestro/docs/tools/xsearch.md
oss-sync 77ee3bc426
Some checks are pending
CI / build-and-test (push) Waiting to run
sync: update from private repo (ddadfd71)
2026-07-08 23:35:00 +00:00

8.2 KiB
Raw Blame History

X / Twitter ツールXSearch / XUserPosts / XPostDetail / XTimeline / XFetchCardMedia

twitter-cli を内部で呼び出して X (旧 Twitter) のデータを取得する read-only ツール群。

認証設定(必須)

X ツールは tools.x_cli_command で指定した外部 CLI を呼び出す。どちらの CLI でも Cookie 認証が必要。Settings UI の "Tools" セクションで設定:

  • X Auth Token: ブラウザの auth_token cookie の値
  • X ct0: ブラウザの ct0 cookie の値

任意:

  • X Proxy: http://proxy:port 形式
  • X Chrome Profile: cookie 抽出元のプロファイルパス

設定が無いと「認証エラー」で失敗する。

バックエンド CLIx-adapter / twitter-cli

2026 年に X.com が Web クライアントを新バンドルx-web / sign.o*.js)へ移行し、 従来の twitter-cli が依存する x_client_transaction の transaction-id 生成が壊れた Failed to init ClientTransaction → 全リクエストが HTTP 404 → exited with code 1)。

復旧のため、新バンドルに追従している twscrapetransaction-id 生成 XClIdGen + 検索/ユーザー投稿/詳細)と twikit(ホームタイムラインの GraphQL endpoint 定義)を 使う twitter-cli 互換アダプタ x-adapter を導入した。x.ts は無改修で、x_cli_command を切り替えるだけ。

セットアップ:

./scripts/install-x-adapter.sh          # 隔離 venv に twscrape/twikit を入れ ~/.local/bin/x-adapter を作る
# config.yaml:
#   tools:
#     x_cli_command: [x-adapter]

X が再び取得を壊した場合(おおむね 2〜4 週ごと)の修復レバー:

./scripts/install-x-adapter.sh --upgrade   # twscrape / twikit を最新へ

x-adapter のサブコマンドは twitter-cli と同じ(search / user-posts / tweet / feed)で、同じ YAML を stdout に吐く。実装は scripts/x-adapter/x_adapter.py、 pure マッピング関数の単体テストは scripts/x-adapter/test_x_adapter.py

XSearch — 投稿検索

XSearch({
  query: "ローカル LLM",
  limit: 20,
  tab: "Latest",     // Top / Latest / Photos / Videos
  full_text: true,   // 長文の省略を避ける
  compact: false,    // true で token 節約
  output_path: "x/local-llm.txt"   // 任意: output/x/ 配下に保存
})

XUserPosts — ユーザー投稿一覧

XUserPosts({
  username: "elonmusk",   // @ なし
  limit: 50,
  full_text: true
})

XTimeline — ホームタイムライン(ログイン中アカウント)

XTimeline({
  tab: "for_you",    // for_you (デフォルト) / following
  limit: 20,         // デフォルト 20, 最大 50
  full_text: true,
  compact: false,
  output_path: "x/timeline.txt"   // 任意
})

設定済みの auth_token / ct0 cookie に紐づくアカウントのホームタイムラインを返す。 tab: "for_you"(おすすめ)と tab: "following"(フォロー中)を切り替えられる。 内部的には twitter feed [-t following] を呼ぶ。検索ではなく「ログイン中ユーザーが 普段見るフィード」を取得したいときに使う。出力・メディア DL の扱いは XSearch と共通。

XPostDetail — 投稿の詳細+リプライ

XPostDetail({
  tweet: "https://x.com/.../status/1234567890",
  // tweet ID だけでも、長文記事 URL (https://x.com/.../article/1234567890) でも可
})

返り値にはリプライツリーが含まれる。議論の流れを追いたいときに使う。

X 長文記事X Articles

対象が長文記事ポストの場合、text は記事への t.co リンク 1 本だけになる。 記事の中身は article キーに入る:

data:
  - id: '1234567890'
    text: https://t.co/xxxx        # 記事ポストの本文はリンクのみ
    article:
      title: 記事タイトル
      previewText: 冒頭のプレビュー文
      plainText: 記事本文の全文(プレーンテキスト)
      publishedAtISO: '2026-07-02T00:04:51+00:00'
      coverImageUrl: https://pbs.twimg.com/media/XXXX.jpg
  • plainText はデフォルトで 12,000 文字で切り詰め、plainTextTruncated: true が付く。 全文が必要なら full_text: true を渡す
  • 記事内の埋め込み画像・動画は media[] に合流する(先頭 20 件まで)。通常の 投稿メディアと同じく自動ダウンロードされ localPath が付くので、そのまま ReadImage / AnnotateImage に渡せる。動画の扱いは tools.x_download_video に従う
  • カバー画像(coverImageUrl)は自動ダウンロード対象外。必要なら DownloadFile に渡す
  • 記事ページ(x.com/{user}/article/{id})を WebFetch で読むことはできない (ログイン壁で失敗する)。記事は必ずこのツールで取得する

出力フォーマット

  • デフォルト: 構造化テキスト(投稿者・本文・いいね数等)
  • compact: true: token 節約版(簡潔表記)
  • output_path 指定時: ファイルにも保存(パスは output/x/ 相対)

メディアの自動ダウンロード

X / Twitter ツールは取得した投稿に紐付く画像 / 動画 (poster) を自動的に ワークスペースにダウンロードして localPath を返す。LLM はそのパスを ReadImage / AnnotateImage / Bash 等に直接渡せる。

# 出力例 (XPostDetail / XUserPosts / XSearch 共通)
data:
  - id: '1234567890'
    media:
      - type: photo
        url: https://pbs.twimg.com/media/AAA.jpg?name=large
        localPath: logs/x-media/1234567890/0.jpg     # ← 自動付与
        bytes: 384172

保存先は {workspace}/logs/x-media/{tweet_id}/{N}.{ext}。同じ tweet を再取得しても 既存ファイルは上書きしない (idempotent)。

動画の扱い

設定で挙動を切り替える (tools.x_download_video):

モード 挙動
thumbnail (default) poster (静止画 jpg) のみ DL。内容把握に十分で軽量
full variants から最高 bitrate の mp4 を DL。サイズ大なので明示的に有効化
never 動画系は完全にスキップ

サイズ上限

tools.x_media_max_mb (default 25) を超えるメディアはスキップしてログに記録。 content-length ヘッダで判定し、ボディが膨張した場合も DL 後に再度チェックする。

完全に無効化したいとき

tools:
  x_download_media: never        # 全 X ツールでメディア DL を無効化

XSearch / XPostDetail で media: [] が返るが、tweet が quiz / poll / link card 形式で card 画像があるはずだと LLM が判断した時のみ呼ぶ専用 tool。

XFetchCardMedia({
  tweet: "https://x.com/someuser/status/1234567890"
  // または tweet: "1234567890" (この場合 screen_name 任意)
})

挙動:

  • Playwright で X.com を開き、GraphQL response + 対象 article の DOM から pbs.twimg.com/(media|card_img)/... URL を抽出
  • 抽出した URL を logs/x-media/{tweetId}/ に DL
  • 成功すれば保存パスを返す
  • 0 件なら "no card media found" を返す (LLM は plain text と判断)

重要: 1 回の呼び出しに Playwright 起動 + ページ遷移で約 14 秒かかる。 XSearch / XUserPosts / XPostDetail からは自動発動しない。LLM が以下の 状況でのみ明示的に呼ぶこと:

  • XPostDetail が media: [] を返した
  • かつ tweet 本文が画像クイズ / 投票 / link preview を示唆する
  • かつその画像の中身が次の判断に必要

text-only tweet には呼ばないこと (14 秒を無駄にする)。

トラブルシューティング

  • 認証エラー: cookie の有効期限切れ。ブラウザで取得し直して Settings に再投入
  • rate limit: しばらく待ってから再実行。検索回数を絞る
  • twitter-cli not found: scripts/install-twitter-cli.sh で導入が必要
  • media: [] のままで画像が取れない: card / quiz 形式の投稿は X API 自体に メディアが乗らない。XFetchCardMedia を呼んで Playwright 経由で取得する