メインコンテンツまでスキップ

Agent Flow 実行API

概要: ノードとエッジで構成されたワークフローを実行し、結果を Server-Sent Events (SSE) でストリーミング返却するAPIです。Web UI で保存したフロー(Agent Workflow Preset API で取得) の agent_nodes / edges をそのまま投入することで、UI で組んだフローを API 経由で実行できます。


POST /v1/api/agentflow

リクエストでエージェントの Node 構成を受け取り、その順序で処理を実行します。

POST /v1/api/agentflow

Headers

  • api-key : string(required) - rokadoc APIキー

Request Body (multipart/form-data)

必須パラメータ
オプショナルパラメータ
  • chatlog_id : string(optional) - 既存チャットログを継続する場合、過去のレスポンスで返却された chatlog_id を指定。指定しない場合は新規スレッドが作成される
  • space_id : string(optional) - スペース機能を利用する場合はスペースIDを指定
  • upload_file : file(optional) - マルチモーダルノードに画像入力として渡したい場合に指定

リクエストペイロード

encoded_flow にエンコードする JSON は次の構造です:

{
"message": "rokadocの主な機能を教えて",
"highlight_display": false,
"agent_nodes": [ ... ],
"edges": [ ... ]
}
  • message : string - ユーザーの質問・入力テキスト
  • highlight_display : boolean - 最終応答にハイライト要素情報を含めるか(デフォルト: false)
  • agent_nodes : array - エージェントノードの配列(Preset API のレスポンスと同形式)
  • edges : array - ノード間の接続定義(Preset API のレスポンスと同形式)

agent_nodesedges の中身は、Web UI のフローエディターで作成・保存したプリセットの構造をそのまま使うのが最も確実です。Preset API の GET レスポンスを取得 → 必要なフィールド抽出 → message と組み合わせて base64 エンコード、というフローを推奨します。

Request Example

# 1. preset を取得
PRESET=$(curl -s "https://api.rokadoc.ntt.com/v1/api/agent-workflow-presets/${PRESET_ID}" \
-H "api-key: ${ROKADOC_API_KEY}")

# 2. agentflow 用ペイロードを base64 化(python でJSON組み立て例)
ENCODED_FLOW=$(python3 -c "
import json, base64, sys
preset = json.loads('''${PRESET}''')
payload = {
'message': 'rokadocの主な機能を教えて',
'highlight_display': False,
'agent_nodes': preset['agent_nodes'],
'edges': preset['edges'],
}
print(base64.b64encode(json.dumps(payload, ensure_ascii=False).encode()).decode())
")

# 3. SSE 受信(curl -N でバッファリング無効化)
curl -N -X 'POST' \
"https://api.rokadoc.ntt.com/v1/api/agentflow" \
-H "api-key: ${ROKADOC_API_KEY}" \
-F "encoded_flow=${ENCODED_FLOW}"

レスポンス

Content-Type: text/event-stream で SSE イベントが順次返却されます。各イベントは data: <JSON>\n\n の形式で、最後に data: [DONE]\n\n で終了します。

イベント種別

type発火タイミング主なフィールド
chatlog_idストリーム開始時に1回id (新規 or 既存の chatlog_id)
node_start各ノードの処理開始時node (ノードID)
message_chunkLLM応答の逐次トークンcontent (1文字), node
message_endあるノードの応答完了時node
search_info検索系ノード (search_agent等) でretrieve実行時node, retrieve_queries[] (検索1回ごとのクエリ), search_result[], highlight_elements[]
chat_titleフロー終盤、チャットタイトル生成完了時title
interrupthuman_input ノードで中断(ユーザー入力待ち)した場合status: "waiting_for_input", next_node
[DONE]ストリーム終端(生のテキスト、JSON ではない)

イベントのサンプル

data: {"type": "chatlog_id", "id": "019dd1e2-02aa-75f4-a441-08814e838b88"}

data: {"type": "node_start", "node": "node-1776740196598"}

data: {"type": "message_chunk", "content": "r", "node": "node-1776740196598"}

data: {"type": "message_chunk", "content": "o", "node": "node-1776740196598"}

data: {"type": "message_end", "node": "node-1776740196598"}

data: {"type": "search_info", "node": "node-1774414389098", "retrieve_queries": ["rokadocの機能"], "search_result": [...], "highlight_elements": [...]}

data: {"type": "chat_title", "title": "rokadocの主な機能まとめ"}

data: [DONE]

interrupt イベントによる対話中断と再開

フローに human_input ノードが含まれる場合、そのノードに到達するとSSEストリームは interrupt イベントを送って終了します。

data: {"type": "interrupt", "status": "waiting_for_input", "next_node": "node-xxxxxxxxxxx"}

data: [DONE]

中断されたフローを再開するには、同じ chatlog_id を指定して再度 /v1/api/agentflow を呼び出しますmessage には次のユーザー入力テキストを設定してください。サーバー側でチェックポイントから再開し、続きのノードから処理が進みます。

# 中断後の再開
payload = {
"message": "<ユーザーの追加入力>",
"highlight_display": False,
"agent_nodes": preset["agent_nodes"],
"edges": preset["edges"],
}
encoded_flow = base64.b64encode(json.dumps(payload, ensure_ascii=False).encode()).decode()

requests.post(
"https://api.rokadoc.ntt.com/v1/api/agentflow",
headers={"api-key": api_key},
data={
"encoded_flow": encoded_flow,
"chatlog_id": "<前回のレスポンスの chatlog_id>",
},
stream=True,
)

エラー

400 Bad Request - ペイロード不正

encoded_flow のbase64デコード失敗、JSON パース失敗、agent_nodes の形式不一致、ノード数超過などの場合。

{
"detail": "Validation Error: ..."
}

注意事項

  • encoded_flow の中身(agent_nodes / edges)はノード型ごとに必要なフィールドが決まっています。手書きで構築するよりも、Agent Workflow Preset API でUI作成済みのプリセットを取得して再利用するのが確実です
  • ノード数には上限があります(超過時は 400 が返ります)
  • SSE ストリームは Nginx 等のリバースプロキシでバッファリングされるとリアルタイム性が損なわれます。クライアント側では stream=True(Python requests)や curl -N を使用してください
  • [DONE] は JSON ではなく生の文字列として送信されるので、JSONパース処理ではこの行を例外扱いしてください