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

ビヘイビアツリーボット

公式リポジトリのexamples/bt-botは、ビヘイビアツリーとLLMを組み合わせた自律行動ボットのテンプレートです。 ツリーが行動の順序と割り込みを管理し、LLMは発話と選択肢の判断を担当します。

セットアップ

git clone https://github.com/urth-inc/metatell-ai-bot.git
cd metatell-ai-bot
pnpm install
cd examples/bt-bot
cp .env.example .env

.envにはルームURL、必要に応じた認証トークン、LLM API、音声サービスの設定を記入します。 詳しくは設定リファレンスを参照してください。

pnpm dev -- https://metatell.app/YOUR_ROOM_ID

主に編集するファイル

ファイル用途
my-bot/bot.config.jsonボット名、挨拶、巡回地点、実行間隔、アニメーション割り当てを設定します。
my-bot/tree.json行動の分岐と順序を定義します。
my-bot/persona.mdLLMが使うキャラクター設定を記述します。
my-bot/custom-nodes.ts独自の条件と行動を追加します。

srcはテンプレートの実行エンジンです。 通常のカスタマイズはmy-bot配下で行ってください。

ツリーの基本

{
"root": {
"type": "priority_selector",
"children": [
{
"type": "sequence",
"children": [
{ "type": "condition", "name": "mentioned" },
{ "type": "action", "name": "llm_reply" }
]
},
{ "type": "action", "name": "patrol_next" }
]
}
}
ノード動作
selector子を上から試し、実行中の子を完了まで継続します。
priority_selector実行中も上位の子を再評価し、メンションなどを割り込ませます。
sequence子を順番に実行し、失敗した時点で停止します。
inverter子の成功と失敗を反転します。
cooldown前回の成功から指定時間が経つまで子を実行しません。
repeat子を指定条件で繰り返します。
condition状態を判定します。
action発話、移動、アニメーションなどを実行します。

変更後はJSON Schemaとノード定義に対して検証します。

pnpm check

ボットの起動中にtree.jsonを保存した場合、検証に成功したツリーだけが再読み込みされます。

組み込みの条件

名前主なパラメーター用途
mentionedなしボット宛てのメンションまたは認識音声があるかを判定します。
user_nearbyrange指定距離以内にユーザーがいるかを判定します。
is_aloneなし自分以外に誰もいないかを判定します。
anyone_in_roomなし自分以外のユーザーがいるかを判定します。
user_countminユーザー数が指定値以上かを判定します。
chat_containsword直近のチャットに語句が含まれるかを判定します。
cooldownseckey同じキーの前回成功からの経過時間を判定します。
random_chancep0から1の確率で成功します。
blackboard_equalskeyvalueblackboardの値を比較します。
time_elapsedsec起動から指定秒数が経過したかを判定します。

既定では、他のボットは在室人数、近くのユーザー、在室ユーザー一覧の判定対象から除外されます。 監督下のマルチボット検証で他のボットも対象にする場合のみ、.envALLOW_BOT_PERCEPTION=1を設定してください。

組み込みの行動

名前主なパラメーター用途
saytextチャットで発言します。音声設定が有効な場合は音声でも発言します。
move_toxyz指定座標へ移動します。
patrol_nextなし設定した巡回地点を一つ進みます。
move_to_userなし最も近いユーザーのそばへ移動します。
look_at_userなし最も近いユーザーの方向を向きます。
emoteanimation固定のアニメーションを再生します。
emote_from_blackboardkeyblackboardで選ばれたアニメーションを再生します。
waitsec指定秒数待機します。
set_blackboardkeyvalueblackboardへ値を書き込みます。
report_usersなし在室ユーザーを発言します。

サンプルのbt-botでは、my-bot/custom-nodes.tsgreet_userを追加登録しています。 組み込みの行動ではありません。

LLM行動

名前用途
llm_replyメンションまたは認識音声へペルソナに沿って返信します。
llm_say現在の状況に応じた自発的な発言を生成します。
llm_choose選択肢から一つを選び、blackboardへ保存します。

llm_sayllm_chooseを自発的に実行する分岐は、連続呼び出しを避けるためcooldownで囲んでください。

独自ノードを追加する

import {
registerAction,
registerCondition,
} from "../src/engine/registry.js";

registerCondition("has_ticket", (ctx) => {
return ctx.bb.get("hasTicket") === true;
});

registerAction("announce", async (ctx) => {
if (ctx.signal?.aborted) return "FAILURE";
await ctx.api.emote("greet");
if (ctx.signal?.aborted) return "FAILURE";
return (await ctx.api.say("まもなく開始します")) ? "SUCCESS" : "FAILURE";
});

行動はSUCCESSFAILURERUNNINGのいずれかを返します。 非同期処理が上位の分岐に割り込まれた場合は、awaitの直後にctx.signal.abortedを確認し、発話など次の副作用を止めてください。

運用上の安全策

テンプレートには発話間隔、移動速度、ルーム境界、他ボット発言の無視などの安全策があります。 OPERATOR_SESSION_IDSを設定すると、指定した運営の/killallで停止できます。

セッションIDは接続によって変わる可能性があるため、運用前に値を確認してください。 実験用のUNSAFE_MODEは通常運用で有効にしないでください。