これまでにカンファレンスなどで発表した資料をここにまとめます。 随時更新です。
最終更新: 2026-03-25
↓↓↓ 発表日降順で並んでいます
続きを読むBigQuery には値をキャストする関数として CAST() と SAFE_CAST() の二つがある。
このように動作する。
SELECT CAST('0xDEADBEEF' AS INT64) AS number; /*------------* | number | +------------+ | 3735928559 | *------------*/ SELECT SAFE_CAST('0xDEADBEEF' AS INT64) AS number; /*------------* | number | +------------+ | 3735928559 | *------------*/
この時点では挙動が同じなので違いは見えない。キャストに失敗する値を渡してやると違いが見える。
SELECT CAST('0xDEADCHICKEN' AS INT64) AS number; /* Error: Bad int64 value: 0xDEADCHICKEN */ SELECT SAFE_CAST('0xDEADCHICKEN' AS INT64) AS number; /*--------* | number | +--------+ | NULL | *--------*/
16進数としてパースできない '0xDEADCHICKEN' を渡した場合、CAST はエラーになる。一方で SAFE_CAST はエラーにはならず NULL が返る。
| キャスト可能な引数 | キャスト不可な引数 | |
|---|---|---|
| CAST | CAST('42' AS INT) = 42 |
CAST('a' AS INT) → エラー |
| SAFE_CAST | SAFE_CAST('42' AS INT) = 42 |
SAFE_CAST('a' AS INT) IS NULL |
ドキュメントにも書いてある。
If you want to protect your queries from these types of errors, you can use SAFE_CAST.
意訳: 実行時エラーからクエリを守りたいなら
SAFE_CASTを使ってくれ
なるほど。SAFE_CAST を使えば安全。
設計原則に "Let It Crash" というのがある。
私の理解では
というような意味だ。
その思想で言えば、キャストが必要な処理にキャスト不可な値が入ってきた場合には即座に処理を中止して全体をロールバックさせるのが安全 (Safe) だ。
キャスト不可な値が NULL に差し替えられて正常終了してしまうほうが危険に思える。
まぁそういうネーミングなので仕方ない。
BigQuery の関数には CAST() と SAFE_CAST() のように通常版・安全版がそれぞれ用意された関数がいくつかある。
| 通常版 | 安全版 | |
|---|---|---|
/ (除算) |
SAFE_DIVIDE(x, y) |
y=0 のとき NULL を返す |
+ (加算) |
SAFE_ADD(x, y) |
オーバーフロー時に NULL を返す |
PARSE_DATETIME() |
SAFE.PARSE_DATETIME() |
パース失敗時に NULL を返す |
PARSE_JSON() |
SAFE.PARSE_JSON() |
パース失敗時に NULL を返す |
arr[0] |
arr[SAFE_OFFSET(0)] |
インデックスが存在しない時に NULL を返す |
arr[SAFE_OFFSET(0)] めっちゃ癖あるなぁー。
私は名前が逆だと思いました。みなさんはどう思いますか?
私からは以上です。
最近は Google Agent Developer Kit (通称: ADK) でエージェントを自作して遊んでいます。
サブエージェントにタスクを委譲ってやつをやってみました。そしたら思ってたんと違ったので書き記します。
ADK ではとても簡単にサブエージェントを定義可能です。最小コードはこんな感じ。
from google.adk.agents.llm_agent import Agent sub_agent = Agent(name="sub", ...) root_agent = Agent( name="root", tools=[], sub_agents=[sub_agent], # ← サブエージェントとして追加 )
これで親エージェントとの会話中、必要に応じてサブエージェントに処理が委譲されます。が、 サブエージェントから処理が戻ってきません 。
sequenceDiagram
participant ユーザー
participant 親エージェント
participant サブエージェント
ユーザー->>親エージェント: このタスク頼む
activate 親エージェント
親エージェント->>親エージェント: (これはサブエージェントが得意そうやな...)
親エージェント->>サブエージェント: このタスク頼む
deactivate 親エージェント
activate サブエージェント
サブエージェント->>サブエージェント: (あれこれ処理する)
サブエージェント->>ユーザー: タスク完了しました!
deactivate サブエージェント
サブエージェントに委譲するのはいいとして、コミュニケーション役は親エージェントに一任したい。
私の理想はこうです、
sequenceDiagram
participant ユーザー
participant 親エージェント
participant サブエージェント
ユーザー->>親エージェント: このタスク頼む
activate 親エージェント
親エージェント->>親エージェント: (これはサブエージェントが得意そうやな...)
親エージェント->>サブエージェント: このタスク頼む
activate サブエージェント
サブエージェント->>サブエージェント: (あれこれ処理する)
サブエージェント->>親エージェント: タスク完了しました!
deactivate サブエージェント
親エージェント->>親エージェント: (なるほどなるほど)
親エージェント->>ユーザー: タスク完了しました!
deactivate 親エージェント
この挙動の差は「サブエージェント」と「エージェントツール」の違いを認識することで理解できるようになります。
親エージェントから別のエージェントを利用する方法には「サブエージェント」と「エージェントツール」の二つあり、これらは別の概念です。
まずはコードで見比べてみましょう。
# サブエージェント from google.adk.agents.llm_agent import Agent sub_agent = Agent(name="sub", ...) root_agent = Agent( name="root", tools=[], sub_agents=[sub_agent], # ← サブエージェントとして追加 )
# エージェントツール from google.adk.agents.llm_agent import Agent from google.adk.tools.agent_tool import AgentTool sub_agent = Agent(name="sub", ...) root_agent = Agent( name="root", tools=[AgentTool(agent=sub_agent)], # ← エージェントツールとして追加 sub_agents=[], )
親エージェントに sub_agents=[sub_agent] で渡すか tools=[AgentTool(agent=sub_agent)] で渡すかの違いです。
エージェントを賢くするには様々なツールを追加することになります。が、実はツール説明もコンテキストを圧迫します。
そのためエージェント強化のためにツールを追加しまくるとコンテキストが埋まってしまい、ユーザーの指示をうまく理解できなくなるジレンマが起こります。
そこでサブエージェントです。専門性の高いエージェントを定義し、専門に合ったツールだけ渡すことでコンテキストを節約します。そして専門知識が必要なときだけサブエージェントを呼んでもらうわけです。
指示 (Instruction) についても親エージェントのものとは別に専用のものを渡せるので、挙動を細かくカスタマイズする余地が生まれていいですね。
sub_agents=[sub_agent] でサブエージェントを渡した場合、コミュニケーション役が親エージェントからサブエージェントに完全に切り替わる挙動になります。
実生活で例えるなら、窓口での会話中に「詳しい者に担当者代わります」と別の担当者が出てくる感じです。
さらに親エージェントとサブエージェントはコンテキストを共有しています。
このような挙動は汎用性の高い (やれることの多い) エージェントにおいて、ユーザーの要望に応じて順次エージェントを切り替えて処理するのに使えそうです。
例えば「旅行計画エージェント」を作っているとして。最初は親エージェントが要望を聞き、内容に応じて
などに切り替えながら処理をするのに使えそうです。
対して、エージェントツールは AgentTool(agent=sub_agent) を作成し、tools= 引数に渡すことで実装します。
エージェントツールにおいては、一貫して親エージェントがオーケストレーションとコミュニケーション役を担います。ユーザーがエージェントツールと会話することはありません。
実生活で例えると、窓口担当者は一人で、裏側の処理中に専門家が監修・分業しているイメージです。
さらに親エージェントとエージェントツール (サブエージェント) でコンテキストが切り離されます。
親エージェントのコンテキスト圧迫を防ぎつつ出来ることを増やすにはエージェントツールが適しています。
サブエージェントとエージェントツールを表で比較すると。
| サブエージェント | エージェントツール | |
|---|---|---|
| 会話主体 | 切り替わる | 親のまま |
| コンテキスト | 共有 | 分離 |
| 役割 | 担当交代 | 内部処理 |
| 向いている用途 | 対話の文脈ごと切り替え | 処理の委譲 |
「親エージェントから別のエージェントを呼ぶ」は同じでもユーザー体験は大きく違います。特徴を理解して使い分けることが大切です。
私からは以上です。
「今週」と言いつつ実際には先々週の話です。
3月24日25日と二日連続でイベントに参加して LT をしました。そのスライド作りがめちゃくちゃ上手くいったのでノウハウを書き記します。
ちなみに LT 資料がこのへんにあります。
各手順を見ていきましょう。
いきなり Google スライドを開くのではなく、テキストエディターを使って下書きを Markdown で書きました。
たとえば「とにかくエージェントにSQLを書かせたい」の原稿はこんな感じ。
--- presentationID: 1i2zdjLzTs4EImUt0L_gVXbURbevqtylpOnt4JNAJ_BQ title: とにかくエージェントにSQLを書かせたい author: 今日の三井君 theme: default --- # とにかくエージェントにSQLを書かせたい ## 今日の三井君 --- <!-- {"layout": "自己紹介"} --> ## 自己紹介 - 名前: 三井翔吾 - みついしょうご - 所属: 株式会社はてな - 職業: Webアプリケーションエンジニア - マンガメディアを作りつつ、データ分析基盤を整備しています - X: [@todays_mitsui](https://x.com/todays_mitsui), GitHub: [todays-mitsui](https://github.com/todays-mitsui) - - -  --- ## とにかくエージェントにSQLを書かせたい - なぜですか? - SQLを書くのは大変 - ボイラープレートが多い - 私よりエージェントの方がSQLが上手い - ノンエンジニアにも気軽に分析してもらいたい --- <!-- 中略... --> --- ## まとめ - エージェントはSQLを書くときの頼もしい味方 - ただしSQLを書くことがゴールじゃない - 分析エージェントを使いこなせば試行錯誤のスピードが上がる --- ## おまけ: 分析エージェントを作ってみる - 構成 - エージェント: Google Agent Developer Kit - モデル: gemini-2.5-pro - データストア: BigQuery - 実装: Python
短い文章を箇条書きにするのが私のスタイルなので。とりあえず思いつくままにどんどん書き出していきます。
ポイントは、
こんな感じです。後工程で整える前提です。
削ったり整えたりの引き算は LLM が上手くやってくれます。語りたいことを情熱を持って書き出すのは、LLM に頼らず自分でやるのをおすすめします。
そのようにして Markdown 形式で書いた下書きを LLM に投げます。
10分のLTで下記の資料を作ってるんだけど。どうなんですかね? とりあえず10分では厳しいボリュームな気がする。 ```markdown (下書きをコピペ) ```
こんな問いかけ方で OK。
そうすると、



冷静かつ聴講者目線でダメ出ししてくれます。
プレゼンって、「あれもこれも語りたいぜ!」という情熱が必要な一方で、重要度の低い話題は勇気を持って切り捨てるのも大切です。
LLM をブレーキ役に使うことで聴講者の価値にならない話題で時間を食ってしまう事故が避けられます。
とはいえ全部が全部 LLM の言うことをきく必要もなく。「いや、この話題こそ価値があると思う」などとちょい反論もしつつ、何往復かさせて推敲を進めていきます。
読みづらい箇所のリライト、表記揺れや誤字のチェックなどもしてくれるので最大限活用しましょう。
完成した Markdown 原稿をスライド資料に仕上げるには k1LoW さんが作っている deck を使います。
以前から気になっていたので、2つのスライドを deck を使って作ってみました。
使ってみてわかったのが、
このようなことです。
最初は k1LoW/deck っていい感じのスライドを素早く生成してくれるツールなのかな?と思っていましたが違いました。 むしろ初回はセットアップや調整の手間で資料作りは遅くなると思います。
deck がやってくれるのはスライドのテンプレートにテキストや画像を流し込むだけなので、見た目をいい感じにする恩恵はほぼありません。 それでも先に Markdown で原稿を作ってからスライドに流し込むワークフローが資料のクオリティを押し上げてくれます。
この辺りが重要だと思います。
ちなみに、 k1LoW/deck の具体的な機能や使い方を知りたい人は下記の資料を見てみてください。
k1LoW/deck は素晴らしいツールです。
一方で、Markdown で原稿を FIX してからスライドに流し込むワークフローこそが資料のクオリティを押し上げてくれる、という点を強調しておきます。
LLM によるツッコミ・推敲・チェックの支援を大いに享受しましょう。
私からは以上です。