GitHub Copilot - TECH PLAY - TECH PLAY

TECH PLAY

GitHub Copilot

イベント

該当するコンテンツが見つかりませんでした

マガジン

技術ブログ

前回 は、X の投稿を1件名指しして、正規の API 経由で取ってくる話を書きました。今回は向きが逆で、何があるか分からないものを探す側の話です。 この記事を読み終えると、X を情報源にした調べものを手元から回せるようになります。「この1週間、この話題について X で何が言われているか」を投げると、賛否が割れている論点と、その代表になっている投稿の URL が返ってくる。 新しいツールの不具合も、値上げへの反応も、使った人の詰まりどころも、記事にまとまる何日も前に X に出ます。なのに調べものを AI に任せると、そこだけ空白になるんですよね。それを埋めるのが Grok です。乗り換える話ではなくて、足りない X 検索だけを外から足す話をします。 今日話すのはこの3つです。 なぜ Grok だけ、何も繋がずに X を探せるのか 叩き方と、返ってくるもの。絞り込みは効くけど、件数だけは決められない 答えの中身を変えられるのは reasoning.effort だけ 払った額は出てきません。別の会社の規約で書けないので、X に直接お金を払う側の話は 前回 を見てください。あと、やるのは「探す」であって「全部集める」ではないです。Grok にはコーディング agent もありますが、扱うのは X 検索の部分だけです。 Grok なら、何も繋がずに X の中を探せます X を検索する道具が、最初から手元にある状態で始められます。繋ぐ作業も、X 側との別契約もいりません。 追加の契約も実装もなしに X Search が最初から載っているのは、いまのところ Grok だけ です。 なぜ、ほかの AI では返ってこないのか 前回、 x.com/robots.txt を開いて、X が AI のクローラを名指しで締め出していることを確かめました。あのときは「だから自分でスクレイピングしてはいけない」という文脈で読んでいたんですが、同じ宣言が 他の AI にも刺さっている んですよね。規約と宣言を守る側は通らない。だから返ってこない。 他の AI でも、前回紹介した公式 MCP サーバや X API の検索エンドポイントを自分で繋げば叩けます。ただしそれは、繋ぐ作業と X 側の従量課金という別の財布が要る話です。xAI は X を持っている側なので、この門の内側にいます。 紛らわしいのを一つ。GitHub Copilot でも Grok は選べますが( サポートされているモデル に Grok 4.5・4.6 が GA で載っています)、渡ってくるのはモデルだけで X Search は付いてきません。 用意するのは API キーと残高だけです ここからは grok.com の画面に貼る話じゃなくて、手元から API を叩く話です。 用意するものは2つ。xAI のコンソールで発行する API キーと、前払いの残高です。従量課金なので、残高が無いと最初の1回も通りません。ここは前回の X API と同じですね。モデルは reasoning モデルの grok-4.6 を使います。 叩いてみると、返ってくるのは散文と URL です エンドポイントは POST https://api.x.ai/v1/responses 、認証は Authorization: Bearer $XAI_API_KEY 。 tools に {"type": "x_search"} を1つ入れるだけで X 検索が有効になります。 curl https://api.x.ai/v1/responses \ -H "Authorization: Bearer $XAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-4.6", "input": [{"role": "user", "content": "直近1週間の X で話題になっているものを教えて"}], "tools": [{"type": "x_search"}], "reasoning": {"effort": "low"} }' 最初につまずいたのが、返ってくるものの形です。検索結果の一覧じゃなくて、日本語の散文で書かれた回答と、引用された投稿の URL が返ってきます。骨組みだけ抜くとこうです(抜粋・省略あり)。 { "model": "grok-4.6", "reasoning": {"effort": "low"}, "output": [ {"type": "reasoning"}, {"type": "custom_tool_call", "name": "x_keyword_search", "input": "{\"query\":\"(\\\"Claude Code\\\" OR Codex) (課金 OR コスト) min_faves:20 since:2026-09-04\",\"limit\":\"10\",\"mode\":\"Latest\"}"}, {"type": "custom_tool_call", "name": "x_keyword_search", "input": "..."}, {"type": "message", "content": [{ "type": "output_text", "text": "直近1週間で盛り上がっていたのは……(日本語の散文が続く)", "annotations": [ {"type": "url_citation", "url": "https://x.com/<handle>/status/<id>", "start_index": 334, "end_index": 392} ] }]} ], "usage": { "input_tokens": 46627, "output_tokens": 1875, "output_tokens_details": {"reasoning_tokens": 1306}, "server_side_tool_usage_details": {"x_search_calls": 7} } } 生の投稿データがそのまま落ちてくると思っていたので、ここで期待とズレました。「まず生データをもらってから自分で考える」というやり方が、この道具 単体 ではできないんですよね。探すところも読むところも、モデルにお任せする形になります。原文がどうしても要るなら、引用された URL を前回作った X API 側の取得に渡すことになります。 代わりに、モデルが実際に投げた検索クエリは custom_tool_call にそのまま残ります。何回検索したかは usage.server_side_tool_usage_details.x_search_calls に入っています。次の節の観測は、この2つを読んだものです。JSON のどこを読むかの注意は、記事の末尾に付録として置いておきます。 絞り込みは効きます。件数だけは決められません ツール側には、公式に絞り込みの口があります( X Search のパラメータ 、2026-09-14 時点)。 パラメータ 何を絞るか allowed_x_handles / excluded_x_handles 投稿者のハンドル(各最大20件。両方を同時には指定できない) from_date / to_date 期間(ISO 8601) enable_image_understanding / enable_video_understanding 投稿内の画像・動画も読ませるか 僕は期間をツール側とプロンプトの両方に書きました。ツール側だけで効いているかは確かめていないんですが、プロンプト側は効いているのが見えます。「いいね20以上に絞って」「期間は 2026-09-04 以降」と日本語で書くと、モデルが組み立てた検索クエリに min_faves:20 と since:2026-09-04 が入っていました。 lang:ja は頼んでもいないのに自分で使っていたくらいです。確認できるのは モデルが演算子を正しく組み立てること までで、返ってきた投稿が本当に条件を満たしていたかは追っていません。 ところが、件数だけはどうやっても動きません。モデルが自分で決める limit は、どの条件を渡しても "10" で固定でした。「最大50件見て」と明示しても 10 のままです。代わりに検索の回数が増えます。返ってきた投稿の本文は入力トークンに積まれるので、回数が増えれば入力も増える。指示の出し方が消費に効いてくるのはこの経路です。 じゃあリクエスト側で止められないのかと REST リファレンス を見ると、口は2つあります。そして、2つとも効きません(2026-09-11 時点)。 パラメータ 公式の説明 実際どうなるか search_parameters.max_search_results 使用する検索結果の最大件数 渡すと HTTP 410 が返って、リクエストごと死ぬ。 Live search is deprecated. Please switch to the Agent Tools API というメッセージ付き max_tool_calls このレスポンスで許可するツール呼び出しの最大数 2 を渡すと HTTP 200 で通って、エラーも無い。でも実際に走った検索は6回。同じ条件で付けずに投げたときは7回だった 前者は廃止された古い仕組みの残骸で、死ぬので間違えたことはその場で分かります。引っかかるのは後者で、上限を設定したつもりのまま、設定されないで走ります。死ぬほうがまだ親切だったな、と思いました。 effort が low 、 max_turns が 6 の条件で1回試しただけなので、クライアント側のツールになら効くのかもしれません。 ただ、そもそも僕が欲しいのは件数じゃないんですよね。求めているのはトレンドを拾えることであって、正直、50件とかどうでもいい。だから触るのは、次のノブになります。 答えの中身は effort で変えられます 返ってくる答えの中身を動かせるのは、 reasoning.effort だけでした。 low か medium か high を渡します。 既定は high なので、指定しないと一番重い設定で走ります(レスポンスの reasoning にこちらの設定が返ってくるので、省略して投げると high が入っているのが見えます)。 同じ問いを、 low と high だけ変えて投げてみました。投げたのはこれです。 直近1週間の X で、Claude Code / GitHub Copilot / Gemini / Codex の「コスト事故・想定外の課金」 「エージェントの暴走」「権限設計・承認フロー」について盛り上がっている投稿を、いいね20以上に絞って エンゲージメント順に調べて。話題を3〜5個のクラスタに分けて、各クラスタは次を各2行以内で書いて: ①論点(賛否が割れていればその対立も) ②代表投稿URL ③日本語圏か英語圏か。 実際に見た投稿だけに基づき、憶測は書かない。期間は 2026-09-04 以降に限る。 effort 返ってきた内容 検索回数 入力トークン 出力トークン low 話題の名前を並べるだけ。「対立は薄い」と書いて終わり 7 46,627 1,875 high 論点と証拠。賛否が割れている対立を名指しで拾い、具体的な機構(サンドボックス設定でも許可なく外に書けた、といった中身)まで書いてくる。スレッドを辿る呼び出しも走った 17 166,417 7,489 欲しかったのは後者です。話題の名前だけだと、「もう誰かが書いた話」で終わってしまうんですよね。 留保を一つだけ。これは同じ問いを1回ずつ投げただけで、対照も盲検もありません。X のタイムラインは刻々変わるので、同じ effort で2回投げても同じものは返ってきません。信じるかどうかは、自分の問いで一回試してみてほしいです。 残りの2つは、答えの中身を変えません。 走りすぎを止める保険 です。 max_turns はターン数の上限です。ただし公式が「呼び出し回数の上限ではない」と はっきり書いています 。1ターンに複数の呼び出しが並列で載るからです max_output_tokens は reasoning トークンを含めて止まるので、hard cap になるのは実質ここだけです。公式によると 既定は 128,000 最後にもう一つ。2026-09-21 の 12:00 PT から、 X Search の課金単位が変わります 。呼び出し1回あたりから、取れた投稿1件あたりへ、です。公式は「検索やスレッド取得で返った投稿は、親投稿も引用投稿も数える」と書いています。絞りたいのは件数なのに、件数を決めているのはモデルの側という噛み合わなさは、この日から効き方が変わってくるはずです。 で、これを何に使っているか 使い道は2つに寄っています。ひとつは、X にしか出ていない最新の動き。リリース直後の反応や不具合の報告みたいに、記事にまとまる前の段階のものです。もうひとつは、Web 検索では拾えない領域の調査。ブログや公式ドキュメントになったものは AI が普通に拾ってくるので、そこはもう困っていないんですよね。困るのは、まだ誰も記事にしていないのに X では話されている層です。 僕はこれを、自分が書こうとしている領域がもう誰かに埋められていないかの確認に使っています。 叩くたびに手で書くのは続かないので、自分用の skill と CLI にしました。配布はしていないので中身は省きますが、 effort と max_turns をコマンドのフラグに出した のがポイントです。撃つ前にノブを決めないと投げられない形にしてあります。 冒頭の問いに戻ると、X だけ AI が拾ってこない、という話は Grok で埋まります。ただ、埋まり方は「検索結果がそのまま返る」じゃなくて、「探してきた誰かが要約を寄越す」なんですよね。そこは最後まで変わらないところです。 最初の一歩として渡すのは一つだけです。 effort を明示して、1回投げてみてください。既定が high なので、省略するのは「一番重いのを選んだ」のと同じことになります。 付録:返ってきた JSON のどこを読むか 返ってきたものから何かを取り出すとき、どこを読むかの一覧です。 欲しいもの どこを読むか 落とし穴 回答本文 output[] の type == "message" にある content[].text message は複数に分かれることがある 。最後の一つだけ読むと本文を取り落とす 引用された投稿の URL output[].content[].annotations[] の type == "url_citation" ドキュメントは citations と呼んでいるが、 レスポンスに citations というキーは無い 実行された検索 output[] の type == "custom_tool_call" name は x_keyword_search / x_semantic_search / x_thread_fetch の3種。 input にモデルが組んだ検索クエリがそのまま読める 検索した回数 usage.server_side_tool_usage_details.x_search_calls 指示の出し方で増えるのはここ トークン usage.input_tokens / usage.output_tokens / usage.output_tokens_details.reasoning_tokens 返ってきた投稿の本文は入力トークンに積まれる 引用の件数 usage.num_sources_used 信用しない 。引用が7件あるのに 0 を返してきたことがある もう一つ、送った設定が返りに出るかどうかは、効いたかどうかとは別の話です。 送ったもの 返りに出るか 効いたかの確かめ方 reasoning / tools そのまま直下に返る 返ってきた値を読めばいい max_turns 返ってこない x_search_calls の回数で見る max_tool_calls null で返る 同上。 null で返ってくること自体は、効かなかった証拠にはならない ではまた! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AIにX検索を外付けする|Grok APIでXの最新情報を集める first appeared on SIOS Tech Lab .
最近の夏の長さになれたため、9月に涼しい事に戸惑っています。 柾本 彬(本人)です。
前提:楽楽明細とは別のアプリとして作った 起きたこと:12機能を1本のプルリクにまとめた 原因:4層の名前までしか決めていなかった 対策:機械に判定させる範囲を広げ、人が見る範囲を絞る 実例:レビューで通せなかった箇所 次にやるなら:プルリクの切り方から変える チェックリスト:着手前に決めておく項目 編集後記:インタビューを終えて ラクス技術広報です。 開発本部では、各部署のAI活用の取り組みを技術広報がインタビューし、記事にしています。今回は電子請求書発行システム「楽楽明細」の新しいオプション機能を、AIにほぼ実装させて約2か月でリリースした事例です。 本記事は、AIを使って順調に機能開発が進んだ話だけでなく、うまくいかなかったこと・その対策をまとめています。 AIに任せる範囲を広げる前に、正しさを機械が判定できる状態を作る。 今回はこの状態を作らないまま進めました。その結果、機能ごとに実装の仕方がばらばらになり、1機能のレビューで入った指摘を他の機能に横展開できず、同じ指摘を機能の数だけ受けることになりました。 納期の都合で12機能を1本のプルリクエストにまとめたことも重なり、変更ファイルは700を超え、サーバーサイドのレビュー担当が全量を確認し終えるまでに5営業日かかっています。 新規プロダクトでAI駆動開発を始める方 AIが書いたコードのレビューが追いつかないと感じている方 に向けて、着手前に決めておく項目を記事の最後にチェックリストとして置きました。是非ご参考ください。 [図1:任せる範囲と、機械が判定できる範囲] 前提:楽楽明細とは別のアプリとして作った   楽楽明細は、請求書や支払明細などの帳票を電子発行するクラウドサービスです。帳票のもとになる売上データは、お客様が販売管理システムやExcelで管理しているものを取り込みます。 販売管理システムを使っていないお客様は、売上データをExcelで管理しています。 ・営業や拠点ごとにファイルが分かれ、どれが最新かわからなくなる ・転記のときにミスも起きる ここを解決するために作ったのが、今回の 売上登録オプション です。専用画面で売上データを入力すると、そのまま請求データとしてCSV出力できます。 仕様はプロダクトマネージャーが決めました。AI(Claude)でプロトタイプを作り、動くものをお客様に見せながら40社に話を聞いています。話を聞くうちに最小限の機能で導入いただけるとわかり、最初のプロトタイプから機能を約30%削って、CSV出力と税額計算に必要な設定に絞りました。 楽楽明細本体には手を入れず、別のアプリとして切り出しています。長く運用してきた本体にAIを入れると既存機能を壊す可能性があるため、影響範囲を限定してAIに任せる範囲を広げる判断です。 項目 内容 期間 開発決定4月7日 → リリース5月末(実質2か月未満) 体制 設計・実装は2026年1月入社の川島卓大さんがほぼ一人。 サーバーサイドとフロントエンドで各1名がレビュー。 技術 Java、Spring Boot、React、TypeScript、PostgreSQL AIの使い方 仕様の書き起こしはClaude Code、kiro(cc-sdd)でspec化してエージェントに読ませる。 実装の主軸はCodex。 git worktreeで機能ごとに作業を隔離し、複数セッションを同時に走らせる。 起きたこと:12機能を1本のプルリクにまとめた   実装に使える期間は実質1か月弱で、機能は12ありました。機能ごとにプルリクエスト(以下プルリク)を切ってレビューを待つ余裕がないため、まず全機能をつなげて動かし、そこから改善する方針を選びました。 項目 実績 変更ファイル数 700超 サーバーサイドのレビュー 機能単位で半日〜1日。 最初のプルリクを全量見切るまでに5営業日(期間で2週間弱)。 フロントエンドのレビュー 大型プルリクと、機能単位に分割された後続15件のフロント部分を合わせて2人日。 GitHub Copilotによるレビューも入れていましたが、人手で見きれる量を超えています。機能ごとに切り分けてレビューできたのは、パッケージ構成をfeature-firstで先に決めていたためです。 原因:4層の名前までしか決めていなかった   プロダクトマネージャーからの要求仕様書は、お客様の求めるものが整理された状態で渡されています。ただ、そのままAIに渡せる粒度ではなかったと川島さんは語ります。 「そのままでは渡せませんでした。特に受け入れ条件と例外系が足りませんでした。」 そこで要件を「WHEN 条件 THEN 結果」のEARS形式で1アクション単位に分解し、「IF 制約 THEN 拒否」の例外パスを正常系と並べて書いてからspecに落としました。 実装側で先に決めていたのは、feature-firstのパッケージ構成と、DDD(オニオンアーキテクチャ)の4層の名前までです。層の中で誰が何を担うのか、検証はどこでやるのか、副作用はどこに置くのかは決めていませんでした。 その状態で機能ごとに並列でエージェントを走らせると、1機能のレビューで入った指摘を他の機能に横展開できず、同じ指摘を機能の数だけ受けることになりました。 「仕様自体は要件通り作成できているものが多かったが、責務が分離できていないものが多く、レイヤー間の妥当性を見る時間が多かった。」 要求がテストできる形になっていても、実装方針が決まっていなければ、AIはそれぞれの解釈で書きます。 対策:機械に判定させる範囲を広げ、人が見る範囲を絞る   [図2:判定を3段に分ける] CIとpre-commitは最初から入れていました。ルールの書き出しとマージゲートの追加は、機能ごとに実装がばらばらになった反省から足したものです。 「一番効いているのは『できました』と言わせず証拠を出させることです。」 川島さんは、サブエージェントの「テストが通った」という報告も鵜呑みにせず、親のエージェントがdiffとテスト出力を自分で確認します。 レビューは一次をGitHub CopilotとClaude Codeのスキルで出し、人が二次で見ます。観点が複数あるときは同じエージェントに全部任せず、観点ごとにサブエージェントを分けて並列で走らせます。指摘にはmust、should、ask、imo、nitのラベルを付け、対応するかどうかを人が判断しやすくしています。 実例:レビューで通せなかった箇所   本機能にて、サーバーサイドとフロントエンドのレビューを担当した2人に「レビューで通せなかった箇所」についてお伺いしました。 領域 レビューで通せなかった箇所 サーバーサイド メール送信のように非同期で構わない処理が、トランザクションの中に入っていた。 初期のプルリクでは、メールは送信されたのにDBがロールバックされ、無効なパスワード初期化用URLがユーザーに届く実装になっていた(リリース前に修正)。 サーバーサイド 業務ロジックがユースケースやインフラの層に流れ出す責務違反。 サーバーサイド N+1が起きやすい構造。 明細行20行の売上データを取得するのに、最初はSQLが23本走っていた。 フロントエンド 方針はバックエンドで検証して送信時に表示することだったが、全画面にリアルタイムバリデーションが入っていた(全画面から削除)。 フロントエンド すでにある共通コンポーネントを使わず画面ごとに直書きし、ドラッグ・アンド・ドロップも複雑に自前実装していた(ライブラリを使う形に置き換え)。 フロントエンド テーブル内のテキストフィールドに1文字打つごとに、テーブル全体が再レンダリングされていた。 レビューを担当した2人が、共通して口にしたことがあります。 「『動く』のと『そのまま出せる』の間には距離がある」 また、これから同じ進め方を始めるチームへ、2人からのコメントです。 サーバーサイド レビュー担当者 「設計、実装の前にどうやってAIをハンドリングをしていくかという工程をちゃんと設けるべきではあった。期日までが短く急ぎ早で始めたものの手戻りも多く、事前準備をちゃんと設けていても間に合わせられていたのではと思う。 」 フロントエンド レビュー担当者 「レビューする側もAIを使っていいということ。作る速度が上がる分、見る側もAIで理解スピードを早めないとレビューが追いつかなくボトルネックになる。」 次にやるなら:プルリクの切り方から変える   [図3:プルリクの切り方] 切れ目を先に決めておけば、レビューは内側から外側へ積み上げる順に流れます。 一人でフルスタックに進めた体制では、フロントとバックエンドの間で調整が発生しないため、動くものを作る速度は出ました。一方で、一人にかかる負担は大きくなりました。API規約を先に確定させれば、フロントとバックエンドを分担できます。着手前にAIのハンドリングを詰める工程を置くことも、次の案件に向けた課題として残りました。 チェックリスト:着手前に決めておく項目   冒頭でもお伝えした通り、本取り組みから得た知見を基に着手前に決めておく項目をまとめました。 ご自身のプロジェクトに当ててみてください。 仕様と設計で決めておくこと (→ 原因の章 ) □ 受け入れ条件と例外系を、1アクション単位で書き出したか(EARS形式など) □ 各層で誰が何を担うか、検証はどこでやるか、副作用はどこに置くかを決めたか 機械に判定させる仕組み (→ 対策の章 ) □ CIで必須にする項目を並べたか(lint、format、型チェック、単体テスト、secret scanning、依存パッケージの実在チェック) □ テストを実データに近い環境で流せるか(Testcontainersなど) □ 機械では拾えない観点を、プロジェクト固有のレビュー観点として文字にしたか □ エージェントに、テスト出力とdiffを証拠として出させる運用にしたか 分割の単位 (→ 次にやるならの章 ) □ API規約(インターフェース)を、実装より先に確定させたか □ プルリクの切れ目を、レビューできる大きさで先に決めたか 最後に、川島さんからのメッセージです。 「AIに任せる範囲を広げる前に、正しさを機械が判定できる環境を先に作ることが大事だと思いました。最初の壁はコードが書けないことではなく、動いているように見えて設計方針から外れたコードが、レビューの追いつかない速度で積み上がることです。AI駆動開発で変わるのは、コードを書く仕事の比重です。良し悪しを定義し検証する仕事へ重心が移ります。ツールは半年で入れ替わりますが、この土台はどのツールに乗り換えても効き続けます。」 編集後記:インタビューを終えて   取材していて印象に残ったのは、川島さんもレビュー担当の2人も、うまくいった話より「次はこうする」を具体的に話してくれたことでした。700ファイルのプルリクは、社外に出すには気の重い話だと思います。それでも数字と経緯をそのまま出してくれたので、この記事が書けました。 開発本部では、うまくいったところとやり直したいところの両方を、これからも技術広報が聞いてご紹介していきます。

動画

該当するコンテンツが見つかりませんでした

書籍