endueendue
← 活用例
Agent API

Agent APIでTinを自社サービスに組み込む

StudioでAPIキーを発行すれば、サーバーやスクリプト、自動化ツールからHTTPリクエスト1つでエージェントに仕事を任せられます。最初のキー発行から複数ターンの会話まで、Tinを例にたどります。

Tinは、散らばった考えをはっきりした次の一歩に整理してくれるエージェントです。ふだんはendueのチャットでTinと話す人がほとんどです。APIを開けば、同じTinがあなたの作ったものの中でも働きます。ノートアプリの「計画にする」ボタンの裏で、毎朝動くスクリプトの中で、フォームが届くたびに走る自動化の中で。

API経由のTinは、チャットで話すTinと同じエージェントです。同じ指示、スキル、コネクタ、メモリを使い、利用量はあなたのアカウントに計上されます。サーバーを立てる必要も、モデルをつなぐ必要もありません。

連携のしくみ

  1. Studioで、Tinにだけ使えるAPIキーを発行します。
  2. あなたのサーバーが、そのキーを付けてTinにリクエストを送ります。本文は、してほしいことを伝える1文だけでかまいません。
  3. Tinが回答を返します。やり取りはendueの会話一覧にも保存されるので、あとからWebで読み返せます。

こんな場面に向いています

  • 自社アプリの機能として。ユーザーのメモをTinに送り、返ってきた計画を自社の画面に表示します。ユーザーがendueの存在を知る必要はありません。
  • スケジュールで動くジョブとして。cronジョブが昨日やり残したタスクを送ると、Tinが今日やるべき3つに絞り込みます。結果の行き先を決めるのはあなたのコードです。社内ポータルへの投稿でも、データベースでも、チャットメッセージでもかまいません。
  • ノーコードの自動化ツールから。Zapier、Make、n8nのようにHTTPリクエストを送れるツールなら、コードを書かずにTinを呼び出せます。

結果をendueの中で受け取れれば十分なら、ルーティンのほうが簡単です。APIは、結果を自社のシステムに取り込む必要があるときに選んでください。

必要なもの

  • endueのアカウントとエージェント1つ。この記事ではTinを使います。
  • リクエストの送信元。ターミナル、プロダクトのサーバー、HTTPリクエストを送れる自動化ツールのいずれかです。
  • キーの安全な保管場所。サーバーの環境変数やシークレットマネージャーなどです。

ステップ1. StudioでAPIを開く

Tinを開き、上部でStudioに切り替えると、エージェントの構成が表示されます。「01 Requests come in」列にAPIカードがあります。クリックすると、右側にAPIパネルが開きます。

StudioのTin。「Requests come in」列にAPIカードがあり、右側のAPIパネルにエンドポイントとサンプルリクエストが表示されている。

パネル上部のPOSTアドレスが、Tinのエンドポイントです。その下のcurlサンプルはワンクリックでコピーでき、TinのエージェントIDがすでに入っています。

ステップ2. Tin用のキーを発行する

Issue key(キーを発行)をクリックし、2つの項目を入力します。

  • Key name(キー名)。キーをどこで使うのかを書きます。たとえば「Planner app server」(プランナーアプリのサーバー)です。この名前は、このキー経由で届いた会話の横に表示されます。キーが複数あっても、どれを失効させればよいかひと目でわかります。
  • Expiration(有効期限)。無期限、30日、90日、365日から選びます。テスト中は短めにしておくほうが安全です。

Issue(発行)をクリックすると、sk_で始まるキーが1度だけ表示されます。ボックスを閉じると二度と表示できないので、すぐにコピーして安全な場所に保管してください。なくした場合は、失効させて新しいキーを発行します。パネル上部のサンプルリクエストにも新しいキーが入るので、そのままコピーしてすぐに試せます。

左はキーの発行フォーム。名前に「Planner app server」を入力し、「Expires in 90 days」を選んだ状態。右は発行直後の画面。キーが1度だけ表示され、専用キーの一覧に「Planner app server」が追加されている。

ここで作ったキーはTin専用です。ほかのエージェントは呼び出せません。すべてのエージェントを呼び出せるアカウント全体のキーは、Settings › Account › API Keysで別に発行します。ただ、必要なエージェントが1つだけなら、専用キーのほうが安全です。

ステップ3. 最初のリクエストを送る

ターミナルからすぐに試せます。キーはコマンドに直接書かず、環境変数に入れておきます。AGENT_IDの部分には、Studioでコピーしたアドレスをそのまま使ってください。

export ENDUE_API_KEY="sk_..."   # ステップ2で発行したキー

curl -X POST https://platform.endue.ai/api/public/v1/agents/AGENT_ID/invoke \
  -H "Authorization: Bearer $ENDUE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input": "Turn this into a plan for this week: I want to start a small newsletter for our cafe. I have about 5 hours this week."}'

Tinが処理を終えると、次のようなレスポンスが返ります。

{
  "success": true,
  "data": {
    "run_id": "...",
    "session_id": "cnv_...",
    "conversation_id": "cnv_...",
    "agent_id": "...",
    "status": "completed",
    "finish_reason": "final",
    "output_text": "Here's a week that gets the first issue out without eating your weekend. ...",
    "usage": { "input_tokens": 1830, "output_tokens": 264, "total_tokens": 2094 }
  }
}

特に重要なフィールドは3つです。

  • output_text:Tinの回答です。あなたの画面に表示するのはこの部分です。
  • session_id:会話のIDです。次のリクエストで送り返すと、会話を続けられます。conversation_idにも同じ値が入っていて、Studioのヒントではこちらの名前が使われています。
  • status:completedは、Tinが最後まで回答したことを示します。incompleteは、ステップ数を使い切ったか、人の判断が必要なところで止まったことを示します。リクエストをもっと具体的にして、もう一度試してください。

ステップ4. 会話を続ける

ユーザーが「水曜日は無理です」と返信したとします。その内容を前のレスポンスのsession_idと一緒に送ると、Tinはすでに作った計画を修正します。

{
  "input": "I can't do Wednesday. Move that part to Thursday and redo the plan.",
  "session_id": "cnv_..."
}

session_idを省くと、新しい会話が始まります。ユーザーごと、またはメモごとに会話を1つにまとめたいなら、session_idをデータベースに一緒に保存しておきます。

ステップ5. プロダクトに組み込む

ノートアプリの「計画にする」ボタンを思い浮かべてください。何よりも大事なルールが1つあります。Tinを呼び出すコードはサーバーに置くことです。ブラウザやモバイルアプリに置いたキーは、見ようと思えば誰でも読めてしまいます。画面はあなたのサーバーと通信し、サーバーがTinと通信します。

Node.jsのサーバーなら、次のようになります。

// サーバー側のコード。キーは環境変数から読み込みます。
const TIN_URL = 'https://platform.endue.ai/api/public/v1/agents/AGENT_ID/invoke';

export async function askTin(input, sessionId) {
  const res = await fetch(TIN_URL, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.ENDUE_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(sessionId ? { input, session_id: sessionId } : { input }),
  });
  const body = await res.json();
  if (!res.ok) throw new Error(body.error?.message ?? `HTTP ${res.status}`);
  return { plan: body.data.output_text, sessionId: body.data.session_id };
}

毎朝実行するPythonスクリプトなら、さらに短くなります。

import os
import requests

res = requests.post(
    "https://platform.endue.ai/api/public/v1/agents/AGENT_ID/invoke",
    headers={"Authorization": f"Bearer {os.environ['ENDUE_API_KEY']}"},
    json={"input": "Left over from yesterday: reply to the quote, order coffee beans, blog draft. Give me three things to do today."},
    timeout=120,
)
res.raise_for_status()
print(res.json()["data"]["output_text"])

デフォルトでは、Tinが処理を終えるまで待ってから、すべてをまとめて返します。じっくり考える必要のあるリクエストは数十秒かかることがあるので、タイムアウトは長めに設定してください。チャットのように、書かれるそばからテキストを表示したい場合は、リクエストに"stream": trueを追加します。すると、Webチャットと同じSSEストリームを受け取れます。run_created、テキストの断片を運ぶdeltaイベント、doneの順に届きます。

すべての呼び出しはendueに記録されます

API経由で届いた会話は、TinのサイドバーのAPIグループにまとまります。呼び出し元のメッセージには「API caller」というラベルが付き、タイトルの横にはどのキーを経由したかが表示されます。回答がおかしいと感じたら、Tinが何を頼まれ、何と答えたのかをここで正確に確認できます。

TinとのAPI会話。サイドバーのAPIグループにセッションが3つ並び、メインビューにはAPI callerのリクエストとTinの週間計画が表示されている。タイトルの横にキー名「Planner app server」が見える。

これらの会話は、endue上では読み取り専用です。続けるには、同じsession_idを付けてもう一度APIを呼び出すしかありません。

Studioの構成ビューも変わります。新しいキーがAPIカードにActiveとして表示され、Tinへ線が伸びます。

キー発行後のStudioの構成ビュー。API列に「Planner app server」キーがActiveの状態で置かれ、右側にはTinが使うコネクタが並んでいる。

本格的に使う前に

API呼び出しの前には、誰も座っていません。そのためendueは、API呼び出しを無人実行として扱います。

  • メール送信のように、何かを外に送ったり削除したりする操作は、承認を待たずに拒否されます。検索のように読み取るだけの操作は、通常どおり動きます。
  • Tinが質問する必要があっても、答える人がいません。必要な情報は最初から渡してください。締め切り、使える時間、返してほしい形式などです。

Tinが下書きや計画を返し、送信や保存はあなたのコードが行う。この分担がいちばんうまくいきます。

キーを安全に保つ

  • キーはサーバーにだけ置く。ブラウザのコード、モバイルアプリ、gitリポジトリには決して入れません。
  • 使う場所ごとにキーを1つ。「Planner app server」と「Morning summary script」(朝の要約スクリプト)のようにキーを分けておけば、漏えいしても失効させるのは1つだけで済みます。
  • 失効はすばやく。APIパネルでRevoke(失効)を押すと、そのキーを使ったリクエストは1分以内にブロックされます。
  • 有効期限を設定する。期限が近いキーや期限切れのキーは、パネルとStudioに表示されます。

ステータスコードの意味

  • 401:キーがない、間違っている、期限切れ、または失効済みです。
  • 403:別のエージェント専用のキーでTinを呼び出しました。
  • 404:エージェントIDが間違っているか、session_idが別のエージェントのものです。
  • 409:同じセッションの前のリクエストがまだ実行中です。完了してから送り直してください。
  • 402:プランの利用上限に達しました。Usage(利用量)ページで残りを確認してください。

リクエストのフィールドと制限の詳細は、Agent APIのドキュメントにまとめています。