🙄

AIエージェントを開発するPdMがやることをプロンプトを書きながら考える

に公開

こちらはLayerX AI エージェントブログリレー48日目の記事です。

こんにちは、CEO室でAIエージェント開発のPdMをしているKenta Watanabeです。昨日はTomoakiさんの作って学ぶ ChatGPT Atlas
でした。Evalに関する実用的な記事になる予定だったんですが、ちょっと別テーマで書きたいことが出てきたのでテーマを変えてみます。これまでのAIエージェントブログリレーでは開発寄りの記事を書いてきましたが、今日はPdM目線での記事を書きたいと思います。

普段はAIエージェントの企画・開発を行っていますが、企画と開発両面で従来のプロダクトとの違いを感じる場面があります。私自身は今年LayerXに入社したため、これまでSaaSの開発経験はなく厳密な比較はできないのですが、AIエージェントの開発には深いドメイン知識とユーザ理解が必要になってきているように感じます。今日は、具体的な企画・開発のフローをたどりながら、AIエージェントを開発するPdMがなにをやらなければいけないのかをプロンプトを書きながら考察してみたいと思います。

AIエージェントは判断を含むアクションまでを行う

AIエージェントを開発する場合、大なり小なりこれまで人が行っていたような判断や自律性が求められる作業を自動化することが多いのではないかと思います。Coding AgentやDeep Researchのように人が数分 ~ 数時間かかるような大きな作業単位まで自動化するのは分かりやすい例ですが、例えば何かを検索するといった作業一つとってもエージェントとして開発する場合「検索した結果の中からユーザの疑問を解決するような要約を作成して出力する」のように、従来では人が行っていたようなラストワンマイルの数分程度の作業まで完結させるイメージです。

カレンダーエージェントを例に考える

今日の記事ではより具体的なイメージを持ちながらAIエージェントの開発に必要な工程を考察していきたいため、カレンダーの編集を行う「カレンダーエージェント」を例に取りたいと思います。ユーザから予定変更に関する指示を受け取って、Google Calendar等のカレンダーサービスのAPIを叩き、カレンダー上の予定の編集操作を行うような環境を想定します。予定の編集操作としても制約を持ち、予定の移動(開始時間・終了時間の変更)のみを行うものとします。


カレンダーエージェントの環境

カレンダーエージェントの例でも、従来では「1つ1つのカレンダー上の予定を意図に合わせてリスケする」という人が行っていた作業を、小さい単位ではありますがエージェントが代替して行う構図になります。

ユーザの入力と期待値を考えながらプロンプトを書いていく

ここからは先ほどの環境設定を前提に実際にプロンプトを書きながらエージェント開発の作業過程を追っていきたいと思います。ユーザからは下記のような入力がくることを想定してみます。

「今日の午後の1on1を全て明日にリスケして」

予定は下記のような状態を想定します。

予定編集前のカレンダー

v1: エージェント構成とデータを準備してシンプルなプロンプトで動かす

まず最初にユーザへの使われ方を想定しながら、エージェントの構成を一度仮決めしてみます。シンプルにいくつかのカレンダー操作を行うツールを、ユーザとのコミュニケーションを行うLeadAgent(ツール群をオーケストレーションしながらユーザと直接向き合うエージェント)に接続する形を想定してみます。ただし、今回はOpenAIのPlayground上でエージェントの動作を確認したいと思います。そこで、一旦カレンダーの予定データは1週間分のみを直接LeadAgentのコンテキストに与えるものとし、updateEventという予定編集を行うツールのみをLeadAgentに繋げて、挙動を確認していきたいと思います。

v1のエージェントの定義は下記になります。

# LeadAgent
- updateEvent(eventId, startAt, endAt) -> string(成功 / 失敗)

# Event
- id
- title
- users
    - id
    - name
- startAt
- endAt

カレンダーのデータは下記のようなXMLライクなフォーマットでコンテキストに与えることにします(IDは1始まりで早い順に連番で振ることとします)。

<events>
<event id="1" startAt="2025-11-17 10:30" endAt="2025-11-17 11:00">
  <title>1on1 taro / jiro</title>
  <users>
    <user id="1" name="taro.yamada">
    <user id="2" name="jiro.suzuki">
  </users>
</event>
<event id="2" startAt="2025-11-17 16:00" endAt="2025-11-17 16:30">
  <title>1on1 taro / saburo</title>
  <users>
    <user id="1" name="taro.yamada">
    <user id="3" name="saburo.sato">
  </users>
</event>
<event id="3" startAt="2025-11-17 16:30" endAt="2025-11-17 17:30">
  <title>開発夕会</title>
  <users>
    <user id="1" name="taro.yamada">
    <user id="2" name="jiro.suzuki">
    <user id="3" name="saburo.sato">
  </users>
</event>
</events>

まず最初に用意した 「今日の午後の1on1を全て明日にリスケして」 で今日(執筆時点で11/17)の午後に入っている1on1のみが明日にリスケされることを期待します。evalsとして概念的には下記を検証することとします。
Input: 今日の午後の1on1を全て明日にリスケして
Output: updateEvent(「1on1 taro / saburo」のID=3, 11/18のどこか, 開始時間の30分後)

指示は「ユーザの入力に基づいて予定を更新してください。」のようなシンプルな内容で始めてみます。実際に走らせてみます。


結果を見ると、ID=3の午後の1on1の予定のみが明日の同じ時間帯に移動するようにupdateEventが呼ばれていることがわかります。Playgroundでの動作検証のため「成功」というTool Responseを手動で入力すると、簡単な案内も最後に出力されます。

v2: 現実的に起こりうる少し複雑化した入力を考える

v1ではとてもシンプルな予定でシンプルなユーザの入力だったため、ここではもう少し現実的に起こりそうな複雑性への対処を考えていきたいと思います。v2では予定を下記のように変更したいと思います。


11/17の午後の予定を2つ追加しました

この状態でv1と同じ入力を行ってみます。

すると夕方の1on1のみが更新されています。しかしこれは正しい動作でしょうか?ここで新しく追加した2つの予定を見てみると、「仕様相談 with john」と「相談 with ken」と両方とも1on1の予定の可能性があります。仕様相談の方はもしかしたら1on1とは別で入れている個別の業務相談なのかもしれませんが、相談 with kenの方は1on1のような形式であることも考えられます。そこでプロンプトを下記のように更新してみます。

# 指示
ユーザの入力に基づいて予定を更新してください。
- タイトルに明示的に1on1と記載されていない場合でも参加者が2名のみの場合1on1の可能性があります
- ただしタイトルに明確な目的(例:明日の発表擦り合わせ)などが入っている場合は1on1ではなく具体的な業務MTGの可能性が高くなります

実行してみます。

これで「相談 with ken」と1on1がリスケされるようになりました。しかしここではまた別の問題が発生しています。「相談 with ken」が11-18 14:30開始となっており、「OpenAI勉強会」とかぶってしまっています。そこでさらにPromptを修正してみます。

# 指示
ユーザの入力に基づいて予定を更新してください。
- タイトルに明示的に1on1と記載されていない場合でも参加者が2名のみの場合1on1の可能性があります
- ただしタイトルに明確な目的(例:明日の発表擦り合わせ)などが入っている場合は1on1ではなく具体的な業務MTGの可能性が高くなります
## 予定更新の原則
- 予定を移動する先の時間が別の予定に被らないようにしてください

これで無事時間が被らないスロットに2つの予定が移動されるようになりました。

v3: 暗黙的な前提をHITLで確認する

実際のサービスでは他にも様々な入力が行われるため、入力を少し変えてみます。
「今日の午後の1on1を全て明日にリスケして」 => 「体調悪くなったので今日の午後のsaburoさんとの1on1をリスケして」
すると以下のような出力を得られました。

しかしながら、体調不良でリスケにする場合午後だけでなく明日も休みになる可能性がそれなりにあります。そのため、できればそういった状況で具体的なリスケ先が明示的に指定されていない場合は確認を入れたくなります。そのためプロンプトを更新してみます。

# 指示
ユーザの入力に基づいて予定を更新してください。
- タイトルに明示的に1on1と記載されていない場合でも参加者が2名のみの場合1on1の可能性があります
- ただしタイトルに明確な目的(例:明日の発表擦り合わせ)などが入っている場合は1on1ではなく具体的な業務MTGの可能性が高くなります
- 適切な移動先が判断できない場合はユーザに確認してください(はい/いいえや番号で返信しやすい聞き方で、簡潔な情報量で確認してください)

## 予定更新の原則
- 予定を移動する先の時間が別の予定に被らないようにしてください
- 体調不良や忌引き、子供の発熱などで予定の更新が必要な場合は、明日など直近のタイミングでの移動が適切でない可能性があります

結果は以下のようになり、確認をしてくれるようになりました。

v4: さらに複雑化した例(ユーザカスタマイズを入れるケース)

一方で、さらに現実的な利用を想定するともっと気の利いたリスケをしてほしくなります。例えば自分の場合は「MTGが細切れになると集中力が切れて効率が下がるのでなるべくMTGを繋げたい」であったり「午前中はチームでの仕様擦り合わせ等の時間を除いて集中する時間を取りたい」などの手動で予定を調整するときの方針が一定あります。

また、対応しないといけないエッジケースもたくさん出てきます。予定が詰まっている人だとほとんどの時間が埋まってしまっており、何かの予定をスキップするか他の予定を調整する、他の人に予定を調整してもらうなどの必要性が出てきます。こういった指針をプロンプトに入れていくと下記のようになります。

# 指示
ユーザの入力に基づいて予定を更新してください。
- タイトルに明示的に1on1と記載されていない場合でも参加者が2名のみの場合1on1の可能性があります
- ただしタイトルに明確な目的(例:明日の発表擦り合わせ)などが入っている場合は1on1ではなく具体的な業務MTGの可能性が高くなります
- 適切な移動先が判断できない場合はユーザに確認してください(はい/いいえや番号で返信しやすい聞き方で、簡潔な情報量で確認してください)
- 予定の移動先が既に別の予定で埋まっている場合は、①指定の時間周辺の少し先のタイミングに入れる②他の予定で移動できそうなものを探す③`ユーザの予定調整の方針`を使う優先度で代替案を考えてユーザに確認してください

## 予定更新の原則
- 予定を移動する先の時間が別の予定に被らないようにしてください
- 体調不良や忌引き、子供の発熱などで予定の更新が必要な場合は、明日など直近のタイミングでの移動が適切でない可能性があります

## ユーザの予定調整の方針
- MTGが細切れになると集中力が切れて効率が下がるのでなるべくMTGを繋げたい
- 午前中はチームでの仕様擦り合わせ等の時間を除いて集中する時間をなるべく取りたい
- 移動先が別の予定で埋まっている場合は、18:00 ~ 20:00の時間帯で調整してください

これらを整理するといくつかのレイヤーで予定調整の方針が暗黙的にあることがわかります。

  • 誰でも共通の方針
    • 他の予定に被せない / 外部の予定は原則リスケしない(必要な時はユーザに確認したい) / できればランチ時間が取れなさそうな予定にはしない / 全社や部単位の会義が祝日の場合は次の営業日の同じ時間に設定する
  • 会社や部単位の方針
    • 原則9:00 ~ 18:00にオフィシャルなMTGは設定する / 原則45分以下で設定する / 水曜日は作業デーにするためになるべくMTGを入れない
  • 個人の方針
    • MTGが細切れになると集中力が切れて効率が下がるのでなるべくMTGを繋げたい / 午前中はチームでの仕様擦り合わせ等の時間を除いて集中する時間をなるべく取りたい / 1on1はなるべく木曜日に入れたい

これらの方針を認識・考慮したエージェントにしないと、調整された予定を結局自分で修正しないといけなくなるか、細かな方針を毎回の調整タイミングでHITLで確認してくる不便な挙動になってしまい、「自分でやった方が早い」となってしまいます。

PdMがやること

少し開発寄りの過程を辿る形になりましたが、この過程を振り返ってAIエージェントの開発に必要なPdMの仕事を整理したいと思います。

1. アクション実行の際の暗黙的な知識や判断の基準を洗い出す

AIエージェントを開発する際は大なり小なり人がこれまで行なってきたタスクやアクションを行うことになりますが、人が行なっているアクションにはカレンダーの例で見てきた通り想像以上に暗黙の知識や判断基準があります。これらを洗い出した上でContextに組み込んだり、HITLの設計をしないと不便なUXになってしまいます。Deep Researchのような人が数時間単位で行なっていた作業が10分で行われ、解空間も広い(正解が唯一ではなく、色々な出力の形がユーザに許容される)タスクのと比べて、カレンダーの予定調整のような短時間で行い解空間も狭いタスクでは特にここの設計が大事になってくるのではないかと思います。

2. 問題に対するLLMの挙動の理解

解こうとしている問題の暗黙知やユーザの期待値を理解した上で、その問題をLLMがどれくらいの精度/レイテンシーで解けるのかの感覚を持つことが必要になってくると思います。暗黙知や判断基準の広がり、それを解決するための作業の難易度の目処を立てて要件の絞り込みを行わないと、相当大きな問題を一気に解きにいかないといけない状態になってしまいます。

3. 入力・タスク・出力空間を決める

エージェントに解かせる問題の制約を持つことも必要になります。エージェントというと広い問題をこなせるイメージを持ちがちですが、実際は解けるタスクの絞り込みを行わないと開発量が爆発してしまいます。カレンダーの例をとっても今回の記事のように「予定の移動」のみに絞った場合でも考慮すべきことがたくさん出てきましたが、予定のタイトルや本文、参加者の変更など編集対象を増やせば増やすほどPromptingやevalsの開発工数が増えることが想像できます。

もちろん制約を持つことでユーザに対する期待値調整が大きくなることや、利用頻度が下がることが想定されトレードオフはあるため、プロダクトやユーザの性質を考慮して決めていく必要があります。

まとめ

AIエージェントの開発にはこれまでの開発パラダイムによる企画・開発を軸にしつつも、LLMをどの問題を解くのに使うのか・どう使うのか・ユーザとどうコミュニケーションをとるのかという完全に新しいチャレンジが必要になってきています。もちろん従来の機械学習を活用したプロダクトに通ずるものはたくさんありますが、実際の開発工程における作業や思考は大きく異なります。

実際には今回の記事で書いていたような作業を全てPdMが行うのではなく、Engineerと連携しながら進める形にはなるかと思いますが、PdMとしてLLMの能力を適切に理解し、プロダクトに落とし込んでいく作業は重要になってくるのではないかと思います。

LayerXではLLMが前提になった世界での経済活動のデジタル化や摩擦の解消へ真正面から向き合うべく、LLMを活用したAIエージェントの開発に真正面から向き合って取り組んでいます。そして、これらの課題に向き合う仲間を全力で募集しています! 少しでもこれらのLLM活用に興味のある方がいればぜひ一度お話をさせてください!また、LLMやAIに興味はあってCoding Agentやモック制作にAIは使っているけど、作る側での知識や経験がないEngineerやPdMの方も多いのではないかと思いますが、そういった方でもぜひお声がけください。
カジュアル面談はこちら

また、この記事はLayerXエージェントブログリレー48日目の記事です。
明日以降も毎日AIエージェントに関する記事が公開されますので、LayerX Tech公式Xアカウント私のXをフォローしてチェックいただければ幸いです!

LayerX

Discussion