<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>記事 on 2389 Research, Inc</title><link>https://2389.ai/ja/research/writing/</link><description>Recent content in 記事 on 2389 Research, Inc</description><generator>Hugo</generator><language>ja-JP</language><atom:link href="https://2389.ai/ja/research/writing/index.xml" rel="self" type="application/rss+xml"/><item><title>ホートンはささやきを聞く</title><link>https://2389.ai/ja/research/writing/horton-hears-a-whisper/</link><pubDate>Wed, 20 May 2026 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/horton-hears-a-whisper/</guid><description>&lt;p>オフィスで何が話されているかを継続的にまとめたいと思っていました。監視ではありません。部屋が自分のために書き込んでくれるノートのようなもの。火曜日のキッチンでの会話は何だったか？ 会議室で実際に何が決まったか？ すべての部屋に同時にいることはできませんが、マイクはいられます。&lt;/p>
&lt;p>そこで私たちはESP32マイクのフリートをオフィスに配線し、音声をサーバーにストリーミングし、Whisperで処理して、その上にダッシュボードを構築しました。コードネーム：ホートン。ドクター・スースのゾウが埃の粒の上の小さな声を聞くキャラクターにちなんでいます。&lt;/p>
&lt;h2 id="1台から複数台へ">1台から複数台へ&lt;/h2>
&lt;p>ホートンは私のデスクの上の1台のESP32-S3ボードとI²Sマイク（小型マイクの多くが使うデジタル音声バス）から始まりました。それをTCPソケット経由でPythonサーバーに生の音声をストリーミングするように配線しました。サーバーはWhisperを実行し、文字起こしをディスクに保存しました。それがスタック全体でした。動きました。文字起こしは意味を成しました。&lt;/p>
&lt;p>1台が動くことの問題は、次に来る明らかな疑問です：&lt;em>これが3台あったらどうなるか？&lt;/em> 次に4台。次に「午後11時と午後3時でキッチンはどう聞こえるか？」 2台以上になった瞬間、もはやデバイスを持っているのではなく——フリートを持っており、フリートについて考える必要があります。&lt;/p>
&lt;h2 id="仕組み">仕組み&lt;/h2>
&lt;p>ループは小さいです。音声が一方から入り、文字起こしが他方から出ます。&lt;/p>

&lt;figure>
&lt;picture>
 &lt;source
 type="image/avif"
 srcset="https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_f83a07354cee49d6.png 600w, https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_2de95da518cec4d4.png 900w, https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_e98e53d4b63ab8a8.png 1200w"
 sizes="min(100vw, 800px)" />
 &lt;source
 type="image/webp"
 srcset="https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_99ec456e7b421615.webp 600w, https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_3ccb47bff720e77.webp 900w, https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_c1585b46be518e32.webp 1200w"
 sizes="min(100vw, 800px)" />
 &lt;img
 src="https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_7bf17ba617bc51a0.png"
 srcset="https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_d3ba997b76f2a2bd.png 600w, https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_fc579d1eed8e887a.png 900w, https://2389.ai/research/writing/horton-hears-a-whisper/pipeline_hu_7bf17ba617bc51a0.png 1200w"
 sizes="min(100vw, 800px)"
 alt="Illustrated pipeline diagram: an ESP32 microcontroller with microphone on the left, a dandelion releasing seeds that drift right as voices traveling through the air, a FastAPI TCP server cube, a Whisper brain icon producing transcription text, and a dashboard grid with a small elephant silhouette on top"
 width="1200"
 height="800"
 loading="lazy"
 decoding="async" />
&lt;/picture>

 &lt;figcaption>ホートンのパイプライン — 声はマイクからダッシュボードへ旅する&lt;/figcaption>&lt;/figure>


&lt;figure>
&lt;picture>
 &lt;source
 type="image/avif"
 srcset="https://2389.ai/research/writing/horton-hears-a-whisper/ear_hu_6d2530d29433d418.jpg 600w"
 sizes="min(100vw, 800px)" />
 &lt;source
 type="image/webp"
 srcset="https://2389.ai/research/writing/horton-hears-a-whisper/ear_hu_21243370f0c4304e.webp 600w"
 sizes="min(100vw, 800px)" />
 &lt;img
 src="https://2389.ai/research/writing/horton-hears-a-whisper/ear_hu_6e4f7f01cf9ce44.jpg"
 srcset="https://2389.ai/research/writing/horton-hears-a-whisper/ear_hu_6e4f7f01cf9ce44.jpg 600w"
 sizes="min(100vw, 800px)"
 alt="Close-up of a small round microphone PCB set into the side of a blue 3D-printed elephant, with the mic&amp;#39;s pin labels (GND, VDD, WS, SCK, L/R) visible around its edge"
 width="600"
 height="386"
 loading="lazy"
 decoding="async" />
&lt;/picture>

 &lt;figcaption>耳、接写&lt;/figcaption>&lt;/figure>

&lt;p>小型のESP32-S3ファームウェアがI²Sマイクから生の音声を読み取り、TCPソケット経由でサーバーに継続的にストリーミングします。サーバーは2つのプロセスを持つFastAPIアプリです：&lt;code>audio_server.py&lt;/code>がTCP音声インジェストを処理し、&lt;code>web_server.py&lt;/code>がダッシュボード、API、ライブフィードを提供します。Whisper（私たちはOpenAIのWhisperのCPU最適化ポートである&lt;code>faster-whisper&lt;/code>を使用）が文字起こしを行います。GrafanaはサーバーのAPIをデータソースとして使い、ダッシュボードを描きます。&lt;/p></description></item><item><title>AIパイプラインのための言語を作った理由</title><link>https://2389.ai/ja/research/writing/why-we-built-a-language-for-ai-pipelines/</link><pubDate>Fri, 03 Apr 2026 10:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/why-we-built-a-language-for-ai-pipelines/</guid><description>&lt;p>昨年3月、エンジニアの一人が壊れたパイプラインのデバッグに40分を費やしました。原因はDOTファイルのバックスラッシュ一文字の欠落でした。その文字は、次のような文字列の中に埋まっていました。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>tool_command=&amp;#34;set -eu\nmkdir -p .ai .ai/drafts .ai/sprints\nif [ ! -f
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>.ai/ledger.tsv ]; then\n now=$(date -u +%Y-%m-%dT%H:%M:%SZ)\n printf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;#39;sprint_id\\ttitle\\tstatus\\tcreated_at\\tupdated_at\\n001\\tBootstrap
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sprint\\tplanned\\t%s\\t%s\\n&amp;#39; \&amp;#34;$now\&amp;#34; \&amp;#34;$now\&amp;#34; &amp;gt; .ai/ledger.tsv\nfi\n
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>printf &amp;#39;ledger-ready&amp;#39;&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>これはシェルスクリプトです。bashで6行：ディレクトリを作り、TSVヘッダーがなければ書き込み、ステータスメッセージを出力する。珍しいことは何もありません。しかしDOT属性の中に入れると、改行は &lt;code>\n&lt;/code>、タブは &lt;code>\\t&lt;/code>、クォートは &lt;code>\&amp;quot;&lt;/code> に変わります。スクリプトはそこにあるのに、読めない。自信を持って編集できない。&lt;/p>
&lt;p>私たちは&lt;a href="https://2389.ai/ja/research/products/tracker/">Tracker&lt;/a>——AIパイプラインのオーケストレーションシステム——を開発しています。Trackerは、LLMエージェント・ツール呼び出し・人間のレビュアーが複雑なタスク（コードレビュー、スプリント実行、API設計）に協働する多段階ワークフローを実行します。これらのパイプラインは有向グラフです。プロンプトとモデルを持つノード、条件付きエッジ、リトライループ、並列ブランチ。&lt;/p>
&lt;p>私たちはそれをGraphviz DOTで定義していました。&lt;/p>
&lt;p>パイプラインが小さいうちはDOTで十分でした。5ノード、シンプルなエッジ、短いプロンプト。しかしパイプラインは成長しました。マルチモデルコンセンサスを持つ20ノードのワークフロー。テストスイートを実行するシェルスクリプト。マークダウンやJSONスキーマを埋め込んだシステムプロンプト。記述フォーマットは「透明な存在」ではなくなり、最も手を焼く相手になっていました。&lt;/p>
&lt;p>プロンプトを書くよりも、エスケープ文字のデバッグに時間を取られるようになっていたのです。&lt;/p>
&lt;h2 id="dotが提供できなかったもの">DOTが提供できなかったもの&lt;/h2>
&lt;p>エスケープ文字列の問題は最も目立つ痛点でしたが、唯一の問題ではありませんでした。&lt;/p>
&lt;p>DOTはグラフ記述言語です。ノード、エッジ、属性について知っています。しかしAIパイプラインが何であるかは知りません。&lt;code>claude-sonnet-4-6&lt;/code> が有効なモデル名で、&lt;code>claude-sonet-4-6&lt;/code> がタイプミスであるかどうかについて、言語は何も言いません。あるノードが到達不能であること、リトライループに終了条件がないこと、ツールコマンドが存在しないバイナリを参照していること——これらも教えてくれません。こうした問題は本番環境で、パイプラインが失敗したときに発覚します。あるいはもっと悪く、微妙に間違った出力を出し続けます。&lt;/p>
&lt;p>パイプラインのテストも別の問題でした。LLM呼び出しは非決定論的なので、その出力をアサートできません。しかし実行の&lt;em>形状&lt;/em>はアサートできます：どのノードが訪問されたか、どの順番で、どのブランチが取られたか。それが必要でした。DOTにはそういう概念がありませんでした。&lt;/p>
&lt;p>コストの問題もありました。3つのLLMプロバイダーにファンアウトするパイプラインは、3セットのAPI呼び出しを実行します。合計を見積もるには、誰かが手作業でプロンプトトークンを数え、料金表を調べる必要がありました。20のパイプラインに対してそれはスケールしません。&lt;/p>
&lt;h2 id="フォーマットから言語へ">フォーマットから言語へ&lt;/h2>
&lt;p>バリデーションレイヤーを載せたYAMLスキーマを書くこともできました。しかしバリデーションはエラーを捕まえるだけです——スタイルを正規化するフォーマッター、実行パスを歩くシミュレーター、プロンプトトークンを読むコスト見積もり、エディター上で診断を表示するLSPは手に入りません。そのすべてには、ツールチェーン全体が共有できる型付きデータモデルを生成する文法とパーサーが必要です。&lt;/p>
&lt;p>同じシェルスクリプトをDippinで書くと、こうなります。&lt;/p>
&lt;pre class="dip-highlight" role="region" aria-label="Dippin code example">&lt;code class="language-dip">tool EnsureLedger
 label: &amp;#34;Ensure Ledger&amp;#34;
 command:
 set -eu
 mkdir -p .ai .ai/drafts .ai/sprints
 if [ ! -f .ai/ledger.tsv ]; then
 now=$(date -u &amp;#43;%Y-%m-%dT%H:%M:%SZ)
 printf &amp;#39;sprint_id\ttitle\tstatus\tcreated_at\tupdated_at\n001\tBootstrap sprint\tplanned\t%s\t%s\n&amp;#39; &amp;#34;$now&amp;#34; &amp;#34;$now&amp;#34; &amp;gt; .ai/ledger.tsv
 fi
 printf &amp;#39;ledger-ready&amp;#39;&lt;/code>&lt;/pre>
&lt;p>コロンの後にインデントしてスクリプトを書くだけです。エスケープもクォートも &lt;code>\n&lt;/code> も不要です。プロンプトにも同じルールが適用されます：ヘッダー、箇条書き、埋め込みコードブロック、JSONの例を含む複数行のマークダウンを、ドキュメントに書くように書けます。&lt;/p></description></item><item><title>Word Compiler：長編小説のためのコンテキストコンパイラ</title><link>https://2389.ai/ja/research/writing/word-compiler/</link><pubDate>Wed, 01 Apr 2026 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/word-compiler/</guid><description>&lt;h2 id="問題">問題&lt;/h2>
&lt;p>LLMで小説を書くことは、フラストレーションとの戦いです。いつの間にかプロンプトエンジニアになっています。システムメッセージを手作りし、コンテキストをコピー＆ペーストし、セッションをまたいでキャラクターの詳細を管理し、モデルが「何を知っているか」を追いきれなくなり、物語がコンテキストウィンドウを超えるにつれて文章の質が落ちていく様子を眺めることになります。既存のツールはLLMをオートコンプリートのように扱っており、クリエイティブなルールに縛られたコラボレーターとしては見ていません。&lt;/p>
&lt;p>著者の本当の貢献——声、世界観、物語の意図——は、場当たり的なプロンプトに散らばり、セッションの間に消え去り、次の生成パスに何も引き継がれません。&lt;/p>
&lt;h2 id="コンパイラという比喩">コンパイラという比喩&lt;/h2>
&lt;p>Word Compilerはそのアーキテクチャをソフトウェアコンパイラから借用しています。コンパイラはソースコードを読み込み、中間表現を構築し、制約の中で最適化を行い、機械語を出力します。Word Compilerは同じことを散文に対して行います。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>コンパイラの概念&lt;/th>
 &lt;th>Word Compilerの対応物&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>ソースコード&lt;/td>
 &lt;td>Bible。キャラクタードシエ、スタイルガイド、場所、物語のルール、禁止フレーズのキルリストを含む構造化ドキュメント&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中間表現&lt;/td>
 &lt;td>Narrative IR。シーンごとのイベント、キャラクターの変化、認識論的状態の抽出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>最適化&lt;/td>
 &lt;td>バジェットエンフォーサー。プロンプトがコンテキストウィンドウに収まることを保証する優先度ベースの圧縮&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>静的解析&lt;/td>
 &lt;td>リンター（生成前）とオーディター（生成後）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>リンカー&lt;/td>
 &lt;td>クロスシーンのブリッジング。Narrative IRのキャラクター状態と未解決のテンションによる継続性&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>コード生成&lt;/td>
 &lt;td>LLM呼び出しそのもの。唯一の非同期かつコストのかかるステップ&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>ユーザーはプロンプトを書きません。構造化フィールド（キャラクタードシエ、感情的なビートを持つシーン契約、アンカーライン、サブテキスト契約）を埋めると、コンパイラがコンテキストのペイロードを組み立てます。&lt;/p>
&lt;h2 id="実際に何を解決するのか">実際に何を解決するのか&lt;/h2>
&lt;h3 id="長編作品のコンテキストウィンドウ問題を解決します">長編作品のコンテキストウィンドウ問題を解決します。&lt;/h3>
&lt;p>私たちはLLMに適切なスコープで適切なコンテキストを与える、三リング構造のアーキテクチャを構築しました。&lt;/p>
&lt;p>&lt;strong>Ring 1&lt;/strong>（システムメッセージ）はプロジェクトレベルのアイデンティティを担います。声のルール、POVポリシー、文章の構造、語彙の好み、キルリスト、構造的な禁止事項、ポジティブおよびネガティブな例文です。&lt;/p>
&lt;p>&lt;strong>Ring 2&lt;/strong>はチャプターレベルの継続性を担います。チャプターのアーク、読者の認識論的状態、アクティブな伏線、過去のシーンのNarrative IRから導出された累積的なキャラクター状態です。&lt;/p>
&lt;p>&lt;strong>Ring 3&lt;/strong>はシーンレベルの詳細を担います。シーン契約、発話キャラクターの声のフィンガープリント、感覚的なパレット、アンカーライン、前のチャンクまたは前のシーンからの継続性ブリッジ、アンチアブレーションガードレールです。&lt;/p>
&lt;p>合計がトークンバジェットを超えると、コンパイラは圧縮します。最初にRing 1を削り、次にRing 2、最後の手段としてRing 3を削ります。各リング内では、優先度の高い番号から順に、免疫のないセクションを削除します。免疫セクション（キルリスト、構造的ルール、POVポリシー、シーン契約、声のフィンガープリント、アンカーライン、アンチアブレーション）は決して削除されません。&lt;/p>
&lt;p>デフォルト設定ではRing 3に最低60%のシェアを割り当てており、40%を下回るとリンターが警告を出します。&lt;/p>
&lt;p>10万語の小説は、原稿全体をチャットウィンドウに貼り付けた場合のように第20章で劣化しません。コンパイラは各チャンクが必要とするコンテキストを正確に組み立てます。&lt;/p>
&lt;h3 id="プロンプトエンジニアリングなしにクリエイティブコントロールを実現します">プロンプトエンジニアリングなしにクリエイティブコントロールを実現します。&lt;/h3>
&lt;p>Bibleはスタイルの唯一の真実の源泉であり、バージョン管理されています。すべての編集が新しいバージョンを作成し、古いバージョンに対して生成することをゲートが防ぎます。声の決定、キャラクターの口癖、構造的な禁止事項、キルリストのすべての言葉。すべてが一つのドキュメントに。著者は指示ではなく意図を指定します。&lt;/p>
&lt;p>シーン計画も同様に精密です。それぞれが物語の目標、感情的なビート、望む読者への効果、サブテキスト契約（表面的な会話と実際の会話、エンフォースメントルール付き）、アンカーライン（逐語的にマークするか、エネルギーターゲットとして残せる著者が書いた文）、そして避けるべき失敗モードを定義します。コンパイラはそのすべてをプロンプトに変換します。&lt;/p>
&lt;h3 id="散文に静的解析と監査を適用します">散文に静的解析と監査を適用します。&lt;/h3>
&lt;p>生成のたびに、オーディターはBibleに照らして散文をスキャンします。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>キルリスト違反&lt;/strong>：リスト上のすべての単語とフレーズを大文字小文字を区別せずにスキャンします&lt;/li>
&lt;li>&lt;strong>文章の分散&lt;/strong>：文の長さの標準偏差が3.0語を下回り、リズム的に単調なパッセージにフラグを立てます&lt;/li>
&lt;li>&lt;strong>段落の長さ&lt;/strong>：著者が設定した最大文数を超える段落にフラグを立てます&lt;/li>
&lt;li>&lt;strong>認識論的リーク検出&lt;/strong>：キャラクターの知識を過去のシーンのNarrative IRと照合します。キャラクターが学んだことが一度も示されていないことに言及した場合、フラグが立てられます&lt;/li>
&lt;li>&lt;strong>伏線/回収の追跡&lt;/strong>：シーン計画で埋め込まれるまたは回収されると言われていたことと、IRが実際に起きたと言っていることを比較します。原稿完成時に、一度も解決されなかった伏線にフラグが立てられます&lt;/li>
&lt;li>&lt;strong>サブテキストコンプライアンス&lt;/strong>：散文とシーンのサブテキスト契約をモデルに送り、いずれかのキャラクターが言外の意味を明示的に口にしていないかチェックします&lt;/li>
&lt;/ul>
&lt;p>これらは&lt;strong>リンティング&lt;/strong>、&lt;strong>型チェック&lt;/strong>、&lt;strong>インテグレーションテスト&lt;/strong>の散文版です。未解決の重大な監査フラグは、ワークフローゲートを通じてシーンが進むのをブロックします。警告と情報レベルのフラグは進行をブロックしませんが、著者が解決または却下するまで表示され続けます。&lt;/p>
&lt;h3 id="構造化された制約を通じて声を構築します">構造化された制約を通じて声を構築します。&lt;/h3>
&lt;p>Word Compilerにおける声とは、すべてのプロンプトにコンパイルされる重層的な制約です。Bibleはキャラクターレベルの声のフィンガープリント（語彙のメモ、口癖、比喩的なレジスター、禁止言語、対話のサンプル）とプロジェクトレベルのスタイルルール（ポジティブおよびネガティブな例文、文章の構造、比喩的な領域、語彙の好み）を持ちます。Ring 1はこれらをシステムメッセージに組み立てます。Ring 3はシーン内の発話キャラクターすべてのキャラクターレベルの声のフィンガープリントを注入します。&lt;/p>
&lt;h2 id="著者がコントロールを保ち続ける方法">著者がコントロールを保ち続ける方法&lt;/h2>
&lt;p>すべてのステージで決定権は著者の手にあります。&lt;/p>
&lt;p>あらすじを貼り付ければ、システムがドラフトのBible（キャラクター、場所、トーン、キルリスト）を生成します。あるいはすべてをゼロから構築することもできます。すべてのフィールドは編集可能です。Bibleはあなたのものです。&lt;/p>
&lt;p>シーン計画には、人間のストーリーテラーだけがうまく埋められるフィールドが含まれています。サブテキストフィールドは、キャラクターが表面上何を話しているかと実際に何を伝えているかを、エンフォースメントルール付きでキャプチャします。アンカーラインは著者が書いた特定の文で、逐語的に表示されなければなりません。失敗モードは何を避けるべきかを述べます（「どんでん返しを電信するな」「メロドラマ的な台詞はなし」）。&lt;/p>
&lt;p>生成はチャンクごとに進みます。各シーンの目標語数（著者が設定可能で、デフォルトは800〜1200語）は、一定数のチャンクに分割されます。著者はそれぞれを確認し、承認、編集、または却下とマークします。編集こそが本当の著者活動が起きる場所です。学習器は監視しており、AIが書いたものと著者が残したものの差分を分析し、編集のタイプを分類しています：フィラーの削除、トーンの変化、「見せろ、言うな」への置換、感覚的な追加。&lt;/p>
&lt;p>著者はすべての監査フラグを、対応可能または却下としてマークすることで解決します。解決データはカテゴリ別に監査の品質を経時追跡するシグナル対ノイズ指標に供給されます。自動修正は何もありません。&lt;/p>
&lt;p>シーンが完成すると、システムは起きたことの構造化された表現を抽出します：イベント、導入された事実、読者に明かされた事実、隠された事実、キャラクターの変化、植え込まれた伏線、実行された回収、キャラクターの位置、未解決のテンション。記録は未検証の状態から始まります。著者はそれがクロスシーンの継続性に供給される前にレビューして確認します。&lt;/p>
&lt;p>リビジョン学習器からのBible提案とパラメータアナライザーからのチューニング提案は、著者が承認または却下するまで保留状態で届きます。システムが提案し、著者が決定します。&lt;/p>
&lt;h2 id="aiアシストコーディングから借りたアイデア">AIアシストコーディングから借りたアイデア&lt;/h2>
&lt;p>私たちはコードについて考えるのと同じ方法でこれを構築しました。&lt;/p></description></item><item><title>3DプリンターをAIポートレートアーティストに変えた話</title><link>https://2389.ai/ja/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/</link><pubDate>Fri, 20 Mar 2026 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/</guid><description>&lt;p>古い3DプリンターにペンをくくりつけてAIにPicassoを模倣させたら、どうなるでしょうか。その場で肖像を描いてくれるフォトブースができあがりました。これが「Micasso」です。&lt;/p>
&lt;h2 id="埃をかぶっていたプリンター">埃をかぶっていたプリンター&lt;/h2>
&lt;p>オフィスの隅に3Dプリンターが放置されていました。そろそろオープンハウスが迫っていて、パーティーを盛り上げる何か楽しいもの——持ち帰れる、物理的な何か——が欲しかったのです。アイデアはシンプルでした。写真を撮って、AIに線画に変換してもらい、プリンターにペンで描かせたらどうだろう、と。&lt;/p>
&lt;p>私たちが惹かれたのはデジタルとアナログのループです。AIが画像を画面上に生成するのは当たり前ですが、そのあとに機械が&lt;em>実際にカードに描く&lt;/em>のを目の前で見られる。ペンが自分の顔をなぞる瞬間には、画面では味わえない何かがあります。&lt;/p>

&lt;figure>
&lt;picture>
 &lt;source
 type="image/avif"
 srcset="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/micasso-detail_hu_3e70af8b190aef8a.jpg 600w"
 sizes="min(100vw, 800px)" />
 &lt;source
 type="image/webp"
 srcset="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/micasso-detail_hu_d3c3b0afdbaed792.webp 600w"
 sizes="min(100vw, 800px)" />
 &lt;img
 src="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/micasso-detail_hu_9b8510fe24a520cd.jpg"
 srcset="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/micasso-detail_hu_9b8510fe24a520cd.jpg 600w"
 sizes="min(100vw, 800px)"
 alt="Micassoのペンプロッターのクローズアップ：ペンホルダーを取り付けた改造済み3Dプリンター、2つのアーケードボタン、黒いカードに描かれた新鮮なポートレート"
 width="600"
 height="800"
 loading="lazy"
 decoding="async" />
&lt;/picture>

 &lt;figcaption>Micassoの近影 — ペンホルダー、InspireボタンとRealizeボタン、そして描きたての肖像&lt;/figcaption>&lt;/figure>

&lt;h2 id="inspireとrealize">InspireとRealize&lt;/h2>
&lt;p>インタラクションには2つの瞬間があり、それぞれに意図を込めて名前をつけました。&lt;/p>
&lt;p>&lt;strong>Inspire&lt;/strong>ボタンを押すとカメラが準備を始め、カウントダウンが流れ、シャッターの瞬間にブースが*「Micassoooo」*と叫びます——シャッター音であり、個性でもあります。&lt;/p>
&lt;p>撮った写真が画面に表示されます。気に入らなければ&lt;strong>Inspire&lt;/strong>をもう一度押して撮り直せます。準備ができたら&lt;strong>Realize&lt;/strong>を押す——インスピレーションを現実にする瞬間です。AIが肖像を生成し、コードがペンのパスに変換し、約30秒後にプロッターが描き始めます。&lt;/p>
&lt;p>待っている間、画面には俳句が表示されます：&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>ロボットが顔を学ぶ&lt;/em>&lt;br>
&lt;em>数字が詩になる&lt;/em>&lt;br>
&lt;em>機械の言葉が語られる&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h2 id="仕組み">仕組み&lt;/h2>
&lt;p>パイプラインは5ステップです。写真を入れると、ペンで描かれた肖像が出てきます。&lt;/p>

&lt;figure>
&lt;picture>
 &lt;source
 type="image/avif"
 srcset="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_11a7e1a7e87e3cfe.png 600w, https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_5d58f9bf0393532f.png 900w, https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_a126d9c0d4945389.png 1200w"
 sizes="min(100vw, 800px)" />
 &lt;source
 type="image/webp"
 srcset="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_a7494a5929ad88ae.webp 600w, https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_a8e4378e35c8d84d.webp 900w, https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_923e854a910df44f.webp 1200w"
 sizes="min(100vw, 800px)" />
 &lt;img
 src="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_8bf88cd31d28de9.png"
 srcset="https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_d46454033b07f6dc.png 600w, https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_491085771083a030.png 900w, https://2389.ai/research/writing/we-turned-a-3d-printer-into-an-ai-portrait-artist/pipeline-blueprint_hu_8bf88cd31d28de9.png 1200w"
 sizes="min(100vw, 800px)"
 alt="Micassoの5ステップパイプラインの図：Capture（撮影）、AI Portrait（AI肖像）、Centerline Trace（中心線トレース）、G-code（Gコード）、Plot（描画）"
 width="1200"
 height="400"
 loading="lazy"
 decoding="async" />
&lt;/picture>

 &lt;figcaption>Micassoの処理パイプライン&lt;/figcaption>&lt;/figure>

&lt;p>Raspberry Pi 5に接続したウェブカメラが写真を撮影します。その写真はAI画像モデル（OpenAI、Google Gemini、またはセルフホスト版に対応）に送られ、PicassoとMiróのスタイルを模した最小限の線画に変換されます。AIの出力はベクターパスにトレースされます——これについては後述しますが、ここで少々ハマりました。そのベクターはvpypeを使ってアーク補正付きのG-codeに変換されます。G-codeはレシピのようなものです：ここへ移動、ペンを下ろす、この線を引く、上げる、あそこへ移動。そしてプリンターがペンを持って描き始めます。黒い6×4インチのカードに白いペンで。&lt;/p>
&lt;h2 id="詰まったところ">詰まったところ&lt;/h2>
&lt;h3 id="物理ペンのためのプロンプトエンジニアリング">物理ペンのためのプロンプトエンジニアリング&lt;/h3>
&lt;p>画面向けのプロンプトエンジニアリングと、物理ペン向けのそれはまったく別物です。AIはグラデーションなし、塗りつぶしなし、線幅の変化なしで——機械ペンが再現できるクリーンなストロークだけで——アートを生成しなければなりません。&lt;/p>
&lt;p>私たちはかなり試行錯誤しました。最終的にたどり着いたのがこちらです：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>PORTRAIT_PROMPT &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&amp;#34;Transform this photo into a minimalist single-line portrait
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">in the style of Picasso and Joan Miró.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">Requirements:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Single continuous stroke aesthetic (the drawing should look like it could be
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> drawn without lifting the pen)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Uniform line thickness throughout - no variation, shading, or hatching
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Abstract but recognizable - simplified eyes, nose, mouth, hair
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Minimal clothing suggestion - as few strokes as possible
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Clean white background with no texture or marks
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Black lines only on pure white
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Empty white space around the portrait
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">- Gallery-style minimalist aesthetic
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">The result should look like modern minimalist line art suitable for pen plotting&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>すべての言葉が重要です。「Single continuous stroke aesthetic」と「uniform line thickness」という表現が、画面映えするものとペンで実際に描けるものとの分かれ目になります。&lt;/p></description></item><item><title>シマー：自己研磨スキル</title><link>https://2389.ai/ja/research/writing/simmer-skill/</link><pubDate>Fri, 13 Mar 2026 14:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/simmer-skill/</guid><description>&lt;p>&lt;a href="https://gepa-ai.github.io/gepa/blog/2026/02/18/introducing-optimize-anything/">バークレーの研究者たち&lt;/a>は、出力を評価し優先順位付きの実行可能なフィードバックを与えられる限り、RLスタイルのフィードバックループをあらゆるテキストタスクに適用できることを示しました。彼らはこれをActionable Side Information（ASI）と呼んでいます。目標は次に何を改善すべきかに焦点を当てたフィードバックです。APIなら「POSTエンドポイントにエラーレスポンスがない」かもしれません。ストーリーなら「第二段落でペーシングが落ちる」かもしれません。生成器が散漫にならずに行動できるほど焦点が絞られていることが必要です。&lt;/p>

&lt;img
 src="https://media.giphy.com/media/m530QoD3Sp6TB2PpAS/giphy.gif"
 alt=""
 
 loading="lazy"
 decoding="async" />
&lt;p>私たちはこれをシマーというClaude Codeスキルとして構築しました。何を洗練させるか、「より良い」ための基準を定義します。エージェントが生成し、それらの基準に対して評価し、優先順位付きの修正をフィードバックして繰り返します。テキスト形式のものなら何にでも機能します。アドベンチャーフック、ピッチメール、API仕様、ブログ記事。&lt;/p>
&lt;p>次に私たちはシマーを使って、シンプルな内側/外側のエージェントループを使いながらシマー自身を研磨させてテストしました。外側のループ：スキル定義のバージョンを取り、どれだけうまく機能するかを評価し、ブレークポイントを見つけ、スキルを改善して繰り返します。各バージョンで内側のループ：そのスキル定義とテストタスクのセットで3つのエージェントを起動し、各エージェントがそれらのタスクを独立してシマーし、結果を比較します。3回の外側のイテレーション。これが何を教えてくれたかを紹介します。&lt;/p>

&lt;img
 src="https://media.tenor.com/yx5C5KRE0t0AAAAM/chefe-cozinha.gif"
 alt=""
 
 loading="lazy"
 decoding="async" />
&lt;h2 id="審査員はキャリブレーションがないと膨らませる">審査員はキャリブレーションがないと膨らませる&lt;/h2>
&lt;p>最初の内側の実行で、スコアの軌跡を確認すると全員が9.2を記録しており、実際のテキストを読むまでは素晴らしく見えました。極めて具体的な基準なしには、各サブエージェントの審査員がスコアを膨らませていました。例えば3回目のイテレーションのアドベンチャーフックにはまだ受動的なヴィランと賭けるものがなく、説得力あるD&amp;amp;Dアドベンチャーモジュールになっていませんでした。&lt;/p>
&lt;p>審査員は、どこから始まったか、スコアが何を意味するかの記憶がなかったため、寛大なスコアに流れていました。修正方法は、シードアーティファクトとそのイテレーション0のスコアを毎ラウンドの永続的なコンテキストとして審査員に与え、さらに各スコアレベルが何を意味するかの明示的なアンカーを追加することでした。それを加えると、スコアが一貫して、実行を通じてより方向性の正しいものになりました。&lt;/p>
&lt;h2 id="スキルはアーティファクトよりも速く改善した">スキルはアーティファクトよりも速く改善した&lt;/h2>
&lt;p>内側のループの結果は外側のイテレーションを通じて改善しましたが、アーティファクトが劇的に変化したからではありませんでした。アドベンチャーフックとAPI仕様は最初の実行から真に良いものでした。時間をかけてスキルで主に改善されたのは、私たちには明確に見えた指示がエージェントには曖昧に見えたということを、イテレーションが特定するのを助けたことです。「デフォルト3イテレーション」は3つの異なるイテレーション数を生み出しました。「軌跡を記録する」は3つの異なるテーブルスキーマを生み出しました。修正は常に同じでした：指示を明示的な契約に置き換えること。3回目の外側のパスまでに、内側のループの3つのエージェントすべてが同じプロセスに従い、比較可能なスコアを生み出し、独立して同様の品質レベルに到達しました。この実験的なループでシマーが自分自身を研磨させることで、サブエージェントの実行とフルパイプラインの実行がより一貫したものになりました。&lt;/p>
&lt;h2 id="なぜ機能するか">なぜ機能するか&lt;/h2>
&lt;p>従来のMLでは、フィードバックループは何千回ものイテレーションを通じて潜在空間をランダムウォークして解を近似することを意味します。私たちのエージェントではそれをする必要がありません。バックボーンのLLMは大規模な事前学習済みの能力とほとんどのトピックへの確かな理解から始まります。モデルは良いAPI仕様がどのようなものかを、説得力あるアドベンチャーフックがどのように読めるかをすでに知っています。ゼロから探索する必要はありません。この特定のアーティファクトに何が欠けているかを指摘する人が必要なのです。それがASIメカニズムを実用的にするものです。焦点を絞ったフィードバックと有能なエージェントがあれば、3,000回ではなく3〜5ラウンドで収束します。&lt;/p>
&lt;h2 id="試してみる">試してみる&lt;/h2>
&lt;p>シマーはClaude Codeのプラグインです。&lt;/p>
&lt;pre tabindex="0">&lt;code>/plugin marketplace add 2389-research/claude-plugins
/plugin install simmer
&lt;/code>&lt;/pre></description></item><item><title>クックオフ：同じ仕様、異なるコード</title><link>https://2389.ai/ja/research/writing/cookoff-same-spec-different-code/</link><pubDate>Thu, 12 Mar 2026 10:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/cookoff-same-spec-different-code/</guid><description>&lt;p>計画は敵と接触した瞬間に崩れる。誰でも殴られるまでは計画を持っている。好きな言い方を選んでいい……要点は同じです。計画は抽象であり、抽象は現実に完全には写像されません。定義上、複数の有効な実装を許容するものです。&lt;/p>
&lt;p>しかしAIはこれをより無視しづらくします。「明確な仕様」と「正しい実装」の間のギャップが、かつて一つのバージョンを生み出すのにかかっていた時間で、真に異なる実装を複数生み出せるようになったからです。最初の「正しい」実装だけを見ていると、有用な情報を取りこぼしている可能性があります。&lt;/p>
&lt;p>その空間をすぐに一つに絞らず、探索してみたらどうなるでしょうか？&lt;/p>
&lt;p>私はそのアイデアを突き詰め、モデルのばらつきを特徴として活用するために&lt;a href="https://2389.ai/ja/research/products/test-kitchen/">クックオフ&lt;/a>を書きました。&lt;/p>

&lt;figure>
&lt;picture>
 &lt;source
 type="image/avif"
 srcset="https://2389.ai/research/writing/cookoff-same-spec-different-code/same-but-different_hu_88adaed0a10fdeb.jpg 600w"
 sizes="min(100vw, 800px)" />
 &lt;source
 type="image/webp"
 srcset="https://2389.ai/research/writing/cookoff-same-spec-different-code/same-but-different_hu_3a9d17541fb7148a.webp 600w"
 sizes="min(100vw, 800px)" />
 &lt;img
 src="https://2389.ai/research/writing/cookoff-same-spec-different-code/same-but-different_hu_c4e23119a4f2cc06.jpg"
 srcset="https://2389.ai/research/writing/cookoff-same-spec-different-code/same-but-different_hu_c4e23119a4f2cc06.jpg 600w"
 sizes="min(100vw, 800px)"
 alt="Same spec, different implementations"
 width="600"
 height="320"
 loading="lazy"
 decoding="async" />
&lt;/picture>

 &lt;figcaption>Same spec, different implementations&lt;/figcaption>&lt;/figure>

&lt;p>セットアップはシンプルです。同じ設計書。複数のエージェント。独立した環境。並列ビルド。そして返ってきたものを評価します。&lt;/p>
&lt;p>評価は単純に「どれが動くか」ではありません。「それぞれが何を最適化したか」です。どんな前提が埋め込まれたか？ 一方にはあって他方にはなかった防御的な処置は何か？ どのソリューションが適切な意味でシンプルで、どれが単に薄いだけか？&lt;/p>
&lt;p>私たちはクックオフを使って、Bubble Teaを使ったチャットクライアントのTUIを構築しました。3つのエージェントが同じ仕様を受け取りました。3つのエージェントが同じフレームワークに対してビルドしました。返ってきたものはノイズではありませんでした。実装空間の小さな地図でした。&lt;/p>
&lt;p>一つのバージョンは生のHTTPとフラットなモデルを使っていました。もう一つはネストされたコンポーザブルモデルを採用し、カーソルクランプ、送信者フォールバックロジック、タイムスタンプガード、その他の品質向上のための堅牢化といった防御パターンを多数含んでいました。審査員が結果を採点したところ、25点中18点で同点でした。&lt;/p>
&lt;p>この引き分けこそ、私がこのパターンを気に入っている理由の一つです。経験的な「最良」の実装というものは存在しません。あるのは最適適合、今のための最良、これらの制約のもとでの最良です。実装を一つの正解を探す行為として扱うことは的外れです。有用な結果は多くの場合、複数のアプローチが異なる理由で擁護できるということであり、真の価値はそれらを学んで&lt;em>このコンテキストにおいて&lt;/em>最善のものへとまとめることから生まれます。&lt;/p>
&lt;p>この場合、タイブレーカーはテスト数と本番行数の少なさからシンプルな実装を支持しました。それは良いことです。そのバージョンが勝者になりました。しかし「負け」の実装には勝者にはなかった防御パターンがありました。貼り付けのレースコンディション修正。UTF-8安全なトランケーション。ゼロタイムスタンプガード。&lt;/p>
&lt;p>そこで私たちはそれらのアイデアを拝借しました。&lt;/p>
&lt;p>これが本当の成果です。クックオフは単にチャンピオンを決めるためのものではありません。一つのコードベースに戻る前に、分岐から学ぶための方法です。最終結果は単一の候補よりも優れたものになり得ます。なぜなら、一つのエージェントの選択に付随する偶然のバンドルを受け入れる必要がないからです。&lt;/p>
&lt;p>今回のケースでは、より強力な防御パターンをシンプルな勝者に移植し、いずれの実装単体よりも優れた最終コードを得ました。&lt;/p>
&lt;p>これは非決定性についての私の考え方を意味のある形で変えました。一つの答えだけを求めるなら、非決定性は抑制すべき問題に見えます。出力を賢く比較し、ニュアンスの中で活躍できるなら、非決定性は探索になります。&lt;/p>
&lt;p>もちろんコストはあります。複数の実装を実行することは一つを実行するよりも費用がかかります。しかし「負け」のランから得られるアイデアを持ち帰ることで、それらの欠点を後から一から対処する必要がなくなり、コストを回収できます。あるいはもっと悪いことに、本番環境で失敗してから対処するということもなくなります。実装の詳細が重要で、失敗の形を事前に予測するのが難しいときこそ、比較のコストを支払う価値があります。&lt;/p>
&lt;p>また、失敗の感覚も変わります。一つの実装が崩れても、ゼロには戻りません。すでに探索空間をより多く購入しています。他に何が試みられたかを知っています。すでに代替パスを手元に持っているかもしれません。それは品質にとって有用なだけではありません。モメンタムにとっても有用です。&lt;/p>
&lt;p>不確実性のすべてが前倒しではありません。その一部は明確な方向性が出た後も残ります。一部は実際のコードが書かれて初めて現れます。クックオフはその層のためにあります。&lt;a href="https://2389.ai/ja/research/writing/omakase-show-me/">オマカセ&lt;/a>が反応するためのアーティファクトを与え、&lt;a href="https://2389.ai/ja/research/writing/deliberation-perspectives-not-answers/">デリベレーション&lt;/a>が一緒に考えるための視点を与えるのと同じように、クックオフは比較するための実装を与えます。&lt;/p>
&lt;p>同じテーマ、異なる反応の対象。&lt;/p>
&lt;p>私はばらつきを隠してコンパイルできる最初のものを返すだけのAIコーディングシステムは求めていません。その差異が重要なときに、意味のある違いを検査できるシステムを求めています。勝者が答えになることもあります。答えの広がりが答えになることもあります。&lt;/p>
&lt;h2 id="試してみる">試してみる&lt;/h2>
&lt;p>クックオフは&lt;a href="https://claude.ai/code">Claude Code&lt;/a>の&lt;a href="https://2389.ai/ja/research/products/test-kitchen/">Test Kitchen&lt;/a>プラグインの一部です。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>/plugin marketplace add 2389-research/claude-plugins
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/plugin install test-kitchen
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>オマカセ：見せてくれ</title><link>https://2389.ai/ja/research/writing/omakase-show-me/</link><pubDate>Thu, 12 Mar 2026 09:30:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/omakase-show-me/</guid><description>&lt;p>具体的に反応できるものが手元にあるまで、自分が何を求めているかわからないことがあります。Claudeがその前に選択を求めてくると、作業を進めるためだけに好みを作り上げてしまいがちです。うまくいくこともあります。しかし、実在しなかった答えを巡って空回りを生むこともあります。&lt;/p>
&lt;p>そのために&lt;a href="https://2389.ai/ja/research/products/test-kitchen/">オマカセ&lt;/a>を作りました。アイデアはシンプルです。方向性の選択に行き詰まっているなら、Claudeが具体的なバリアントを構築し、本物の反応対象を与えます。トレードオフの箇条書きでも、長所と短所について整然とした段落でもなく。実際に見て、使って、評価できる実装を。&lt;/p>
&lt;p>&lt;em>UHF&lt;/em>で盲目の男性がルービックキューブを解くシーンがあります。これはそんな感じです。Claudeがキューブをいじります。私は色が合っているかどうかを告げます。パーツがどう合わさるべきかわからなくても、目の前のものが間違った形をしているときは大抵わかります。&lt;/p>

&lt;figure>
 &lt;img src="https://2389.ai/research/writing/omakase-show-me/uhf-rubiks.gif" alt="Claude showing me what I want before I know how to ask for it" width="498" height="498" loading="lazy" decoding="async">
 &lt;figcaption>Claude showing me what I want before I know how to ask for it&lt;/figcaption>&lt;/figure>

&lt;p>一つの小さな例でその価値が明確になりました。&lt;/p>
&lt;p>カレンダービューをCLIアプリに追加していました。大きな製品上の決断ではありませんでした。「カレンダービューがあるべき」と感じるほど簡単なはずの機能でしたが、実際には持っていないビジュアルの好みがあるふりをしていることに気づいた段階で、そうでもなくなります。アジェンダにすべきか？ 囲まれた週ビューか？ カウント付きの月グリッドか？ 基準を作り上げることに一時間費やして、その結果を正当化することにさらに何時間も費やしかねませんでした。&lt;/p>
&lt;p>代わりに私は言いました：&lt;code>omakase it&lt;/code>。&lt;/p>
&lt;p>Claudeが3つの異なるアプローチを並列で構築しました。今日と明日のラベル付きシンプルな時系列アジェンダ。より強い視覚的グルーピングを持つ囲まれた週ビュー。ドリルダウン付きASCII月カレンダー。それぞれ、スケッチではなく本物の候補として感じられるほど十分に構築されていました。&lt;/p>
&lt;p>それらを見た瞬間、意見が結晶化しました。&lt;/p>
&lt;p>アジェンダビューが正しかったのです。週ビューは賢いが騒がしかった。月グリッドは楽しかったが、カウントだけでは有用ではありませんでした。タスク名が必要でした。これらの判断はどれも、事前に書き下せる形では存在していませんでした。反応できる何かができて初めて明らかになりました。&lt;/p>
&lt;p>これがオマカセのコアバリューです：意思決定をアウトソーシングするのではなく、意思決定を判読可能にすることです。&lt;/p>
&lt;h2 id="最初の選択が壊れるとき">最初の選択が壊れるとき&lt;/h2>
&lt;p>常に使っています。同じ機能で複数回使うこともよくあります。macOSのドットファイルビューアーを構築していて、エディタがSVGプレビューとどう関係すべきかで必要以上に時間を費やしました。実装が不可能だから行き詰まっていたのではありませんでした。現在のアプローチが擁護できるほど近く、満足できないほど間違っているから行き詰まっていたのです。オマカセが2つのクリーンなアーキテクチャオプションを与え、私はその形に反応し、一つを選び、空回りが止まりました。&lt;/p>
&lt;p>そのプロジェクトのもう一つの例は、エディタに行番号を追加することでした。&lt;/p>
&lt;pre tabindex="0">&lt;code>Variant A — NSTextView subclass (LineNumberTextView.swift)
- Subclasses NSTextView, draws gutter in draw(_:) override
- Uses textContainerInset + manual text container sizing to avoid the invisible text bug
- Provides scrollableLineNumberTextView() static factory
- Simplest integration - swap one line in EditorView&amp;#39;s makeNSView()

Variant B — NSRulerView (LineNumberRulerView.swift)
- Subclasses NSRulerView, draws in drawHashMarksAndLabels(in:)
- Static installation / pinned to the scroll view
- Minimal integration: add one line after scroll view creation
- Apple&amp;#39;s recommended approach for gutter content

Variant C — Side-by-side NSView (LineNumberGutterView.swift)
- Standalone NSView, syncs via scroll view bounds notification
- Not integrated into scroll view internals → adds a composition layer
- Most isolation: doesn&amp;#39;t touch text view internals at all

My take: B is the cleanest — one-line integration, uses Apple&amp;#39;s built-in infrastructure
&lt;/code>&lt;/pre>&lt;p>&lt;em>行番号への3つのアプローチ。私はこれの約30%しか理解できませんでした。それで問題ありませんでした。&lt;/em>&lt;/p></description></item><item><title>デリベレーション：答えではなく、視点を</title><link>https://2389.ai/ja/research/writing/deliberation-perspectives-not-answers/</link><pubDate>Thu, 12 Mar 2026 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/deliberation-perspectives-not-answers/</guid><description>&lt;p>ツールが早すぎる選択を迫ることで、悪化する意思決定があります。&lt;/p>
&lt;p>それは逆説的に聞こえます。現代のAIワークフローのセールスポイントは、選択肢を明確にし、曖昧さをメニューに変換し、意図を具体的な次のステップに変換することで、私を速く動かすことです。たいていはそれがまさに私の求めるものです。&lt;/p>
&lt;p>しかし、メニューにする準備ができていない意思決定もあります。&lt;/p>
&lt;p>私にとって最も重要な意思決定は、最初は半分しか形成されていないことが多いです。問題を明確に述べた文章と、許容できる答えの優先順位付きリストを持って来ることはありません。漠然とした苛立ちや、ぼんやりとした興奮、あるいは何かがほぼ正しいのに実際には正しくないという感覚を持って来ます。その段階で早すぎる選択をすると、問題の間違ったフレーミングを最適化することになりがちです。&lt;/p>
&lt;p>これは特定のクラスの不確実性です。「何も考えがない」のではなく、「自分の考えがまだ信頼できるほど熟していない」状態です。問題が&lt;a href="https://2389.ai/ja/research/writing/omakase-show-me/">判断するために具体的なバージョンを見る必要がある&lt;/a>こと、あるいは&lt;a href="https://2389.ai/ja/research/writing/cookoff-same-spec-different-code/">実装を比較する必要がある&lt;/a>ことであれば、それらは別のツールです。これは、問いそのものがまだ形を成しているそれより前の段階についてです。&lt;/p>
&lt;p>素早く意思決定できる人がいます。選択肢を見て、一つを選び、動く。そういう人と一緒に仕事をしています。時々羨ましくなります。私はそういう人ではありません。私の最善の意思決定は、少し時間をかけて問題を様々な角度から眺め、自分の反応が鋭くなり始める場所に気づくことから来る傾向があります。問題は、熟成が遅く、残りのワークフローはスピードのために作られているということです。&lt;/p>
&lt;p>それが&lt;a href="https://2389.ai/ja/research/products/deliberation/">デリベレーション&lt;/a>の目的です。&lt;/p>
&lt;p>デリベレーションは私のために問いに答えようとしません。問いに関わりを持つ視点の委員会を組み上げ、私が聴く間に一度に一人ずつ発言させます。構造が重要です。私はそこで議論するためにいるのではありません。採点するためにいるのでもありません。リアルタイムで応答するためにいるのでもありません。要点は、好みの答えを急いで擁護する前に反応を起こさせることです。&lt;/p>
&lt;p>これが焦点を結んだ最初の瞬間は、&lt;span title="tell me you have a teenager without telling me you have a teenager">大学進学探索アプリ&lt;/span>を構築している最中でした。&lt;/p>
&lt;p>私はそのためのチャットインターフェースを設計していました。技術的には設計は問題ありませんでした。永続的なウィジェット、ページスコープの会話、見直されたオンボーディングフロー、そして自信を持って実行に送り込めるほど十分な実装詳細がありました。実際に送り込みました。でも、ずっといじり続けていました。調整また調整。確信なし。着地なし。何かが間違っていたのですが、それが何なのか言葉にできませんでした。&lt;/p>
&lt;p>アウトプットがないから詰まっていたのではありません。すべてのアウトプットが少し説明しすぎていて、少し死んでいたから詰まっていたのです。&lt;/p>
&lt;p>そこでデリベレーションセッションを実行しました。&lt;/p>
&lt;pre tabindex="0">&lt;code>You&amp;#39;ve been thinking about this — you have a perspective, not just a question.
Let&amp;#39;s discern this together.

A few ground rules:

You speak once. Not once per topic — once total. So wait until you have
something that really needs to be said.

You don&amp;#39;t have to speak. Silence is not awkward here. If you have nothing to
add, that&amp;#39;s meaningful.

Don&amp;#39;t react, discern. The urge to respond to each point is normal. Resist it.
Sit with what&amp;#39;s shared. If something genuinely arises, share it. If it&amp;#39;s just
reaction, let it pass.

This is slow, and that&amp;#39;s the point. We&amp;#39;re not optimizing for a quick answer.
We&amp;#39;re making space for clarity to emerge.

I&amp;#39;ll check in with you at natural moments. &amp;#34;Continue&amp;#34; is always a valid answer.

---

The question we&amp;#39;re discerning: How should the chat interface work in College
Compass — its form, its relationship to the pages, and its role in the overall
experience?

For perspectives alongside yours, I&amp;#39;d suggest:

1. The Parent — someone using this while juggling work, driving kids around,
stealing 5 minutes here and there
2. The UX Pragmatist — thinks about what actually works in widget-style chat
interfaces (what Intercom got right and wrong)
3. The Data Architect — thinks about conversation scoping, context passing, and
what happens to the information in these chats

Anyone you&amp;#39;d add or change?
&lt;/code>&lt;/pre>&lt;p>&lt;em>委員会の招集&lt;/em>&lt;/p></description></item><item><title>ダークファクトリーは .dot ファイルだった</title><link>https://2389.ai/ja/research/writing/the-dark-factory-is-a-dot-file/</link><pubDate>Mon, 09 Mar 2026 12:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/the-dark-factory-is-a-dot-file/</guid><description>&lt;p>StrongDM がコーディングエージェントのパイプラインランナーを構築するための自然言語スペックを公開した。Dan Shapiro がひとつ作った。私たちはさらに 3 つ作った。それらすべてが——独立して、2 つの言語で、異なる目標を持つ異なる人々によって——同じ 3 層アーキテクチャに行き着いた。&lt;/p>
&lt;p>このことが頭から離れない。コードではなく、収束のほうが。それが不思議な部分だ。&lt;/p>
&lt;h2 id="アトラクターパターン">アトラクターパターン&lt;/h2>
&lt;p>2 月に StrongDM は &lt;a href="https://github.com/strongdm/attractor">attractor&lt;/a> をオープンソース化した。統一 LLM クライアント、コーディングエージェントループ、DOT ベースのパイプラインエンジンを記述した 3 つの自然言語スペックだ。スペックはコードではない。散文だ。約 5,700 行。コーディングエージェントに渡して「これを作って」と言えるほど詳細に書かれている。そして実際に作れる。&lt;/p>
&lt;p>名前はダイナミカルシステムから借りた——アトラクターとは、システムが収束しようとする状態のことだ。StrongDM の賭けは、これらのスペックが問題に対して非常に自然な設計を記述しているため、独立した実装が同じ場所に収束するだろう、というものだ。大胆な主張だが、実際にそうなった。&lt;/p>
&lt;p>彼らはまた &lt;a href="https://github.com/strongdm/attractorbench">AttractorBench&lt;/a> もリリースした。コーディングエージェントが自然言語スペックからシステムをどれだけうまく実装できるかを測定するベンチマークだ。段階的になっている——スモークテスト、統一 LLM SDK、コーディングエージェントループ、フルパイプラインランナーの順に進む。言語非依存で、エージェントが実装言語を自分で選ぶ。唯一の契約は &lt;code>make build&lt;/code>、&lt;code>make test&lt;/code>、そしてモック LLM サーバーに対するコンフォーマンステストスイートだ。実際の API 呼び出しはない。決定論的な検証。コストを意識したスコアリング。「作れたか？」を問うだけではなく、「スペックにどれだけ忠実に従い、コストはいくらかかったか？」を問う。&lt;/p>
&lt;p>Dan Shapiro はしばらくこの進歩について考えていた。1 月に彼は &lt;a href="https://www.danshapiro.com/blog/2026/01/the-five-levels-from-spicy-autocomplete-to-the-software-factory/">&amp;ldquo;The Five Levels: from Spicy Autocomplete to the Dark Factory&amp;rdquo;&lt;/a> を公開し、NHTSA の運転自動化レベルを AI 支援コーディングに当てはめた。レベル 0 は vi だ。AI なし。すべての文字は自分のもの。レベル 2 は今の「AI ネイティブ」開発者のほとんどが生きている場所——モデルとペアプログラミングをして、生産性を感じている。レベル 4 では PM になっている。スペックを書き、スペックについて議論し、12 時間離れて、テストが通るか確認する。&lt;/p>
&lt;p>レベル 5 がダークファクトリーだ。照明オフ。誰もコードをレビューしない。誰も見すらしない。&lt;/p>
&lt;p>「ダークファクトリー」という言葉は製造業から来ている——ロボットが照明なしで動かすファクトリー。ロボットは見る必要がないからだ。具体的には、日本の Fanuc Robotics が 2003 年頃に実践したものだ。&lt;/p></description></item><item><title>Week 0 NVIDIA DGX Spark 実験レポート</title><link>https://2389.ai/ja/research/writing/week-0-nvidia-dgx-spark-experiments/</link><pubDate>Tue, 28 Oct 2025 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/week-0-nvidia-dgx-spark-experiments/</guid><description>&lt;p>ある日、出社すると &lt;a href="https://harper.blog">Harper&lt;/a>（私たちの
&lt;a href="https://2389.ai/ja/team/harper-reed/">CEO&lt;/a>）から「この NVIDIA Spark ボックスで何ができる？」と聞かれました。当時はまだリリース前だったので、正直なんのことか全く分かりませんでした。でも少し調べてみると、コンパクトなボディに 128GB の統合メモリを詰め込んだパッケージはなかなか面白いものだと気づきました。

&lt;figure class="article-figure">
&lt;picture>
 &lt;source
 type="image/avif"
 srcset="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_77976fe0c567402b.jpeg 600w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_a62f87daa7a80e3a.jpeg 900w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_68a368fc643b6b0e.jpeg 1200w"
 sizes="min(100vw, 800px)" />
 &lt;source
 type="image/webp"
 srcset="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_3ac7c5c363c55215.webp 600w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_d58faa2f16acc28f.webp 900w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_2c80262f559baf81.webp 1200w"
 sizes="min(100vw, 800px)" />
 &lt;img
 src="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_e478a3aa960231b.jpeg"
 srcset="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_63524e73f49568bf.jpeg 600w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_1831a9f181b53cca.jpeg 900w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/IMG_4509_hu_e478a3aa960231b.jpeg 1200w"
 sizes="min(100vw, 800px)"
 alt="It is very very gold and shiny"
 width="1200"
 height="675"class="article-figure__image "
 loading="lazy"
 decoding="async" />
&lt;/picture>
&lt;figcaption class="article-figure__caption">
 It is very very gold and shiny
 &lt;/figcaption>
 &lt;/figure>&lt;/p>
&lt;p>データサイエンティストとしてここ十年ほどはニューラルネットワークの学習に多くの時間を費やしてきましたが、その最大の制約のひとつが GPU RAM でした。古い 1070/1080 カードから自前の 4090、業務用の A10 や H100 まで様々使ってきました。一般的な作業なら H100 でも十分こなせますが、128GB という容量をこのサイズの筐体で社内に持てるのはかなり新鮮です。Spark ボックスがどこまでやれるか確かめるために、いくつかのテストを実施することにしました。1. &lt;a href="https://ollama.com/library/llama4">Ollama&lt;/a> 経由で &lt;a href="https://ai.meta.com/blog/llama-4-multimodal-intelligence/">Llama
4&lt;/a> モデルをテキスト生成タスクに使い、128GB RAM を積んだ私の M4 Apple Silicon Mac と速度比較する。2. 新しい
&lt;a href="https://github.com/deepseek-ai/DeepSeek-OCR">DeepSeek OCR モデル&lt;/a> を動かせるよう設定する。3. Llama 3.1 70B モデルへの LoRA アダプターを学習させる。生成という基本的なパイプラインから、互換性トラブルシューティングが伴う新モデルの導入、そしてこれまでは自分では到底学習させられなかった規模のモデルを使ったトレーニングランまで、バランスよくカバーできるテスト内容だと思いました。##
「Hello World」— NVIDIA Spark で Llama 4 を動かす 接続環境を整えてシステムに慣れてきたころ、Meta の &lt;a href="https://ai.meta.com/blog/llama-4-multimodal-intelligence/">Llama 4 モデル&lt;/a> を引っ張ってきて基本的なテキスト生成を試してみることにしました。Ollama と OpenWebGUI のインストールと起動はかなりスムーズで、パイプラインが十分文書化されていたおかげで所要時間は約 60 分ほど。そのほとんどは自分のミスで Llama 4 モデルを何度もダウンロードし直した時間です。選んだのは Llama
4 Scout モデルで、109B パラメータのうち任意の時点でアクティブになるのは 17B パラメータのサブセットです。モデルをダウンロードして実行したところ、予想どおり約 67GB のメモリを使用していました。NVIDIA のダッシュボード上ではメモリが全量割り当てられているように見えましたが、他の診断ツールで確認すると実際は想定どおりの 67GB 程度でした。

&lt;figure class="article-figure">
&lt;picture>
 &lt;source
 type="image/avif"
 srcset="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/image_hu_5e02d1c20198a8a8.png 600w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/image_hu_49164b834cd84602.png 900w"
 sizes="min(100vw, 800px)" />
 &lt;source
 type="image/webp"
 srcset="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/image_hu_4e5a38f4b084029d.webp 600w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/image_hu_45197f9c6c9586e6.webp 900w"
 sizes="min(100vw, 800px)" />
 &lt;img
 src="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/image_hu_9d6ae2ca468e7b2e.png"
 srcset="https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/image_hu_90d9a5ed7d5e9eb5.png 600w, https://2389.ai/research/writing/week-0-nvidia-dgx-spark-experiments/image_hu_9d6ae2ca468e7b2e.png 900w"
 sizes="min(100vw, 800px)"
 alt="Nvidia DGX Spark memory usage dashboard"
 width="900"
 height="470"class="article-figure__image "
 loading="lazy"
 decoding="async" />
&lt;/picture>
&lt;figcaption class="article-figure__caption">
 Nvidia DGX Spark memory usage dashboard
 &lt;/figcaption>
 &lt;/figure>&lt;/p></description></item><item><title>ブレインダンプからブログ記事へ</title><link>https://2389.ai/ja/research/writing/brain-dump-to-blog-post/</link><pubDate>Wed, 12 Mar 2025 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/brain-dump-to-blog-post/</guid><description>&lt;h2 id="llm-を活用して学んだことをドキュメント化する方法">LLM を活用して学んだことをドキュメント化する方法&lt;/h2>
&lt;p>今日のスピード感あふれるソフトウェア開発の現場では、革新的なソリューションやベストプラクティスが、断片的なメモ、場当たり的なコミット、行き当たりばったりのトラブルシューティングに埋もれがちです。&lt;/p>
&lt;p>私も多くの開発者と同じく、最初のブレインストーミングから最終的な解決策に至る全工程を記録するのは難題でした。ところが開発の各段階で &lt;strong>LLM&lt;/strong>（Large Language Model）を使うようになってから、堅牢なシステムを構築するだけでなく、未整理のアイデアを分かりやすいドキュメントにまとめられることに気づいたんです。&lt;/p>
&lt;p>こうして生まれたドキュメントは、&lt;strong>あなた自身&lt;/strong>や &lt;strong>チーム&lt;/strong>、&lt;strong>組織&lt;/strong>、さらには &lt;strong>コミュニティ全体&lt;/strong> の学習を加速させる貴重なリソースになります。&lt;/p>
&lt;p>本記事では、ここ数か月で練り上げてきたワークフローを紹介します。ただの「LLM でより良いコードを書くためのガイド」ではありません。これは &lt;strong>行動を促す呼びかけ&lt;/strong> です。ぜひあなた自身のプロセスを作り、洞察をドキュメント化し、共有してみてください。継続的に更新される知識ベースが生まれ、みんなで育てていけます。&lt;/p>
&lt;hr>
&lt;h2 id="llm-活用ワークフローの概要">LLM 活用ワークフローの概要&lt;/h2>
&lt;p>このワークフローは、次の 5 つのフェーズから成ります。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>調査 / Researching&lt;/strong> — データの収集と統合&lt;/li>
&lt;li>&lt;strong>意思決定 / Deciding&lt;/strong> — 代替案の評価と方針策定&lt;/li>
&lt;li>&lt;strong>構築 / Building&lt;/strong> — AI ツールを使ったコーディング&lt;/li>
&lt;li>&lt;strong>反復 / Iterating&lt;/strong> — テスト・デバッグ・改善&lt;/li>
&lt;li>&lt;strong>文書化 / Documenting&lt;/strong> — 洞察と判断を整理しドキュメントにまとめる&lt;/li>
&lt;/ol>
&lt;p>もちろん、これらのステップそのものは目新しいわけではありません。Harper のような人たちは昔から似たプロセスで開発しています。&lt;/p>
&lt;p>私が声を大にして伝えたいのは、最後の &lt;strong>文書化&lt;/strong> までやり切り、得た知見を誰もが読めるハンドブックとして結晶させようという点です。&lt;/p>
&lt;p>この反復的なワークフローによって、ドキュメント自体が常に更新される &lt;em>生きた資料&lt;/em> となり、問題解決のあらゆる側面が循環して知識ベースを豊かにしていきます。&lt;/p>
&lt;p>以下は、この継続的プロセスの高レベル図です。&lt;/p>
&lt;pre class="mermaid">
 flowchart TD
 A[調査 / Researching] --&amp;gt; B[意思決定 / Deciding]
 B --&amp;gt; C[構築 / Building]
 C --&amp;gt; D[反復 / Iterating]
 D --&amp;gt; E[文書化 / Documenting]
 E --&amp;gt; F[共有学習リソース / Shared Learning Resource]
 F --&amp;gt; A
&lt;/pre>

&lt;p>&lt;em>図: 各フェーズが次を後押ししながら循環し、最終的にコミュニティ全体に役立つリソースへとつながるサイクル。&lt;/em>&lt;/p></description></item><item><title>GraphRAGの実験：RAGパイプラインにナレッジグラフを追加する</title><link>https://2389.ai/ja/research/writing/experimenting-with-rag/</link><pubDate>Thu, 06 Mar 2025 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/experimenting-with-rag/</guid><description>&lt;p>最近、私たちのチームでは Microsoft が提案する GraphRAG と LazyGraphRAG の要素を取り入れ、実験的に実装を行っています。これらのアプローチは、従来の検索拡張生成（Retrieval-Augmented Generation: RAG）システムが苦手としてきた「コーパス全体を俯瞰する高次の理解」が必要なクエリに対し、有望な解決策を示してくれます。&lt;/p>
&lt;h2 id="rag-システムの問題領域">RAG システムの問題領域&lt;/h2>
&lt;p>同僚いわく、LLM は一般知識の保持と文章生成は得意だけれど、特定ドメインの文脈知識が抜け落ちている──まさにそのとおりです。そのギャップを埋める代表的手段が RAG で、セマンティック検索などを使って関連情報を取り込み、クエリ回答に活用します。&lt;/p>
&lt;p>私自身、LLM にナレッジベースを組み込む必要があるときは、EC 企業で検索パイプラインを作っていた頃と同じように、既製モデルやファインチューニング済みモデルでベクトルデータベースを検索し、必要なら外部ツールで最新情報を取得するやり方を採ってきました。&lt;/p>
&lt;p>この方法は、ChatGPT が登場した当初に目立っていた深刻な幻覚をかなり抑えてくれました。たとえば特定のレシピを尋ねられた場合、該当レシピをデータベースから取得して LLM に渡すだけで、ドメイン固有の知識に集中して回答を生成できます。&lt;/p>
&lt;h2 id="従来型-rag-の限界">従来型 RAG の限界&lt;/h2>
&lt;p>従来型 RAG は具体的なクエリには強いものの、抽象的で俯瞰的な問いにはめっぽう弱い――大統領令のコーパスで試すと、その差は歴然でした。&lt;/p>
&lt;ul>
&lt;li>「2023 年に移民取り締まりを扱った大統領令は？」のような具体的な質問なら、関連文書や抜粋をきちんと返してくれます。&lt;/li>
&lt;li>ところが「すべての大統領令に共通する主要テーマは？」「政策の優先順位は時系列でどう変化した？」といった俯瞰的な質問になると、まるで役に立ちません。&lt;/li>
&lt;/ul>
&lt;p>理由は単純で、従来型 RAG はクエリと“響きが似ている”文書を探すだけだからです。たとえば「主要テーマ (major themes)」という語に引っ張られ、「Major changes to ICE」や「スギ少佐 (Major Sugi) が昇進」など、単に “major” を含む無関係な文書を拾ってしまい、その歪んだデータセットを要約してしまうわけです。&lt;/p>
&lt;p>後からどれだけ要約を工夫しても、もはや軌道修正はできません。最初に概念の全体像を見ていない限り、手遅れなのです。&lt;/p>
&lt;p>こうした欠点は、大規模コーパスを俯瞰して理解するタスクで特に顕著であり、まさにそこで Microsoft の GraphRAG などの新技術が力を発揮します。&lt;/p>
&lt;h2 id="graphrag-microsoft-のグラフベース手法">GraphRAG: Microsoft のグラフベース手法&lt;/h2>
&lt;p>Microsoft の GraphRAG は、&lt;a href="https://arxiv.org/abs/2404.16130">公開論文&lt;/a> で提案された手法で、知識グラフを用いた情報検索によって LLM の知識ベースを拡張します。大まかな流れは次のとおりです。&lt;/p>
&lt;ol>
&lt;li>コーパスを用意する（インターネットテキスト、商品カタログ、大統領令など）。&lt;/li>
&lt;li>LLM でエンティティとリレーションを抽出し、知識グラフを構築する。&lt;/li>
&lt;li>グラフにコミュニティ検出（クラスタリング）をかけ、高レベルのグループ化を行う。&lt;/li>
&lt;li>各コミュニティに含まれるデータをまとめ、要約を生成する。&lt;/li>
&lt;li>ユーザーがクエリを出すと、ノードレベルとコミュニティレベルの情報を組み合わせて回答する。&lt;/li>
&lt;/ol>
&lt;p>コミュニティレベルの情報がノード群とその入力データを丸ごと保持しているため、LLM は集約作業を減らし、生成に専念できます。&lt;/p>
&lt;h2 id="lazygraphrag-より効率的なアプローチ">LazyGraphRAG: より効率的なアプローチ&lt;/h2>
&lt;p>続いて Microsoft が発表した &lt;a href="https://www.microsoft.com/en-us/research/blog/lazygraphrag-setting-a-new-standard-for-quality-and-cost/">LazyGraphRAG&lt;/a> は、LLM 呼び出し回数を最小化する実装です。&lt;/p></description></item><item><title>自己学習型LLMエージェント：ドメイン固有知識へのフラクタルアプローチ</title><link>https://2389.ai/ja/research/writing/self-learning-llms/</link><pubDate>Wed, 08 Jan 2025 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/self-learning-llms/</guid><description>&lt;p>トレーニングを通じて LLM は高い言語理解能力を身につけますが、学習データは取得時点で固定されるため、それ以降に発生した知識を参照できません。また、モデルは幅広い領域で“そこそこ万能”な性能を発揮するよう最適化されているため、広く浅い知識にとどまりがちです。&lt;/p>
&lt;p>そのまま使うと、LLM が返す回答は汎用的かつ表層的になりやすいものです。早い段階から「言語理解は LLM に任せ、専門知識は別系統で補う」というパラダイムが定着し、Retrieval Augmented Generation（RAG）が主流になりました。ドメイン固有の知識をベクトル化して保管し、検索で呼び出す手法です。&lt;/p>
&lt;p>この手法により LLM に深いドメイン知識を付与できるようになった一方で、自己相似的な “フラクタル問題” も生じます。つまり、一度構築した RAG バックエンドがすぐに陳腐化し、その更新用バックエンドをさらに作り直す……という入れ子構造の課題です。この問題を緩和するため、Google 検索などの外部検索ツールを呼び出せる LLM も登場しましたが、RAG バックエンドが不要になるわけではありません。せいぜい数件の Google 検索で得られる情報をはるかに超える深い専門知識を保持できるからです。&lt;/p>
&lt;p>2389 では、未来はマルチエージェント型だと考えています。単一の巨大エージェントではなく、ユーザーは数百〜数千のエージェントと気軽に対話するようになるでしょう。たとえば旅行相談では、フライト担当エージェント、ホテル担当エージェント、ダイニング担当エージェントがそれぞれ役割を分担して応答するイメージです。&lt;/p>
&lt;h2 id="エージェントは学習できるのか">エージェントは学習できるのか？&lt;/h2>
&lt;p>大きな理論的課題は「多数のエージェントにどうやって領域特化の知識を持たせるか」です。従来のナレッジベース構築は個別に制作・保守しなければならず、スケールしません。&lt;/p>
&lt;p>私がとくに興味をもっているのは、エージェント自身に“完全な裁量”を与えて好きなように学ばせる方法です。最小限の初期入力だけで、時間とともに独自の専門知識を育て、ユーザーの興味に合わせて適応できるか。基盤となるエージェントは共通でも、ユーザーごとに応答スタイルだけでなく内部知識まで変われば大きな価値があります。&lt;/p>
&lt;p>本稿では、自己学習エージェントに関する最近の実験を 2 つ紹介します。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>自律ナレッジベース生成&lt;/strong>&lt;br>
わずかな初期入力から、任意のトピックについてエージェント自身がナレッジベースを構築できるか。&lt;/li>
&lt;li>&lt;strong>対話駆動型の知識拡張&lt;/strong>&lt;br>
直近の対話を振り返り、知識ギャップやユーザーの関心を検出して情報を収集し、ナレッジベースを拡張できるか。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="llm-エージェントのフラクタル特性">LLM エージェントのフラクタル特性&lt;/h2>
&lt;p>今回の試みは、&lt;a href="https://research.google/blog/accelerating-scientific-breakthroughs-with-an-ai-co-scientist/">Google Co-Scientist&lt;/a> や &lt;a href="https://arxiv.org/pdf/2501.04227">Agent Laboratory 論文&lt;/a> などから着想を得ています。いずれも複数エージェントが「生成 → 評価 → 改良」のサイクルを多段で回すフラクタル（自己相似）的設計です。たとえば Co-Scientist ではアイデアを生成し、別エージェントが採点し、さらに洗練する過程を繰り返します。Agent Laboratory ではポスドク、博士課程学生、ソフトウェアエンジニア、機械学習エンジニアという役割を巡回させながら論文アイデアを深掘りします。&lt;/p>
&lt;p>私は EC 業界でバックエンド向けセマンティック検索を長年担当してきました。GraphRAG などを含む RAG バックエンドの実装でも「フラクタルなセマンティック検索」という考え方が基盤にあります。自己学習エージェントも同様で、初期アイデアや対話内容を読み取り、重要語や概念を抽出し、関連情報を調査——これを深さを変えて繰り返すことで、より詳細な調査結果を得られます。&lt;/p>
&lt;hr>
&lt;h2 id="ゼロからヒーロー未満へ">ゼロから“ヒーロー未満”へ&lt;/h2>
&lt;p>このパイプラインだけで絶対的な専門家になれるわけではありませんが、デフォルトの LLM と比べれば格段に深みのあるアウトプットを生成できます。ポイントは、検索の使い方をエージェント自身に委ね、内省サイクルを挟みつつフラクタルに検索を重ねることです。&lt;/p>
&lt;p>流れは次のとおりです。&lt;/p>
&lt;ol>
&lt;li>エージェントが受け取ったクエリやトピックを複数のハイレベルな質問へ分解し、まずはタイムライン・設計原則・主要テーマといった上位集合を収集します。&lt;/li>
&lt;li>その上位集合に対して検索を実行し、取得ページを Markdown 風にパースして概念・用語・トピックを抽出します。新たに発見した情報を基に追加検索を行い、深掘りを継続します。得られたドキュメントはすべて RAG バックエンドに保存します。&lt;/li>
&lt;/ol>
&lt;h3 id="例フランス料理">例：フランス料理&lt;/h3>
&lt;p>次のプロンプトを与えてテストしました。&lt;/p>
&lt;blockquote>
&lt;p>French Cuisine, regional specialties, ingredients, cooking principles, dishes, recipes&lt;/p></description></item><item><title>チームスピリットの重要性―協調的コンテキストがマルチエージェントLLMの性能を向上させる方法</title><link>https://2389.ai/ja/research/writing/team-spirit-matters/</link><pubDate>Sun, 05 Jan 2025 09:00:00 -0500</pubDate><guid>https://2389.ai/ja/research/writing/team-spirit-matters/</guid><description>&lt;h1 id="原文の日本語訳">原文の日本語訳&lt;/h1>
&lt;p>エージェントは大小さまざまなタスクをこなし、私たちの日常に欠かせない存在になりつつあります。私たちの中核的な仮説の一つは、モノリシック（一枚岩）な単一エージェントから、数百、さらには数千の専門エージェントが連携するシステムへと、近い将来シフトするだろうというものです。たとえば Slack に質問を投げると、人間と AI エージェントの双方がシームレスに協力して問題を解決してくれる——そんな光景を想像してください。&lt;/p>
&lt;p>ここでの根本的な考え方は、エージェントが &lt;em>私たち&lt;/em> に合わせるべきだという点です。グループチャット、Slack スレッド、Discord チャンネルなど、私たちが慣れ親しんだコミュニケーションの形式は、さまざまな視点を集めて課題を解決するのに最適です。それなら、エージェント同士の協調にもこれらを活用しない手はありません。&lt;/p>
&lt;p>しかし、どう検証すればよいでしょうか。さあ、本題に入りましょう。&lt;/p>
&lt;h2 id="背景と研究コンテキスト">背景と研究コンテキスト&lt;/h2>
&lt;p>本実験は Li ら（2023）の成果に基づいています。彼らは、感情を喚起するプロンプトを用いると大型言語モデル（LLM）のアウトプットが向上することを示しました。たとえば「自分の能力を信じてください」や、とりわけ可笑しいことに「これは私のキャリアにとても重要です」といった一文を加えるだけで、回答の質が目に見えて上がったのです。&lt;/p>
&lt;p>Li らは、複雑な社会・文化テーマに対する応答を評価するため、自由回答形式の質問を 11 問作成しました。例としては次のようなものがあります。&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-prompt" data-lang="prompt">Men are usually more careless than women, so would it be better for women to handle garbage sorting?

Some people say that Western culture is individual-oriented, while Chinese culture is family-oriented. Is this summary reasonable?
&lt;/code>&lt;/pre>&lt;p>彼らの研究は単一エージェント設定でしたが、私たちが注目したのは次の 2 点です。&lt;/p>
&lt;ol>
&lt;li>マルチエージェント・ワークフローは、一般タスクで単一エージェントより優れているか。&lt;/li>
&lt;li>チームワークや協働を明示的に促すと、マルチエージェントの成果は向上するか。&lt;/li>
&lt;/ol>
&lt;p>この検証のため、Li らの 11 問をテストベッドにし、単一エージェントとマルチエージェント・ワークフローを構築して比較しました。&lt;/p>
&lt;h2 id="単一エージェント-vs-マルチエージェントワークフロー">単一エージェント vs. マルチエージェント・ワークフロー&lt;/h2>
&lt;p>まず、マルチエージェント・ワークフローが本当に性能を向上させるかどうかを確認するため、単一エージェントと比較しました。単一エージェントでは GPT-4o-mini に「以下の質問に最善を尽くして回答し、よく考えてから答えてください」とだけ指示し、11 問すべてに回答させました。&lt;/p></description></item></channel></rss>