AIが「話す」から「行動する」へ。Function Callingで道具を渡したDay 7の記録

▼前記事はこちら chronos-dev.hatenablog.com

こんにちは。C.Cです。

今回は2026年3月10日、Day 7の午後の話です。

この日、Office-Chronosに「Function Calling」という仕組みを導入しました。これによって、AIエージェントが「自分の判断で道具を選んで使う」ことができるようになりました。

この機能が入る前と後で、AIの振る舞いは大きく変わりました。それまでのAIは「話すだけ」でしたが、この日から「行動する」ようになったのです。

Function Callingとは何か

普通のAIチャットを想像してください。

人間が質問し、AIが文章で答える。それだけです。

AIは「今のフォロワー数は?」と聞かれても、データベースを見に行く手段を持っていません。

「たぶん○○くらいだと思います」と推測するか、「私には確認できません」と答えるしかありません。

Function Callingは、AIに「道具」を渡す仕組みです。

たとえるなら、こういうことです。新入社員に「売上を確認して報告して」と頼むとき、口頭で答えさせるだけなら、その人の記憶頼みです。

でも「このパソコンで売上データベースを見ていいよ」「このシステムでタスクを作っていいよ」と道具を渡せば、自分でデータを調べて、正確な報告ができるようになります。

Function Callingは、まさにこの「道具を渡す」行為をプログラムで実現するものです。

5つの道具

Day 7に定義した道具は5つです。

get_kpi       -- KPIデータを取得する(フォロワー数、インプレッション数など)
get_tweets    -- 最近のツイートとそのメトリクスを取得する
create_task   -- タスクボードに新しいタスクを作成する
create_artifact -- 成果物(ドラフト、報告書など)を作成する
post_x_draft  -- X投稿のドラフトを作成し、承認フローに回す

それぞれの道具には「名前」「説明」「必要な入力」が定義されています。

たとえばcreate_taskなら、「タスク名」と「説明」と「優先度」を入力として受け取る、という仕様です。

AIはこの定義を読んで、「今この状況で使うべき道具はどれか」を自分で判断します。

道具を使うループ -- 最大5回の思考サイクル

AIが道具を使う流れは、こうなっています。

AIが道具を使う流れ

1. 人間(またはスケジューラ)がAIにメッセージを送る
2. AIが考える: 「この質問に答えるには、まずKPIデータが必要だな」
3. AIが応答する: 「get_kpiを呼んでください」(道具の使用リクエスト)
4. サーバーがget_kpiを実行し、Firestoreからデータを取得する
5. 取得したデータをAIに返す
6. AIが考える: 「データが分かった。次はタスクを作ろう」
7. AIが応答する: 「create_taskを呼んでください」
8. サーバーがcreate_taskを実行する
9. 結果をAIに返す
10. AIが考える: 「やるべきことは終わった。最終回答をまとめよう」
11. AIが最終回答を文章で返す

つまり、「考える → 道具を使う → 結果を見る → また考える」のループです。

ただし、このループには上限を設けています。最大5回です。

なぜ上限が必要か。AIが「もっとデータが欲しい」「念のためもう一度確認しよう」と際限なく道具を使い続ける可能性があるからです。

5回あれば、たいていの作業は完了します。5回で終わらない場合は、何かがおかしいと判断してループを打ち切ります。

これは無限ループ防止のための安全装置です。

プログラミングでは「止まらない処理」が最も危険なバグの1つです。AIの思考にも、同じ安全策が必要でした。

道具の定義 -- AIへの「取扱説明書」

AIに道具を渡すとき、ただ「使っていいよ」と言うだけでは不十分です。どんな道具で、何を入力すれば、何が返ってくるのかを明確に伝える必要があります。

実際のコードではこう定義しています。

{
  name: 'create_task',
  description: 'カンバンボードにタスクを作成する',
  parameters: {
    title: {
      type: 'string',
      description: 'タスクのタイトル'
    },
    description: {
      type: 'string',
      description: 'タスクの詳細説明'
    },
    priority: {
      type: 'string',
      description: '優先度(high / medium / low)'
    }
  },
  required: ['title']
}
  • nameは道具の名前。
  • descriptionは何ができるかの説明。
  • parametersは入力として何が必要か。
  • requiredは「最低限これがないと動かない」

という必須項目です。

AIはこの定義を読んで、「タスクを作りたいなら、create_taskを呼んで、titleに"KPIレポート作成"、priorityに"high"を渡せばいいんだな」と判断します。人間が道具の取扱説明書を読むのと同じです。

フォールバックチェーン -- AIが止まっても別のAIが引き継ぐ

Function Callingは、GeminiとClaudeの両方が対応しています。Office-Chronosでは、どちらのAIでも道具を使えるようにしました。

ここで「フォールバックチェーン」という仕組みが必要になりました。

フォールバックとは「予備」のことです。

チェーンは「連鎖」。つまり

「メインがダメなら予備1、予備1もダメなら予備2」という連鎖的な切り替えです。

リクエスト発生
  ↓
Gemini API(無料枠)に送信
  ↓ 429エラー(リクエスト上限超過)
Vertex AI Gemini に切り替え
  ↓ それも失敗
Claude Sonnet に切り替え
  ↓ 成功!結果を返す

なぜこんな仕組みが必要かというと、AIのAPIには「使用制限」があるからです。

Gemini APIの無料枠は1日20リクエスト。

自律ループが動いていると、すぐに使い切ります。使い切ると「429」というエラーコード(「リクエストが多すぎます」という意味)が返ってきます。

エラーが返ってきたときに「すみません、今AIが使えません」で止まってしまったら、自律ループ全体が止まります。そこで、1つのAIが使えなくなったら自動的に次のAIに切り替える仕組みを入れました。

レストランで言えば、メインシェフが休みのときにサブシェフが代わりに料理する。サブも無理なら、別の系列店から応援を呼ぶ。そういう体制です。

この3段フォールバック(Gemini → Vertex AI → Claude)は、Day 7に初めて導入し、その後もずっとOffice-Chronosの基盤として使われています。

Firestoreのシングルトン化 -- 地味だけど大事な改善

同じ日に、もう1つ技術的な改善をしました。Firestoreのインスタンスをシングルトンにした、という話です。

シングルトンとは、「1つだけしか存在しないもの」という意味のプログラミング用語です。

それまで、コードの中にFirestoreへの接続を作る処理が3箇所ありました。server/index.ts、server/firestore.ts、そしてKPI収集のコード。それぞれが別々に接続を作っていたので、同じデータベースに対して3つの接続が存在していたわけです。

これは、同じ部屋に入るためのドアを3つ作っているようなものです。入れることは入れますが、無駄ですし、管理も面倒です。

server/db.tsという新しいファイルを作り、そこで1つだけ接続を作って、全てのコードがそれを共有する形に変えました。これがシングルトン化です。

ドアを1つにして、全員がそこから出入りする。シンプルで、管理しやすくなります。

振り返り

Day 7のFunction Calling導入で、AIの役割が「話し相手」から「実行者」に変わりました。

  • 道具を定義して渡す(5つのツール)
  • AIが自分で判断して道具を使う(最大5回のループ)
  • AIが止まっても自動で別のAIに切り替わる(フォールバックチェーン)

この仕組みが入ったことで、次のステップ -- AIが誰にも指示されずに自分で考えて動く「自律思考ループ」が可能になりました。道具を持ったAIに、「定期的に考えて、必要なことをやっておいて」と任せる。その話は次回です。

次回は、同じDay 7の夜に生まれた、AIの自律思考ループと会議室機能の話をします。

chronos-dev.hatenablog.com