ChainOfThought プリミティブは、連続する推論ステップとツール呼び出しパートを折りたたみ式アコーディオンにグループ化します。
assistant-ui 入門 : プリミティブ – ChainOfThought
作成 : Masashi Okumura (@classcat.com)
作成日時 : 04/04/2026
バージョン : assistant-ui@0.0.87
* 本記事は assistant-ui.com/docs の以下のページを参考にしています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
◆ お問合せ : 下記までお願いします。
- クラスキャット セールス・インフォメーション
- sales-info@classcat.com
- ClassCatJP
assistant-ui 入門 : プリミティブ – ChainOfThought
推論ステップとツール呼び出しをグループ化するための折りたたみ式アコーディオン。
ChainOfThought プリミティブは、連続する推論とツール呼び出しパートを折りたたみ式アコーディオンにグループ化します。推論モデルは、最終的な回答を生成する前に、推論トークンとツール呼び出しを出力します。このプリミティブは、「思考中 (Thinking)」トグルの裏でこれらの中間ステップを折りたたむことができます。
Preview

Code
import {
AuiIf,
ChainOfThoughtPrimitive,
MessagePrimitive,
} from "@assistant-ui/react";
function AssistantMessage() {
return (
<MessagePrimitive.Root>
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "text") return <MyText />;
return null;
}}
</MessagePrimitive.Parts>
<ChainOfThought />
</MessagePrimitive.Root>
);
}
function ChainOfThought() {
return (
<ChainOfThoughtPrimitive.Root className="my-2 rounded-lg border">
<ChainOfThoughtPrimitive.AccordionTrigger className="flex w-full cursor-pointer items-center gap-2 px-4 py-2.5 font-medium text-sm hover:bg-muted/50">
Thinking
</ChainOfThoughtPrimitive.AccordionTrigger>
<AuiIf condition={(s) => !s.chainOfThought.collapsed}>
<ChainOfThoughtPrimitive.Parts
components={{
Reasoning: ({ text }) => (
<p className="whitespace-pre-wrap px-4 py-2 text-muted-foreground text-sm italic">
{text}
</p>
),
tools: {
Fallback: ({ toolName, status }) => (
<div className="flex items-center gap-2 px-4 py-2 text-sm">
<span className="font-medium">{toolName}</span>
<span className="text-muted-foreground">
{status.type === "running" ? "running..." : "done"}
</span>
</div>
),
},
}}
/>
</AuiIf>
</ChainOfThoughtPrimitive.Root>
);
}
クイックスタート
通常のメッセージパートを MessagePrimitive.Parts を使用してレンダリングし、同じ MessagePrimitive.Root 内にそれらと一緒に ChainOfThought コンポーネントを配置します :
import {
ChainOfThoughtPrimitive,
MessagePrimitive,
} from "@assistant-ui/react";
<MessagePrimitive.Root>
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "text") return <MyText />;
return null;
}}
</MessagePrimitive.Parts>
<MyChainOfThought />
</MessagePrimitive.Root>
function MyChainOfThought() {
return (
<ChainOfThoughtPrimitive.Root>
<ChainOfThoughtPrimitive.AccordionTrigger>
Thinking
</ChainOfThoughtPrimitive.AccordionTrigger>
<ChainOfThoughtPrimitive.Parts />
</ChainOfThoughtPrimitive.Root>
);
}
Root は <div> をレンダリングし、AccordionTrigger は折り畳み状態を切り替える <button> をレンダリングし、Parts はグループ化された推論とツール呼び出しパートをレンダリングします。
ℹ️ ランタイム・セットアップ: プリミティブはランタイム・コンテキストを必要とします。UI をランタイム (例えば useLocalRuntime(…)) を持つ AssistantRuntimeProvider でラップします。See Pick a Runtime.
基本概念
グループ化の仕組み
ChainOfThoughtPrimitive.Parts は、現在のメッセージのグループ化された推論とツール呼び出しのコンテキストを読み取ります。実際には、MessagePrimitive.Parts を使用して通常の text/image/data パーツをレンダリングし、折り畳み可能な推論ブロックを表示したい場所に ChainOfThoughtPrimitive を別々にレンダリングします。
折り畳まれた状態
アコーディオンはデフォルトでは折り畳まれた状態で開始されます。AccordionTrigger は折り畳まれた状態と展開された状態を切り替えます。折り畳まれた状態に基づいて、パーツを条件付きでレンダリングするためには AuiIf を使用します :
import { AuiIf, ChainOfThoughtPrimitive } from "@assistant-ui/react";
<ChainOfThoughtPrimitive.Root>
<ChainOfThoughtPrimitive.AccordionTrigger>
Thinking
</ChainOfThoughtPrimitive.AccordionTrigger>
<AuiIf condition={(s) => !s.chainOfThought.collapsed}>
<ChainOfThoughtPrimitive.Parts
components={{ Reasoning }}
/>
</AuiIf>
</ChainOfThoughtPrimitive.Root>
Chevron インジケータ
AuiIf を使用して、現在の状態を反映する方向アイコンを表示します :
import { AuiIf, ChainOfThoughtPrimitive } from "@assistant-ui/react";
import { ChevronDownIcon, ChevronRightIcon } from "lucide-react";
<ChainOfThoughtPrimitive.AccordionTrigger className="flex w-full cursor-pointer items-center gap-2 px-4 py-2 text-sm">
<AuiIf condition={(s) => s.chainOfThought.collapsed}>
<ChevronRightIcon className="size-4" />
</AuiIf>
<AuiIf condition={(s) => !s.chainOfThought.collapsed}>
<ChevronDownIcon className="size-4" />
</AuiIf>
Thinking
</ChainOfThoughtPrimitive.AccordionTrigger>
以上
