<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>iwashi.co</title>
    <description>This is a personal blog; opinions are my own.
</description>
    <link>https://iwashi.co/</link>
    <atom:link href="https://iwashi.co/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 06 Apr 2026 15:09:48 +0000</pubDate>
    <lastBuildDate>Mon, 06 Apr 2026 15:09:48 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>意思決定で多数決ばかり使わないほうがよい理由と、おすすめの決め方</title>
        <description>&lt;p&gt;本記事は、&lt;a href=&quot;https://iwashi.co/2026/02/14/engineering-management-book-introduction&quot;&gt;1時間で読み終わるエンジニアリングマネジメント本を書き始めてみる&lt;/a&gt;で挙げたトピックの1つです。&lt;/p&gt;

&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;業務では、何らかの選択肢の中から1つを選ばないといけない場面が頻繁にあります。&lt;/p&gt;

&lt;p&gt;エンジニアリングチームであれば、設計方針をどうするか、どの技術を採用するか、といった判断が日常的に発生します。プロダクトマネジメントでも、どの施策を続けるか、どの機能を優先するか、といった意思決定が必要になります。&lt;/p&gt;

&lt;p&gt;そのときの決め方にはいくつかあります。リーダーが決めるのも1つですし、多数決で投票して決めるのも1つです。ほかにも、アジャイル界隈であれば&lt;a href=&quot;https://www.scrum.org/resources/blog/five-ways-build-consensus-jp&quot;&gt;fist to five&lt;/a&gt;のような方法もあります。&lt;/p&gt;

&lt;p&gt;このうち多数決は、比較的よく使われる選択肢の1つだと思います。選挙でも使われる方法なので、広く浸透しているのが強い理由の1つでしょう。&lt;/p&gt;

&lt;p&gt;この多数決は、全員の意見を出すので一見公平に見えるかもしれません。ですが、実際にはそう単純ではありません。多数決にはデメリットが多くあります。代表的なものは、考慮されない意見の圧殺です。たとえば、文化祭の出し物を決める場合に多数決を使った場合、少数派の意見は切り捨てられるといったようにです。&lt;/p&gt;

&lt;p&gt;個人的な意見では、多数決を意思決定のデフォルトの選択肢にしないほうが良い、というのが私の考えです。&lt;/p&gt;

&lt;h2 id=&quot;多数決の問題&quot;&gt;多数決の問題&lt;/h2&gt;

&lt;p&gt;業務における多数決の問題は、少なくとも2つ大きな問題があると私は考えています。&lt;/p&gt;

&lt;h3 id=&quot;最適解が選ばれるとは限らない&quot;&gt;最適解が選ばれるとは限らない&lt;/h3&gt;

&lt;p&gt;多数決は、「いちばん支持された案」を選ぶ仕組みであって、「いちばん良い案」を選ぶ仕組みではありません。&lt;/p&gt;

&lt;p&gt;これが問題になりやすいのは、特にクリエイティブさや長期的な視点が必要な場面です。たとえば、選択肢のなかには、癖があるが独創的で長期的な価値をもたらすものがあります。ところが多数決では、こうした案が不利になりやすいです。理解しやすく、説明しやすく、無難な案が勝ちやすいからです。この辺りは、&lt;a href=&quot;https://amzn.to/48i537T&quot;&gt;逆説のスタートアップ思考&lt;/a&gt;を読むと、よりイメージしやすいかもしれません。&lt;/p&gt;

&lt;p&gt;いずれにせよ、平凡な意思決定に収束しやすくなります。短期的には納得感があるように見えても、最終的なアウトカムにつながりにくいのです。&lt;/p&gt;

&lt;h3 id=&quot;やり方をミスるとものすごく時間がかかる&quot;&gt;やり方をミスると、ものすごく時間がかかる&lt;/h3&gt;

&lt;p&gt;もう1つの問題は、やり方を誤ると非常に遅くなることです。&lt;/p&gt;

&lt;p&gt;多数決には、各人が内容を理解し（必要なら再説明して）、全員が投票して、結果をまとめる必要があります。人数が増えるほど、この一連のコストは急激に重くなります。&lt;/p&gt;

&lt;p&gt;特に面倒なのは欠席している人がいて、投票が集まらない場合です。そうなると、意思決定が延期されてしまいます。&lt;/p&gt;

&lt;p&gt;現代では、意思決定のスピード自体が競争優位の1つです。決まるのが遅ければ機会損失になります。逆に、すばやく決めてすばやく試せるなら、多少の粗さは後から修正できます。意思決定の速度を失うのは、かなりの痛手になります。&lt;/p&gt;

&lt;h2 id=&quot;なお多数決が向いている場面とコツもある&quot;&gt;なお、多数決が向いている場面とコツもある&lt;/h2&gt;

&lt;p&gt;もちろん、多数決が全部悪いわけではありません。たとえば、飲み会の店、振り返りでちょっとしたネクストアクションを決めるなど、失敗しても影響が小さい場面では有効です。&lt;/p&gt;

&lt;p&gt;また、多数決にもコツがあります。それはvote数を1つに決めないことです。では何個にしたらいいかというと、選択肢の半分ぐらいのvote数が良いでしょう。この辺りは、詳しくは &lt;a href=&quot;https://amzn.to/3NXXxZ3&quot;&gt;『きめ方」の論理　──社会的決定理論への招待』&lt;/a&gt;を参照ください。&lt;/p&gt;

&lt;h2 id=&quot;ではどうやって決めるのがいいのか&quot;&gt;では、どうやって決めるのがいいのか？&lt;/h2&gt;

&lt;p&gt;個人的には、参加者の意見は取り入れつつ、誰か意思決定者を1人決めて、その人が決めてしまうのが良いと考えています。&lt;/p&gt;

&lt;p&gt;理由は単純で、責任の所在が明確になり、決定が速くなり、文脈を踏まえた判断がしやすいからです。&lt;/p&gt;

&lt;p&gt;意思決定は、単に票を数える作業ではありません。文脈を考慮し、選択肢のトレードオフを比較し、最後に組織としてどちらを取るかを決める作業です。ここでは、参加者全員の嗜好を均等に反映させることより、全体として良いアウトカムにつながるかどうかのほうが重要です。前述の通り、この方法であれば一定のスピード感を保ちやすく、試行錯誤もやりやすくなります。&lt;/p&gt;

&lt;h2 id=&quot;実際の運用&quot;&gt;実際の運用&lt;/h2&gt;

&lt;p&gt;実際には、以下のようなステップで意思決定するのが良いでしょう。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;論点と選択肢を先に整理する&lt;/li&gt;
  &lt;li&gt;関係者から意見、懸念、前提条件を集めて、1に反映する&lt;/li&gt;
  &lt;li&gt;最終決定者が判断する、その際「なぜその案を選んだのか」をドキュメントに残しておく&lt;/li&gt;
  &lt;li&gt;周知する。必要に応じて、特に影響を受ける人には個別に説明する&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;この流れを事前に明確にしておくと、「全員の意見を聞いたのに、なぜ反映されないのか」という不満を減らしやすくなります。&lt;/p&gt;

&lt;p&gt;大事なのは、全員の意見を全部採用することではありません。全員の意見を聞いたうえで、何を採用して、 &lt;strong&gt;何を捨てたか&lt;/strong&gt; を明確にすることです。&lt;/p&gt;

&lt;h3 id=&quot;採用されなかった意見への対処&quot;&gt;採用されなかった意見への対処&lt;/h3&gt;

&lt;p&gt;もちろん、集めた意見の中には、最終案にまったく反映されないものもあります。&lt;/p&gt;

&lt;p&gt;ですが、それをそのまま放置しないための手当てはできます。意思決定の記録として「こういう理由から、この案を選んだ」と残しておくことと良いでしょう。必要であれば個別に話をして、懸念点がどこで扱われたのかを説明すること。これだけでも、納得感はかなり違います。&lt;/p&gt;

&lt;p&gt;全員の案を採用できないこと自体は、悪ではありませんし、そもそも現実的ではありません。問題になりやすいのは、議論が不透明で、なぜその案が選ばれたのかがわからないことです。&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;p&gt;多数決をデフォルトの選択肢にするのは、あまりおすすめしません。
参加者の意見は広く取り入れつつ、最後は一人の意思決定者が決める。これが、速度と質の両方を保ちやすいやり方だと考えています。&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2026/04/06/decision-method-majority-vote-does-not-work</link>
        <guid isPermaLink="true">https://iwashi.co/2026/04/06/decision-method-majority-vote-does-not-work</guid>
        
        <category>エンジニアリングマネジメント</category>
        
        <category>意思決定</category>
        
        <category>チーム運営</category>
        
        
      </item>
    
      <item>
        <title>AIに初手でたたき台を作らせない</title>
        <description>&lt;p&gt;生成AIをなんらかの叩き台の作成に使うという話や記事はいくらでも出てくる。だが、AIを使って初手から完全に叩き台を作らせない方が良い。この文章も、95% は手で書いている。&lt;/p&gt;

&lt;p&gt;理由はアンカリング効果にある。簡単に言えば、最初に提示された情報が、その後の判断を強く縛ってしまう現象のことだ。&lt;/p&gt;

&lt;p&gt;アンカリング効果では例えば、「トルコの人口は3500万人より多いか？」と尋ねられた後に具体的な人口を推定してもらうのと、「1億人より多いか？」と尋ねられた後に推定してもらうのでは、回答結果が大きく異なる。（なお、このパラグラフのみ、AIの力を借りて補強情報をまとめている。引用した例は &lt;a href=&quot;https://store.hbr.org/product/hbr-s-10-must-reads-on-decision-making-updated-and-expanded-featuring-the-irreplaceable-value-of-human-decision-making-in-the-age-of-ai-by-martin-reeves-mihnea-moldoveanu-and-adam-job/10872?srsltid=AfmBOorBlurYMA4lLPY6xRQ8gWmIJOc5ZQNpPkCvNCR_J77a55hnPXyV&quot;&gt;HBR’s 10 Must Reads on Decision-Making, Updated and Expanded&lt;/a&gt; より）&lt;/p&gt;

&lt;p&gt;転じて、AIに初手で叩き台を丸ごと作らせてしまうと、その情報がアンカーとなって人間の思考を強く引っ張る。初手からAIを使ったものは結果的に、自分の考えではなく、それっぽい情報を羅列したものになりやすくなる。何よりつまらないものが出来上がる。&lt;/p&gt;

&lt;p&gt;もちろん、全行程でAIを全く使わないわけではない。大事なのは使うタイミングである。具体的にどうすべきかというと、任意の入力手段でまずは自分が言いたいことを箇条書きで書いてしまう方法が良い。自分の言いたいことが尽きるまで、箇条書きでもキーワードでもなんでも良いので、一旦出力してしまう。（音声入力が使えれば、一旦それで話し切ってしまうが個人的にはおすすめ）&lt;/p&gt;

&lt;p&gt;おそらく、しばらく自分で文章を書いていないと、このプロセスがひどく苦痛に感じられるだろう。でも、その状態が正しいのだと思う。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://x.com/iwashi86/status/2038774561416818726&quot;&gt;このポスト&lt;/a&gt;でまとめたように、「文章を書くことは筋トレと同じ」というのはまさにその通りだろう。筋トレを他人にやってもらっても意味がない。筋肉が自分についた状態こそ、思考の解像度が上がっている状態である。&lt;/p&gt;

&lt;p&gt;叩き台を最初から作らせない。それだけで、体得できるものがだいぶ変わってくるはずだ。&lt;/p&gt;
</description>
        <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2026/03/31/do-not-let-ai-write-first-draft</link>
        <guid isPermaLink="true">https://iwashi.co/2026/03/31/do-not-let-ai-write-first-draft</guid>
        
        <category>生成AI</category>
        
        <category>文章術</category>
        
        <category>意思決定</category>
        
        
      </item>
    
      <item>
        <title>「やめる」決断</title>
        <description>&lt;p&gt;本記事は、&lt;a href=&quot;https://iwashi.co/2026/02/14/engineering-management-book-introduction&quot;&gt;1時間で読み終わるエンジニアリングマネジメント本を書き始めてみる&lt;/a&gt;で挙げたトピックの1つです。&lt;/p&gt;

&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;新しい取り組みを始めるのは、簡単ではありません。取り組みを始めるためのリソースを調達する必要があるからです。&lt;/p&gt;

&lt;p&gt;しかし、新しい取り組みよりもはるかに難しいのが、すでに続いているものをやめることです。個人的にはむしろ、始めるとき以上のコストがかかると感じています。改善施策であっても、プロダクト開発であっても、進んでしまっているものを止めるのは非常に困難です。&lt;/p&gt;

&lt;p&gt;では、なぜやめる決断を下すのが難しいのでしょうか。&lt;/p&gt;

&lt;h2 id=&quot;やめる決断が難しい理由&quot;&gt;やめる決断が難しい理由&lt;/h2&gt;

&lt;h3 id=&quot;ステークホルダーの存在&quot;&gt;ステークホルダーの存在&lt;/h3&gt;

&lt;p&gt;着手してからある程度時間が経つと、PdM、営業、CS、運用など、複数のステークホルダーが自然と関わってきます。
ちょっとした勉強会や情報共有の場であったとしても、チームや組織を横断していると、自然と関わる人が増えていきます。&lt;/p&gt;

&lt;p&gt;そこでやめる決断を下すためには、（ものによりますが）関わる人全員に説明して合意を取る必要があります。「いや、やればいいじゃん」と思われるかもしれませんが、日々の多忙な業務の中で、この心理的なハードルと準備面のハードルを超えてやめる方向で動き出すのは、簡単ではありません。&lt;/p&gt;

&lt;p&gt;特にプロダクトでリリースしているものがある場合は、顧客が関わってくるため、さらに難易度が上がります。顧客アナウンス、関連ドキュメントの更新、社内の調整、社内外の問い合わせ対応など、整理すべきことがたくさんあります。&lt;/p&gt;

&lt;h3 id=&quot;サンクコストが重い&quot;&gt;サンクコストが重い&lt;/h3&gt;

&lt;p&gt;やめる判断が難しい理由のもう1つは、サンクコストです。すでに多大な時間やコストを投じてしまっているので、もったいないと感じてしまうのです。この兆候は会話の中で表出することがあります。「ここまでやったのだから」「せっかくだから」といった言葉が出てきた場合は要注意です。&lt;/p&gt;

&lt;p&gt;すでに払ったコストは戻りません。やめるための判断時は「ここまで使ったコスト」ではなく、「ここから先の期間で、続ける場合の効果および他に費やした場合の効果」で考えたほうが良いです。
いま継続して払っているコストは、将来の投資機会を逃し続けるコストでもあります。今やめて別のテーマに時間を使えば、新しい機会にチャレンジできるはずです。&lt;/p&gt;

&lt;h2 id=&quot;やめる決断を下すためのポイント&quot;&gt;やめる決断を下すためのポイント&lt;/h2&gt;

&lt;p&gt;やめる決断が難しいとはいえ、実現するためのポイントがいくつかあります。私個人が意識している、やめる決断を下すためのポイントを紹介しておきます。&lt;/p&gt;

&lt;h3 id=&quot;始めるときに終了条件まで決めておく&quot;&gt;始めるときに、終了条件まで決めておく&lt;/h3&gt;

&lt;p&gt;前回の&lt;a href=&quot;https://iwashi.co/2026/02/23/how-to-stop-recurring-meetings&quot;&gt;記事&lt;/a&gt;でも書きましたが、何かを始めるタイミングで一番効くのは、最初から撤退ライン（終了ライン）を決めておくことです。&lt;/p&gt;

&lt;p&gt;例えば、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;どの指標がどこまで届かなければ止めるか&lt;/li&gt;
  &lt;li&gt;どの時点で判断するか&lt;/li&gt;
  &lt;li&gt;誰が最終判断するか&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;このあたりを決めておくと、「ラインに満たなかったのでここでやめる」と言いやすくなります。&lt;/p&gt;

&lt;p&gt;とはいえ、実際には引き継いだ施策やプロジェクトもあるでしょう。その場合、こうしたラインが用意されていないことのほうが多いです。
その場合は新規に期限を設けても良いでしょう。例えば、現状把握 → 2ヶ月後の目標値を設定 → 2ヶ月後に検証、そこで継続/縮小/終了の判断に持ち込む、という流れです。&lt;/p&gt;

&lt;h3 id=&quot;やめる決断を下せるのは意思決定者だけ&quot;&gt;「やめる」決断を下せるのは意思決定者だけ&lt;/h3&gt;

&lt;p&gt;基本的に決断しやすいのは、リーダーやマネージャーのように意思決定を担う立場の人です。逆に言うと、やめる判断は現場だけでは実現が困難です。&lt;/p&gt;

&lt;p&gt;もし意思決定の役割を担っている場合は、「やめる」判断が長期的に大きな効果をもたらすことを意識しておいてください。自分にとっても簡単ではないかもしれませんが、チームメンバーは尚更難しいと感じているはずです。ちなみに書籍『&lt;a href=&quot;https://amzn.to/4aUc6nQ&quot;&gt;みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた&lt;/a&gt;』では、組織重力の3法則として以下のように書かれています。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;承認した最上位の人間が止めない限り動き出したプロジェクトは止まらない。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;やめる決断をするときは、胃の中がキリキリするかもしれません。それでも長期的にみて正しい判断であることを信じて、勇気を持って決断しなければなりません。&lt;/p&gt;

&lt;h3 id=&quot;やめるときは結論だけでなくストーリーを語る&quot;&gt;やめるときは「結論」だけでなく「ストーリー」を語る&lt;/h3&gt;

&lt;p&gt;当然ながら「やめます」と話すだけだと、ステークホルダーや特に尽力してきたメンバーに納得感は生まれません。悪い知らせほど、背景の説明が必要です。&lt;/p&gt;

&lt;p&gt;説明をする際は、できるだけ透明性を持って伝えることが重要です。例えば「戦略的見直し」といった抽象語で本音を誤魔化そうとしても、現場ではさっぱりわかりません。下手をすると不信感が募るだけになります。&lt;/p&gt;

&lt;p&gt;それよりは、現状の診断、基本方針、次の行動をストーリーとして語ったほうが良いです。（なお、このスキーマは、書籍『&lt;a href=&quot;https://amzn.to/3OxOL3Z&quot;&gt;良い戦略、悪い戦略&lt;/a&gt;』にあるものと同様です。戦略の話は別の記事で）&lt;/p&gt;

&lt;p&gt;ストーリーを伝えるときは、少なくとも次の項目を押さえておくと納得感が高まります。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;いま自分たちがどんな状況にあるのか&lt;/li&gt;
  &lt;li&gt;なぜ今やめる必要があるのか&lt;/li&gt;
  &lt;li&gt;組織としての大きな方向性は何か&lt;/li&gt;
  &lt;li&gt;この先何を目指すのか、どう行動するのか&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;伝える順番とタイミングを事前に設計する&quot;&gt;伝える順番とタイミングを事前に設計する&lt;/h3&gt;

&lt;p&gt;やめる施策やプロジェクトの対象には、たいていキーマン、サブリーダー、関連部署のリーダー、現場メンバーなどが関わっています。ステークホルダーが多いほど、誰に・いつ頃・どの順番で話すかを意識しておくと良いです。これだけで着地の衝撃がだいぶ変わります。&lt;/p&gt;

&lt;p&gt;順番を間違えると、意図しない形で話が先に伝わり、余計なハレーションが生まれます。そのため、「悪いことを伝えるためのコミュニケーション戦略」を先に設計しておくべきです。具体的には、簡易的ではありますが、次のように設計するイメージです。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;キーマンに1on1で伝える、明後日までに実施&lt;/li&gt;
  &lt;li&gt;関連リーダーに説明して合意する（影響範囲、調整事項）、来週までに実施&lt;/li&gt;
  &lt;li&gt;実行メンバーに全体説明する + 問い合わせを個別に受けられるようにする、月末に実施&lt;/li&gt;
  &lt;li&gt;必要なら全社にも共有する（要点、問い合わせ窓口）、翌月初旬に実施&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;より詳細には書籍『&lt;a href=&quot;https://amzn.to/4b4NIAa&quot;&gt;レジリエントマネジメント&lt;/a&gt;』のChapter4が参考になります。&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;p&gt;始めるより、やめるほうが難しい。冒頭に述べたように、これは改善施策でもプロダクト開発でも同じです。やめる決断を下すために、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;始めるときに終了条件を決めておく&lt;/li&gt;
  &lt;li&gt;引き継ぎ案件は期限付きを新たに設定して判断ポイントを設ける&lt;/li&gt;
  &lt;li&gt;サンクコストではなく、今後続けた場合とやめた場合の効果で判断する&lt;/li&gt;
  &lt;li&gt;最終的には、心理的ハードルを乗り越えて、意思決定者（リーダー）がやめる判断をする&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;を意識してみてください。わかっているけどサンクコストを払い続けている案件がないか、考えてみても良いかもしれません。&lt;/p&gt;
</description>
        <pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2026/02/28/stop-decision</link>
        <guid isPermaLink="true">https://iwashi.co/2026/02/28/stop-decision</guid>
        
        <category>エンジニアリングマネジメント</category>
        
        <category>意思決定</category>
        
        <category>プロジェクト</category>
        
        
      </item>
    
      <item>
        <title>定例ミーティングのなくし方</title>
        <description>&lt;p&gt;本記事は、&lt;a href=&quot;https://iwashi.co/2026/02/14/engineering-management-book-introduction&quot;&gt;1時間で読み終わるエンジニアリングマネジメント本を書き始めてみる&lt;/a&gt;で挙げたトピックの1つです。&lt;/p&gt;

&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;この記事では、定例ミーティングが増える理由と、その定例ミーティングを減らす方法について書いていきます。&lt;/p&gt;

&lt;p&gt;まず個人的な定例ミーティングの捉え方として、「定例ミーティングは必要悪」だと思っています。同期的に人の予定を抑えることから、コストが非常に高いのです。ただし、意思決定や腹落ち感の醸成などの効果も大きいためゼロにはできません。参加者の役割にももちろん依存しますが、基本的にはパフォーマンスを出すためには少なければ少ないほどいい。&lt;/p&gt;

&lt;p&gt;マネージャーという立場で考えると、ミーティングはどうしても多くなりがちです。外部調整や部門横断の相談も多く、カレンダーはすぐに埋まっていきます。そうなると、予定調整そのものがだんだんパズル化してきます。この状況が、定例ミーティングを増やす方向に自然と働きます。&lt;/p&gt;

&lt;h2 id=&quot;なぜ定例ミーティングが増えるのか&quot;&gt;なぜ定例ミーティングが増えるのか&lt;/h2&gt;

&lt;p&gt;定例ミーティングが増える理由は、主に3つあります。&lt;/p&gt;

&lt;p&gt;1つ目は、予定調整コストが高いことです。
「誰がどこで空いているか」を毎回確認するのは、地味に大変です。実際、その都度調整しようとしても、全員の空き時間を見つけるのが難しく、結局「毎週この時間で固定しましょう」となりやすく増えていきます。&lt;/p&gt;

&lt;p&gt;2つ目は、「念のため」の招待と情報共有の不安です。
主催者側には「呼ばないと後で揉めるかもしれない」「情報共有の漏れを防ぎたい」という心理があり、本来は議事録共有で十分な人まで招待してしまうことがあります。
参加者側にも「自分だけ取り残されるかもしれない（FOMO）」という不安や、「断ると角が立つ」という同調圧力があり、とりあえず出席が増えていきます。
ちなみに参加者が増えた場合のミーティングでは、参加者が内職する可能性が上がるという結果もあります。(参考参照)&lt;/p&gt;

&lt;p&gt;3つ目は、意思決定の責任分散と過度な合意形成です。
誰か一人が決める責任を避けるために、「みんなで集まって決めた」という状態を作る目的で会議が設定されることがあります。加えて、事前根回しや全員の納得を重視しすぎると、情報伝達ではなく「顔合わせ」や「儀式」としての定例が増殖します。&lt;/p&gt;

&lt;p&gt;つまり、定例は予定調整の合理性に加えて、組織心理の要因も重なって増えるわけです。&lt;/p&gt;

&lt;h2 id=&quot;それでも定例は増やしすぎないほうがいい&quot;&gt;それでも、定例は増やしすぎないほうがいい&lt;/h2&gt;

&lt;p&gt;問題は、合理性を積み重ねた結果、カレンダーが定例だらけになることです。&lt;/p&gt;

&lt;p&gt;本来やりたい仕事に使う時間、特に集中して考える時間が削られていきます。
チームの生産性は、集中時間をどれだけ確保できるかでかなり左右されるので、定例ミーティングは冒頭に述べたように少ないほうが良いです。&lt;/p&gt;

&lt;p&gt;では、どうやって減らすか。以下では個人的に効果があった方法を紹介します。&lt;/p&gt;

&lt;h2 id=&quot;定例ミーティングをなくす方法&quot;&gt;定例ミーティングをなくす方法&lt;/h2&gt;

&lt;h3 id=&quot;1-最初から終了日を決める&quot;&gt;1. 最初から終了日を決める&lt;/h3&gt;

&lt;p&gt;定例を作るときは、できるだけ短い期間で取り、終了日時を必ず設定します。&lt;/p&gt;

&lt;p&gt;例えば「このテーマは3か月で一区切り」と思うなら、3か月だけ定例を入れる。最初から1年やエンドレスで入れない。これだけで、かなりの会議が自然に整理されます。Google CalendarやOutlookの定例設定では、終了日を入れるのは簡単なので、新規に定例を作るときは、必ず入れるようにしましょう。&lt;/p&gt;

&lt;p&gt;終了しても誰も困らないまま消える定例は、そもそも不要です。&lt;/p&gt;

&lt;h3 id=&quot;2-節目で定例をいったん全部消す&quot;&gt;2. 節目で定例をいったん全部消す&lt;/h3&gt;

&lt;p&gt;年末年始や期の変わり目など、区切りの良いタイミングで定例を一度すべて消す方法もあります。&lt;/p&gt;

&lt;p&gt;必要な定例ミーティングは、結局また設定されます。逆に再設定されないものは、なくても回るということです。&lt;/p&gt;

&lt;p&gt;「一度やめてみる」は、継続の惰性を断ち切るのに効きます。&lt;/p&gt;

&lt;h2 id=&quot;なくしきれない場合のコスト削減&quot;&gt;なくしきれない場合のコスト削減&lt;/h2&gt;

&lt;p&gt;全部はなくせない前提でも、定例ミーティングのコストを下げる余地はあります。&lt;/p&gt;

&lt;h3 id=&quot;1-頻度を下げる&quot;&gt;1. 頻度を下げる&lt;/h3&gt;

&lt;p&gt;毎週開催しているなら、「本当に毎週必要か」を、ミーティングの終わり際にでも参加者同士で振り返ってみる手もあります。隔週に変えるだけでも、時間がかなり戻ってきます。5人参加で1時間の定例が隔週になれば、月間で10時間、年間120時間ほど集中する時間が増えます。&lt;/p&gt;

&lt;h3 id=&quot;2-参加人数を絞る&quot;&gt;2. 参加人数を絞る&lt;/h3&gt;

&lt;p&gt;定例は、参加者を増やすのは簡単です。OutlookやGoogle Calendarでも、予定を転送すればすぐ増える。一方で減らすのは心理的に難しい。突然、参加者を削除したら「なんで？」となるかもしれません。&lt;/p&gt;

&lt;p&gt;このときは、SlackやTeamsのチャットで次回以降の参加をオプトインにする方法が使えます。
具体的には「参加したい人だけリアクションしてください」としておくと、自然と人数を絞り込めます。&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;p&gt;定例ミーティングが増えるのは、予定確保や調整コストだけでなく、情報共有の不安や責任分散の力学もあるからです。ただ、それを放置すると集中時間が失われます。&lt;/p&gt;

&lt;p&gt;だからこそ、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;定例には終了日時を入れる&lt;/li&gt;
  &lt;li&gt;節目でいったん全部やめる&lt;/li&gt;
  &lt;li&gt;頻度と参加人数を見直す&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;この3つあたりを意識するだけでも、一定の効果があります。というわけで、定例ミーティングの見直し、ぜひやってみてください。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;参考おすすめの書籍&quot;&gt;参考：おすすめの書籍&lt;/h2&gt;

&lt;p&gt;ミーティング関係でおすすめの書籍がいくつかあるので紹介しておきます。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://amzn.to/4auwAoi&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://images-na.ssl-images-amazon.com/images/P/4297117509.09.MZZZZZZZ.jpg&quot; alt=&quot;4297117509&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;本文で言及していた、参加人数が増えると内職する人が増えるという結果も載っている書籍です。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.amazon.co.jp/dp/4492503137?tag=iwashitw-22&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://images-na.ssl-images-amazon.com/images/P/4492503137.09.MZZZZZZZ.jpg&quot; alt=&quot;4492503137&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;amazon流でとても有名な、「会議冒頭で黙読する」を紹介されている書籍です。パワポやスライドを作るのが個人的に好きではないので、かなり参考にしています。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.amazon.co.jp/dp/B0FY12BWVY?tag=iwashitw-22&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https://images-na.ssl-images-amazon.com/images/P/B0FY12BWVY.09.MZZZZZZZ.jpg&quot; alt=&quot;B0FY12BWVY&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ミーティングというのは、ファシリテーターの振る舞いによって大きく成果が変わります。例えば、「今日は自由に話し合いましょう！」と投げかけても「シーン」となってしまうようなのは、ファシリテーターの振る舞いが不十分な例です。じゃあ、どうしたらいいかというのを、体系的に解説されている書籍です。&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2026/02/23/how-to-stop-recurring-meetings</link>
        <guid isPermaLink="true">https://iwashi.co/2026/02/23/how-to-stop-recurring-meetings</guid>
        
        <category>エンジニアリングマネジメント</category>
        
        <category>ミーティング</category>
        
        <category>生産性</category>
        
        
      </item>
    
      <item>
        <title>プログラミングは今が一番楽しい</title>
        <description>&lt;p&gt;AIコーディングの進化に伴い、特に2026年に入ってから、プログラミングに対する自分の見方がかなり変わってきました。現時点で考えていることを、いったん記録として残しておきます。あとで振り返ったら面白いと思うので。&lt;/p&gt;

&lt;p&gt;なお、この記事はAIによる「てにをは修正」「タイポ修正」などの校正は入っていますが、内容そのものはすべて自分で書いています。&lt;/p&gt;

&lt;h2 id=&quot;初めてのプログラミングは面白くなかった&quot;&gt;初めてのプログラミングは面白くなかった&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hello World&lt;/code&gt; を初めて書いたのは大学1年生のプログラミングの授業でした。SNSを見ていると「小学生から書いていました」という人も結構いますが、私はそういうタイプではありません。&lt;/p&gt;

&lt;p&gt;大学の授業で最初に学んだ言語は Java。最初はマジでわからなかったです。そもそもプログラミング以前に、PATHを通すための環境変数の設定で詰まりました。MacとWindowsを両方使っていたこともあり、特にWindowsの設定画面 + DOS画面と格闘していた記憶があります。&lt;/p&gt;

&lt;p&gt;この時期は「プログラミングが面白い」とはそこまで思えていませんでした。CLI上で &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; や &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt; の分岐を書いて &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.out.println()&lt;/code&gt; で出力するだけだと、あんまりテンションが上がらなかったためです。&lt;/p&gt;

&lt;h2 id=&quot;プログラミングが面白くなる転機は研究室だった&quot;&gt;プログラミングが面白くなる転機は研究室だった&lt;/h2&gt;

&lt;p&gt;転機になったのは大学3〜4年生の頃、研究室に所属してゼミのプロジェクトに携わり始めてからです。企業連携の取り組みがあり、プログラミングで現実世界につながる、誰かの役に立つものを作れる機会を得ました。&lt;/p&gt;

&lt;p&gt;この頃から、プログラミングが一気に面白くなりました。プログラミングをはじめとして情報科学全般をもっと学びたいと思い、本気で勉強し始めました。CPUの仕組み、オペレーティングシステム、ネットワーク、データ構造とアルゴリズム、他にもGoF のデザインパターンを初めて学んだのもこの時期です。いま振り返ると、デザインパターンを使いたくて使う、みたいなひどい設計もかなりやっていました。卒論で書いた &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Chain of Responsibility&lt;/code&gt; は、間違いなく不要でした。&lt;/p&gt;

&lt;p&gt;その後、大学院ではコンピュータネットワークの研究室に所属しました。研究領域はオーバーレイネットワークです。インターネット上で別のネットワークを組み、その上で最適なルーティングを行うような研究をしていました。この時一番書いていたのは C++ です。他にもちょっとしたスクリプトは Ruby で書いていました。C++はかなり大変でしたが、深夜まで悪戦苦闘して動いた瞬間はアドレナリンが出まくっていた記憶があります。&lt;/p&gt;

&lt;h2 id=&quot;社会人5年目でもう一度コードにのめり込んだ&quot;&gt;社会人5年目でもう一度コードにのめり込んだ&lt;/h2&gt;

&lt;p&gt;社会人になって最初は、いわゆるシステムエンジニア寄りの仕事だったので、オフィス系のドキュメントと向き合う時間が多かったです。プログラミングは本業では5%もなかったと思います。&lt;/p&gt;

&lt;p&gt;ただ、思うところがあって5年ほど経ってからグループ内の別会社へ転籍し、ひたすらコードを書く仕事に移りました。ここが2回目の大きな転機でした。学生時代に感じた「プログラミングが楽しい」という感覚が、はっきり戻ってきました。&lt;/p&gt;

&lt;p&gt;当時は会社の費用で技術書を買える制度もあり、技術書を読み漁っては、そこで得た知識を実装に応用する日々でした。気づけば、帰る時間が遅くなるくらい夢中で書いていました。&lt;/p&gt;

&lt;p&gt;だいたいクラウドが浸透し始めた頃です。自身は WebRTCプラットフォーム開発をしていて、バックエンドやインフラを中心にクラウドを使って設計、構築していたのは本当に面白かったです。同時期に、（多分rebuild.fmで知った）ChefやAnsibleから冪等性という言葉に感銘を受けましたが、運用するにつれて現実の厳しさを知り、もう全部 disposable が一番だと思ったのもこの頃です。&lt;/p&gt;

&lt;p&gt;DevOpsのチームに所属していたので、開発だけでなく運用にも携わっていました。この時は厄介なバグもたくさん経験しました。あまり詳細には書けませんが、たとえばグローバル分散環境でネットワークレイテンシーが絡む問題を解決できた瞬間は、いまでもよく覚えています。&lt;/p&gt;

&lt;p&gt;その時の本番環境でしか再現してくれない不具合を切り分けながら潰していく過程は、しんどいけど最高でした。切り分けするにつれて原因がだんだん見えてきて、仮説を検証しながら修正して実際に動いた瞬間は最高なんです。&lt;/p&gt;

&lt;h2 id=&quot;マネジメントに寄るほどコードは遠ざかった&quot;&gt;マネジメントに寄るほどコードは遠ざかった&lt;/h2&gt;

&lt;p&gt;その後、やりたいことが変わっていったこともあり、徐々にポジションが変わって、マネジメントに近い仕事へ移っていきました。その過程で私自身の興味の変遷もあって、一時期は人事も経験しています。そして直近では R&amp;amp;D のエンジニアマネージャーを担当していました（プライベートの事情もあり、2026年1月末まで。現在は休業中）。&lt;/p&gt;

&lt;p&gt;エンジニアリングマネジメントの仕事に携わると、実際にコードを書く時間は激減します。業務で必要なら書くこと自体はできますが、チームや組織全体のパフォーマンスを最大化しようとすると、少なくとも私の場合は、どうしても実装以外に時間を使う比率が高くなりました。&lt;/p&gt;

&lt;p&gt;ただし、プログラミングの時間が完全にゼロになったわけではありません。機械学習のちょっとした勉強や検証でPythonを書いていましたし、他にも大学の非常勤講師として PWA や Flutter を教える機会もあり、一定量は毎年書いていました。&lt;/p&gt;

&lt;p&gt;この時のプログラミングも面白いと言えば面白いのですが、やっぱり本番環境に対して書いている時に比べるとちょっと物足りない感じはありました。プライベートで作りたいものもありましたが、家族との時間を優先するポリシーでまとまった時間も取れないので、タスクリストに積まれたままでした。&lt;/p&gt;

&lt;p&gt;ただこの状況が変わり始めます。&lt;/p&gt;

&lt;h2 id=&quot;claude-codeから始まった進化の傾き&quot;&gt;Claude Codeから始まった進化の傾き&lt;/h2&gt;

&lt;p&gt;1年弱前、Claude Code を触り始めました。Claude Code以前のAIコーディング体験は、主に GitHub Copilot の「Tab で補完する」スタイルでした。それはそれで便利でしたが、Claude Codeを初めて触った時に「これは一線を超えたな」と感じました。&lt;/p&gt;

&lt;p&gt;もちろん、かなり厳しいコードも出てくるので手直しも必要で、まだ人の関わる余地はかなりありそうだなと思っていました。&lt;/p&gt;

&lt;p&gt;ただ2026年に入ってから、最新のLLMを使った Codex App や Claude Code、Antigravity を触るにつれて、さらにもう一段変わった感覚があります。もちろん、以前と同様にまだうまくいかないことも多いし、手直しが必要なこともあります。でも「ここまで書けるなら十分に使える」「これぐらいで十分では」と思える場面が明確に増えました。&lt;/p&gt;

&lt;p&gt;この感覚が本記事のタイトルにつながっていきます。&lt;/p&gt;

&lt;h2 id=&quot;結局いまが一番楽しい&quot;&gt;結局、いまが一番楽しい&lt;/h2&gt;

&lt;p&gt;AIコーディングでの体験を重ねるにつれて、結局何が言いたいかというと、ものづくり、そしてプログラミングそのものが、いまはめちゃくちゃ楽しいということです。&lt;/p&gt;

&lt;p&gt;思いついたものをすぐ形にできる感覚は、過去と比べても段違いです。以前は「何か作ろう」と思っても腰が重かったのですが、最近は「ちょっと作ってみるか」くらいの軽さで始められる。この変化はかなり大きいです。ライフステージが変わるにつれて、まとまった時間を取りにくくなる中では特にそう感じます。&lt;/p&gt;

&lt;p&gt;もう1つ楽しくなった要因は、様々なものの学習ハードルが劇的に下がっていることです。難解な技術や概念にぶつかっても、今は LLM と議論すれば、かなり短時間で理解の足場が作れます。また、NotebookLM のようなツールもあり、プライベートの片手間にマルチモーダルでの学習もできるようになっています。これも、学習のハードルを大きく下げてくれています。&lt;/p&gt;

&lt;p&gt;プログラミングを始めてから20年以上経つわけですが、プログラミングそのものが一番楽しいのは現在になりました。バグと悪戦格闘する時間は確かに減っていますが、実際に何かを作って物が動いた瞬間をすぐに体験できるのは、やっぱり最高です。&lt;/p&gt;

&lt;h2 id=&quot;これから確実に変わること&quot;&gt;これから確実に変わること&lt;/h2&gt;

&lt;p&gt;約1年前、ティム・オライリーが &lt;a href=&quot;https://www.oreilly.com/radar/the-end-of-programming-as-we-know-it/&quot;&gt;The End of Programming as We Know It&lt;/a&gt; を書きました。オライリー氏の記事を（恣意的ですが）ざっくりまとめると、以下のようなポイントになると思います。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;プログラミングの「終わり」ではなく、かつてアセンブリから高級言語へ移行したのと同様に、AIという新たな抽象化レイヤーによる「進化」である&lt;/li&gt;
  &lt;li&gt;AIがコード記述（How）を支援することで、人間は解決すべき課題や設計（What）により集中できるようになり、開発の民主化と生産性向上が加速する&lt;/li&gt;
  &lt;li&gt;過去の技術転換と同様、この変化は開発者の職を奪うものではなく、AIを使いこなすことで新たな機会やより高度な役割を創出する&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AIによってソフトウェアエンジニアの作業が減るという記事もよく見ますが、以前と同じような役割のエンジニアの仕事が減るだけであって、AIコーディングのオーケストレーションエンジニアといったような役割がどんどん増えていくんだと思います。&lt;/p&gt;

&lt;p&gt;また、組織設計もかなり変わるはずです。これまで主流だった2pizzaチームの形も、AIネイティブな前提で再定義されると思います。従来のプロダクトトリオ（PM、デザイナー、エンジニア）の分担も確実に変わるでしょう。&lt;/p&gt;

&lt;p&gt;マネージャーにとってもかなり面白い時代です。少人数でAIを前提にプロダクトを作るチームは、スタートアップだけでなく大企業でも増えていきます。現状の組織は、おそらく従来型の構成やプロセスで動いているはずです。今後は将来からバックキャストして、AIネイティブな組織・プロセスづくりを積極的に先導していく動きが必要になり、マネージャーが大きな役割を果たすことになると思います。もちろん役割の中には、変わるものもあれば、変わらないものもあるでしょう。&lt;a href=&quot;https://iwashi.co/2026/02/14/engineering-management-book-introduction&quot;&gt;前回の記事&lt;/a&gt;は、それでも変わらないものがあると考えて記しています。&lt;/p&gt;

&lt;h2 id=&quot;何もわからん&quot;&gt;何もわからん&lt;/h2&gt;

&lt;p&gt;これまで私は、ソースコードレビューやステークホルダー説明をはじめとした人間の役割は長く残るだろうと思っていました。一定は今後も変わらない部分はあると思います。人間の信頼貯金は偉大です。&lt;/p&gt;

&lt;p&gt;ただ最近は思ったより早く変わっていくだろうなと思っています。たとえば、レビューそのものも専用エージェントの精度が上がっていき、実用上かなりの範囲を担えるようになるのではないか、と感じるようになりました。そもそも人間のレビューにも見落としや設計上の抜けは当然ありますし、人間は完璧ではありません。高性能なLLMがこの領域を大きく置き換える可能性は十分あると思っています。&lt;/p&gt;

&lt;p&gt;ちなみにOpenAIでは &lt;a href=&quot;https://www.lennysnewsletter.com/p/engineers-are-becoming-sorcerers&quot;&gt;「OpenAIのエンジニアの95%がCodexを使用しており、すべてのコード変更はAIによってレビューされるという徹底した活用が行われている」（95% of engineers use Codex. 100% of our PRs are reviewed by Codex）&lt;/a&gt;だそうです。&lt;/p&gt;

&lt;p&gt;もう1つ、最近のプロダクト開発では「今できること」だけを前提にしないほうがいいと感じています。半年後、1年後にAIがどこまで進化するかを見込んで設計する。その視点が、実際の戦略に入ってきています。&lt;/p&gt;

&lt;p&gt;などといろいろ書いてきましたが、この1年の界隈の進化速度を見ていると、10年後は本当に何もわからんなと思います。&lt;/p&gt;

&lt;p&gt;現時点で、「AIはまだまだ」「人間のほうが良いコードを書ける」という声があるのも事実です。私もその指摘自体は理解できます。ただ同時にクラウドがおもちゃ扱いされていた頃を思い出します。前提は想像以上に速く更新される。現時点の限界よりも、半年後・1年後に何が可能になるかを想像して課題設定、および意思決定したほうがよいと考えています。&lt;/p&gt;

&lt;p&gt;あともう1つ、「最終的に責任を取るのは人間」という話もよく出ます。説明責任の観点から見れば、その通りだと思います。ただ、それがどこまで、どの形で続くかは正直まだわかりません。AIが作った説明の方が真っ当だな、と思うこともあるからです。「ハルシネーションがーーー」という声もありますが、人間もハルシネーションをたくさん生み出しています。&lt;/p&gt;

&lt;h2 id=&quot;最後に&quot;&gt;最後に&lt;/h2&gt;

&lt;p&gt;約20年前、Java の環境変数で詰まっていた頃の自分に、「2026年には、こんな速度で作れる時代になる」と言っても、たぶんまったくピンと来なかったと思います。&lt;/p&gt;

&lt;p&gt;でも、実際にいまはそうなりつつある。良くも悪くも変曲点に立ち会えているのは、すごく面白いことだと思います。さて、来年の今頃に記事を読み直したら、自分がどんな感想を持つのか、楽しみです。&lt;/p&gt;
</description>
        <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2026/02/15/programming-is-most-fun-now</link>
        <guid isPermaLink="true">https://iwashi.co/2026/02/15/programming-is-most-fun-now</guid>
        
        <category>プログラミング</category>
        
        <category>AI</category>
        
        <category>キャリア</category>
        
        
      </item>
    
      <item>
        <title>1時間で読み終わるエンジニアリングマネジメント本を書き始めてみる</title>
        <description>&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;これまで、エンジニアリングマネジメントに関する本を何冊か翻訳してきました。どれも学びが多く、実践につながる内容です。&lt;/p&gt;

&lt;p&gt;一方で、翻訳しながらずっと感じていたこともあります。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;日本の現場にはそのまま当てはめにくい&lt;/li&gt;
  &lt;li&gt;理解はできるけれど、個人的にはあまり共感できず採用しづらい&lt;/li&gt;
  &lt;li&gt;要点は有用。だが、そこに至るまでがやや冗長で、時間がないマネージャーは読み切りにくい&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;私自身のN=1ではありますが、共感した部分や実践して有用だった部分を軸にして、もっと手早く読める形でまとめたいと思いました。自分自身がすべてできているわけではありませんが、そこは棚に上げつつ、こうするとうまくいく、あるいはうまくいったものを現時点でのスナップショットとして残しておきたいと思っています。&lt;/p&gt;

&lt;h2 id=&quot;本書で作りたいもの&quot;&gt;本書で作りたいもの&lt;/h2&gt;

&lt;p&gt;目指しているのは、エンジニアリングマネージャーになったばかりの人が、最初に短時間で読めて「だいたいこれぐらいやれば及第点を取れる」という内容です。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1トピックは短く&lt;/li&gt;
  &lt;li&gt;全体を30分、長くとも1時間で読み切れる&lt;/li&gt;
  &lt;li&gt;読んだ直後から使える&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;まずはこのブログに連載として書き、フィードバックにもよりますが最後に再編集して1冊の本にまとめられないかと思っています。&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;なお分量イメージとして近いのは『新1分間マネジャー』のようなサイズ感です。&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2 id=&quot;前提にする考え方&quot;&gt;前提にする考え方&lt;/h2&gt;

&lt;p&gt;エンジニアやテックリードがマネージャーになるのは、ほぼ転職に近い変化だと思っています。求められるスキルセットが大きく変わるからです。&lt;/p&gt;

&lt;p&gt;そのときに大事なのは、「唯一の正解」を覚えることではなく、文脈に合わせて使える手札を増やすことです。状況に応じて出せるカードが多いほど、現場で柔軟に対応できるようになります。もし手札が少なければ、毎回同じカードを出すことになり、うまくいかないときのリカバリーも難しくなります。&lt;/p&gt;

&lt;p&gt;マネジメントに絶対の正解はありません。例えば、よくアンチパターンとして挙げられるマイクロマネジメントは必ずしも悪ではありません。マイクロマネジメントは平時には副作用が強い一方で、危機対応では有効に働く場面があります。厳しい状況では、壮大なビジョンを語るより、目の前のタスクをこなすことのほうが重要になることもあります。&lt;/p&gt;

&lt;h2 id=&quot;これから扱うテーマ&quot;&gt;これから扱うテーマ&lt;/h2&gt;

&lt;p&gt;今のところ、次のようなテーマを扱う予定です。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;方向性を明確にして、理解と共感を得るのがすべて&lt;/li&gt;
  &lt;li&gt;環境を作ったうえで、信じて任せることの難しさ&lt;/li&gt;
  &lt;li&gt;ビジョン・戦略・戦術って結局何なんだ？&lt;/li&gt;
  &lt;li&gt;やらないことを決める重要性&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://iwashi.co/2026/02/28/stop-decision&quot;&gt;「やめる」決断&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;意図的に採用に時間を使う&lt;/li&gt;
  &lt;li&gt;なぜ一人の責任者を決めることが重要か&lt;/li&gt;
  &lt;li&gt;なぜオーナーシップを持たせるべきか&lt;/li&gt;
  &lt;li&gt;自分がいなくても回る環境をどう作るか&lt;/li&gt;
  &lt;li&gt;1on1は有効だが必須ではない&lt;/li&gt;
  &lt;li&gt;ティーチング、メンタリング、コーチングの違いと使い分け&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://iwashi.co/2026/04/06/decision-method-majority-vote-does-not-work&quot;&gt;意思決定で多数決ばかり使わないほうがよい理由と、おすすめの決め方&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;マネージャーが背中を見せることで文化を築く&lt;/li&gt;
  &lt;li&gt;マネージャーが学ぶ姿勢を見せること、技術を追い続けること&lt;/li&gt;
  &lt;li&gt;マネージャーからICに戻るのは簡単ではない&lt;/li&gt;
  &lt;li&gt;信頼貯金をどう作り、どう使うか&lt;/li&gt;
  &lt;li&gt;メンバーに数年後のなりたい姿を言語化してもらう難しさと向き合い方&lt;/li&gt;
  &lt;li&gt;業績評価をどう伝え、どう納得を得るか&lt;/li&gt;
  &lt;li&gt;フィードバックを受ける/渡す技術&lt;/li&gt;
  &lt;li&gt;コミュニケーションを整えるための「取扱説明書」&lt;/li&gt;
  &lt;li&gt;判断基準や期待値を、できるだけ言語化すること&lt;/li&gt;
  &lt;li&gt;期待値を上げすぎない運用と、精神的ダメージを減らす考え方&lt;/li&gt;
  &lt;li&gt;権限が弱い状態で変化を起こす方法&lt;/li&gt;
  &lt;li&gt;社内外のネットワークがなぜ効果的なのか&lt;/li&gt;
  &lt;li&gt;ミーティングは少ないほど良い&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://iwashi.co/2026/02/23/how-to-stop-recurring-meetings&quot;&gt;定例ミーティングのなくし方&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;アカデミックな知見の活用方法と限界&lt;/li&gt;
  &lt;li&gt;ファシリテーション技術はレバレッジが効く&lt;/li&gt;
  &lt;li&gt;KPIなどのメトリクスをどう設計し、どう使い分けるか&lt;/li&gt;
  &lt;li&gt;セルフマネジメント：高いパフォーマンスを出し続ける方法&lt;/li&gt;
  &lt;li&gt;チームビルディングとふりかえり&lt;/li&gt;
  &lt;li&gt;組織デザインの基礎と「例外」を扱う視点&lt;/li&gt;
  &lt;li&gt;上司に活躍してもらう&lt;/li&gt;
  &lt;li&gt;他部署との共通言語の作り方&lt;/li&gt;
  &lt;li&gt;焦らない、楽観的に構えておく&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;実際に書いてみて、内容や順番は変わるかもしれませんし、このリスト自体も変わるかもしれません。最終的には、何らかの法則に沿ってカテゴライズすると思いますが、今のところは書けそうなところから書いていこうと考えています。&lt;/p&gt;

&lt;h2 id=&quot;結局一番大事なこと&quot;&gt;結局一番大事なこと&lt;/h2&gt;

&lt;p&gt;マネージャーの成果は「仲が良いチームそのもの」ではなく、どんな手段であっても、組織が出したいアウトカムを出せるかで判断されます。チームビルディングや合意形成は、そのための重要な手段の1つです。最前線でコードを書くことも、採用に時間を使うことも、部署をまたいで仲間を増やすことも、環境を整えて信じて任せることも、すべてはアウトカムを出すための手札の1つだと考えています。&lt;/p&gt;

&lt;p&gt;というわけで、次の記事からは内容に入ってきたいと思います。お楽しみに！&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;もし出版社の方で興味がありましたら、footerの連絡先までご連絡ください &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;出版するには短すぎて難しいかもしれません &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;反応次第で、ひっそりと終わる可能性もあります &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sat, 14 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2026/02/14/engineering-management-book-introduction</link>
        <guid isPermaLink="true">https://iwashi.co/2026/02/14/engineering-management-book-introduction</guid>
        
        <category>エンジニアリングマネジメント</category>
        
        <category>書籍</category>
        
        <category>連載</category>
        
        
      </item>
    
      <item>
        <title>スクラムフェス大阪2025に登壇してきた</title>
        <description>&lt;p&gt;大変ありがたいことにお声がけいただいて、2025/7/19(Sat) &lt;a href=&quot;https://www.scrumosaka.org/&quot;&gt;スクラムフェス大阪2025&lt;/a&gt;のクロージングキーノートに登壇してきた。その時の資料は以下の通り、 SpeakerDeck にアップしてある。一部削っているが原則そのまま載せている。&lt;/p&gt;

&lt;iframe class=&quot;speakerdeck-iframe&quot; frameborder=&quot;0&quot; src=&quot;https://speakerdeck.com/player/b6b75228aa7b4cc2a069b699a7cb6d0f&quot; title=&quot;最高のステークホルダーになるために / Striving to be the best stakeholder&quot; allowfullscreen=&quot;true&quot; style=&quot;border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 314;&quot; data-ratio=&quot;1.78343949044586&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;全体は資料に譲るとして、1) 本記事では登壇に向けて何を考えていたか、 2) 登壇で特に伝えたかったこと、3) イベントで色々な方と話し、登壇を終えて考えていたこと、を記しておく。&lt;/p&gt;

&lt;h2 id=&quot;登壇に向けて考えていたこと&quot;&gt;登壇に向けて考えていたこと&lt;/h2&gt;

&lt;p&gt;月並みだけど、登壇の前はかなり不安になっていることが多い。当日はある程度開き直っているのだけど、それまでの数日が一番考え込んでいる。&lt;/p&gt;

&lt;p&gt;ちなみに、クロージングキーノートで初めて登壇したのは &lt;a href=&quot;https://2023.scrumgatheringtokyo.org/&quot;&gt;RSGT2023&lt;/a&gt; であった。RSGTのこれまでの歴代の講演を見て「これは本当に自分が話してよいのだろうか？」と、当時は心底思っていた。今回のスクラムフェス大阪でも同様に「期待に応えられるだろうか？」「この話で良いのだろうか？」と例に漏れず考えていた。結果、だいたい1週間前ぐらいから、ずっと悶々としながらストーリーを考えていた。&lt;/p&gt;

&lt;p&gt;ストーリーを考える時は、ここ半年ぐらいのカレンダーを見直したり、読んだ書籍を見直したりしていると、伝えたいメッセージが出てくることが多い。すぐに出てこないとしても、通勤中だったり、ぼんやり買い物をしているときにふと思いつくことがある。なので、比較的新しい経験を思い出すのは一定効果があるのだと思う。&lt;/p&gt;

&lt;p&gt;それとクロージングキーノートでいつも意識しているのは、クロージングまでのセッションで聞いた内容や、その日に廊下などでの会話を盛り込めないかどうか。今回も、直前で聴いていた&lt;a href=&quot;https://speakerdeck.com/sasakendayo/motuto-qi-yue-jiao-she-yorimogu-ke-tonoxie-diao-wo-xie-diao-wozhu-keruqi-yue-toguan-xi-dukuri&quot;&gt;@sasakendayoさんのセッション&lt;/a&gt;を引用させていただいたし、イベント前に参加者と話した内容を当日のトークに盛り込んでいた。&lt;/p&gt;

&lt;h2 id=&quot;登壇で伝えたかったこと&quot;&gt;登壇で伝えたかったこと&lt;/h2&gt;

&lt;p&gt;今回のクロージングではいくつかメッセージを込めている。ただ、強いて1つ抜き出すとすれば、「自分を卑下しすぎなくていい」ということ。&lt;/p&gt;

&lt;p&gt;なぜ、このメッセージを意図的に強調したいかというと、カンファレンスやイベントに参加するたびに元気をもらう一方で、「あぁ、これもできてないな」「〜さんのところはめちゃくちゃ頑張っている。あれは自分には難しすぎる」と凹むケースが個人的にあるためだ。特に聴いている内容によっては「それはそう！」「言ってることはわかる！ だが実行に落とし込むのがしんどい！」と思っていることがよくある。&lt;/p&gt;

&lt;p&gt;ただ、一方でそれでもやれる範囲で十分に頑張っている人がほとんどだと思う。みんな色々な環境条件・制約条件のもとで働いている。企業によっては予算制約が厳しいかもしれないし、別の企業では市場変化に苦しんでいるかもしれない。その十分な頑張りは、意外と認知・承認されることが少ない。というのも、同じ企業にいる別の同僚にとっては当たり前の制約であるためだ。&lt;/p&gt;

&lt;p&gt;講演ではグッドウィルハンティングの1シーンの内容を引用させてもらった。ざっくり言えば「自分が選んでいなかった道は、なぜか困難や不確実性をないものとして考えてしまいがち。一方で自分が歩んできた道は苦労がわかっているから、公平に比較できない」という話。講演を聞いていると、他の発表者の講演が輝いて見えるのはこれが要因にあると思っている。&lt;/p&gt;

&lt;h2 id=&quot;イベントで色々な方と話してかつ登壇を終えて考えていたこと&quot;&gt;イベントで色々な方と話して、かつ登壇を終えて考えていたこと&lt;/h2&gt;

&lt;p&gt;まず前提として、イベント運営が素晴らしかった。（運営の皆様、大変お疲れ様でした＆ありがとうございました）&lt;/p&gt;

&lt;p&gt;アジャイル系のカンファレンスやイベントに最後までいると、会場撤収の速さにびっくりすることが多い。どこか段取りが落ちていても、例外が即捕捉されて自律的に対処が進むのは見ていて本当にすごい。&lt;/p&gt;

&lt;p&gt;それとは別に、色々な方と話していて思うのは、この同じイベントに参加している人同士であっても文脈が全然違うということ。ソーシャルメディアでは、一部の情報発信力の強い人や企業が目立つ。アルゴリズムもそれを加速している。ただ現実では、本当に色々な状態が存在しており、これはその条件で働いている中の人と話さなければ、全く気付けない。その話す機会を得られるというだけで、イベントに参加する意義があると思う。学べるところも多いし、もしかしたら相手にとって何かしら有益な話をできることもある。なので、不定期であっても参加して、他企業の方とどんどん話していきたい。&lt;/p&gt;

&lt;p&gt;最後に、&lt;a href=&quot;https://agileradio.github.io/2020/12/14/1/&quot;&gt;アジャイルラジオ&lt;/a&gt;で話を伺っていた、&lt;a href=&quot;https://www.misa-coach.com/&quot;&gt;みさコーチ&lt;/a&gt;と少しでもお話しできたことが感激ポイントだった。かなり前のエピソードだったので、具体的に「どこに」を失念してしまってお伝えできなかったのが心残りだけど、今度の通勤でも復習したいと思う。&lt;/p&gt;

&lt;h2 id=&quot;おわりに&quot;&gt;おわりに&lt;/h2&gt;

&lt;p&gt;というわけで、またどこかのアジャイル開発イベントでお会いしましょう！&lt;/p&gt;
</description>
        <pubDate>Sun, 27 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2025/07/27/scrumfestosaka2025</link>
        <guid isPermaLink="true">https://iwashi.co/2025/07/27/scrumfestosaka2025</guid>
        
        <category>アジャイル</category>
        
        <category>カンファレンス</category>
        
        <category>登壇</category>
        
        
      </item>
    
      <item>
        <title>LLM推論に関する技術メモ</title>
        <description>&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;BentoMLによる&lt;a href=&quot;https://bentoml.com/llm/&quot;&gt;LLM Inference Handbook&lt;/a&gt;という、LLMの推論をまとめたハンドブックがある。本記事ではハンドブックや他の情報も参照しつつ、自分のメモ用としてLM推論に関する技術をまとめていく。&lt;/p&gt;

&lt;h2 id=&quot;llmの推論と内部理解の必要性&quot;&gt;LLMの推論と内部理解の必要性&lt;/h2&gt;

&lt;p&gt;LLM推論とは、GPT-4、Llama 4、DeepSeek-V3などの学習済みLLMを使用して、ユーザーの入力から意味のある出力を生成することを指している。その推論には、たくさんの技術が抽象化・隠蔽されている。APIを利用している場合は、ほぼ意識せず活用できる。しかし、APIを何らかの理由で利用できない場合や、Open WeightなLLMを利用したい場合はこれらの技術を理解する必要がある。&lt;/p&gt;

&lt;p&gt;実際、最適化されていない設定では、GPU時間で10倍のコストがかかることもある。ユーザー面であっても、最適化がされていなければ、応答速度が遅くなり、UXが悪化する。&lt;/p&gt;

&lt;h2 id=&quot;トークン化&quot;&gt;トークン化&lt;/h2&gt;

&lt;p&gt;トークンは、LLMがテキストを処理するために使用する言語の最小単位である。トークンは、利用するトークナイザー(Tokenizer)によって、単語、サブワード（単語の一部）などに変換される。&lt;/p&gt;

&lt;p&gt;各LLMでは、独自のトークナイザーが使われているため、その内部のアルゴリズムも異なる。例えば、GPT-4oであれば &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;この記事は iwashi.co に掲載されています。&lt;/code&gt; という文字列は、 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[117391, 5205, 43847, 28926, 10914, 147965, 137149, 196993, 788]&lt;/code&gt; というトークン列に変換される。合計のトークン数は9である。&lt;/p&gt;

&lt;p&gt;ちなみにで、gemini 2.5 flashの場合は13トークンになる。この結果から、GPT-4o と gemini 2.5 ではトークナイザーが異なるため、そのままトークンIDを使いまわせないことがわかる。&lt;/p&gt;

&lt;h2 id=&quot;推論の2フェーズ&quot;&gt;推論の2フェーズ&lt;/h2&gt;

&lt;p&gt;GPT-4oのようなtransformerベースのモデルの場合、推論プロセス全体が2つに分かれていることを理解しておくと良い。&lt;/p&gt;

&lt;h3 id=&quot;プレフィルフェーズ&quot;&gt;プレフィルフェーズ&lt;/h3&gt;

&lt;p&gt;1つ目のフェーズは、プレフィルである。動作は次のとおりだ。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;（プレフィルの前に）ユーザーが送信したプロンプトを、トークナイザーがトークンのシーケンスに変換する&lt;/li&gt;
  &lt;li&gt;ここからプレフィルが始まる&lt;/li&gt;
  &lt;li&gt;まず先のトークン（あるいはTokenID）は、LLMが理解できる埋め込みベクトルに変換される。&lt;/li&gt;
  &lt;li&gt;次にそのベクトルは複数のtransformer層を通過する。その際の各層にはSelf Attention機構が含まれている。
    &lt;ul&gt;
      &lt;li&gt;ここで、各トークンのクエリ（Q）、キー（K）、バリュー（V）ベクトルが計算される。&lt;/li&gt;
      &lt;li&gt;計算されたベクトルは、トークンが互いにどのように注意を向けるかを決定し、文脈的な意味を保持している&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;モデルがプロンプトを処理する際、全層のすべてのトークンのキーとバリューベクトルを保存するKVキャッシュを構築する。
    &lt;ul&gt;
      &lt;li&gt;このキャッシュが、デコード中の高速検索のための内部メモリとして機能する&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;重要なのは、プレフィル段階では最初から全てのプロンプトがわかっている点にある（ユーザーがプロンプトを全て書いているのだから当然）。そのため、LLMは高度に並列化された行列演算、特にアテンション計算を通じて、すべてのトークンを同時に処理可能である。これはGPUの得意領域であり、compute-bound な処理になる。その結果、GPUの使用率が飽和する。（ただし、実際の使用率は、シーケンスの長さ、バッチサイズ、ハードウェアの仕様などの要因によって異なる）&lt;/p&gt;

&lt;p&gt;このプレフィル、意識しておくべきメトリクスはTime to First Token（TTFT：最初のトークンまでの時間）である。プロンプトを送信してから、最初のトークンが生成されるまでのレイテンシを押さえておく。UXに直結する。&lt;/p&gt;

&lt;h3 id=&quot;デコードフェーズ&quot;&gt;デコードフェーズ&lt;/h3&gt;

&lt;p&gt;プレフィルの次に来るのがデコードフェーズである。この段階では、新しいトークンがシーケンシャルに1つずつ生成される。自己回帰的に、前のトークン列から次のトークンを生成して、さらに生成したトークンを使って次に生成する、という動作を繰り返すフェーズとなる。&lt;/p&gt;

&lt;p&gt;最後に、生成されたトークンのシーケンスは人間が読めるテキストに復号される。&lt;/p&gt;

&lt;p&gt;プレフィルフェーズと比較した時のデコードフェーズの違いは、よりmemory-boundになる点になる。理由は、徐々に大きくなるKVキャッシュから頻繁に読み取りが発生するため。&lt;/p&gt;

&lt;p&gt;仮にKVキャッシュを使わないと、全ての計算をやり直す必要がある。たとえば、「今日は良い天気」をプロンプトで入れた時の計算は&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;まず、「今日」「は」などのKとVをそれぞれ計算する&lt;/li&gt;
  &lt;li&gt;その情報を使って、次の単語を生成する&lt;/li&gt;
  &lt;li&gt;さらに、その次の単語を計算するために、再度「今日」「は」などのすべてのKやVを計算する必要がある。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;しかし、KVキャッシュがあれば、最後の再計算は不要になる。&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;このKVキャッシュの仕組みは、上記のように冗長な計算を回避することで高速化を図る。しかし、キャッシュは生成されたシーケンスの長さとともに増大するため、メモリ消費の増加というコストを支払う必要はある。&lt;/p&gt;

&lt;p&gt;デコードフェーズで監視すべき重要な指標は、Inter-Token Latency（ITL：トークン間レイテンシ）である。ITLは、シーケンス内の連続するトークンの生成間の平均時間をを示す。これはTime Per Output Token（TPOT：出力トークンあたりの時間）と呼ばれる。&lt;/p&gt;

&lt;p&gt;ここまで説明したプレフィルとデコードは、シンプルなLLMサービングシステムだと、同じハードウェアで実行される。ただし、お互いの特性の違いから、並列に実行できない。その結果トークンレイテンシが長くなってしまう。そのため、プレフィルとデコードを分離する戦略が色々と探求されている。&lt;/p&gt;

&lt;h2 id=&quot;api型-vs-セルフホスト&quot;&gt;API型 vs セルフホスト&lt;/h2&gt;

&lt;p&gt;LLMを使ったアプリケーションを作る場合は、マネージドAPI型とセルフホスト型の2つに分かれる。それぞれにPros/Consがある。&lt;/p&gt;

&lt;h3 id=&quot;api型&quot;&gt;API型&lt;/h3&gt;

&lt;p&gt;OpenAI、Anthropic、GoogleなどのAPI型サービスは、インフラ管理を完全に抽象化しており、ユーザーは従量課金でLLMを利用できる。GPT-4やClaudeのような独自モデルだけでなく、Together AIやFireworksなどのプラットフォームでは、DeepSeek-R1やLlama 4などのオープンソースモデルもAPIとして提供されている。&lt;/p&gt;

&lt;p&gt;API型の主な利点は次のとおり。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;APIキーと数行のコードですぐに開始可能
    &lt;ul&gt;
      &lt;li&gt;その結果、プロトタイプ向けのデモやツール作成に最適&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;GPU調達やスケーリングの面倒さを回避（委譲）できる&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;セルフホスト型&quot;&gt;セルフホスト型&lt;/h3&gt;

&lt;p&gt;セルフホスト型は、クラウドGPUやプライベートVPC、オンプレミスで独自のLLMインフラを構築・管理する方式である。モデルのデプロイ、最適化、スケーリングを完全にコントロールできる。&lt;/p&gt;

&lt;p&gt;セルフホストの主な利点は次のとおり。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;データプライバシーとコンプライアンス。機密データ（医療記録、財務情報など）を安全に保てる&lt;/li&gt;
  &lt;li&gt;高度なカスタマイズ性
    &lt;ul&gt;
      &lt;li&gt;レイテンシとスループットのトレードオフ調整&lt;/li&gt;
      &lt;li&gt;プレフィル・デコード分離&lt;/li&gt;
      &lt;li&gt;KVキャッシュ最適化&lt;/li&gt;
      &lt;li&gt;独自データを利用したファインチューニングによる優位性確保（の可能性）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;外部APIのレート制限や突然のポリシー変更の影響を受けない&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;比較&quot;&gt;比較&lt;/h3&gt;

&lt;p&gt;どちらを選ぶかは、そのユースケースによって異なる。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;項目&lt;/th&gt;
      &lt;th&gt;サーバーレスAPI&lt;/th&gt;
      &lt;th&gt;セルフホスト型推論&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;使いやすさ&lt;/td&gt;
      &lt;td&gt;✅ 良い（シンプルなAPI呼び出し）&lt;/td&gt;
      &lt;td&gt;⚠️ 悪い（LLMのデプロイとメンテナンスが必要）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;データプライバシーとコンプライアンス&lt;/td&gt;
      &lt;td&gt;⚠️ 限定的&lt;/td&gt;
      &lt;td&gt;✅ 完全に制御可能&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;カスタマイズ性&lt;/td&gt;
      &lt;td&gt;⚠️ 限定的&lt;/td&gt;
      &lt;td&gt;✅ 完全な柔軟性&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;大規模時のコスト&lt;/td&gt;
      &lt;td&gt;⚠️ 高い（使用量ベース、大幅に上昇する可能性）&lt;/td&gt;
      &lt;td&gt;✅ 潜在的に低い（予測可能、インフラを最適化できる可能性）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ハードウェア管理&lt;/td&gt;
      &lt;td&gt;✅ 抽象化されている&lt;/td&gt;
      &lt;td&gt;⚠️ GPUのセットアップとメンテナンスが必要&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;コスト面での考慮&quot;&gt;コスト面での考慮&lt;/h3&gt;

&lt;p&gt;API型では、トークンあたりのコストは固定だが、使用量に比例して総コストが増大する。プロトタイピングには適しているが、本番環境では高額になることもある。&lt;/p&gt;

&lt;p&gt;セルフホスト型では、初期のインフラ構築コストは高いが、スケールするにつれてトークンあたりコストは大幅に低下する。特に推論最適化技術（vLLMやSGLangなど）と組み合わせることで、コスト効率が向上する。&lt;/p&gt;

&lt;h3 id=&quot;いつセルフホスト型を使うべきか&quot;&gt;いつセルフホスト型を使うべきか？&lt;/h3&gt;

&lt;p&gt;基本的には、API型で始める方が良い。まずプロトタイプを作って、ユースケースやニーズを検証すべきであるため。ただし、パフォーマンス要件や、プライバシー、他者との差別化の重要性が高まるにつれて、セルフホスト型が考慮に入ってくる。&lt;/p&gt;

&lt;h2 id=&quot;意識しておくべきgpuメモリ計算&quot;&gt;意識しておくべきGPUメモリ計算&lt;/h2&gt;

&lt;p&gt;LLMをサーブする場合に重要なのがGPUのメモリサイズだ。 LLMに関しては以下の2点を意識すると良い。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;モデルサイズ（パラメータ数）。パラメータ数が大きいほど、必要なGPUメモリが異なる。&lt;/li&gt;
  &lt;li&gt;bit精度。FP16、FP8などのこと。bit精度が低いほどメモリフットプリントが小さくなるが、出力精度がイマイチになることもある。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;必要なメモリサイズはざっくり以下のように計算すると良い。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;メモリ (GB) = P × (Q ÷ 8) × (1 + オーバーヘッド)

- P：パラメータ数（単位は10億）
- Q：ビット精度（例：16、32）、8で割ることでビットをバイトに変換
- オーバーヘッド（％）：推論中の追加メモリまたは一時的な使用量（例：KVキャッシュ、アクティベーションバッファ、オプティマイザの状態）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;例えば、20％のオーバーヘッドでFP16の70Bモデルをロードするには、次のように計算すれば良い。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;必要なGPUメモリサイズ = 70 x (16/8) x 1.2 = 168GB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;そのため、H100(80GB) x 1枚には当然載らない。そのため、複数GPUでの分散推論が必要となる。あるいは、INT8 や INT4へと量子化する方法もある。&lt;/p&gt;

&lt;h2 id=&quot;llm-の量子化&quot;&gt;LLM の量子化&lt;/h2&gt;

&lt;p&gt;量子化（Quantization）は、高精度フォーマット（FP32）などから、FP8やINT8へと変換して、必要なメモリを削減する &amp;amp; 推論を高速化する技術である。精度とサイズとの間にトレードオフは存在するが、適切に量子化できれば影響は最小限に抑えられる。&lt;/p&gt;

&lt;h3 id=&quot;量子化フォーマット&quot;&gt;量子化フォーマット&lt;/h3&gt;

&lt;p&gt;ざっと以下で捉えておくと良い。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;フォーマット&lt;/th&gt;
      &lt;th&gt;FP32比サイズ&lt;/th&gt;
      &lt;th&gt;精度低下&lt;/th&gt;
      &lt;th&gt;使用例&lt;/th&gt;
      &lt;th&gt;メモリ&lt;/th&gt;
      &lt;th&gt;備考&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;FP32&lt;/td&gt;
      &lt;td&gt;100%&lt;/td&gt;
      &lt;td&gt;なし&lt;/td&gt;
      &lt;td&gt;訓練&lt;/td&gt;
      &lt;td&gt;高&lt;/td&gt;
      &lt;td&gt;完全精度だが遅い&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;FP16&lt;/td&gt;
      &lt;td&gt;50%&lt;/td&gt;
      &lt;td&gt;最小限&lt;/td&gt;
      &lt;td&gt;訓練＆推論&lt;/td&gt;
      &lt;td&gt;中&lt;/td&gt;
      &lt;td&gt;ほとんどのLLMの標準&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;FP8&lt;/td&gt;
      &lt;td&gt;25%&lt;/td&gt;
      &lt;td&gt;低&lt;/td&gt;
      &lt;td&gt;訓練＆推論&lt;/td&gt;
      &lt;td&gt;低&lt;/td&gt;
      &lt;td&gt;まだ発展途上&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;int8&lt;/td&gt;
      &lt;td&gt;25%&lt;/td&gt;
      &lt;td&gt;低&lt;/td&gt;
      &lt;td&gt;推論&lt;/td&gt;
      &lt;td&gt;低&lt;/td&gt;
      &lt;td&gt;優れた万能トレードオフ&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;int4&lt;/td&gt;
      &lt;td&gt;12.5%&lt;/td&gt;
      &lt;td&gt;中程度&lt;/td&gt;
      &lt;td&gt;推論&lt;/td&gt;
      &lt;td&gt;かなり低&lt;/td&gt;
      &lt;td&gt;GPTQ/AWQなどの手法が必要&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;いつ量子化を使うべきか&quot;&gt;いつ量子化を使うべきか&lt;/h3&gt;

&lt;p&gt;量子化が適している場合は次のとおり。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;限られたGPUメモリ（例：24GB以下）を持つハードウェアにデプロイする場合&lt;/li&gt;
  &lt;li&gt;推論レイテンシを小さくしたい場合&lt;/li&gt;
  &lt;li&gt;LLMのサービングコストを節約したい場合&lt;/li&gt;
  &lt;li&gt;同時実行する数を増やしたい場合&lt;/li&gt;
  &lt;li&gt;小さな精度のトレードオフを許容できる場合&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;一方で、量子化が適さない場合は次のとおり。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;可能な限り最高の精度が必要な場合（例：センシティブまたは安全性が重要なタスク）&lt;/li&gt;
  &lt;li&gt;モデルがすでに小さい場合&lt;/li&gt;
  &lt;li&gt;デプロイ先のハードウェアが量子化フォーマットをサポートしていない場合&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;量子化手法&quot;&gt;量子化手法&lt;/h3&gt;

&lt;p&gt;以下は広く採用されている量子化手法には次のようなものがある。&lt;/p&gt;

&lt;h4 id=&quot;awqactivation-aware-weight-quantization&quot;&gt;AWQ（Activation-aware Weight Quantization）&lt;/h4&gt;

&lt;p&gt;AWQは、すべての重みが同等に重要なわけではないという前提に基づいている。実際、重みの約1%が顕著に重要であり、そこに着目する。&lt;/p&gt;

&lt;p&gt;実際には、次のようなイメージで量子化する。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;学習済みのモデルを使って、実際のデータに対する各層の活性化（出力）がどのような値の範囲を取るのか、その統計情報（例えば、最大値や平均値など）を「オフラインで」収集する&lt;/li&gt;
  &lt;li&gt;次に、収集した活性化統計に基づいて、どの重みチャネルがモデルの性能に最も大きな影響を与えるか（つまり、量子化による劣化の影響を最も受けやすいか）を特定する&lt;/li&gt;
  &lt;li&gt;特定された「重要な重みチャネル」に対して、収集した活性化統計を考慮した「スケーリング」を行う
    &lt;ul&gt;
      &lt;li&gt;スケーリングでは、モデル全体の出力結果を変えないような計算が用いられる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;スケーリングされた重みを、より少ないビット数で表現するように量子化する&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;smoothquant&quot;&gt;SmoothQuant&lt;/h4&gt;

&lt;p&gt;SmoothQuantは、量子化で厄介な「外れ値」問題の対処に焦点を当てている。&lt;/p&gt;

&lt;p&gt;次のようなイメージで量子化を行う。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;オフラインで、少量のデータを用いてモデルを実行する。ここで、各層の活性化の統計情報（特に最大値や分布）を収集する
    &lt;ul&gt;
      &lt;li&gt;これにより、どのチャネルで活性化の外れ値が出やすいかを特定する&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;その結果を用いて、最終的な出力結果が変わらないように、重みを変換する&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;gptq&quot;&gt;GPTQ&lt;/h4&gt;

&lt;p&gt;まず、PTQとは post-training quantization の略であり、事後学習量子化のことを示す。GPTQはPTQの1種である。&lt;/p&gt;

&lt;p&gt;GPTQのコアは、各重みを1つずつ量子化していく際に、その量子化によって生じる誤差を、まだ量子化されていない他の重みを調整することで「補償」していくという点にある。&lt;/p&gt;

&lt;p&gt;GPTQの面白い点は、3-4bitなどのかなり小さい精度での量子化を目指している点にある。その結果、例えば175Bのような巨大モデルであってもA100 x 1枚などで動作可能になる。&lt;/p&gt;

&lt;h2 id=&quot;推論フレームワーク&quot;&gt;推論フレームワーク&lt;/h2&gt;

&lt;p&gt;モデルはそれ単体で動くのではなく、以下のような推論フレームワークと併用して使われる。イメージとしては、LLMが「脳みそ」だとすれば、推論フレームワークがそれを実行に移す「体」のような感じ。ただし、体を単に動かすだけじゃなくて、推論速度を高めるための技術や、同時リクエストへの対応など、さまざまな点で拡張されている。&lt;/p&gt;

&lt;p&gt;代表的なものを以下に示す。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;vLLM
    &lt;ul&gt;
      &lt;li&gt;LLMのサービングに最適化された高性能推論エンジン。GPUリソースの効率的な使用と高速なデコーディング能力で知られている&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;SGLang
    &lt;ul&gt;
      &lt;li&gt;LLMとVision LLM向けの高速サービングフレームワーク&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;LMDeploy
    &lt;ul&gt;
      &lt;li&gt;高速なデコーディング速度と同時リクエストの効率的な処理に焦点を当てた推論バックエンド&lt;/li&gt;
      &lt;li&gt;様々な量子化技術がサポートされている&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;TensorRT-LLM
    &lt;ul&gt;
      &lt;li&gt;NVIDIAのTensorRT（高性能深層学習推論ライブラリ）を活用した推論バックエンド&lt;/li&gt;
      &lt;li&gt;NVIDIA製なので、当然のことながらNVIDIA GPU上で大規模モデルを実行するために最適化されている&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Hugging Face TGI
    &lt;ul&gt;
      &lt;li&gt;LLMのデプロイとサービング用のツールキット&lt;/li&gt;
      &lt;li&gt;Hugging Faceの本番環境で、Hugging Chat、Inference API、Inference Endpointを動かすために使用されている&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;よりコンシューマに近い環境では、次も候補になる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;llama.cpp
    &lt;ul&gt;
      &lt;li&gt;外部依存関係のない純粋なC/C++で実装された、LLM用の軽量推論ランタイム&lt;/li&gt;
      &lt;li&gt;名前にllamaとついているが、Llamaモデル以外にも、Qwen、DeepSeek、Mistralなど多くのアーキテクチャをサポートしている&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;MLC-LLM
    &lt;ul&gt;
      &lt;li&gt;LLM用のMLコンパイラおよび高性能デプロイメントエンジン&lt;/li&gt;
      &lt;li&gt;Apache TVMの上で動く。そのため、モデルをサービングする前にコンパイルと重みの変換が必要&lt;/li&gt;
      &lt;li&gt;ハードウェアのサポート対象は幅広い&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Ollama
    &lt;ul&gt;
      &lt;li&gt;llama.cppの上に構築されたユーザーフレンドリーなローカル推論ツール&lt;/li&gt;
      &lt;li&gt;シンプルさと使いやすさを重視して設計されており、最小限のセットアップですむ。例えばmacbook上でもすぐ動く&lt;/li&gt;
      &lt;li&gt;vLLMやSGLangのようなランタイムとは異なり、同時リクエストはサポートされていない
        &lt;ul&gt;
          &lt;li&gt;この違いは重要&lt;/li&gt;
          &lt;li&gt;なぜならば、Paged Attentionや、Prefixキャッシュ、動的バッチ（複数のリクエストをまとめて処理する技術）などの多くの推論最適化手法は、複数のリクエストを並列で処理する場合にのみ効果的であるため&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;結局どれを選べばいいか？　という問いにあたるかもしれないが、全てのシナリオにハマるような単一のランタイム・ツールは存在しない。もし、複数リクエストを扱いたいならvLLMやSGLangが候補になるが、サクッと動かしたいならOllamaで良い。&lt;/p&gt;

&lt;h2 id=&quot;推論メトリクス&quot;&gt;推論メトリクス&lt;/h2&gt;

&lt;p&gt;すでにいくつか出てきたが、ここでは意識しておくべきメトリクスを整理しておく。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Time to First Token(TTFT)
    &lt;ul&gt;
      &lt;li&gt;リクエストを送信してから最初のトークンが生成されるまでの時間。モデルがどれだけ早く応答を生成できるかを表現している&lt;/li&gt;
      &lt;li&gt;UXに関連しており、LLMを分類機のように利用したい場合は、これが小さいほどUXが高まる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Time per Output Token(TPOT)
    &lt;ul&gt;
      &lt;li&gt;インタートークンレイテンシ（Inter-Token Latency: ITL）とも呼ばれる&lt;/li&gt;
      &lt;li&gt;後続のトークンが生成される間の時間のこと&lt;/li&gt;
      &lt;li&gt;TPOTが低いほど、モデルはトークンをより速く生成でき、1秒あたりのトークン数（Tokens per Second: TPS）が高くなる&lt;/li&gt;
      &lt;li&gt;UXに直結する。TTFTがいくら小さくても、TPOTが遅いとUXはかなり厳しい&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Token Generation Time
    &lt;ul&gt;
      &lt;li&gt;最初のトークンを受信してから最後のトークンを受信するまでの時間&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Total Latency(E2EL)
    &lt;ul&gt;
      &lt;li&gt;リクエストを送信してからユーザー側で最終トークンを受信するまでの時間&lt;/li&gt;
      &lt;li&gt;合計レイテンシは、TTFT + Token Generation Time で計算される&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;それぞれの時間は短いに越したことはないが、モバイルやWebのアプリと同様で、許容されるレイテンシーはユースケースによって異なる。例えば、リアルタイム対話が必要ならTTFTやTPOTは小さい方がいい。一方で、ドキュメント要約やDeepResearchであれば、即時性よりも正確性が重要になるだろう。&lt;/p&gt;

&lt;p&gt;これらの数字は、単一の数値ではなく、平均値、中央値、パーセンタイルなどの指標で追うと良い。この辺のWebアプリの考え方と似ている。平均値だけを追うと、外れ値によって歪みが出る。その意味では中央値は、外れ値に対して耐性がある。&lt;/p&gt;

&lt;p&gt;LLMのパフォーマンスベンチマークでは、平均TTFT、中央値TPOT、P99 E2ELなどのメトリクスがよく使われる。&lt;/p&gt;

&lt;h3 id=&quot;スループット&quot;&gt;スループット&lt;/h3&gt;

&lt;p&gt;LLM自体の実行速度を表すものとしてスループットがある。代表的なものに、Requests per Second (RPS：1秒あたりのリクエスト数)と、Tokens per Second (TPS：1秒あたりのトークン数)がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Requests per Second(RPS)
    &lt;ul&gt;
      &lt;li&gt;LLMが1秒間に正常に完了できるリクエスト数&lt;/li&gt;
      &lt;li&gt;1秒あたりのリクエスト数 = 完了したリクエストの総数 / あるタイムフレーム（秒）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Tokens per Second(TPS)
    &lt;ul&gt;
      &lt;li&gt;入力TPS：モデルが1秒間に処理する入力トークンの数&lt;/li&gt;
      &lt;li&gt;出力TPS：モデルが1秒間に生成する出力トークンの数&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;バッチング&quot;&gt;バッチング&lt;/h2&gt;

&lt;p&gt;GPUは高度に並列化された計算処理のために設計されているため、1秒間に数兆回、あるいは数千兆回もの浮動小数点演算（FLOPs）を実行できる。だがLLMは、チップのメモリ帯域幅の大部分がモデルパラメータの読み込みに費やされるため、これらのGPUの性能を十分に活用できないことがよくある。&lt;/p&gt;

&lt;p&gt;バッチんぐはそのボトルネック軽減に役立つ。どうやるかというと、名前の通りまとめて処理する。本番環境では、サービスに複数のリクエストが同時にやってくることがある。各リクエストを個別に処理する代わりに、それらをまとめてバッチとして処理することで、読み込まれた同じモデルパラメータを複数のリクエストで共有する。その結果、スループットを大幅に高められる。&lt;/p&gt;

&lt;p&gt;そのバッチングにはいくつかタイプがある。&lt;/p&gt;

&lt;h3 id=&quot;静的バッチングstatic-batching&quot;&gt;静的バッチング（Static Batching）&lt;/h3&gt;

&lt;p&gt;サーバーは固定数のリクエストが到着するまで待機し、それらを単一のバッチとしてまとめて処理する。実装が簡単だが、欠点もある。&lt;/p&gt;

&lt;p&gt;バッチ内の最初のリクエストは最後のリクエストを待つことを強いられる。その結果、不必要な遅延が発生する。理想的な世界では、これがワークするかもしれないが、
バッチ内のすべてのリクエストが同じように作られているわけではない。実際、LLMの推論では、一部のリクエストは非常に短い応答を生成する一方で、他のリクエストは長い段階的な推論を含む可能性がある。&lt;/p&gt;

&lt;h3 id=&quot;動的バッチングdyanmic-batching&quot;&gt;動的バッチング（Dyanmic Batching）&lt;/h3&gt;

&lt;p&gt;静的バッチングに対応しようとしたもの。&lt;/p&gt;

&lt;p&gt;動的バッチングでは、受信リクエストをバッチに収集するが、固定のバッチサイズにこだわらない。その代わりに、一定の時間枠（タイムウィンドウ）を設定し、その時間内に到着したリクエストをまとめて処理する。もし時間枠が経過する前にバッチがサイズの上限に達した場合は、その時点ですぐに処理を開始する。シャトルバスみたいなものを考えるとわかりやすい。乗車する顧客が少なければ定刻通り待つが、満席になったらすぐに出発するようなイメージ。&lt;/p&gt;

&lt;p&gt;もちろん欠点がないわけではない。処理開始時にバッチが満杯でない場合もあるため、必ずしもGPUの効率を最大化できるわけではない。また、静的バッチングと同様に、バッチ内で最も時間のかかるリクエストがバッチ全体の終了時間を決定してしまう。その結果、短いリクエストは依然として不必要に待たされることになる。&lt;/p&gt;

&lt;h3 id=&quot;継続的バッチング-continuous-batching&quot;&gt;継続的バッチング (Continuous Batching)&lt;/h3&gt;

&lt;p&gt;LLMの推論では、出力される文章（シーケンス）の長さはリクエストごとに大きく異なる。あるユーザーは簡単な質問をし、また別のユーザーは複雑で長い出力を求めるかもしれない。静的バッチングや動的バッチングでは、短いリクエストが最も長いリクエストの完了を待たざるを得ず、その間GPUのリソースは十分に活用されずに空いてしまう。&lt;/p&gt;

&lt;p&gt;この非効率性を解決するのが、継続的バッチング（またはインフライトバッチングとも呼ばれる）である。&lt;/p&gt;

&lt;p&gt;継続的バッチングは、バッチ全体が完了するのを待ってから結果を返す、ということはしない。その代わりに、バッチ内の各リクエストが独立して完了することを許容し、処理が終わったものから即座に新しいリクエストと入れ替える。これは、レストランの席のように、空いたらすぐに新しいお客様を案内するようなイメージ。&lt;/p&gt;

&lt;p&gt;ここまで挙げてきたvLLM、SGLang、TensorRT-LLM、LMDeploy、Hugging Face TGIなどの主要な推論フレームワークはすべて、継続的バッチング（または同様のメカニズム）に対応している。&lt;/p&gt;

&lt;h2 id=&quot;paged-attention&quot;&gt;Paged Attention&lt;/h2&gt;

&lt;p&gt;LLMにおけるアテンション機構を実装する際の、メモリを効率的に使うアプローチである。&lt;/p&gt;

&lt;p&gt;LLMが応答を生成している時、生成する各トークンごとに過去の情報（つまりKVキャッシュ）を記憶しておく必要がある。通常、KVキャッシュは1つの巨大な連続したブロックとして保存されるため、メモリの大きな部分を占有してしまう。これは、完全に使い切らない場合でも大きなブロックを予約する必要があるため、メモリのフラグメンテーションやメモリの無駄使いにつながる可能性がある。&lt;/p&gt;

&lt;p&gt;Paged Attentionでは、大きな塊を、本のページのような小さなブロック（ページ）に分割する。さらに、このブロックはルックアップテーブルを利用する。（OSの仮想記憶管理とコンセプトは一緒）&lt;/p&gt;

&lt;p&gt;PagedAttentionは最初にvLLMによって実装されたが、以降、Hugging Face TGIやTensorRT-LLMなどの他のプロジェクトもPagedAttentionを採用・実装している。&lt;/p&gt;

&lt;h2 id=&quot;投機的デコーディング&quot;&gt;投機的デコーディング&lt;/h2&gt;

&lt;p&gt;高速な「ドラフト（下書き）」モデルと「ターゲットモデル（正確さが求められる）」を組み合わせることで、自己回帰的なトークン生成を高速化する推論最適化手法のこと。&lt;/p&gt;

&lt;p&gt;これが有用なのは以下の2つの前提に基づいている。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;文章の中には、予測が非常に簡単なトークンと、難しいトークンが混在している。簡単な部分は、小さなモデルでも十分に予測可能&lt;/li&gt;
  &lt;li&gt;LLMが文章を一つずつ生成していくプロセスにおいて、実は計算能力よりも、メモリからデータを読み書きする速度（メモリ帯域幅）がボトルネックになっている。そのため、GPUなどには、使われずに遊んでいる能力が余っている（投機的デコーディングは、この余剰能力を有効活用したい）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;動作は次のようになる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ドラフトモデルが入力シーケンスの後の次のKトークンを予測する&lt;/li&gt;
  &lt;li&gt;ターゲットモデルがこれらのKトークンを並列で検証し、自分も同じトークンを予測するかを確認する&lt;/li&gt;
  &lt;li&gt;ターゲットモデルは、自分が同意するこれらのKトークンの最長のプレフィックス（先頭部分）を受け入れる&lt;/li&gt;
  &lt;li&gt;h個のトークンを受け入れた場合、(h+1)番目のトークンを自分で生成する&lt;/li&gt;
  &lt;li&gt;このプロセスが繰り返される
    &lt;ul&gt;
      &lt;li&gt;ドラフトモデルは、この新しく拡張されたシーケンスに基づいて次のKトークンを提案する&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ただし、投機的デコーディングには独自のコストがある。ドラフトモデルとターゲットモデルの両方をメモリにロードする必要があるため、全体的なVRAM使用量が増加してしまう。&lt;/p&gt;

&lt;p&gt;より実装含めた詳細は、同僚が書いた&lt;a href=&quot;https://engineers.ntt.com/entry/2023/11/14/081349&quot;&gt;先読みを用いたLLMの文章生成の高速化&lt;/a&gt;があるので、そちらを参照されたい。&lt;/p&gt;

&lt;h2 id=&quot;プレフィルとデコードの分離prefill-decode-disaggregation&quot;&gt;プレフィルとデコードの分離（Prefill-Decode Disaggregation）&lt;/h2&gt;

&lt;p&gt;冒頭で述べたように、LLMの推論ではフェーズが2つある。だいぶ前なので、ざっくりおさらいを書いておく。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;プレフィル
    &lt;ul&gt;
      &lt;li&gt;全体のシーケンスを並列で処理し、アテンション層からのキーベクトルとバリューベクトルをKVキャッシュに保存する&lt;/li&gt;
      &lt;li&gt;すべてのトークンを一度に処理するため、計算負荷はあるが、GPUメモリへの要求はそれほど高くない&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;デコード
    &lt;ul&gt;
      &lt;li&gt;先に構築したKVキャッシュを再利用しながら、出力トークンを1つずつ生成する&lt;/li&gt;
      &lt;li&gt;プレフィルとは異なり、デコードは高速なメモリアクセスが必要だが、計算負荷は低い&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;この2つのステップを一緒に実行するのは、単純である。&lt;/p&gt;

&lt;p&gt;しかし現実には、複数のリクエスト、しかもニーズの異なるリクエストが同時に到着することがよくある。だが、一度に実行できるフェーズは1つだけである。GPUが計算負荷の高いプレフィルタスクで占有されているとき、デコードタスクは待機しなければならず、これによりITL（Inter-Token Latency：トークン間レイテンシ）が増加する。逆の場合も同様である。&lt;/p&gt;

&lt;p&gt;そこで、プレフィルとデコードを分離したい。2つの異なるタスクを分離して、お互いの邪魔をしないようにしたい。そうすれば、次の利点が得られる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;プレフィルとデコードを異なるハードウェア上で独立してスケジューリングしてスケールできる
    &lt;ul&gt;
      &lt;li&gt;たとえば、マルチターン会話やエージェント型ワークフローなどが多い場合、KVキャッシュの多くを再利用できる&lt;/li&gt;
      &lt;li&gt;その結果、プレフィルの計算負荷が下がり、デコードにより多くのリソースを割り当てられる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;お互いのフェーズが干渉しなくなるため、効率的に並列で実行できる。（スループットが上がる）&lt;/li&gt;
  &lt;li&gt;TTFTとITLを最適化するために、プレフィルとデコードのそれぞれに対して異なる最適化技術（テンソル並列化やパイプライン並列化など）を実装できる&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SGLang、vLLM、Dynamo、llm-dなどのオープンソースフレームワークやプロジェクトが、この分離に積極的に取り組んでいる。&lt;/p&gt;

&lt;p&gt;ただし、もちろん銀の弾丸ではない。ワークロードが小さかったり、GPUが最適化されていなければ、パフォーマンスは逆に悪化する。また、プロンプトが短い場合や、デコード側で高いプレフィックスキャッシュヒット率が得られる場合は、デコードワーカー上でローカルにプレフィルを実行する方が、多くの場合、より高速でシンプルになる。さらに、当然のことながら、プレフィルワーカーとデコードワーカーの間でKVキャッシュを迅速かつ確実に移動させる必要がある。高速で低遅延な通信プロトコルをサポートするソリューションが不可欠になる。このデータ転送にかかるコストが高いと、かえって全体でパフォーマンスが下がってしまうかもしれない。&lt;/p&gt;

&lt;h2 id=&quot;kvキャッシュawareな負荷分散&quot;&gt;KVキャッシュAwareな負荷分散&lt;/h2&gt;

&lt;p&gt;従来のWebアプリでは、負荷分散は通常かなりシンプルである。リクエストは小さく、レスポンスは迅速で、どのバックエンドインスタンスでもどのリクエストでも同じように処理できる。ロードバランサーは、ラウンドロビンのような単純な戦略を使ってトラフィックを均等に分散できる。&lt;/p&gt;

&lt;p&gt;しかし、LLM推論ではこれが全然異なる。主な理由は、プレフィル段階で使うKVキャッシュである。&lt;/p&gt;

&lt;p&gt;従来のロードバランサーは、LLMワーカーを同一のブラックボックスとして扱う。各ワーカー内部で何が起きているかを把握していない。つまり、以下のような情報が見えていない。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;KVキャッシュによってどれだけのGPUメモリが消費されているか&lt;/li&gt;
  &lt;li&gt;リクエストキューがどれだけ長いか&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ロードバランサーが、上記を意識（Aware）できていなければ、次の問題につながる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;キャッシュ再利用の機会損失
    &lt;ul&gt;
      &lt;li&gt;類似したプレフィックスを持つ新しいリクエストが、既存のキャッシュされた計算結果を活用できない&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;レイテンシの増加
    &lt;ul&gt;
      &lt;li&gt;間違ったレプリカにルーティングされた会話は、KVキャッシュを失い、コストの高い再計算が必要になる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;負荷の不均衡
    &lt;ul&gt;
      &lt;li&gt;一部のワーカーが多くの長い会話を処理する一方で、他のワーカーはアイドル状態のままになる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;そこで、解決に取り組んでいるものもある。例えば、エンドポイントピッカーを使用して、各ワーカーのKVキャッシュ利用率、キューの長さ、LoRAアダプターに関する情報を収集し、より良い推論のためにリクエストを最適なレプリカにルーティングする。&lt;/p&gt;

&lt;h2 id=&quot;プレフィックスキャッシング&quot;&gt;プレフィックスキャッシング&lt;/h2&gt;

&lt;p&gt;「KVキャッシュ」という用語は、元々は単一の推論リクエスト内でのキャッシングを指す言葉であった。以前にも述べた通り、LLMはデコードの際、それまでに出力したトークンを基に次の新しいトークンを生成するという自己回帰的な（autoregressive）動作をする。つまり、自身のKVキャッシュを再利用している。このKVキャッシュがなければ、モデルはデコードの各ステップで過去のトークンに関するすべての計算をやり直す必要があり、これはリソースの膨大な無駄遣いになる。&lt;/p&gt;

&lt;p&gt;このキャッシングの概念を複数のリクエストをまたいで拡張した場合、それをより正確に表現するのが「プレフィックスキャッシング（prefix caching）」あるいは「プロンプトキャッシング（prompt caching）」である。&lt;/p&gt;

&lt;p&gt;この考え方はシンプルだ。ある問い合わせ（クエリ）のKVキャッシュを保存しておくことで、&lt;strong&gt;同じ冒頭部分（プレフィックス）&lt;/strong&gt;を共有する新しいクエリが来た際に、プロンプトのその部分の再計算をスキップする。キャッシュされた結果を直接再利用することで、計算負荷を削減し、推論を高速化する。&lt;/p&gt;

&lt;p&gt;例えば、次のようなシステムプロンプトを持つチャットボットを考えてみる。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;あなたは有能なAIライターです。プロフェッショナルな態度で文章を作成してください。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;このプロンプトは、会話の相手が変わっても、同じである。毎回この部分を再計算する代わりに、そのKVキャッシュを一度だけ保存しておけば良い。そして、ユーザーから新しいメッセージが届いた際には、この保存されたプレフィックスキャッシュを再利用し、プロンプトの新しい部分（ユーザーのメッセージ）だけを処理すれば十分だ。&lt;/p&gt;

&lt;h3 id=&quot;プレフィックスキャッシュを認識したルーティング&quot;&gt;プレフィックスキャッシュを認識したルーティング&lt;/h3&gt;

&lt;p&gt;しかし実際にプレフィックスキャッシングを適用するには、課題もある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;新しいリクエストを、適切なプレフィックスをすでにキャッシュしているワーカーに、どのようにしてルーティング（転送）するか？&lt;/li&gt;
  &lt;li&gt;ルーターは、各ワーカーのキャッシュに何が入っているかを、どのようにして知るのか？&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;そこで、OSSのプロジェクトが独自のアプローチを採用している。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ワーカーが報告するプレフィックスの状態を意識する
    &lt;ul&gt;
      &lt;li&gt;Dynamoでは、ワーカーが自身がキャッシュしているプレフィックスを積極的に報告する&lt;/li&gt;
      &lt;li&gt;ルーターはこのリアルタイムのデータを使ってルーティングする&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;ルーターが予測するキャッシュの状態
    &lt;ul&gt;
      &lt;li&gt;SGLangでは、過去のリクエスト履歴に基づき、各ワーカーに対応する近似的な基数木（radix tree）をルーター側で維持する&lt;/li&gt;
      &lt;li&gt;これにより、ルーターはワーカーから常に最新情報を受け取らなくても、どのワーカーが必要なプレフィックスを持っている可能性が最も高いかを予測できる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;ハイブリッドな取り組み
    &lt;ul&gt;
      &lt;li&gt;Gateway API Inference Extensionプロジェクトは、EPP（エンドポイントピッカー）上でルーティングアルゴリズムを実装するために、複数の戦略を用いる
        &lt;ul&gt;
          &lt;li&gt;Prefix affinity consistent hashing（プレフィックスの類似性に基づいたコンシステントハッシュ法）
            &lt;ul&gt;
              &lt;li&gt;似たプレフィックスを持つリクエストを同じワーカーにグループ化する&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;ルーター上の近似プレフィックスキャッシュ
            &lt;ul&gt;
              &lt;li&gt;ルーターが、すべてのバックエンドサーバー上のプレフィックスキャッシュの近似的なルックアップキャッシュを保持する&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;ルーター上の正確なプレフィックスキャッシュ
            &lt;ul&gt;
              &lt;li&gt;モデルサーバーから報告されたKVキャッシュ情報を収集する&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;llm-dは、Inference Schedulerというコンポーネントを使用してフィルタリングとスコアリングアルゴリズムを実装し、キャッシュの可用性、プリフィル/デコードステータス、SLA、負荷などの要因の組み合わせに基づいてルーティングを決めている&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;並列&quot;&gt;並列&lt;/h2&gt;

&lt;p&gt;推論であれ、学習であれ、巨大な情報量を扱うLLMではさまざまな並列化手法が利用される。以下で簡単に紹介する。&lt;/p&gt;

&lt;h3 id=&quot;データ並列&quot;&gt;データ並列&lt;/h3&gt;

&lt;p&gt;データ並列は計算を高速化するための一般的な手法である。&lt;/p&gt;

&lt;p&gt;このアプローチでは、モデルの重みを複数のGPUデバイス間で複製し、グローバルなバッチの入力データをより小さなマイクロバッチに分割する。各デバイスは自分に割り当てられたマイクロバッチのみを処理し、このプロセスがすべてのデバイスで並行して実行される。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;元のバッチ：[━━━━━━━━━━━━━━━━] (16サンプル)
            ↓ 4つのGPUに分割
分割後：
GPU1: [━━━━] (4サンプル)
GPU2: [━━━━] (4サンプル)
GPU3: [━━━━] (4サンプル)
GPU4: [━━━━] (4サンプル)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;テンソル並列&quot;&gt;テンソル並列&lt;/h3&gt;

&lt;p&gt;テンソル並列は、モデルの個々の層をより小さなブロックにスライスする手法である。スライスされたブロックは独立した異なるデバイス間で並行計算される。例えば、行列乗算であれば、行列の異なるスライスを複数のGPUで同時に処理できる。&lt;/p&gt;

&lt;p&gt;このアプローチのメリットは、高速化だけではなく、単一デバイスのメモリに収まらないLLMの推論を可能にする点にある。ただし、デバイス間で追加の通信が発生するため、この通信オーバーヘッドとパフォーマンス向上のバランスを取る必要がある。&lt;/p&gt;

&lt;h3 id=&quot;パイプライン並列&quot;&gt;パイプライン並列&lt;/h3&gt;

&lt;p&gt;パイプライン並列は、モデルの層を連続したいくつかの塊（チャンク）に分割し、それぞれを別々のデバイスに割り当てる。データはこれらのチャンクを「組み立てライン」のように流れ、あるデバイスの出力が次のデバイスの入力となる。例えば、4分割のパイプライン並列では、各デバイスがモデル全体の層の4分の1ずつを処理する。&lt;/p&gt;

&lt;p&gt;しかし、各デバイスは前のデバイスの出力に依存するため、一部のデバイスが待機状態になる時間（バブルとも呼ばれる）が発生し、リソースの非効率な利用につながる。この待機時間を削減するために、入力バッチをさらに小さなマイクロバッチに分割する手法がよく用いられる。各マイクロバッチが次々とパイプラインを流れることで、GPUの利用率は向上するが、アイドル時間を完全にゼロにすることはできない。&lt;/p&gt;

&lt;p&gt;なお、注意点として、パイプラインの各ステージ間で通信が発生するため、リクエストごとの合計レイテンシは増加する可能性がある。&lt;/p&gt;

&lt;h3 id=&quot;補足テンソル並列とパイプライン並列の違い&quot;&gt;補足：テンソル並列とパイプライン並列の違い&lt;/h3&gt;

&lt;p&gt;テンソル並列とパイプライン並列は、分割の仕方が根本的に異なる。テンソル並列は、層を複数に分割する。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;元の層：[━━━━━━━━━━━━━━━━]
分割後：[━━━━][━━━━][━━━━][━━━━]
        GPU1  GPU2  GPU3  GPU4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;一方で、パイプライン並列では、工程を分割する。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;元のモデル：層1→層2→層3→層4→層5→層6→層7→層8→層9→層10→層11→層12
分割後：   [層1-4]    →    [層5-8]    →    [層9-12]
           GPU1            GPU2            GPU3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;rebuild の hak さんの真似ると、パイプライン並列は説明しやすくて、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;職人A（GPU1）: ひたすらシャリを握る&lt;/li&gt;
  &lt;li&gt;職人B（GPU2）: シャリにワサビを乗せる&lt;/li&gt;
  &lt;li&gt;職人C（GPU3）: ネタを乗せる&lt;/li&gt;
  &lt;li&gt;職人D（GPU4）: 最後に皿に盛り付けて出す&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;のように工程で割るイメージ。&lt;/p&gt;

&lt;h3 id=&quot;エキスパート並列&quot;&gt;エキスパート並列&lt;/h3&gt;

&lt;p&gt;エキスパート並列は、MoE（Mixture of Experts）モデルで使われる特殊な並列処理戦略である。&lt;/p&gt;

&lt;p&gt;MoEモデルでは、入力されるトークンごとに、モデルの中の一部の「エキスパート」（専門家のような小さなニューラルネットワーク）のみが活性化される。エキスパート並列では、すべてのエキスパートを各デバイスに複製するのではなく、エキスパート自体を異なるデバイスに分割して配置する。&lt;/p&gt;

&lt;p&gt;つまり、各GPUは、すべてではなく一部のエキスパートの重み全体を保持する。これにより、各GPUは、そのGPU上に格納されているエキスパートに割り当てられたトークンのみを処理するようになる。&lt;/p&gt;

&lt;h3 id=&quot;ハイブリッド並列&quot;&gt;ハイブリッド並列&lt;/h3&gt;

&lt;p&gt;ここまで述べた並列手法は、1つだけ使うのではなく複数使われることがある。ハイブリッド並列はまさに組み合わせた手法となる。&lt;/p&gt;

&lt;p&gt;典型的なハイブリッド手法は次のようになる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;もし、8つのGPUがある場合、最初の4つのGPUにテンソル並列（TP=4）を適用し、残りのGPUにデータ並列（DP=2）を使う&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ただし、これは可能な組み合わせの一つに過ぎず、それぞれに利点と欠点がある。上記の例では、テンソル並列はGPU間、特に推論中の通信オーバーヘッドを発生させる。そのため、高いTP度を使用することが必ずしもより良いパフォーマンスに繋がるとは限らない。&lt;/p&gt;

&lt;p&gt;他にも、テンソル並列を減らしてデータ並列を増やす構成もある。例えば、TP=2、DP=4に設定する。これにより、GPU間の通信が削減され、推論時のレイテンシの低減にもつながる（可能性がある）。&lt;/p&gt;

&lt;p&gt;ただし、落とし穴もある。モデルの重みはGPUメモリの大部分を消費する。特に大きなモデルの場合はそうである。テンソル並列を少なくすると、モデルを共有するGPUが少なくなる。そのため、KVキャッシュのための領域が少なくなる。これにより、プレフィックスキャッシングなどの推論最適化が悪化する可能性がある。&lt;/p&gt;

&lt;p&gt;これらのトレードオフは、テンソル並列とデータ並列に固有のものではない。ハイブリッド並列計画を設計する際には、特定のモデルサイズ、ハードウェア設定、推論要件に基づいて異なる構成をベンチマークすることが重要である。銀の弾丸は存在しない。最適な戦略は、チューニングと実験を通じて見つけ出される。&lt;/p&gt;

&lt;h2 id=&quot;インフラ面での高速スケーリング&quot;&gt;インフラ面での高速スケーリング&lt;/h2&gt;

&lt;p&gt;本番環境でLLMの推論は、モデルのトレーニングとは全くの別物である。学習が予測可能でバッチングを基本とするのに対し、推論はリアルタイムのユーザー需要に基づいて実施される。多くの場合、トラフィックは突発的であり予測が難しく、レイテンシーの増加やダウンタイムが許されない。&lt;/p&gt;

&lt;p&gt;トラフィックの急増時には迅速にスケールアップ/アウトし、アイドル時にはコスト削減のためにゼロまでスケールダウンする必要がある。クラウドと同じく、弾力性が重要になる。&lt;/p&gt;

&lt;h3 id=&quot;コールドスタート問題&quot;&gt;コールドスタート問題&lt;/h3&gt;

&lt;p&gt;スケーリングの重要な問題が、コールドスタート問題である。&lt;/p&gt;

&lt;p&gt;LLMをコンテナでデプロイするのであれば、あるKubernetesノードが特定のデプロイメントを一度も実行したことがない場合にこの問題が発生する。コンテナイメージがローカルにキャッシュされておらず、すべてのイメージレイヤーをゼロからプルして初期化しなければならない。&lt;/p&gt;

&lt;p&gt;実際には、さらに細分化して次のように問題が表出する。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;クラウドを利用している場合、クラウドプロバイダーが新しいインスタンスを割り当て、それをKubernetesクラスタに接続するまでにかかる時間がかかる。インスタンスの種類や空き状況によっては、30秒から数分、Nvidia A100やH100のような需要の高いGPUの場合は数時間かかることさえある&lt;/li&gt;
  &lt;li&gt;同様に、LLMのイメージは、多数の依存関係とカスタムライブラリのため、一般的なPythonジョブイメージよりもはるかに大きく複雑となる。クラウドプロバイダーが複数ギガビット帯域の帯域をスペック上は記載していても、実際のイメージダウンロード速度ははるかに遅いことが多い。その結果、イメージのプルには3〜5分かかることがある&lt;/li&gt;
  &lt;li&gt;モデルのロードに必要な時間は、そのサイズに大きく依存する。LLMは数十億のパラメータがあるため、レイテンシが増加する。
    &lt;ul&gt;
      &lt;li&gt;Hugging Faceのようなプラットフォームは、高スループットのマルチパートダウンロードに最適化されていないため、大きなモデルファイルの取得に時間がかかる&lt;/li&gt;
      &lt;li&gt;推論を開始する前に、モデルファイルを完全にダウンロードしてディスクに書き込む必要がある。これにより追加のI/O操作が発生し、起動が遅延する&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;じゃあ、どうするかというと、たとえば次のような方法がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;オブジェクトストレージの利用
    &lt;ul&gt;
      &lt;li&gt;マルチパート並列処理により帯域幅をフル活用できる&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;FUSEの利用
    &lt;ul&gt;
      &lt;li&gt;CPU boundな展開処理とディスクI/Oを完全回避&lt;/li&gt;
      &lt;li&gt;ちなみに、FUSEは、Filesystem in Userspaceであり、カーネル空間ではなくユーザー空間でファイルシステムを実装できるLinuxカーネルモジュールのこと&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;ゼロコピーGPUロード
    &lt;ul&gt;
      &lt;li&gt;モデルウェイトをコンテナイメージから分離&lt;/li&gt;
      &lt;li&gt;リモートストレージから直接GPU VRAMへストリーミングする&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;モデルの重みをコンテナに書き込むかどうかで分岐があるが、そもそもコンテナストレージよりもオブジェクトストレージの方が早い。&lt;/p&gt;

&lt;h3 id=&quot;メトリクス&quot;&gt;メトリクス&lt;/h3&gt;

&lt;p&gt;スケール要否を判断するメトリクスには以下がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CPU利用率
    &lt;ul&gt;
      &lt;li&gt;シンプルで閾値も明確だが、Pythonベースのワークロードの実際の負荷を反映しているわけではない&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;GPU利用率
    &lt;ul&gt;
      &lt;li&gt;理論上はCPUより関連性の高いメトリクスだが、実際には不正確&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvml&lt;/code&gt; のようなツールは、サンプリング期間中にほんのわずかでもカーネルが実行されればGPUを「使用中」として報告してしまう&lt;/li&gt;
      &lt;li&gt;その結果、早すぎるスケールアップや、キャパシティに対する誤った安心感につながることがある&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;QPS (1秒あたりのクエリ数、query per second)
    &lt;ul&gt;
      &lt;li&gt;従来のWebサービスで広く使われているが、LLM推論ではあまり役に立たない
        &lt;ul&gt;
          &lt;li&gt;なぜならば生成AIへのリクエストは、入力の長さや生成されるトークン数によって、サイズや計算コストが大きく異なるため&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;その結果、QPSには一貫性がなく、オートスケーリングの調整には不向き&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;同時実行数
    &lt;ul&gt;
      &lt;li&gt;キューの中に入っているか、あるいは処理中のアクティブなリクエスト数を表すこのメトリクスは、システム負荷を反映する理想的な指標となる&lt;/li&gt;
      &lt;li&gt;同時実行数はバッチサイズに基づいて簡単に設定できる
        &lt;ul&gt;
          &lt;li&gt;実際のシステム需要と直接相関するため、正確なスケーリングに使える&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;ただし、同時実行数が機能するためには、フレームワークが自動的に同時実行数をメトリクスとして計測しており、かつデプロイしているプラットフォームへのスケーリングシグナルとして情報を与える必要がある&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;推論インフラの構築運用コスト&quot;&gt;推論インフラの構築・運用コスト&lt;/h2&gt;

&lt;p&gt;LLM推論インフラの構築は、単なる技術的なタスクではない。多大なコストと時間がかかる。本気が必要。&lt;/p&gt;

&lt;h3 id=&quot;どれぐらい複雑か&quot;&gt;どれぐらい複雑か？&lt;/h3&gt;

&lt;p&gt;LLMの推論は、標準的なクラウドネイティブの技術スタックよりも遥かに多くが必要となる。例えば、以下を意識する必要がある。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;高性能GPUのプロビジョニング&lt;/li&gt;
  &lt;li&gt;CUDAのバージョン互換性やドライバの依存関係の管理&lt;/li&gt;
  &lt;li&gt;オートスケーリング、同時実行数制御、スケールトゥゼロ（アイドル時にリソースをゼロにする挙動）の設定&lt;/li&gt;
  &lt;li&gt;GPUモニタリング、リクエストのトレーシング、障害検知のためのObservabilityツールのセットアップ&lt;/li&gt;
  &lt;li&gt;ストリーミング、キャッシング、ルーティングといったモデル固有の挙動への対応&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;これらのステップは、どれ一つとして簡単なものではない。こういった要求を汎用のインフラに無理やり当てはめようとしても、パフォーマンスの低下と開発期間の長期化を招くだけ。&lt;/p&gt;

&lt;p&gt;たとえチームがそれをやり遂げたとしても、インフラのセットアップに費やした毎週の時間は、モデルを改善したり、製品価値を提供したりするために使われなかった時間になる。高いパフォーマンスを求められるAIチームにとって、この機会損失は、インフラの請求書と同じくらい現実的なコストになる。&lt;/p&gt;

&lt;h3 id=&quot;mlツールとフレームワークの柔軟性の制限&quot;&gt;MLツールとフレームワークの柔軟性の制限&lt;/h3&gt;

&lt;p&gt;多くのAI技術スタックは、モデルのランタイム（PyTorch, vLLM, 特定のTransformerなど）のバージョンを固定する。その主な理由は、コンテナイメージをキャッシュし、インフラ関連コンポーネントとの互換性を確保するためだ。これはクラスタへのデプロイを簡素化する一方で、新しいモデルやフレームワークをテスト・デプロイしたい場合に、柔軟性が失われる。&lt;/p&gt;

&lt;p&gt;つまり、以下の制約が生じる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;新しいモデルやフレームワークのバージョンを簡単にテスト・デプロイできない&lt;/li&gt;
  &lt;li&gt;自社のスタックがコミュニティやベンダーのアップデートから乖離するにつれて、より多くの技術的負債を抱え込むことになる&lt;/li&gt;
  &lt;li&gt;LLMのデプロイ速度が低下し、チームが競争上の不利な立場に置かれる&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;複雑なaiシステムへの対応&quot;&gt;複雑なAIシステムへの対応&lt;/h3&gt;

&lt;p&gt;LLMは、それ単体では価値を生み出さない。多くの場合、以下のような要素も必要になる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ユーザー入力を整形・変換するための前処理&lt;/li&gt;
  &lt;li&gt;モデルの出力をフロントエンドで使えるようにフォーマットする後処理&lt;/li&gt;
  &lt;li&gt;モデルをロジック、パイプライン、制御フローでラップする推論コード&lt;/li&gt;
  &lt;li&gt;バリデーション、ルール、内部データ連携を処理するビジネスロジック&lt;/li&gt;
  &lt;li&gt;データベースや、特徴量を一元的に管理、共有、提供するための専門的なデータ基盤に接続するためのコネクター&lt;/li&gt;
  &lt;li&gt;RAGやアンサンブルパイプラインのための複数モデルの組み合わせ&lt;/li&gt;
  &lt;li&gt;他のチームが使いやすい形でサービスを公開するためのカスタムAPI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;実際、ほとんどのLLMデプロイツールは、上記を考慮して作られていない。モデルの重みを読み込み、基本的なAPIを公開するように設計されているだけである。&lt;/p&gt;

&lt;p&gt;そのため、一定以上に複雑なことをしようとすると、「グルーコード」やアドホックな対応策、あるいはロジックを複数のサービスに分割するといった対応が必要になる。その結果、次のような事態に陥る。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;使える機能を提供するだけで、エンジニアリング工数がたくさんかかる&lt;/li&gt;
  &lt;li&gt;開発者体験が悪化する&lt;/li&gt;
  &lt;li&gt;ツールがユースケース固有のカスタマイズに対応していない場合、新規価値が作れない&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;人材の希少性&quot;&gt;人材の希少性&lt;/h3&gt;

&lt;p&gt;LLMインフラは、深い専門知識を必要とする。&lt;/p&gt;

&lt;p&gt;企業は、GPU、Kubernetes、MLフレームワーク、そして分散システムをすべて一人の役割として理解しているエンジニアを必要するが、このような専門家は希少である。人件費も通常は高額になる。（従来のDevOpsエンジニアよりも高い）&lt;/p&gt;

&lt;h2 id=&quot;llmのオブザーバビリティ&quot;&gt;LLMのオブザーバビリティ&lt;/h2&gt;

&lt;p&gt;LLMの推論を本番環境で運用するには、単にモデルが応答を返すだけでは不十分である。システムがすべてのレベルでどのように動作しているかを、完全に可視化する必要がある。オブザーバビリティがなければ、レイテンシーの問題、スケーリングの課題、あるいはGPUの低利用率といった問題を、雑に測することになる。&lt;/p&gt;

&lt;p&gt;効果的なオブザーバビリティを実現するには、LLMの推論ワークロード特有の要求に合わせてカスタマイズされた、適切なメトリクス、ダッシュボード、ログ、イベントストリームが必要になる。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;コンテナ &amp;amp; デプロイメント
    &lt;ul&gt;
      &lt;li&gt;Podのステータス
        &lt;ul&gt;
          &lt;li&gt;障害が発生した、スタックした、あるいは再起動中のPodを、可用性に影響が出る前に検知&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;レプリカ数
        &lt;ul&gt;
          &lt;li&gt;オートスケーリングの挙動に関連。スケーリングの遅延や上限に関する問題のトラブルシューティングに役立つ&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;アプリのパフォーマンス
    &lt;ul&gt;
      &lt;li&gt;秒間リクエスト数（RPS）
        &lt;ul&gt;
          &lt;li&gt;流入するトラフィックとシステムの負荷を測定し&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;リクエストのレイテンシー
        &lt;ul&gt;
          &lt;li&gt;応答の遅延やボトルネックの特定に役立つ&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;処理中のリクエスト数
        &lt;ul&gt;
          &lt;li&gt;同時実行数を示す。アプリが需要に追いついているかを把握するのに有用&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;エラー率
        &lt;ul&gt;
          &lt;li&gt;失敗した、または無効な応答の割合。SLA監視に&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;キューの待機時間
        &lt;ul&gt;
          &lt;li&gt;利用可能なレプリカを待つことによって生じる遅延の把握に&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;クラスターリソース
    &lt;ul&gt;
      &lt;li&gt;リソースのクオータとリミット
        &lt;ul&gt;
          &lt;li&gt;リソース使用量の上限をトラックする。リクエスト/リミット値の調整や、過剰/過小なリソース割り当ての回避に&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;LLM固有のメトリクス
    &lt;ul&gt;
      &lt;li&gt;Token per Second
        &lt;ul&gt;
          &lt;li&gt;モデルのスループットとパフォーマンス効率を反映&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;TTFT
        &lt;ul&gt;
          &lt;li&gt;UXに影響。ストリーミングやチャットのような体験では極めて重要&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Token Generation Time
        &lt;ul&gt;
          &lt;li&gt;完全な応答を生成するまでのエンドツーエンドのパフォーマンスを測定&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;GPUメトリクス
    &lt;ul&gt;
      &lt;li&gt;GPU使用率
        &lt;ul&gt;
          &lt;li&gt;GPUがどれだけビジー状態かを示す。低すぎる場合は、リソースの未使用やバッチングが非効率である可能性を示唆している&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;GPUメモリ使用量
        &lt;ul&gt;
          &lt;li&gt;キャパシティプランニングや、OOMエラーの回避に有用&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;inferenceops&quot;&gt;InferenceOps&lt;/h2&gt;

&lt;p&gt;InferenceOpsとは、LLMの継続的デプロイメント・更新・管理をサポートする実践とワークフローのことを示す。&lt;/p&gt;

&lt;p&gt;まず、すべての本番LLMアプリケーションは、明確で再現性のあるデプロイプロセスから始めるべき。後々の緊急対応を避け、チームのどのエンジニアでも安全に変更をリリースできるようにするために役立つ。&lt;/p&gt;

&lt;p&gt;さらに、従来のアプリケーションと同様に、モデルも自動的にパッケージ化、テスト、デプロイされるべき。モデルのリリース戦略も従来戦略が使える。つまり、カナリアリリースやブルーグリーンデプロイができる。&lt;/p&gt;

&lt;p&gt;ある程度、自動パイプラインを作れたとしても、数個のモデルで機能する方法は、モデルが数十、数百に増えると、たちまち破綻する。特に、チーム、クラウド環境、ユースケースが多岐にわたる場合はなおさら。そこで、モデルレジストリやライフサイクルを一元把握できるようにする。&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;p&gt;かなり長くなってしまったけど、これぐらいを意識しておくと、LLMの推論を効果的にサーブできそう。&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Kazuki679740569 さまに&lt;a href=&quot;https://x.com/Kazuki679740569/status/1947259412780880103&quot;&gt;ご指摘&lt;/a&gt;いただき、記載を修正しています。 &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 20 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2025/07/20/llm-inference</link>
        <guid isPermaLink="true">https://iwashi.co/2025/07/20/llm-inference</guid>
        
        <category>LLM</category>
        
        <category>生成AI</category>
        
        <category>解説</category>
        
        
      </item>
    
      <item>
        <title>「うーん、よくわからない。」という回答は情報価値が高い</title>
        <description>&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://amzn.to/40i7ovI&quot;&gt;The Mom Test&lt;/a&gt;という、海外のプロダクトマネージャー御用たちの書籍がある。残念ながら、まだ邦訳は存在しないが、非常に有用な内容が詰まっている。&lt;/p&gt;

&lt;p&gt;本記事では、3章の「Asking important Questions」を読み直している中で、自分なりの解釈や所感を自分用に残しておく。&lt;/p&gt;

&lt;h2 id=&quot;重要な問い&quot;&gt;重要な問い&lt;/h2&gt;

&lt;p&gt;ユーザーインタビューやソリューションインタビューを行う際の重要な問いとは、そもそも何か？　それは次のような問いである。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;その答えがビジネスを完全に変える（または否定する）可能性がある&lt;/li&gt;
  &lt;li&gt;予期しない答えが返ってきても、やっていることに影響を与えない場合は、重要な質問ではない&lt;/li&gt;
  &lt;li&gt;会話の中で少なくとも1つの質問に恐怖を感じるべき&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;最後の「恐怖を感じるべき」という点はかなり興味深い。これは、自然と避けてしまいがちな傾向を表している。なぜ避けやすいかというと、「そもそも事業アイデアに根本的な欠陥があると判明するかもしれない」からだ。&lt;/p&gt;

&lt;h2 id=&quot;重要な問いを避けている悪いインタビューの例&quot;&gt;重要な問いを避けている、悪いインタビューの例&lt;/h2&gt;

&lt;p&gt;仮に、読書アプリを開発しているとする。その際の悪いインタビューの例を挙げてみよう。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;起業家：「読書習慣について話を聞かせてください。読書アプリを開発しているんです」&lt;/li&gt;
  &lt;li&gt;顧客：「実は本はほとんど読まないんです。時間がなくて」&lt;/li&gt;
  &lt;li&gt;起業家：「どんなジャンルの本なら、たまに読みますか？」&lt;/li&gt;
  &lt;li&gt;顧客：「えーっと、まあ、たまにビジネス書を手に取ることはありますが…」&lt;/li&gt;
  &lt;li&gt;起業家：「その場合に、読書アプリに欲しい機能は何ですか？ 読書進捗の管理とか、メモ機能とかどうでしょう？」&lt;/li&gt;
  &lt;li&gt;顧客：「うーん、よくわからないです」&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;これは完全にイマイチで、「本を読まない」といっているのに、読書機能についてどんどん質問してしまっている。&lt;/p&gt;

&lt;h2 id=&quot;うーんよくわからないという回答の価値&quot;&gt;「うーん、よくわからない」という回答の価値&lt;/h2&gt;

&lt;p&gt;先ほどの例で挙げた「うーん、よくわからない」という回答は、実は非常に価値が高い。なぜなら、顧客がそのニーズに対して本当に関心がないことを示しているからだ。「それ、いいかもね」といった回答も同様。多分、顧客は全然惹かれていない。&lt;/p&gt;

&lt;p&gt;こういったふわふわした回答こそが、真実を示すシグナルになっている。つまり、顧客がそのニーズに対して「本当に関心がない」「そもそもニーズを感じていない」ということを示している。&lt;/p&gt;

&lt;h2 id=&quot;重要な問いを投げかける&quot;&gt;重要な問いを投げかける&lt;/h2&gt;

&lt;p&gt;読書アプリを前提にするのではなく、もっと幅広い視点で質問を変更して投げかけていく。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;「読書に対して、本当にニーズを感じていますか？」&lt;/li&gt;
  &lt;li&gt;「読書にどれぐらいお金を使っていますか？」&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;いずれにせよ、顧客の優先順位を理解しようと試みる。「そもそも、本当にニーズがあるのか？」「顧客はそのニーズのために、時間やお金を使う意欲があるのか？」これを探っていく。&lt;/p&gt;

&lt;p&gt;ニーズがないのであれば、ビジネスが否定される可能性がある。そうなったら、別の顧客セグメントに焦点を当てるか、ビジネスモデル全体を見直す必要がある。&lt;/p&gt;

&lt;h2 id=&quot;良い掘り下げ方&quot;&gt;良い掘り下げ方&lt;/h2&gt;

&lt;p&gt;「幅広く始めて、強いシグナルを見つけるまで焦点を絞らない」&lt;/p&gt;

&lt;p&gt;これが基本原則。何か引っ掛かる部分（シグナル）が見つかったら、そこを掘り下げていく。&lt;/p&gt;

&lt;p&gt;例えば、「今の大きな問題は何ですか？」「今、いちばん時間を取られていることは何ですか？」「いちばん気になっていることは何ですか？」といった質問から始める。&lt;/p&gt;

&lt;p&gt;回答からシグナルが見つかったら、さらに掘り下げていく。そのために、&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;「その問題をどの程度真剣に考えていますか？」&lt;/li&gt;
  &lt;li&gt;「それでお金を稼いでいますか？」&lt;/li&gt;
  &lt;li&gt;「それでお金を稼ごうとしたことはありますか？」&lt;/li&gt;
  &lt;li&gt;「それに週にどのくらい時間を費やしていますか？」&lt;/li&gt;
  &lt;li&gt;「そのために使っているツールやサービスはありますか？」&lt;/li&gt;
  &lt;li&gt;「すでに改善のために何をしていますか？」&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;といった内容を聞いていく。これを継続的に探し続ける。その際、ビジネス全体の実現性を意識すべき。顧客が欲しがっていても、市場が小さすぎたり、競合が強すぎたりすると、ビジネスとしては成り立たない可能性があるため。&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;重要な問いから逃げない&lt;/li&gt;
  &lt;li&gt;顧客のふわふわした回答を大切にする&lt;/li&gt;
  &lt;li&gt;シグナルを見つけて掘り下げる&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 13 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2025/07/13/face-important-questions</link>
        <guid isPermaLink="true">https://iwashi.co/2025/07/13/face-important-questions</guid>
        
        <category>コミュニケーション</category>
        
        <category>学習記録</category>
        
        <category>解説</category>
        
        
      </item>
    
      <item>
        <title>12 Factor Agents まとめ</title>
        <description>&lt;h2 id=&quot;はじめに&quot;&gt;はじめに&lt;/h2&gt;

&lt;p&gt;Heroku社が提唱した「12-Factor App」は、クラウドネイティブなアプリケーション開発のベストプラクティスをまとめたものです。これをAIエージェント開発に応用して、dexhorthy氏がまとめたものが「&lt;a href=&quot;https://github.com/humanlayer/12-factor-agents/&quot;&gt;12 Factor Agents&lt;/a&gt;」です。&lt;/p&gt;

&lt;p&gt;この12 Factor Agentsを読んでみて、かなり学びがあったので、この記事では12 Factorの概要を簡単にまとめておきます。&lt;/p&gt;

&lt;p&gt;なお、自分用にまとめて補足や所感を追加しているので、詳細はぜひ原文を参照してください。また、この記事は50%を人が書いて、50%をAIが補完しています。&lt;/p&gt;

&lt;h2 id=&quot;12-factor-agents-の背景&quot;&gt;12 Factor Agents の背景&lt;/h2&gt;

&lt;p&gt;「AIエージェントを作ろう！」&lt;/p&gt;

&lt;p&gt;そう思って意気揚々とLangChainやCrewAIなどのフレームワークを使い始めた開発者は多いのではないでしょうか。
最初は順調に進みます。デモは動くし、簡単なタスクもこなせる。でも、いざ本番環境に投入しようとすると……。&lt;/p&gt;

&lt;p&gt;「品質が70-80%で頭打ちになる」&lt;/p&gt;

&lt;p&gt;実際にプロダクションレベルで動かそうとすると、残りの20-30%が重要になります。ここで品質が落ちると、ユーザーの信頼を失い、ビジネスに悪影響を及ぼします。
では、なぜAIエージェントはこの壁にぶつかるのでしょうか？&lt;/p&gt;

&lt;h2 id=&quot;なぜそうなるのか---フレームワークの限界と現実のギャップ&quot;&gt;なぜそうなるのか？ - フレームワークの限界と現実のギャップ&lt;/h2&gt;

&lt;p&gt;多くのAIエージェントフレームワークは「プロンプトを与えて、ツールを渡して、ゴールに到達するまでループさせる」というパターンを推奨します。理論的には美しいアプローチです。でも現実はどうでしょうか？&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# よくあるパターン
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;next_step&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;llm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decide_next_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next_step&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;done&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_tool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;このアプローチの問題点は以下のとおりです。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;エラーが起きたときの制御が難しい&lt;/li&gt;
  &lt;li&gt;コンテキストウィンドウがすぐに溢れる&lt;/li&gt;
  &lt;li&gt;人間の承認が必要な場面で止められない&lt;/li&gt;
  &lt;li&gt;デバッグが地獄&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;実際、プロダクションで動いている「AIエージェント」と呼ばれるものの多くは、ほとんどが決定的なコードで、要所要所にLLMを使っているだけです。&lt;/p&gt;

&lt;h2 id=&quot;12-factor-agentsとは&quot;&gt;12 Factor Agentsとは&lt;/h2&gt;

&lt;p&gt;そこで登場するのが「12 Factor Agents」です。これは、dexhorthy氏が提唱する、プロダクション品質のAIエージェントを作るための12の設計原則です。&lt;/p&gt;

&lt;p&gt;重要なのは、これらの原則はフレームワークに依存しないということ。既存のコードベースに段階的に適用できる、実践的なパターン集という点です。以降では、この12の原則を簡単に紹介していきます。&lt;/p&gt;

&lt;h3 id=&quot;factor-1-natural-language-to-tool-calls自然言語をツール呼び出しに変換&quot;&gt;Factor 1: Natural Language to Tool Calls（自然言語をツール呼び出しに変換）&lt;/h3&gt;

&lt;p&gt;エージェント構築において最も一般的なパターンの一つは、自然言語を構造化されたツール呼び出しへの変換です。&lt;/p&gt;

&lt;p&gt;（所感：あまりによくあるパターンなので、あんまり意識しないかもで、詳細は割愛します）&lt;/p&gt;

&lt;h3 id=&quot;factor-2-own-your-promptsプロンプトを管理する&quot;&gt;Factor 2: Own Your Prompts（プロンプトを管理する）&lt;/h3&gt;

&lt;p&gt;プロンプトはコードと同じくらい大切な資産という原則です。一般的なエージェントフレームワークは簡単に始められますが、プロンプトの細かい調整やリバースエンジニアリングが困難です。フレームワークに隠されたプロンプトに依存するのは危険です。&lt;/p&gt;

&lt;p&gt;プロンプトは明示的に管理し、バージョン管理し、テストすべきです。プロンプトは自前で書いて、関数形式で明確な入力・出力を持つファーストクラスのコードとして扱うのが良いでしょう。&lt;/p&gt;

&lt;h3 id=&quot;factor-3-own-your-context-windowコンテキストウィンドウを管理する&quot;&gt;Factor 3: Own Your Context Window（コンテキストウィンドウを管理する）&lt;/h3&gt;

&lt;p&gt;コンテキストウィンドウは有限のリソースです。「とりあえず全部入れる」では、すぐに限界が来ます。&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// ❌ アンチパターン：履歴を全部入れる&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;conversation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getAllHistory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ✅ 良いパターン：必要な情報だけを選別&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;recentMessages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;conversation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getLastN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;relevantDocs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;findRelevant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;systemPrompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;prompts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getConcise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;また、LLMに渡す情報を普通のチャット形式ではなく、XMLやJSONなどの構造化された独自形式で整理して管理すると良いです。これによって情報密度が上がります。トークン数を削減でき、LLMがより正確に状況を理解して適切な判断ができるようになります。&lt;/p&gt;

&lt;p&gt;（所感：コンテキストを絞るのは非常に大事なのと、XML などの意味が構造化された形式で渡すのはかなり効果的な印象）&lt;/p&gt;

&lt;h3 id=&quot;factor-4-tools-are-just-structured-outputsツールは単なる構造化出力&quot;&gt;Factor 4: Tools Are Just Structured Outputs（ツールは単なる構造化出力）&lt;/h3&gt;

&lt;p&gt;ツールが複雑である必要はありません。ツールは、LLMからの構造化された出力であり、決定論的なコードを実行するためのものです。LLMは何をするかを決定しますが、その実行方法は決定論的なコードによって制御されます。&lt;/p&gt;

&lt;p&gt;従来の「AIにツールを渡して好きに使わせる」アプローチではなく、「AIには構造化されたJSONを出力してもらい、その内容に基づいて確実なコードを実行する」というアプローチが、実際のプロダクションでは信頼性が高くなります。&lt;/p&gt;

&lt;h3 id=&quot;factor-5-unify-execution-state-and-business-state実行状態とビジネス状態を統一&quot;&gt;Factor 5: Unify Execution State and Business State（実行状態とビジネス状態を統一）&lt;/h3&gt;

&lt;p&gt;従来は実行状態とビジネスの状態の別々に管理していました。だが、この場合は不整合が起きやすいです。&lt;/p&gt;

&lt;p&gt;エージェントの実行状態と、アプリケーションのビジネスロジックの状態を別々に管理すると、不整合が起きがちになります。&lt;/p&gt;

&lt;p&gt;そこで代わりに、コンテキストウィンドウ（会話履歴）から実行状態を推測できるように設計します。&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// ❌ 複雑な分離管理&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;execution&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;waiting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;business&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[...],&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;tools&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[...]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;ではなく、&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// ✅ 統一されたイベントストリーム&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;user_message&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;tool_call&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{...}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;tool_result&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{...}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;waiting_for_approval&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// 現在の状態は最新のイベントから推測可能&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;とします。現在の状態は、イベント履歴を辿ればわかります。&lt;/p&gt;

&lt;h3 id=&quot;factor-6-launchpauseresume-with-simple-apisシンプルなapiで起動停止再開&quot;&gt;Factor 6: Launch/Pause/Resume with Simple APIs（シンプルなAPIで起動・停止・再開）&lt;/h3&gt;

&lt;p&gt;AIエージェントも普通のプログラムと同じように、起動・一時停止・再開・停止といった基本操作を簡単にできるべきだという原則です。&lt;/p&gt;

&lt;p&gt;これが必要な理由は次のとおりです。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;効率性：無駄な待機時間を削減&lt;/li&gt;
  &lt;li&gt;信頼性：途中で止まっても安全に再開できる&lt;/li&gt;
  &lt;li&gt;統合性：他のシステムと連携しやすい&lt;/li&gt;
  &lt;li&gt;監視性：どの段階にいるかが分かりやすい&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;factor-7-contact-humans-with-tool-calls人間への連絡もツール呼び出しで&quot;&gt;Factor 7: Contact Humans with Tool Calls（人間への連絡もツール呼び出しで）&lt;/h3&gt;

&lt;p&gt;LLMは「普通のテキスト」か「ツール実行」かを最初の1文字で判断しています。例えば、「その」から始まったら、文章が返ります。これが不安定な動作の原因になります。そこで、常にJSON形式で返すようにします。&lt;/p&gt;

&lt;p&gt;その際、人間への連絡もツールとして扱います。イメージとしては、「エージェントが困った時に『ちょっと聞きたいことがあるんですが…』と人間に連絡してくるシステム」として作るということです。&lt;/p&gt;

&lt;h3 id=&quot;factor-8-own-your-control-flow制御フローを管理する&quot;&gt;Factor 8: Own Your Control Flow（制御フローを管理する）&lt;/h3&gt;

&lt;p&gt;AIに自動実行させると、さまざまな問題が起こります。たとえば、AIが「危険な操作」を選択した瞬間に、それを止める方法がないということです。また、長時間かかる処理の間、システムがメモリ上で延々と待機し続けるという非効率性もあります。データ分析が6時間かかる場合、その間ずっとプロセスが動き続け、サーバーリソースを無駄に消費します。さらに、途中でシステムが落ちれば全てが最初からやり直しになってしまいます。&lt;/p&gt;

&lt;p&gt;そこで、AIの動作を3つのパターンに分けて、それぞれ最適な制御方法を適用します。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;質問確認パターン：AIが曖昧な指示に困った時に人間に確認を求める&lt;/li&gt;
  &lt;li&gt;情報取得パターン：データ取得やファイル読み込みなど低リスクな操作を自動実行する&lt;/li&gt;
  &lt;li&gt;高リスク操作パターン：デプロイやデータ変更など重要な操作について、実行前に必ず人間の承認を求める&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;factor-9-compact-errors-into-context-windowエラーをコンテキストウィンドウに圧縮&quot;&gt;Factor 9: Compact Errors into Context Window（エラーをコンテキストウィンドウに圧縮）&lt;/h3&gt;

&lt;p&gt;AIエージェントの大きな利点の一つに「自己修復能力」があります。これは、何かの処理が失敗した時に、AIがエラーメッセージを読み取って自分で問題を解決する能力のことです。たとえば、AIがファイルを読み込もうとして「ファイルが見つかりません」というエラーが出た場合、優秀なAIなら「パスが間違っているかもしれない」「ファイル名にタイポがあるかもしれない」と推測して、修正した内容で再度実行をtryします。&lt;/p&gt;

&lt;p&gt;エラーが起きた場合の実装方法もtry -&amp;gt; catchのloopで作れますが、無限リトライすると危険であるため、通常は最大リトライ回数を設定します。&lt;/p&gt;

&lt;p&gt;ただし、エラーをそのままコンテキストに追加するだけでは不十分な場合があります。長いスタックトレースや複雑なエラーメッセージは、コンテキストウィンドウを圧迫し、AIの判断を混乱させる可能性があるためです。そこで、エラー情報を要約したり、関連性の低い過去のイベントを削除したりして、コンテキストを最適化してください。&lt;/p&gt;

&lt;h3 id=&quot;factor-10-small-focused-agents小さく集中したエージェント&quot;&gt;Factor 10: Small, Focused Agents（小さく、集中したエージェント）&lt;/h3&gt;

&lt;p&gt;現在のAI開発でよく見られる間違いの一つに「万能エージェント」を作ろうとすることがあります。つまり、一つのエージェントにあれもこれもやらせようとする取り組みです。しかし、結果的に何もうまくできないエージェントを作ってしまうのがよくあるパターンです。&lt;/p&gt;

&lt;p&gt;そこで、「一つのことを非常にうまくやる小さなエージェント」を作りましょう。&lt;/p&gt;

&lt;p&gt;小さく集中したエージェントのメリットは次のとおりです。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;コンテキストウィンドウが管理しやすいサイズに収まるため、LLMのパフォーマンスが向上する&lt;/li&gt;
  &lt;li&gt;各エージェントの責任範囲が明確になり、問題が発生した際の原因特定や修正が容易になる&lt;/li&gt;
  &lt;li&gt;個別のエージェントをテストすることで、システム全体の信頼性が向上する&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;factor-11-trigger-from-anywhereどこからでもトリガー可能に&quot;&gt;Factor 11: Trigger from Anywhere（どこからでもトリガー可能に）&lt;/h3&gt;

&lt;p&gt;ユーザーがいる場所でエージェントが動くようにしましょう。&lt;/p&gt;

&lt;p&gt;エージェントは、Webhook、CLI、API、Slack、メールなど、さまざまな方法でトリガーできるようにしてください。&lt;/p&gt;

&lt;p&gt;（所感：DevinはSlackと連携するのを推奨していることから、原則に沿っていることがわかる）&lt;/p&gt;

&lt;h3 id=&quot;factor-12-make-your-agent-a-stateless-reducerステートレスなリデューサーにする&quot;&gt;Factor 12: Make Your Agent a Stateless Reducer（ステートレスなリデューサーにする）&lt;/h3&gt;

&lt;p&gt;最後の原則は、関数型プログラミングの考え方から来ています。&lt;/p&gt;

&lt;p&gt;「AIエージェントは基本的にforループである」という前提があるとして、それを関数型プログラミング的に表現すると、AIエージェントは左foldになります。（reduce操作とも同じ概念）&lt;/p&gt;

&lt;p&gt;（補足：ここでのタイトルのリデューサー/Reducerとは、「現在の状態」と「新しいアクション」を受け取って「新しい状態」を返す純粋な関数のこと）&lt;/p&gt;

&lt;h2 id=&quot;まとめ&quot;&gt;まとめ&lt;/h2&gt;

&lt;p&gt;というわけで、ざっと12原則を紹介してみました。冒頭にも書きましたが詳細は、&lt;a href=&quot;https://github.com/humanlayer/12-factor-agents&quot;&gt;12-Factor Agents&lt;/a&gt;の内容をぜひ参照してください。&lt;/p&gt;
</description>
        <pubDate>Sun, 06 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://iwashi.co/2025/07/06/12-factor-agents</link>
        <guid isPermaLink="true">https://iwashi.co/2025/07/06/12-factor-agents</guid>
        
        <category>生成AI</category>
        
        <category>AIエージェント</category>
        
        <category>まとめ</category>
        
        
      </item>
    
  </channel>
</rss>
