■ 1. 旧システムで直面した課題とDDD導入の背景
- 勤怠管理システムの複雑性: 勤怠システムは、法律や就業規則、企業ごとの勤務体系の違いなどにより、複雑なルールと例外が膨大に存在する。
- 旧システムの課題:
- 処理の不明確さ: 自作フレームワークをベースにしていたため、処理の所在が不明確であった。
- 深刻な属人化: 「この処理の正解は〇〇さんしか知らない」という状況が頻発し、知識が特定のベテランメンバーに偏っていた。
- 高い教育コスト: 新メンバーにとってコードと業務知識の紐付けが難しく、システム理解に大きなハードルがあった。
- DDD導入の目的: 「何をどこで処理しているのかが不明確」という最大の課題を解決するため、新システムのリニューアル時にDDD(ドメイン駆動設計)を採用した。
■ 2. DDD導入によるシステムの改善と属人化の解消
- ドメインの整理とモデル化: 「現実の勤怠の仕組みを、チーム全員が同じ言葉で説明できるようにする」というアプローチで、勤怠ドメインの整理とモデルへの落とし込みを行った。
- 代表的なモデルの例:
- 労働パターン: 勤務区分やカレンダーなど、勤怠計算に必要な設定を定義する。
- 打刻: 出退勤・休憩といった「事実」だけを表し、「遅刻」などの解釈は加えない。
- 勤務実績: 打刻や計算で計上された、その日の「働いた結果」を表現し、ユーザーへの表示に用いる。
- 休暇履歴: 有休の付与・取得・消滅をすべて履歴として積み上げることで、残日数を自動的に導けるようにし、値の正当性に関する懸念を解消する。
- 共通理解の促進:
- ユビキタス言語の活用: 「労働パターン」「打刻」「勤務実績」「休暇履歴」といったモデル名を指して会話できるようになり、以前の曖昧な表現を解消した。
- 属人化の解消: 知識がモデルに閉じ込められ、チーム全体で共有できるようになり、仕様確認やレビューがスムーズになった。
■ 3. 9年間の運用で実感したDDDの価値
- チーム知識の維持: DDDは「複雑な業務知識をチーム全体で維持し続ける仕組み」として機能した。
- 価値の具体例:
- 新メンバーの立ち上がり加速: 旧システムのように勤怠ドメインの理解に数カ月かかることはなくなり、「休暇履歴」などの用語ベースで理解できるようになった。
- 制度変更への柔軟な対応: 制度やルールの変更が発生した場合、該当モデルにルールを追加・修正するだけで対応できるようになった。
- 最終的な評価: 9年間の運用を経て、DDDは単なる設計手法ではなく、「複雑な勤怠ドメインをチームみんなで理解し続けるための心強い道具」であり、「あのときDDDを選んでよかった」と心から言える。
■ 1. 権限管理の重要性とアンチパターン
- 権限管理ミスの影響: 給与や取引先情報などの機密情報公開につながり、サービスへの信頼が低下し、事業への大きな損失を招くため、ミスは許されない。
- よくあるアンチパターン:
user.admin?やuser.super_admin?のように役割に依存した判定を行うこと。- 役割は事業やサービスの変化(市場、企業規模、機能)に伴い変わりゆくため、役割に依存した実装は変化に弱く、権限が暗黙的になり、技術負債の原因となる。
- 推奨されるアプローチ: 役割(
admin?)に依存せず、権限に依存した判定(例:user.can_create_project?)にすることで、権限が明示的になり、コードリーディングや変更時の整合性確認が容易になる。■ 2. 権限管理の要素整理とPunditの問題点
- 権限管理の要素分解: 権限管理を整理する上で、以下の4つの要素に分割できる。
- 対象: Model(例:
Project)- 操作: CRUDやその他のアクション(例:
update)- 役割(RBAC): Role-Based Access Control(例:
管理者アカウント、外部アカウント)- 条件(ABAC): Attribute-Based Access Control(例:
作成者、担当者)- Punditの問題: Punditを利用した場合、一つのポリシーメソッド内で役割と条件の判定が混在し、複雑な判定ロジックになると、「通常ユーザーは更新できるか?」といった問いに対し、すぐに回答できない(理解で間違えやすい)という問題が生じる。
- 例:
管理者かマネージャーかつ担当者か作成者ならできる...のような論理演算の連なりは、一目で理解しにくい。■ 3. 要素を適切に分割したModuleの実装と実現方法
- Moduleの設計思想: 役割と条件を分離し、権限を対象・操作・役割・条件の4要素で明示的に定義する。
- 実装の概要:
- ディレクトリ/ファイル構造: 対象ごとにディレクトリを作成し、その中に役割ごとにファイル(権限の具体クラス)を作成する。
- 権限の判定: 権限の具体クラス内で、対象の基底クラスで定義した条件(例:
assignee?やauthor?)を英語と論理演算(||や&&)でシンプルに組み合わせて表現する。- メタプログラミングの活用: 対象と役割から権限のクラスを特定する際に使用し、権限の追加・変更を容易にする。
- 利用時のモード:
- recordモード: 特定のレコードに対して権限があるかを判定する(例:
Context.new.can_update?(@project))。- scopeモード: 権限があるレコードのみに絞り込む(例:
Context.new.scope_for_read(Project))。- listモード: クライアント(Next.jsなど)に渡すための権限の一覧を取得する。
■ 4. 良い設計がもたらす影響
- 間違えない実装の実現: 役割と条件を分離し、権限を明示的に記述することで、実装・利用・理解のすべてのフェーズで間違いを減らす(不具合の発生件数がゼロ、社内からの問い合わせがゼロ)。
- 開発生産性の向上: CSやPdMがGitHub上のコードを直接見て理解できるようになり、エンジニアへの問い合わせ対応時間が削減された。
- クライアント(Next.js)への影響:
- Railsから渡された権限の一覧(JSON)にNext.jsが依存することで、Next.js側でも役割に依存しない実装が自然に実現した。
- 権限によるUIの制御を(例: 編集ボタンの表示/非表示)宣言的に記述できるようになり、フロントエンドの技術負債も防いでいる。
■ 1. 「完璧を目指さない」アーキテクチャの必要性
- Lambda利用の現実的な課題: 初期は快適だが、データ量増加による15分制限の壁や、構成変更時のYAMLの複雑化(記述量爆発)、型安全性なしによる実行時エラー多発といった問題が生じる。
- 構成変更の困難さ: 実行時間超過への対応策として「Lambda分割」や「Fargate移行」があるが、いずれも複雑化や大幅な構成変更が必要となり困難である。
- 進化の鍵: 完璧な初期設計は存在せず、要件変化に柔軟に対応できる仕組み、すなわち構成変更の容易さと将来の拡張性がアーキテクチャの進化には重要である。
- 進化的アーキテクチャの定義: ビジネス要件や技術の進歩といった絶え間ない変化に適応できるように設計された柔軟性の高いソフトウェアアーキテクチャであり、漸進的な変更、適応度関数(客観指標)、多重な次元(性能、セキュリティなど)の統合管理が特徴である。
■ 2. CDKによる実践的進化パターン
- パターン1:Lambda → Fargate 移行:
- 課題: 15分実行時間制限、スケーラビリティの限界がある。
- 解決アプローチ: コンテナ化による時間制限の解除とECS Fargateによる自動スケーリングで解決する。
- CDKの優位性: SAMでの移行時の記述量増加が6.3倍なのに対し、CDKでは2.1倍に抑制され、移行時の複雑度を約1/3に抑える。
- パターン2:EventBridge+Lambda → Step Functions 移行:
- 課題: トレーサビリティ不足、分散イベント処理の複雑化、障害時の影響範囲特定困難がある。
- 解決アプローチ: Step Functionsによる一気通貫ワークフローへの統合と実行状況の可視化、エラーハンドリングの集約により、障害調査時間を大幅に短縮する。
- CDKの優位性: 既存の
grant()メソッドがそのまま使え、型安全性によりコンパイル時にエラーを検出でき、複数のLambda関数の連携を一つのファイルで管理しやすい。- パターン3:DynamoDB → Aurora 移行:
- 課題: 複雑なクエリ要件の増大、NoSQLの限界がある。
- 解決アプローチ: Auroraへの切り替えとSQLによる柔軟なクエリ実行で対応し、CloudWatch Syntheticsによる性能監視(適応度関数)を強化する。
- CDKの優位性:
synthetics.Canary()で継続的な監視をコード化するなど適応度関数の実装が容易である。また、cdk diffにより変更点を確認しながら漸進的な変更を実現し、セキュリティ要件も1行の変更でIAMベースからVPCベースへ移行できる。■ 3. 進化的アーキテクチャの実現とCDKの価値
- SAM vs CDKの比較:
- 構成変更時の記述量: SAMは爆発的に増加するが、CDKは管理可能である。
- 変更影響の可視化: SAMは困難だが、CDKは
cdk diffで確認可能である。- 権限・接続管理: SAMは複雑なYAMLが必要だが、CDKは
grant/connectionsで直感的である。- 結果: 長期的な開発・保守性においてCDKが優位であり、進化的アーキテクチャの実現を可能にする。
- CDKの総合的な価値:
- 構成変更時の記述量を大幅に削減し(SAMの1/3の複雑度)、変更影響の事前確認が可能である。
- 直感的な権限・接続管理を実現し、段階的移行を支援する。
- 結論: アーキテクチャは「完璧な初期設計」を目指すのではなく、「育てるもの」である。サーバーレス環境において、CDKを活用することで、要件変化に柔軟に対応できる段階的な改善アプローチでアーキテクチャを進化させる。
■ 1. 過去の経緯と問題意識
- パーフェクトRailsでの記述: 2014年発売の『パーフェクトRuby on Rails』において、筆者はServiceクラスをコントローラーとモデルの中間に位置し、モデルの処理をまとめるインターフェースとして定義した。
- 後の見解の変化: 2016年末に「サービス クラスとか作るのは止めてくれ」という記事を公開し、わずか2年半で記述内容と異なる意見を表明した。
- 再議論のきっかけ: 2024年の懇親会での議論を機に、Serviceクラスの是非について改めて考察するに至った。
- Fat Modelの問題: Railsがビジネスの現場で多用されるにつれ、ActiveRecordの特性からくるFat Model(巨大化したモデル)の問題が顕在化し、その解決策としてServiceクラスが言及されるようになった。
■ 2. Serviceクラスの定義と乱用の難しさ
- DDDにおけるService: エンティティや値オブジェクトに責務を持たせると不自然になる場合に、振る舞いに着目して命名し責務を定義するものであり、命名はユビキタス言語に由来する必要がある。
- パーフェクトRailsでの役割: 処理そのものをカプセル化し、業務知識と実装のメンタルモデルを一致させる役割があると記述した。
- 乱用の危険性: 「乱用は危ないから考えてから使う」という基準の度合いが人によってバラバラであり、単純に複雑な処理に名前を付けて良いわけではないという理解が共有されていなかった。
- チーム開発での課題: チーム開発では共通認識が重要であり、Serviceクラスの基準が不明確だと一貫性が失われ、コードの全体像の把握や保守が困難になる。
■ 3. 現実的な解決策としてのFormクラス
- Railsの基本的な層: Controller、Model、Viewの基本的なレイヤーを守ることで、共通認識の維持と想像のしやすさというフレームワークの利点が得られる。
- Formクラスの役割: Serviceクラスと同じく複雑な処理の置き場所だが、Webアプリケーションにおけるパラメーターハンドリングとトランザクションコントロールを扱うという、より限定的な文脈に対処する。
- Serviceクラスとの違い: Formクラスは画面やユースケース(アクション)と紐づき、ActiveModel/ActiveRecordのインターフェースと親和性が高いという、名前から具体的なイメージが想像できる利点がある。
- 共通の難しさ: ServiceやFormを利用しても、結局ActiveRecordのメソッドレベルの境界をどこに設定するかという、モデルの整理から逃れられない。
■ 4. 根本的な重要事項とServiceクラスの今後
- 最も重要なこと: ServiceやFormといった表現技法は重要ではなく、RDBと向き合い、ActiveRecordを使いこなし、ドメインコンテキストの理解を深めることが重要である。
- ドメインコンテキストの理解: 複雑なシステム設計では、コンテキストマップ(境界づけられたコンテキスト)を作成し、システム内のコンポーネントと相互作用を設計する。
- モジュラーモノリスの導入: コンテキストの境界を明確にし、依存関係を一方向に保つための現実的な選択肢として、モジュラーモノリスが挙げられる。
- Serviceクラスの復活: モジュラーモノリスによってコンポーネントの境界が明確になった時、Webインターフェースに限定されないコンポーネントレベルの公開エントリポイントとしてServiceクラス(またはそれに類するもの)の利用は意味を持つ。
- 継続的な開発の難しさ: Serviceクラスを使う場合は、チームメンバー全員で利用ケースと言語化された必要性を共有することが不可欠である。ソフトウェア設計は、ビジネスの発展を継続的にサポートするために何度も判断を下し、改善し続ける営みである。
■ 問題領域の特定: 在庫管理の「神テーブル」
- 深刻な現状: モノタロウの基幹システム(受注・配送・発注ドメイン)には、商品の在庫状況に関する属性がたった一つの巨大なテーブルに保存されている。
- 複雑性の原因:
- レコード数は5000万件以上に及び、関連する更新ユースケースは80以上、参照ユースケースは730以上存在する。
- 各ドメインがこのデータ構造に密に依存しており、データ構造の変更は入出荷停止リスクなど、ビジネス基本業務に深刻な影響を与える。
- この「神テーブル」は在庫の状態のみを持ち、状態に至った経緯(理由)を把握できない。
- 必要な数値の導出に他のテーブルとの結合が生じ、「在庫状況の管理」という文脈で担保すべき不変条件の範囲が曖昧になっている。
- 課題への取り組み: 業務とシステムの可変性を取り戻すため、この不要な複雑性の本丸である「在庫状況問題」の分割に取り組むことを決定した。
■ 課題の分割とドメインモデルの仮説構築
- 分割の常套手段: 「神クラス」分割の常套手段にならい、以下の手順で問題解決にアプローチした。
- (1) 在庫状況に関連する更新ユースケースを網羅的に洗い出す。
- (2) どのドメインがどの属性を更新しているか分類する。
- (3) 属性のオーナー候補ドメインを仮定する。
- 在庫ドメインの仮説検証:
- 存在が不確かな「在庫ドメインとその属性」を仮定し、既存の更新ユースケースが破綻なく処理できるか慎重に確認した。
- 大規模ワークショップでモブプログラミングを実施し、在庫ドメインの属性と責務のイメージをつかんだ。
- 更新ユースケースをシーケンス図に起こし、ドメインシステム間のメッセージングを確認した。
- 成果: 上記の密な調整を経て、ついに「在庫ドメインはあります!」という仮説(存在)に至り、積年の課題に切り込むことができた。
■ ドメイン駆動設計(DDD)によるアプローチ
- DDDの採用理由:
- 問題領域が基幹業務であること。
- 在庫管理の柔軟性がモノタロウの競争優位性の源泉となり得ること。
- 最大の目的が業務とシステムの可変性を取り戻すことであるため。
- 体制強化: DDDエキスパートやリソース不足という足踏み要因を解消するため、専任チームを結成し、AWSプロフェッショナルサービスの支援を受けた。
- モデリングの手順:
- ビッグピクチャーの作成: フルフィルメント全体の業務イベントを可視化する大規模なイベントストーミングを実施。
- プロセスモデルの作成: 在庫状況の業務領域に絞り込み、イベントがどのように発生したかを分析。
- ドメインモデルの導出と洗練:
- プロセスモデル上の集約を取り上げ、コマンドを振る舞い、必要となる値を属性として推定した。
- 属性をエンティティと値オブジェクトに分けて集約を構成した。
- その後、業務・モデル・コードを往復する試行錯誤(禅問答)を重ね、概念構成図などを活用しながらモデルを洗練させた。
■ レイヤードアーキテクチャによる実装と品質向上
- アーキテクチャの採用: 導出されたドメインモデルを実装するためにレイヤードアーキテクチャを採用し、以下の4層で構成した。
- ビュー層: イベント受付(イベントハンドラ)
- アプリケーション層: ビジネスロジック実行、ユースケース管理(集約のロードと振る舞い呼び出し)
- ドメイン層: ビジネスルール、ドメインモデル定義(在庫集約、リポジトリインタフェース)
- インフラストラクチャ層: データベースアクセス、外部システム連携(リポジトリ実装)
- 依存関係の逆転: ドメイン層がインフラストラクチャ層に依存するのを避けるため、リポジトリのインタフェースをドメイン層で定義し、実装をインフラストラクチャ層で行うことで回避した。
- メリット(保守性の向上):
- 各層の責任と関心事が独立し、システム全体の理解が容易になる。
- 層間の依存が限定されることで、コードの変更の影響範囲が限定され、変更容易性が向上する(例: 同期→非同期への変更がビュー層の書き換えのみで済む)。
- ソフトウェアの「質」の向上: 「良いソフトウェア」であるために、設計原則の共有と定期的なリファクタリングを実施。
- リファクタリングの例(アプリケーション層):
- 複数のユースケースで共通していた「集約をロード→イベント適用→集約を保存」の処理の流れを特定。
- SingleEntityCommandServiceという単一のサービスに共通処理を集約し、ユースケースごとにCommandインタフェースを渡す形にリファクタリングした。
- これにより、コードの重複が減り、再利用性、メンテナンス性、拡張性が向上した。
■ 今後の展望
- 活動の継続: 在庫ドメインの成果を基幹システム分割・モダナイズ活動の一環として、今後も多くの業務領域に取り組む。
- 全体最適: 個別の業務領域と並行して、基幹システム全体の構造とマスタデータ管理の最適化を進める必要がある。
- 知見の共有と仲間探し: 得られた知見のドキュメント化やワークショップ開催を通じて、活動を推し進めるためのより多くの仲間を求めている。
■ 1. 設計を体得できていない状態とは
- 問題の本質: 設計が何か分からなければ設計はできない
- 教える側と教わる側のすれ違い:
- 教える側は「図や表を通じてシステムを考えられる」と考えるが、教わる側は「システム=コード」と捉えている
- 教える側は設計によって重要な課題が洗い出せると考えるが、教わる側はコードが分からないと課題も分からないと感じる
- 設計していないことに気付かない問題: 初学者は「DB→モデル→コントローラ→ビュー」という手順を説明するだけで設計したと思い込む
- 手順による実装の実態: 実装前に全体を考えず、マイグレーションから作業を進めて最後に何を作れたか理解する状態
■ 2. 設計の定義
- 設計とは: コードのレベルで考えることなく、全体としてどういう構造や技術的要素を使ってどんなものを作るのが良さそうかを考え、作業の段取りを考えても良い状態にすること
- ベテランと初学者の違い:
- ベテランは抽象度の高いレベルでシステムをまず考える
- 初学者はコードのレベルだけでシステムを考えがち
- 設計は手順の前に来る: 手順を考える前にシステムの構造を考える必要がある
■ 3. 逆算による設計メソッド
- 順算との対比: 従来の「手順による開発」をまだ見えないゴールに向かってコードを順番に作る「順算」に例える
- 逆算の流れ:
- まず完成したシステムを思い浮かべる
- 中核的な「実現したいこと」にフォーカスする
- 「それには何が必要か」を順々に考えていく
- 目的: 設計がよく分からない人を設計世界へ導入する手法である
■ 4. 実践例:ユーザーCSVインポート機能
- 完成形の想像:
- 大量登録時の時間やメモリの問題を想定
- 一部エラー時の処理方針を検討
- エラー情報の表示方法を検討
- インポート履歴の必要性を検討
- 課題の洗い出しと仮置き:
- 非同期処理にすることを仮置き
- 全部失敗方式を仮置き
- Importモデルでエラー情報と履歴を管理
- ゴールの設定: 実際にCSVからユーザーが登録・更新されることを本質的なゴールとする
■ 5. ステップと名前付け
- ステップの定義: 見つけた「実現したいこと」「必要なこと」に短い名前をつけて形を書き出す
- 名前付けの重要性:
- 設計は大きな粒度で考える活動である
- 長い概念を短い名前に置き換えることで脳内スペースを節約できる
- 設計は名前をつける行為の積み重ねである
- 具体例: 「インポートすること」自体をモデルにしてImportと命名する
■ 6. 開発領域の整理と手順計画
- 領域分け: 処理の順番や処理が書かれる場所の違いに注目して大まかにグルーピングする
- 手順の考え方:
- データが準備しやすい流れを考える
- 本質的なこと、難しいことをなるべく先にやる
- 設計後の手順の質の変化: DB→モデル→コントローラ→ビューではなく、Import登録→インポートロジック→一覧・詳細といった機能単位の手順になる
■ 7. デザインパーツの活用
- デザインパーツとは: 再利用性のある小さな設計パーツで、アーキテクチャや考え方を指す
- 主要なカテゴリ:
- データ構造(ActiveRecord、関連、制約など)
- 処理構造(MVC、コールバック、非同期処理など)
- 個別機能・Gem(認証、認可、検索機能など)
- 効果: 色々なデザインパーツを理解していれば速く妥当な設計ができる
■ 8. 今日伝えたいこと
- 全体が機能するように設計する: アプリケーションだけでなくシステム全体が機能するように設計することが重要である
- システムコンポーネントとパターンの組み合わせ: パターンを組み合わせてシステムを構成することで全体の構造が現れる
- 初学者向けの手法: 完成形をイメージして中核的な価値の実現から逆算で1つ1つ要素の形を決めていく
■ 検証概要と設定
- 比較対象: RedisとPostgreSQLをキャッシング用途に使用した場合のパフォーマンスを比較検証。
- 環境設定: Kubernetes上で、PostgresまたはRedisを2CPU/8GiBメモリに制限し、デフォルト設定で実行。
- データセット: 事前に3000万件のデータを投入し、GET(取得)、SET(設定)、混合(Read/Write)の3種のワークロードで性能を測定。
■ パフォーマンス検証結果
- 総合性能: すべてのワークロード(GET/SET/混合)において、RedisがPostgreSQLよりも高速な結果となった。
- Redis側のボトルネック: Redisの処理能力ではなく、HTTPサーバー側のCPUが上限に達したことがボトルネックとなっていた。
- PostgreSQL側のボトルネック: 制限された2コアのCPUを使い切り、PostgreSQL側がボトルネックとなっていた。
- 非ログ記録テーブルの効果: PostgreSQLで非ログ記録テーブルを使用することで、特に書き込み(SET)性能は大幅に改善されたが、Redisの速度には及ばなかった。
■ 筆者の結論と考察
- 速度の優位性: RedisがPostgreSQLより高速であるという事実は認めている。
- 依存関係の削減: ほとんどのプロジェクトではPostgreSQLの性能で十分であり、Redisという新しい依存関係を追加しないことの利点を重視するため、Postgresを使い続ける。
- 性能の評価: Postgresの性能(7425リクエスト/秒、1日5億件以上のリクエストに相当)は、大半のプロジェクトの要件を満たす十分なものである。
- 柔軟な設計: キャッシュにインターフェースを設けておくことで、将来的に性能不足が生じた際にRedisへの切り替えを容易に行えるようにする。
■ 先進的プロンプトテクニックの概要と課題
- Backstep Prompting: 結論に至る思考プロセスをモデルに後退(バックステップ)させ、自己評価・修正させる手法である。
- 目的と効果: 推論の正確性向上、ハルシネーション(幻覚)の抑制、思考プロセスの透明化に寄与する。
- Scaffolding(スキャフォールディング): 複雑なタスクを小さなサブタスクに分解するための手順(足場)をプロンプトに含めるアプローチである。
- 目的と効果: 複雑な問題解決能力の向上、回答の網羅性と一貫性の確保、出力形式の制御に有効である。
- 先進手法の課題: Backstep PromptingやScaffoldingは強力だが、毎回複雑なプロンプトを考える手間がかかり、「プロンプト職人」の腕に依存するという「人力での煩雑な作業」という課題がある。
■ 新しい対話法「モノローグ法」の提案
- 主語の転換: 従来のAIとのやり取りは命令形(Imperative)でAI(You)が主語であった。モノローグ法では、プロンプトの主語をあなた自身(I)に変え、一人称の表明形(Declarative)で思考をつぶやく。
- AIの役割変化: AIは「命令を待つ部下」から、ユーザーの思考に耳を傾ける「思考のパートナー」へと役割が変わる。AIの応答は思考の触媒として機能するが、無視できる自由があり、ユーザーの思考の流れを邪魔しない。
- メリット: ユーザーは「AIへの指示を考える」という制約から解放され、純粋に自分自身の思考を深める知的作業に集中できる。これにより、自然な形でBackstep PromptingやScaffoldingと同様の効果を得る。
■ モノローグ法のメカニズムと学術的裏付け
- 思考の触媒: AIの控えめな応答は、ユーザーの思考を客観的に捉え構造化するきっかけを与え、ユーザー主導でのScaffolding(思考の足場作り)を共同で行うプロセスとなる。
- 無視できる自由: 心理的なプレッシャーなしにAIの提案を無視・自己修正できる環境は、思考の寄り道や自己修正を促し、Backstep Promptingと同様の内省を自然に実現する。
- 学術的関連性: モノローグ法は、思考プロセスを外部化することで推論能力を高めるChain-of-Thought (CoT)、対話を通じて思考を洗練させるIterative Refinement、そして人間による自己批判・修正をAIと協調して行うSelf-Correctionの研究潮流と関連性が高い。
基調講演でサマット氏は、AndroidとグーグルのAIサービスである「Gemini」がスマートフォンだけではなく、テレビやスマートウォッチなど、ほかのデバイスからも利用できるようになってきたことを紹介。その上で、ユーザーが質問して答えを得る「オンデマンドモデル」から、AIがユーザーが抱える次の問題を「予測し」、アシスタンスを提供する「よりプロアクティブなモデル」へと移行すると指摘する。
その上で、基調講演のホストを務めていたクアルコムのモバイル・コンピュート&XRグループジェネラルマネージャーであるアレックス・カトージアン氏(Alex Katouzian)がサマット氏へ「より大型のディスプレイデバイス」での生産性の変化について問う。
するとサマット氏はAndroidエコシステムのすべてのデバイスに対して「シームレスに一緒に機能すること」をユーザーの多くが望んでいると解説。ノートパソコンという形態に対して、グーグルではChromeOSを提供し成功した、とした上で、AIの進歩から「可能な限り迅速に、ラップトップのフォームファクターにもたらすか」(サマット氏)という課題を指摘する。
そこで現在、グーグルが実行していることはChromeOSの体験をもとに、Androidに融合することとして、その融合について「来年に向けて非常に興奮している」と説明。2026年の投入を示した。
■ 1. 非同期処理の定義と採用基準
- 非同期処理の定義: Webサービスにおける非同期処理は、AWS SQSやGoogle Cloud Pub/Subなどのメッセージキューを利用し、バックエンドサーバーがキューにメッセージを入れ、ワーカーがそれを非同期に処理する仕組みを指す。
- 構造: クライアント → バックエンドサーバー → AWS SQS/Pub/Sub → ワーカー
- 採用基準: 非同期処理は基本的に面倒であるため、同期処理では要件を満たせない時にのみ採用すべきである。
- 同期処理で要件を満たせないケース:
- 大規模な時間のかかる処理: 巨大なCSVファイルのダウンロードやアップロード・DB登録処理など、利用者を長時間待たせたり、DBに高負荷をかけたりする場合。
- 高RPS(Request Per Second)環境での外部API呼び出し: レイテンシの高い外部APIを複数回叩くエンドポイントに大量のリクエストが集中し、バックエンドサーバーのリソース(コネクションプールなど)が枯渇したり、スケール効率が悪化したりする場合。
■ 2. 非同期処理で考慮すべき面倒なポイント(設計フェーズ)
- (1) メッセージキュー/タスクキューに対する理解:
- 課題: AWS SQSやGoogle Cloud Pub/Subなど、利用する仕組みの仕様、機能、オプション、制限を正確に理解しておく必要がある。
- 運用上の考慮点: メッセージが溜まった際のワーカー数の手動スケールの必要性、それに必要なアラートやメトリクスの取得・設定を設計に含めるべきである。
- (2) ワーカー処理が失敗したときのリカバリ方法:
- 課題: ワーカーの処理は100%成功しないため、失敗時のリカバリ方法を設計する必要がある。
- 手動リカバリ: 失敗頻度が低い場合は、エンジニアが手動でメッセージを再キューイングする方法が考えられるが、手順の複雑化や手順書の最新性維持が困難になる可能性がある。
- 自動リカバリ: 失敗した処理をDBに記録し、定期実行バッチでリトライする方法が考えられるが、実装の手間やバッチ自体の失敗対応、処理タスク数の設計など、考慮点が多くなる。
- (3) ボトルネックの確認と対策:
- 課題: 非同期処理を採用しても、最終的に処理はどこかで実行されるため、ボトルネックや負荷は残る。特にRDBがボトルネックになる可能性が高い。
- 具体的なボトルネック: DBへの複雑なクエリや大量クエリによるDB負荷、メッセージ集中によるワーカー数クオータ上限到達、アラート発火などが考えられる。
- 対策例:
- 同時に実行できるワーカー数を制限する。
- ワーカー処理用に専用のDBインスタンス(分析用DBなど)を用意する。
- メッセージキューにキューイングできるメッセージ数を制限する。
- ワーカー処理にsleepを入れ、クエリ実行間隔を長くする。
- 補足: ハイトラフィックな非同期処理では、RDBよりもNoSQLやNewSQLといったスケールするDBとの相性が良い。
■ 3. 結論
- システムのスケーラビリティ: 非同期処理は面倒ではあるが、システムのスケール性能やサービス間の疎結合化を実現する上で非常に魅力的である。
- 将来の展望: ある程度の規模のシステムでは非同期処理の利用が避けられないため、エンジニアや組織は、システムのスケールに合わせて非同期処理を適切に扱えるようになるための変化への投資が必要となる。
- 重要性: 非同期処理は実装自体は簡単だが、設計フェーズで上記の面倒なポイント(仕様理解、リカバリ、ボトルネック)を考慮しなければ、リリース後の運用で大きな問題が発生する可能性が高い。
■ 1. DHH(David Heinemeier Hansson)の問題点
- DHHの人物像: Ruby on Railsの生みの親であるDHHは、成功した賢い人物であると評価されている一方、「Ruby界のFox News」と表現され、議論好きで反動的、反知性的、そして無礼な人物であると批判されている。
- 思想の変遷: DHHは、自身のブログで、当初は中道的な政治的信条を持つように見えたが、数年かけて反キャンセルカルチャー、反DEI、反トランスジェンダー、そして最終的にはナショナリズムへと傾倒していった。
- ファシズム的言説: ロジャー・グリフィンのファシズムの定義(国民の再誕を求めるポピュリスト的な超国家主義)を引用し、DHHの最近のロンドンに関するブログ投稿が、この「ファシズム」に該当すると指摘している。彼は、人種的多様性を否定し、人種的に純粋だった過去を賛美している。
- 矛盾: DHHは過去に「郷愁を嫌う」と述べていたにもかかわらず、近年の投稿では、DEIやキャンセルカルチャーが問題視される前の時代への郷愁を強く示している。
■ 2. RubyおよびRailsコミュニティのガバナンスの問題
- DHHの権力: DHHはRailsの著作権を保有し、Rails Foundationの創設者兼議長であり、彼の政治的信条にもかかわらず、Ruby Centralのような組織や、カンファレンスやポッドキャストなどのコミュニティから引き続き発言の場を与えられている。
- Ruby Centralへの不信感: Ruby Centralは、明確な事前通知やコミュニケーションなしに、RubyGems.orgのGitHubコードベースの管理権を強制的に引き継ぎ、全てのメンテナーのアクセスを取り消した。この不透明な行為により、コミュニティからの信頼を失っている。
- 企業の影響力: Railsの運営はShopifyからの資金に大きく依存しており、DHHやShopifyのCEOであるTobi Lütkeのような、右派の思想を持つ人物にコミュニティの方向性が左右されている。
- 行動規範の機能不全: RubyおよびRailsの行動規範は「寛容のパラドックス」に陥っており、憎悪に満ちた言説を排除できない構造になっている。
■ 3. 解決策と今後の展望
- 民主的な組織への移行: 企業スポンサーに依存するのではなく、コミュニティが主導する民主的な組織を設立することを提案している。この組織は、公開されたメンバーシップと民主的に選出されたリーダーシップを持ち、RubyGemsやRailsといった重要なプロジェクトを管理する。
- フォークの可能性: DHHがRailsの著作権を保有しており、自ら辞任する可能性が低いことから、RailsやRubyGemsのコミュニティ・フォーク(分岐)が必要になる可能性がある。
- 行動の呼びかけ: コミュニティは現状に甘んじるべきではないと主張している。DHHやRuby Centralに反発してコミュニティを去ったメンテナーたちが、新しいガバナンスの下で復帰することを呼びかけている。
言い訳しているひとは、自分が言い訳していると知っているし、自分を虚飾しているひとは自分が虚飾していると知っている。心の表層では気づいていないけれど、深層では知っている。だから、ストレスがかかり、メンタルが病んでいく。
心の深層は自分ではみえない。だけど、徴候は現れる。人に会いたくなくなったり、何かを喋る時に口角がひきつる。話している相手が不自然に沈黙する。酒が欲しくなる。そうした徴候をとらえて、あれ、オレ、なにか誤魔化してないか、と探ることはできる。
■ 1. 非同期処理を採用する動機
- 領域をまたぐ処理: 異なるビジネス領域(例: 注文、配達)間の連携において、サービス同士を疎結合にするために非同期処理を採用している。これにより、一部の領域の障害が他の領域に波及するカスケード障害を防いでいる。
- 同期処理のミニマル化: クライアントアプリからのAPI呼び出しなど、高速なレスポンスが求められる処理において、同期処理を最小限に抑えている。これにより、APIのレイテンシを低く保ち、ユーザー体験を向上させている。
■ 2. 非同期処理の具体的な実装例
- ピック・パックの例: ピッキングAPIではピックのみを同期的に行い、パック予定への追加は非同期に実行している。これにより、APIの応答速度を維持している。この設計には、「ピックができたら必ずパック予定に追加できる」といった前提条件の確認と、結果整合性が許容される業務手順の確立が必要である。
- データ集計の例: 都度クエリによる集計が難しい場合、イベント駆動型の非同期処理でデータを事前に集計している。これにより、単一プロセス内での処理に起因する競合やサーバ停止時の処理漏れを防ぎ、確実に処理を実行できるようになった。
■ 3. 技術スタックとアーキテクチャ
- 技術要素: Firestore、Eventarc、Cloud Runを組み合わせて非同期処理を実現している。
- 処理の流れ:
- (1) Firestoreにドキュメントを書き込む。このドキュメントはイミュータブル(不変)な非同期メッセージとして扱われ、イベント発生日時や一意の識別子を含む。
- (2) EventarcがFirestoreの書き込みをトリガーとしてメッセージを検知し、Cloud Pub/Subにプッシュする。
- (3) Cloud Pub/SubのSubscriptionが、メッセージをCloudEventsの形式でCloud RunにHTTPリクエストとして送信する。
- (4) Cloud Run上で、メッセージを受信したイベントハンドラが後続の処理を実行する。
- 実装の工夫:
- サブスクライバー側: メッセージの重複処理を防ぐための排他制御や、メッセージの順序を正しく処理するためのユーティリティライブラリを用意している。
- 参考パターン: アウトボックスパターンを参考にしている。FirestoreとEventarcの組み合わせが、データベースをポーリングするよりも運用が容易であることを評価している。
■ 4. 非同期処理導入のステップ
- ステップ1: gRPCリクエストハンドラ内で、イベントハンドラをプログラム上で同期的に実行する。
- ステップ2: gRPCリクエストハンドラ内で、イベントハンドラをプログラム上で非同期的に実行する。この段階で本番環境と同等のメッセージ流量を検証し、フィーチャーフラグを用いてステップ3への切り替え準備を行う。
- ステップ3: gRPCリクエストハンドラ内ではイベントの永続化のみを行い、イベントハンドラの実行は別プロセス(Cloud Run)に完全に移管する。これにより、システム全体が非同期処理となる。
20代の数年間SIで働いた。1年以上前に退職して今は別業界にいる。
今日、Evernoteを整理していたら「退職理由、SIの嫌な点」というメモが発掘された。退職直前のかなりストレスがたまっていた時期に書き殴った文章だった。学生の頃の私は絵を書いたりしていて、ものづくりで暮らしたいな〜などと思って始めたプログラミングが楽しかったので安易に受託開発業を選んでしまったが、その後悔が如実に表れていた。
一部自分でも覚えていない話もあったがコンテンツとしては面白かったし、今でもシステムインテグレーター業界で消耗する若者を減らしたいとは思うので公開してみる。
以下、同メモに加筆・修正したものなのでファンタジーだと思って読んでくれ。
■ 工数至上主義
受注した時点で売上がおよそ確定するので、後はその予定工数に収めて納品できれば御の字という考え方。よくある話だが、見積がおかしくても顧客と対等な関係が築けていないから追加請求もできない。時間(工数)をかければ良い成果物ができるかもしれないがそれを説明して顧客に嫌な顔をされたくないから、限られた工数の中での最善を尽くす。最善を尽くす、聞こえは良いが要は手を抜く。
つまり、どう頑張っても売上は同じなのだから、良いもの・価値を生むものを作ろうと考えない人が多い。社内で開発者と呼ばれる人間もそうだし、マネジメント層はそういうものづくり志向を持った人をリスク扱いすることもある。
これが諸問題の根源で、いかに述べるような組織・プロジェクトが出来上がっていく。
■■ 作業効率化しない
マニュアル作業の正確さをかたくなに信じてる人だらけで、ITとは何なんだと考えさせられる。
私は定型作業を効率化しようとjsやrubyでスクリプトを書いたりしていた。テストデータを開発用DBに突っ込んだり、テキスト処理して整形したり、Excelからコード生成したりするよくあるやつ。
あるとき上司に肩越しに自分の作業を覗かれて「何やってるの?」と聞かれ、そういうスクリプトを作ってると答えたら、工数とリスクの話をされた。曰く「そのスクリプト作るのに何日かかるの?工数に乗ってないよね?」「スクリプトのテストもちゃんとしないと結果が正しいって保証できなくない?」と。この時はイラッとして「30分でできる数十行のスクリプトだし自分の作業工数内で完結する。むしろ後工程や別の人でも同じことを再現性できて楽になる」とか真面目に説明してプログラムも見せたが、読もうとはせず(読めないので)1時間無駄にした。
■■ 技術力いらない
前述したようなビジネスモデルだから、営業力と、予定工数で無難にプロジェクトを終えるマネジメント力が大事。IT企業だが開発者は自社で持たない。不況の時に待機コストが発生するリスクがあるし、自社で抱えるより単価の安い開発者が人材派遣系の企業や下請けにいっぱいいるから。
社長があるとき社内広報で「技術は買うものだ」と言っていた。文脈で明らかに技術=技術者のことだったので、使い捨ての人売り業と揶揄されていることへの自覚が無いと思う。
そういう人が集まっているor残っている組織なので開発者はほとんどいない。20〜30人ぐらいの課に1人ぐらいの割合でstaticおじさんがちらほらいるぐらい。大体20代からプロジェクトリーダーという立場をやり始め、だんだん大型の案件を扱えるようになっていき、後は出世ゲーム。部長のお気に入りが課長になり、部門長のお気に入りが部長になる。その繰り返し。
開発案件でのBP(ビジネスパートナー、委託先、派遣、下請け)比率は自分の周りだと1:5ぐらいが多い。プロパー社員一人が5人の開発を仕切る、みたいな形。案件規模によりだいぶ差があると思う。この比率が高い=マネジメント力のある組織と考える会社はこの数字を上げようと必死で、比率の低い組織は評価が下がる。
私は開発が好きだったのでエンジニアとして生きていきたい、というようなことを評価面談の度に伝えているが、その度に会社の目指す方向を説かれてモチベーションが下がる。
■■ 意識の低い開発者メンバー
上述の通り、案件で接する開発者は基本的に社外の人間なのだが、彼らの技術力と意識の高さにはものすごいばらつきがある。言われたものはなんでもこなせる人、何でこの歳まで技術者やれてるんだと疑う人、このプロジェクトはおかしいと良い意味で騒ぐ人、何も意見を言わない人、CっぽくJavaを書く人、人当たりは良いが技術力がいまいちな人、すぐ休む人、バグやミスを隠す人…etc。
まぁ色んな人がいるのはどの業界のどの職種も同じだが問題は質だ。私の主観になるが本当にエンジニアとして尊敬できるレベルの人は1%いるかいないか。というのも、ほとんどの技術者は長年SIやその周辺企業と付き合ってきているので同じ体質に染まっているのだ。顧客が良いといえば良いという態度(この場合の顧客は私が所属する企業)、請負の場合は工数を超えない範囲で手を抜く姿勢、その他諸々。技術力だけをひたすら磨き続けてきたという人はごく一部だけだったし、そんな人でもGitHubアカウント持ってない・ブログやってない・OSSに貢献したことない、といった具合でクローズドな世界で生きている。
そうした技術者とやっていく中で最も厄介なのが教育コストだ。案件のあるなしで人が都度入れ替わり、新しい人が来るたびに同じシステム・技術要素の説明をして何とかやる気が出るようモチベートして、というのを繰り返すのに疲れた。私の会社固有の変なルールの説明はてきとうにしておいて、私は技術が好きな仲間が欲しかったので今のシステムの課題と技術面での改善や展望をよく話す。が、あまり食いつかれることはない。これは私の問題だが、そうした期待と落胆のループも疲弊の一因だ。
■■ static BP
ある時、一つの課に6年近くいるというBPと一緒に仕事をする機会があった。その課にはプロパーの技術者が長いことおらず、彼がその課の技術的中心を担っているという話だった。抜けられると途端に色んなものが崩壊するからという理由で、その人の派遣元にはかなり高額の単価を支払っていたと聞いた。課員が口をそろえて「あの人はすごい」「何でもできる」というので初めはかなり期待していた。
だが、拍子抜けした。あまりにも仕事が雑なのだ。コミットされたコードはTODOコメントだらけだし、バグがあまりにも多かった。一度も実行されずにコミットされ、他の人がチェックアウトした時点で判明したバグなんかもあった。それでも声が大きく、プロパーが技術を知らないのをいいことに自分のブランディングに完全に成功していた。客先にも顔を出し、信頼を得ているらしかった。「自分は設計が得意でテスト以降の工程には興味が無い」と言っていた。確かに彼が関わった各システムには独特の概念が埋め込まれた設計があったが、その複雑な設計は保守性が低く、他の開発者が触ると容易にバグを引き起こしていた。
また、彼はJavaの有名なフレームワークであるStrutsを拡張したいわゆるオレオレフレームワークを開発しており、それの出来は悪くなかったと思う。そのフレームワークに欠けているものをうまく補うような形になっていた。だがフレームワークのバージョンを上げると壊れるというのが残念な点で負債になりかけていた。
私は異動したが、彼は今でもそこにいると聞いた。
■ 技術の話
■■ テストコード書けない
(最低限のものしか作らないから)安くて早い!という触れ込みで売っているので、テストの工数が異常に少ないことも多い。特にテストコードを書くなんてもってのほか。そういう世界でやってきた人ばかりなので、30や40超えたマネジメント側は「テストコードって何?」状態だ。大型の改修案件が来た時にはコア機能だけでもテストを書いていこうと見積段階から社内で提案したが「顧客に『そんなメリットあるなら何で今までのプロジェクトではやってないの?』って問われるから、絶対言うなよ」と拒否された。
保守案件をやっていた頃、時間を捻出してコソコソとテストコードを書いたりしていた。その案件を離れてしばらく後、ある時リポジトリを覗いたら私が書いたテストコードがばっさり消えていて驚いた。コミットログから課内のstaticおじさん的な人が消したとわかったが、そのコミットコメントが「現在使用していないコードを削除」だった。これはもう問う気も失せて何も言えなかった。
■■ リファクタできない
先述したようにテストがそもそもないプロジェクトが基本なのでリファクタできないのだが、たとえテストがあったとしても勝手なリファクタは許されない。ソースコードは顧客の持ち物なので同意なしに改変することはいわば契約違反なのだ。たとえ内的品質が向上してコスト削減に繋がるとしても、そのためにお金を支払う顧客はまずいない。
■■ レビューない
私がいたどの案件にもコードレビューがなかった。リーダーと開発者数人という構成の場合、まず開発者は全員下請けでリーダーは技術の心得がない場合が多い。そうなると彼らの成果物の良し悪しを図るのは目に見えるシステムの挙動と実施されたテスト結果のExcel報告書だけになる。これが非常に非効率で、少しコードを読めばわかる明らかなバグや仕様理解の齟齬が頻発していた。特に受入試験と呼ばれるリリース直前の顧客側での最終確認や本番稼働中におけるhotfixは全機能をきちんとテストせずにデプロイされることが多く、そのhotfixがさらなるバグを引き起こしたりもしていた。
そもそもテストを書けという話だがテストが無いプロジェクトに足すのはかなり大変なので、レビューサイクルをきちんと回すだけでもかなり変わる。実際、私が入った案件ではすべてのコミットに目を通すようにし、明らかな問題は都度指摘することで品質の向上に繋がった。欲を言えば他の開発者にもレビューしてもらいたいが、下請けの彼らの工数を増やすことは嫌がられる。
■■ 新規技術試せない
無難にプロジェクトをこなすことと新しい技術を試すことの両立こそ技術者の腕の見せどころだと思っているが、ほとんどの場合それは許されなかった。新規にせよ継続にせよ案件を受注する段階で営業やマネジメント層と顧客間で「今回は過去に実績のあるこの技術でやります」という契約が結ばれているからだ。その技術(言語やフレームワーク)がいかに古く、保守性も将来性もないものだとしても受注できればよいし、その技術のサポート切れか何かの拍子で再度リプレイス案件でも受注できればさらにラッキーぐらいの考えでいる。
常に横に倣えのアーキテクチャは私にとって面白くはなかった。
■■ 横に倣え
また横に倣えが加速してさらに悪い事に、同じアーキテクチャ・ネットワークを再利用するために既存のサーバに新システムも相乗りすればよいという発想も珍しくない。「資産の再利用によりコスト削減」という触れ込みだったが、ただでさえスケールしない低スペックのオンプレミスサーバ上で複数のアプリケーションサーバを運用した結果、予想通り耐障害性が下がった。
また、Oracleのライセンスが高いという理由で一つのDBインスタンス上に10数個のシステムが同時稼働しているなんてこともあった。1つのシステムが高負荷なクエリを投げたせいで関連する全システムが共倒れになったこともあったがOracleのバグとして報告していた。
■■ static Perlおじさん
新人の頃にOJTでstaticおじさんの下に付いたことがあった。そのとき担当したのはPerlでデータ連携用のバッチを書くという開発業務だったのだが、最悪の思い出だ。
まずプログラム構造仕様書というのを書かされた。メソッド単位でのモジュールを全てExcel上に記述し、処理の順番と内容を説明するという謎資料だった。あまりに意味がわからなかったので「UMLのクラス図を書けばよいのですか?」と聞いたら「Perlにクラスなんて必要ない。構造化プログラミングを研修でならってないのか」と返ってきた。「俺が前に書いたPerlのバッチがあるから参考にしろ」と言われ、あるリポジトリをチェックアウトして見てみると1ファイル4,000行の.plがいくつか並んでいた。その時の私は何もわかっていなかったのでそういうものかと思ってしまったが後で調べて明らかにおかしいと気づいた。
また、そのプロジェクトのメイン言語はJavaで、Eclipseを使っていたのでPerl用プラグインを入れてコーディング・デバッグをしていたらやめろと言われた。理由は「Eclipse上で動くPerlが信用できない。サクラエディタで書いてプリントデバッグすれば充分だ」と言われた。その時の私は何もわかっていなかったので、プラグインの品質が悪いとかそういう話かと思い「じゃあvimで書きます」と言ったら「サクラエディタにしろと言っただろ!」と一喝され、vim vs サクラエディタという史上類を見ないエディタ論争が起きた。
■ 待遇・制度
■■ 給与
SI業界の中では高いのかもしれないが決してよくはない。4年目(たぶん25歳)ぐらいで残業込みで年収400万にやっと届いたがそこからほとんど変わっていない。30歳の先輩に聞いたところ「500万前後、残業してない場合の月の手取りは未だに20万切ることがある。残業抜きでは新婚生活が厳しい」と言っていた。いわゆる年功序列がきっちりしていてこのまま続けてもしばらくは給与が伸びないということがわかった。
個人での貢献で差がつくのは±10万程度。その程度ならいっそ無くてもいいのでは、と思う。というかそもそも生産性をきちんと評価する制度が存在しない。これはどの組織でも難しい問題だと思うが、形骸化した評価制度で上司の気に入った人間にS評価を付けているだけならいっそ止めたほうが時間の無駄にならなくてよい。
■■ マシン
会社から貸与されるノートPCは低スペックすぎて開発には使い物にならない。なので開発者は基本的にデスクトップを使用せざるを得ないのだがこれもメモリ4G、1.2GHz程度で大したマシンでもない。本当に開発する気がない。
■ 組織の問題
■■ とにかくクローズドな組織
いつの間にかどこかで意思決定がされていて、関与する機会がほとんどない。だがほとんどの社員がそれで良いと思ってる。失敗しても自分が決めたことじゃないから上層の責任だ、そう言えるので楽だから。
情報共有をしない、というか意図的にしないようにしているとまで感じる。連絡はメールと添付ファイルベースで行っているし、共有のファイルサーバなんてのもあったが一部のフォルダは権限を持った人間しか見られない。何で他の部や課が行った過去の見積や提案資料が自由に見られないんだよ。
ソースコードのリポジトリも同様。外部に公開しないのはまだわかるが、プロジェクト外にすら基本は公開していない。別に奪われて困る大した技術もない。
会社が用意した提案資料共有サイトみたいなのもあったが、それに至ってはもっとひどい。課長以上もしくは部長から承認を与えられた者のみ閲覧可能。共有とは。
■■ 意思決定の遅さ
どうでもいいことを決めるにも承認や根回しや説得が必要になる。それがプロジェクトの利害関係者ならまだわかるものの、まったく関わっていない上長(課長や部長、時には部門長)を通さないと進まないという異常さ。
■■ コスト削減
利益率向上のためにコスト削減ということがしきりに言われており、過剰なコスト削減対応が生産性の低下を招いている。たとえば顧客に見せる資料以外は白黒で印刷しろ、みたいなルール。色がないために情報が伝わりにくい。というかそもそも印刷せずに各自のノートPCで見ろという話だが、先述したようにノートPCは低スペックすぎるので多くの社員がデスクトップを使っている。ITとは。
本当に無駄としか思えない承認・申請フローの煩雑さに加え、使っているシステムの使い勝手も悪く、ひどい日は一日がそうした事務作業で終わる。しかもそのシステムは自社で以前開発したものだというから泣けてくる。こんな作業が定常的に発生するのでいっそ事務員を派遣で雇うべきという提案が何度もされたが、課の予算をオーバーするから無理だという回答しか返ってこない。
■■ 残業削減
表向きは社員の健康促進という触れ込みで残業時間削減を全社的に取り組んでいる。残業減らせと声をかけただけでは誰も帰らないので、勤怠システムと入退館管理システムを監視し、削減できていない組織や人間の評価を下げるようになった。
その結果、サービス残業が復活した。30時間を超えると部長に説明しないといけない、50時間を超えるとその上へ…みたいなループ。表向きの残業時間削減・コスト削減としては成功したかもしれないが、社員の残業時間を管理するとかいう無駄な仕事を増やしたし、管理される社員のストレスとサービス残業に繋がったので下策だと思う。
他人の残業時間をExcelにまとめる仕事があって、そこに給与が発生してると思うと泣きたい。
そもそも無駄な作業や工数至上主義で作業効率が悪いから残業しているので、残業が少ない奴が偉いと一斉に舵取りしただけでは生産性をちゃんと評価できていないことに変わりはない。一昔前の残業多い奴は頑張ってて偉い、というのと本質レベルで何も変わっていない。
■ 辞め方
- このメモを端折って伝える
- このメモを公開して炎上する
■ 1. FrostDBとは何か
- 概要: Goで書かれたオープンソースの列指向データベースである。
- ユースケース: 観測可能性(Observability)、セキュリティ、およびアプリケーションのデータ分析のために設計されている。
■ 2. 主な特徴
- 高速性: 実行時に最適化された並列クエリ実行エンジンと、高度なベクトル化されたクエリ処理により、非常に高速なクエリ応答を実現している。
- データ形式: Apache Arrowインメモリ形式でデータを管理し、他のシステムとの統合が容易である。
- スケーラビリティ: 水平方向へのスケーリングが可能で、大規模なデータセットや高スループットの取り込みをサポートしている。
- 圧縮: Zstdによる高度なデータ圧縮を行い、ストレージコストを削減している。
- 効率性: ストレージからの読み込みを最小限に抑え、クエリの実行効率を最大化している。
■ 3. 用途と利点
- リアルタイム分析: 観測可能性データ(メトリクス、ログ、トレース)やセキュリティイベントのストリーミング分析に適している。
- コスト削減: 高いデータ圧縮率と効率的なクエリ実行により、インフラコストを大幅に削減できる。
- オープンソース: Apache ArrowやApache Parquetなどのオープンソースエコシステムと連携しており、拡張性やカスタマイズ性が高い。
- 開発言語: Goで開発されており、パフォーマンスと安全性の両方を確保している。
■ 4. プロジェクトの現状と展望
- プレリリース段階: 現在はまだプレリリース版であり、本番環境での利用は推奨されていない。
- 今後の開発: 開発チームは、より多くのユーザーシナリオに対応するための機能追加やパフォーマンスの最適化に取り組んでいる。
あるある会話
PM「顧客からこういう要望が来たのですが、技術的にできますか?」
エンジニア「できると思いますが、開発が必要ですね。」
PM「工数見積ってください。」
エンジニア「見積る前にその機能で顧客が本当に何をしたいか確認したいです」
PM「顧客折衝は私の仕事です」
エンジニア「は?」
続き
PM「一応顧客に聞いてみます(まあ見積出す時に言お)。まず工数と費用出してください」
エンジニア「見積りました」
PM「この機能を既存WBSに入れることってできますか?人増やせばいけますか?それとも後で追加した方がいいですか?」
エンジニア「(なんでこっちでばっかり対応せなあかんねん)」
PMがエンジニアリング分からないと起きる事。例えば他部署から「これ技術的に出来ますか?」と質問された時に自分では判断できないため「持ち帰って検討します!」もしくは「毎回エンジニアを同伴させる」という事になりますね。これでも回りますが、リーダーシップという点で少し頼りないですよね
■ 1. AI時代のドキュメントのあり方
- アジャイルとドキュメント: アジャイルソフトウェア開発では、ドキュメントより対話や変化への対応が重視されてきた。しかし、AI時代には、AIとの対話や協調、変化への対応をスムーズに進めるための「意味のあるドキュメント」が必要不可欠となる。
- ドキュメントの役割:
- 対話のスケール: 意思決定の「なぜ」と「何」を記録し、継続的・正確な対話を可能にする。
- 知識の共有: 人間とAIが共有できる「知識の種」となる。
- 変化の適応: 過去の履歴を「足跡」として残し、それを基に未来の更新や提案を行う。
■ 2. 従来のドキュメントの悩みとAIによる解決
- 一般的な悩み:
- 「探せない」「バラバラ」: 情報が分散し、必要な情報を見つけられない。
- 「読まれない」「残らない」「更新されない」: ドキュメントが活用されない。
- 「時間がかかる」: ドキュメント作成に手間がかかる。
- AIによる解決:
- 探す・まとめる: AIが文書内を検索・要約し、情報を探してくれる。
- 書く: AIとの共作により、ドキュメント作成の時間を大幅に短縮できる。
- 残す・更新する: AIへの指示が必要となるため、人間が主導権を握る必要がある。
■ 3. 「ADR(Any Decision Record)」の導入
- 課題解決: 従来のADR(Architecture Decision Record)は、アーキテクチャ以外の意思決定を記録しにくい、粒度が不明瞭、組織に定着しにくいといった課題があった。
- 「全部残す」文化: Dress Code株式会社では、これらの課題を解決するため「ADR(Any Decision Record)」という考え方を採用している。
- 記録対象: どんな小さな意思決定もドキュメントとして記録する。
- ツール: Notionをドキュメントツールとして利用し、Notion AIを活用している。
- 文化の定着: ドキュメントを書くためのきっかけ作りとして、毎週の書き溜めやSlackでのスタンプによるストック、フィードバックの共有会などを設けている。
- メリット:
- 検索性向上: 「Notion AI」が代わりに見つけてくれるようになる。
- 粒度の問題解消: 領域や大小に関わらず記録するため、粒度に悩まなくなる。
- オンボーディングの効率化: 新入社員が「Notion AI」に質問することで、過去の意思決定の経緯を簡単に把握できる。
■ 4. 今後の改善点
- 更新されない問題: 最終更新日や編集者の表示は行っているが、依然としてドキュメントが更新されないという課題は残っている。
- 仕様記載の場所: 仕様をADRに含めるか、PBI(product backlog item)に記載するかという判断に迷いが生じることがある。現状は、ADRを書いてPBIにリンクさせている。
- 作成者への感謝: ドキュメントを作成した人への感謝を表現する文化をさらに醸成する必要がある。
■ 1. 身銭を切るとは何か
- 定義: 失敗した場合に相応のペナルティを支払う覚悟を持つことである。
- 具体的内容: 給料やクビといった金銭的、物質的損失ではなく、自身の評判、プライド、チームからの信頼、時間、精神的なストレスなど、目に見えない資産を賭けて仕事に臨むことである。
- プロフェッショナリズム: プロフェッショナルとは、仕事の結果に責任を持ち、「言われた通りに作っただけ」という言い訳を使わない姿勢のことである。
■ 2. エンジニアが身銭を切らない理由
- 「心理的安全性」の誤解: 「率直な意見を言える環境」が「失敗しても責められない環境」と誤って解釈されている。これにより、失敗を恐れず、責任を回避する文化が生まれている。
- キャリアの流動性: 転職市場が活発なため、プロジェクトの失敗や技術的負債を「次の会社に移ればリセットできる」という考え方が広まっている。
- 「技術的に正しい」という隠れ蓑: ユーザーにとって価値がない結果でも、「技術的には正しい」という言葉を盾にして責任を回避する傾向がある。
- 集団責任という幻想: 「チーム全体で責任を持つ」という理念が、「誰も責任を持たない」ための言い訳として変質している。
■ 3. 身銭を切ることの代償
- リスクの非対称性: 成功すれば評価されるが、失敗しても大きなペナルティがない。エンジニアにとっては「学習機会」でも、ユーザーにとっては「不便」でしかない。
- 同じ失敗の繰り返し: 痛みを伴わない失敗は他人事として処理され、そこから学びが得られない。
■ 4. 身銭を切ることのメリット
- 意思決定の質向上: 自分が責任を負う覚悟があれば、安易な技術選定や適当な設計は避けるようになる。
- 学習曲線の急上昇: 失敗から来る痛みは、深い学びにつながり、知識が実践で使えるものになる。
- プロフェッショナルとしての承認: 結果に責任を持つことで、単なる「作業者」から真の「エンジニア」として認められる。
- 本物の自信: 身銭を切って成功・失敗を経験することで、揺るぎない自信が身につく。
■ 5. 組織における身銭の力
- 少数決原理: 組織の重要な意思決定は、最も失うものが大きい人、つまり最も身銭を切っている人の意見が採用される原理に基づいている。
- 信頼の獲得: 日頃から責任を負う姿勢を見せることで信頼を獲得し、その発言に重みが生まれる。身銭を切る個人の必死さが、組織全体の方向性を決定する。
技術の変化が加速し組織やツールが多様化する今、最適なアーキテクチャをどう描くか。
アーキテクチャは、プロダクトの特性やチームのあり方によって最適解が異なり、普遍的な正解は存在しません。 トレンドを追うだけでは不十分で、設計に込めた意図を自らの文脈で捉えて継続的に見直していくことが求められます。
本カンファレンスでは、アーキテクチャの構想・判断・構築にまつわるリアルな知見を共有し、多角的な視点から設計判断への理解を深めます。自社にとって最適な構成を考えるための視点とヒントを、実践につながるかたちで持ち帰っていただける場を目指します。
■ 1. オーナーシップを持てない原因
- 越境の困難さ:
- アンチパターン: ソフトウェアエンジニアが、プロダクトの仕様やビジネス上の解決策に対して意見を言いにくい構造が存在する。
- ベンダー(外部委託): 産業構造上、発注者の要求をそのまま受け入れるインセンティブが強く、より良い解決策を提案する動機が薄い。
- 内製:
- 「仕様の実現が仕事」という誤った認識を持つ組織がある。
- 「余計な仕事をさせたくない」という善意や、「相手の考えをひっくり返すのは悪い」という過剰な遠慮が、議論の妨げになっている。
- 注意: そもそもエンジニア自身がオーナーシップを持ちたくない場合は、議論の対象外である。
■ 2. オーナーシップのレベル分け
- 3つの段階: オーナーシップには以下の3つのレベルが存在する。
- システムに対するオーナーシップ: 障害対応や他者の問題解決など、明確に任されていないシステムの部分にも積極的に関わること。
- プロダクトに対するオーナーシップ: ユーザー課題を解決するため、仕様に対してより良い提案をすること。
- ビジネスに対するオーナーシップ: プロジェクトの制約(コスト、人員、納期など)を考慮し、現実的な解決策を提案すること。
■ 3. オーナーシップ獲得のステップ
- 段階的なアプローチ:
- まず、獲得しやすいシステムに対するオーナーシップから始めるべきである。
- システムに対する積極的な関わりは、周囲(非エンジニア)からの信頼獲得につながる。
- この信頼を基盤として、プロダクトやビジネスへの口出し・手出しが可能になり、より高いレベルのオーナーシップを持つことができる。
■ 4. 組織と個人の対応
- 硬直した組織: 非常に硬直した組織では、このアプローチが通用しない場合もある。その場合は、無理に立ち向かわず、別の場所で経験を積むことも一つの選択肢である。
- 個人のマインド: 本人も周囲もオーナーシップを望んでいるにもかかわらず持てない場合は、越境を阻む構造を認識し、段階的に行動を起こすことが解決策となる。
■ 1. 既存ツールの課題
- Goの標準ツール: Go言語には、コードの抽象構文木(AST)を解析し、整形するツールが備わっている。
ast.Walk()とVisitorを使うことで、ASTのノードを走査・変更できる。- ツールの限界:
ast.Walk()は、既存ノードの内容やサブノードの変更は可能だが、ノード自体を別のノードに置き換えることはできない。これは、ある種の式を別の種類の式に書き換える場合などに必要となる。■ 2. gorewriteの機能と利点
- 解決策: 「gorewrite」は、この問題を解決するために開発されたツールである。
- 主要機能:
ast.Walk()と似ているが、Rewriterという機能拡張されたVisitorを使用する。このRewriterは、修正したast.Nodeを返すことが可能である。- 利点: 既存のノードを別のノードに置き換えることができ、コードの書き換えをより柔軟に行うことができる。利用者は
ast.Walk()の代わりにRewrite()を呼び出すだけでよい。
■ 1. EMの役割を巡る議論
- 問題の背景: エンジニアリングマネージャー(EM)の役割は多岐にわたり、「コードを書くべきか」「書くべきでないか」など、人によって意見が大きく異なる。
- 役割の変化: EMが担う役割は、チームの状況、個人の得意分野、組織でのEMの定義などによって変化する。
■ 2. マネジメント領域の分解
- 4つのマネジメント領域: 一般的に、EMの役割は以下の4つに分解される。
- プロダクトマネジメント: プロダクトの方向性を定める。
- プロジェクトマネジメント: スケジュールやタスクを管理する。
- ピープルマネジメント: メンバーの育成や評価を行う。
- テクニカルマネジメント: 技術的な意思決定や課題解決を行う。
- 役割の委任: EMはこれらの領域すべてをカバーするが、特定の得意分野を持つメンバーに一部のマネジメントを任せることがある。
■ 3. EMの6つの役割パターン
筆者は、EMの具体的な動き方として以下の6つのパターンに整理している。
- Development Project Manager:
- 特徴: プロジェクト型開発において、機能リリースとスケジュール管理に重きを置く。
- 比重: プロジェクトマネジメントの色が濃い。
- Mini-CTO:
- 特徴: 経営レベルで技術戦略や組織の未来に関する意思決定を行う。
- 比重: 現場の細かい進行には関わらず、事業実現のための技術的な意思決定を推進する。
- Technical Team Lead:
- 特徴: テックリードに近い役割で、技術的な意思決定やリードを行う。
- 比重: テクニカルマネジメントに重点を置く。プロジェクト管理はチーム全体で分担する。
- Cross-Organization:
- 特徴: チーム横断的な技術課題や連携の問題を解決する。
- 比重: 大規模な組織で機能不全を防ぐために必要な役割である。Technical Program Managerもこのパターンに属する。
- Product Owner:
- 特徴: 技術的要素が強いプロダクトにおいて、プロダクトオーナーとして技術と事業価値のバランスを取りながら意思決定を行う。
- 比重: 技術的知見が不可欠なプロダクトマネジメントを担う。
- Organization Development / Organizational Designer:
- 特徴: 組織開発や組織設計、エンジニア固有の採用・人事施策を担当する。
- 比重: ピープルマネジメントを広く深く行う。
■ 4. パターンの傾向とまとめ
- 傾向:
- 上段(Development Project Manager, Technical Team Lead, Product Owner): チーム内に軸足を置き、チームと共に活動することが多い。
- 下段(Mini-CTO, Cross-Organization, Organizational Designer): チーム外に軸足を置き、自律的なチームに大部分の実行を委譲する。
- 活用の意義:
- EMの役割は多岐にわたるため、認識のズレや期待のズレが生じやすい。
- これらのパターンを理解することで、自身のチームのEMがどの役割を担っているかを明確にし、期待のズレを減らすことができる。
- 結論: EMはどのような関わり方であってもエンジニアリング領域の責任を期待されている。
■ 1. イベントストーミングの基礎
- 目的: イベントを起点として、ビジネスプロセスやシステムのモデリングを行う手法である。
- 構成要素:
- アクター: コマンドを実行する主体である。
- コマンド: 何らかのアクションを実行する意図や要求である。
- 集約: コマンドを処理するオブジェクトである。
- イベント: ビジネス上で発生した重要な出来事や事実である。
- リードモデル: データの読み取りに最適化されたデータ構造やビューである。
- ポリシー: 自動化された判断ロジックであり、nrs流では条件を空欄にして「必ず」を意味させる。
- 外部システム: 対象システムの境界外にあるシステムである。
- ルール:
- 付箋は特定の付箋からしか繋げられない。
- 複数のイベントは結果の分岐や並列に起きる出来事を表す。
- 実践方法:
- ワーキングセッション: メンバー全員が理解した上で取り組む。一気に進むが、経験がないと難しく、長時間かかる。
- ヒアリング: ファシリテーターがヒアリングを進める。短時間でまとまりやすいが、ファシリテーターの技量に依存する。
■ 2. イベントストーミング図からコードへの変換
- 変換の前提: 今回のセッションでは、イベントストーミング図をトランザクションスクリプト、ドメインオブジェクト、複合パターン、バッチ処理といったコードに変換する。
- 単純な処理: アクターからコマンドが投げられ、リードモデルに繋がるパターンは、コントローラーとアプリケーションサービスで実装する。
- ポリシーが絡む処理: コマンドの実行中に条件分岐が発生する場合(例:写真が同時にアップロードされた場合)、アプリケーションサービス内でポリシーとして実装する。
- 外部システムとイベントの分岐: 決済処理のように外部システムとの連携と、その結果(成功/失敗)によってイベントが分岐するパターンは、アプリケーションサービス内で外部サービスを呼び出し、結果に応じて異なる処理を行う。
- バッチ処理: 一括で大量のデータを処理するバッチ処理も、イベントストーミングのパターンとして表現できる。
■ 3. イベントストーミング図の活用と注意点
- 図の目的: 図はすべての情報を表現することが目的ではなく、実装に役立つドキュメントとして活用すべきである。
- 図の種類:
- ビジネスプロセスモデリング: ビジネスの流れを可視化する。
- システムモデリング: より実装に即した設計を行う。
- コードとの一致: 図とコードを完全に一致させたい場合は、イベントソーシングのような手法を適用する必要がある。
■ 1. 問題提起
- 「技術的には可能」問題: 実際には多くの問題(影響範囲、品質、コスト、スケジュール)があり、「できない」と心の中で考えているにもかかわらず、表面上は「技術的には可能」と答えてしまう問題である。
- このような回答は、曖昧さから相手に不評を買う原因となる。
■ 2. 解決策:「できる」と「やる」の分離
- 責任の明確化:
- 「できる」: 技術的な可否は回答者(自分)の責任である。
- 「やる」: 実行の決定は相手の責任である。
- 伝え方: 「できますが、〇〇が必要です。やりますか?」という形で、技術的な可否と、それに伴う条件(スケジュール変更、コスト増加など)を一息に伝える。
- 前提条件: このコミュニケーションを可能にするためには、腹を割って話せる信頼関係が不可欠である。それが築けないプロジェクトは成功が難しいと判断している。
■ 3. 「じゃあ見積もって」への対処
- 本気度の確認: 見積もりはプロジェクトの中心メンバーに負担をかけるため、安易に引き受けず、相手の本気度を確認すべきである。
- 顧客への伝え方:
- 原則: 「お金がかかってもやるなら見積もります」という姿勢を伝える。
- 具体的提案:
- 金額で示す: 「最低でも〇〇人月かかりますが、それでもやるべきかご判断いただけますか?」
- 金額以外で示す: 「1か月リリース延期が必要かもしれません」といった形で、影響範囲を伝える。これにより、相手は金額を直接聞かなくても判断できる。
■ 4. まとめ
- 重要なのは、「できる」ことと「やる」ことを明確に分離し、それぞれに責任を持たせることである。
- 見積もりの依頼に対しても、相手の本気度や重要度を確認し、プロジェクトのリスクを避けるべきである。
■ 1. プログラミング言語構文と自然言語
- 問題提起: プログラミング言語の構文はしばしば自然言語(特に英語)に似せられるが、これは必ずしも合理的な設計ではない。
- 暗黙の仮定: 「自然言語のように読める構文が良い構文である」という暗黙の仮定が存在するが、この妥当性を考察する必要がある。
■ 2. 構文の合理性を測る基準
- import文の語順:
- 論点:
import以外のキーワードで始まる構文は不便か。- 例: Pythonの
from ... import ...や、Haskellのimport qualified ...の語順は、慣れていないと不便に感じられることがある。- 合理性:
- 視認性:
importキーワードと対象の名前が近い方が読みやすい。- 編集の利便性: テキストエディタのソート機能で簡単に並び替えができるよう、先頭にキーワードが来る方が良い。
- 頭でっかち構文の是非:
- 論点: 重要な要素が長い修飾子によって後回しにされる構文は読みづらいか。
- 例: C/C++における長い返り値の型定義、Haskellにおける長い型制約。
- 合理性:
- 可読性: 関数の名前など、重要度の高い部分が先に来る方が、コードを読み進めやすい。
- 対策: C++11の
autoや、Rust/Swiftのwhere節のように、重要度の低い部分を後置にできる構文がより合理的である。- 前置キーワードの必要性:
- 論点:
ifやtryのような構文を示すキーワードが、対象の式の前にあった方が良いか。- 例: PerlやRubyの後置if文、Pythonのif式は賛否が分かれる。Standard MLの
handle式のように前置キーワードがない構文は失敗だったと筆者は考えている。- 合理性:
- 可読性: 構文の種類を示すキーワードが先頭にある方が、コードの構造を素早く理解できる。
- 例外: Lisp/SchemeのS式は前置キーワードの原則を徹底しているが、必ずしも広く普及しているわけではない。
■ 3. 自然言語とプログラミング言語の違い
- 大きな構造: プログラムはモジュールやクラス、関数といった構造を持ち、必要な部分だけを把握して読めることが重要である。
- 記号の活用: プログラミング言語では記号を多用するため、スマホのキーボードや音声入力には不向きである。また、記号が多すぎるとコードが暗号化する問題もある。
- インデントの活用: プログラミングではインデントで構造の深さを明示する。固定幅のインデントが一般的なエディタでうまく機能するよう、言語設計を工夫することが望ましい。
- 規則性: 自然言語には例外が多いが、プログラミング言語は学習コストの観点から、例外を減らして規則的であるべきである。
- 表現の多様性: 自然言語では同じ内容を別の言い方で表現するが、プログラミング言語では一つの内容に対する書き方は一つに定まっている方が、定型的に読み書きできて望ましい。
■ 4. 結論
- 多様な合理性: プログラミング言語の合理性は、「人間が書く・読む」「コンパイラが処理する」「シンプルなエディタやIDEで編集する」など、様々な観点から議論できる。
- 自然言語との距離: プログラミング言語と自然言語は異なる媒体であるため、自然言語に似せた構文が無条件に優れているとは言えない。
■ 1. 世界モデルの概要と歴史
- 定義: AIが外界や環境を内部的にシミュレーションし、未来予測や因果関係を理解するための内部モデルである。
- 起源: 1943年、心理学者ケネス・クレイク氏が提唱した「生物が世界の内部モデルを持つことで、行動の結果を予測できる」という考えに由来する。
- 歴史的変遷:
- AI研究初期には「ブロックの世界」を理解する「SHRDLU」などで世界モデルの考えが取り入れられた。
- しかし、当時のモデルは現実世界の複雑さを再現できず、「明示的な世界モデルを持たなくても環境に適応できる」という世界モデル不要論へと傾いた。
- 近年の深層学習の向上と膨大なデータの利用により、再び世界モデルが注目されている。
■ 2. 世界モデルと大規模言語モデル(LLM)
- LLMの「創発能力」:
- 絵文字から映画タイトルを推測したり、訓練されていないオセロをプレイしたりする能力が創発されることから、研究者の間で「LLMがすでに世界モデルを内部に持っているのではないか」という疑問が生まれている。
- 「世界モデル」と「ヒューリスティックの塊」の違い:
- パヴラス氏の見解によると、LLMはあくまで「ヒューリスティックの塊」である。
- ヒューリスティック: 膨大なデータから得た「断片的な経験則の網羅」を組み合わせる近似アルゴリズムであり、高精度な対応はできるものの、一貫性や確実性に欠ける。
- 世界モデル: 道路の1%が遮断された場合でも、地図全体を再構築して最適な経路を見つけるなど、因果関係を深く理解できる。ヒューリスティックの塊であるLLMでは、このような状況で精度が急落する。
■ 3. 世界モデルの意義と展望
- 汎用人工知能(AGI)の実現: 世界モデルはAGIを実現するための重要な目標である。
- 応用分野: 自動運転車の未来予測や、ロボットの安全な行動計画などへの応用が期待されている。
■ 1. 問題の定義
- マッチョスクラム問題:
- 概要: 「弱さを見せず、困難に打ち勝つ姿勢が価値である」というマッチョイズムがスクラムに過剰に持ち込まれる問題である。
- 具体例:
- 自己管理の強制: 「チームが自律的に解決すべき」「自己管理できないのは未熟だから」といった圧力が生まれる。
- 自己否定的な改善: 振り返り(レトロスペクティブ)が「なぜできなかったか」を指摘し合う場になり、自己否定につながる。
- 過剰なアウトカム志向: 「成果を出せない人は貢献していない」という空気が生まれ、多様性が失われる。
- スクラム教問題:
- 概要: ある原則やルール(スクラムガイドなど)を絶対視する教条主義がスクラムに持ち込まれる問題である。
- 具体例:
- スクラムガイドの絶対化: 「スクラムガイドに書いてあるから正しい」とし、現場の現実を無視した形式主義に陥る。
- アレンジの否定: 現場の状況に合わせたスクラムのアレンジが許されず、「正しいスクラムができない現場が悪い」と見なされる。
- イベントの儀式化: スクラムイベントが形式的なものとなり、本来の目的である対話や改善の場として機能しなくなる。
■ 2. 問題の発生要因
- スクラムそのものの問題:
- 抽象的なガイド: スクラムガイドが意図的に抽象的であるため、日本人の気質もあり「あるべき姿」にとらわれやすくなる。
- 曖昧な認定制度: 認定制度や研修制度が、マッチョ化や宗教化を防ぐ機能を持たない。
- スクラムに関わる人の問題:
- 不満の捌け口: スクラムの理想を、既存の環境への不満の捌け口として利用し、「スクラムを実現できない環境が悪い」と他者を攻撃してしまう。
- 権威性: スクラムマスターやアジャイルコーチといった立場が、無自覚に権威性を振りかざしてしまう。
■ 3. 問題の解決策
- 「スクラムを実践する」:
- 経験主義に立ち返る: 「やってみて、観察し、学び、変えていく」という試行錯誤のプロセスを重視する。現状を悪と決めつけず、まず中立的に受け入れ、「なぜそうなっているのか」を掘り下げ、関係者で共有する。
- 「なぜスクラムなのか」を考える: 「スクラムガイド通りにやればうまくいく」という考えを捨て、現状とのギャップを正しく把握する。
- 「進め方マップ」の活用: プロジェクトの特性(要件定義の進め方、開発の進め方)を可視化する「進め方マップ」を活用し、チームの現状を客観的に認識する。
- 柔軟なアプローチ: 要件が複雑な場合は四半期サイクルなど、現場のジレンマを解決するアプローチを検討する。
■ 4. 結論:「別の強さ」
- スクラムにおいて「強さ」や「正しさ」を求めることは、チームにプレッシャーを与え、柔軟性を失わせる。
- 真の強さとは、「誰か/何かが間違っている」と断定するのではなく、「いま、どうなっているのだろう」「どうすれば、よりよくなるのだろう」と問い続け、対話を続けることである。
- この現実を受け入れ、揺らぎながらも問い続ける姿勢こそが、マッチョスクラム問題やスクラム教問題を解決する「別の強さ」である。
■ 立ち上げ
- 目的: 大枠のスケジュールを関係者間で合意する。
- 実施事項:
- プロジェクト憲章の作成: プロジェクトの主要なマイルストーン(要件定義は〇月末、ベータ版は〇月末など)を記述し、全体像を共有する。
- 重要な期限の認識合わせ: 年内リリースや法的期限など、クリティカルなマイルストーンについて認識を合わせる。
■ 計画
- 目的: 詳細なスケジュールを作成する。
- 実施事項:
- 1. スケジュールマネジメント計画の策定: スケジュールをどのように作成・管理するか、そのルールや手法を決定する。
- 2. アクティビティの定義: WBS(Work Breakdown Structure)を用いて、やるべきことを作業可能な単位(アクティビティ)まで分解する。スコープ管理と密接に関連している。
- 3. アクティビティ所要期間の見積もり: 各アクティビティを完了させるために必要な人員や資材を検討し、所要期間を見積もる。
- 4. アクティビティの順序関係の検討: アクティビティ間の依存関係を明確にし、ネットワークダイアグラムで可視化する。
- クリティカルパスの特定: 開始から終了までの最も長い経路(クリティカルパス)を特定する。この経路が遅延すると、プロジェクト全体の遅延に直結する。
- 5. スケジュールの作成: ガントチャートなどを用いて、全てのアクティビティの期間と依存関係を統合したスケジュールを作成する。
■ スケジュール策定のポイント
- スコープとの整合性: スコープ(やるべきことの全体量)とスケジュールに整合性があるか確認する。
- リソースと稼働率の考慮: 人員や設備などのリソース、およびその稼働率を考慮し、無理のない計画を立てる。
- バッファの設定: 予期せぬリスクに備え、スケジュールに余裕(バッファ)を持たせる。一般的に、スケジュール全体の3%程度が推奨される。
- ステークホルダーのレビューと承認: 関係者からのレビューと承認を得て、スケジュールをベースラインとして確定する。
- アジャイルにおけるスケジュール管理:
- ウォーターフォールモデルのように最初に詳細なスコープを定義するのではなく、プロダクトビジョンといった大きなスコープを設定する。
- リリース時期の目標に向け、スプリント(決められた短い期間)ごとに計画を柔軟に策定・実行する。
- スケジュールのベースラインは作らず、状況に応じて柔軟に調整する。
■ 実行
- 目的: 計画されたスケジュールに沿って作業を進行させる。
- 実施事項:
- 進捗確認: 計画に沿って作業が行われているか確認する。
- 作業指示: 各アクティビティを担当者に明確に割り当て、開始・完了時期を共有する。
■ 監視・コントロール
- 目的: 進捗を監視し、必要に応じて修正・調整する。
- 実施事項:
- 1. 定量的管理: スケジュールのベースラインと現状の進捗を常に比較し、定量的に把握する。
- EVM(Earned Value Management): 出来高を数値化して管理する手法である。計画された出来高(Planned Value)と実際に得られた出来高(Earned Value)を比較することで、進捗の遅れや進み具合を客観的に判断できる。
- 2. 逸脱への是正措置: 遅延が検知された場合、リソースの追加、作業順序の変更、スコープの削減など、是正措置をタイムリーに実行する。
- 3. ステークホルダーへの合意形成: スケジュール変更が発生した場合、そのインパクトを関係者に説明し、合意を得る。合意された変更は、新たなベースラインとして設定・周知する。
■ 終結
- 目的: プロジェクトがスケジュール通りに完了したかを確認し、正式にクローズする。
- 実施事項:
- 完了確認: 当初のスケジュール通りに完了したかを確認する。
■ 1. スコープ(作業範囲)の曖昧さ
- 原因:
- 作業範囲の未定義: プロジェクト開始時に「何を作るか」が明確になっていない。
- 追加作業の発生: 要件確認の段階で、当初の想定外の作業(業務フロー作成、システム選定、役員向け資料作成など)が次々と追加される。
- 対策:
- アウトプットの定義: 最終的に「何を作るか」を事前に明確にする。
- WBS(Work Breakdown Structure)の活用: WBSはスケジュールのツールと思われがちだが、本来は作業範囲(スコープ)を定義するためのツールである。これに記載されていないアウトプットは作成しない、という合意を形成する。
- 成果物定義の具体化: 「要件定義書」のような曖昧な成果物ではなく、「業務フロー」「要件一覧」など、より詳細な要素で定義する。
■ 2. スケジュール作成のスキル不足
- 原因:
- 経験不足: 作業ステップや工数(かかる時間)が分からず、感覚的に計画を立ててしまう。
- 楽観的な見積もり: 実作業にかかる時間を過小評価し、無理なスケジュールを作成する。
- 対策:
- 過去データ・有識者の知見活用: 過去のプロジェクトデータや経験者からの意見を参考に、見積もりの精度を高める。
- 計画段階でのレビュー: 期間に合わせるような辻褄合わせの計画ではなく、現実的なスケジュールになっているか、入念にレビューする。
■ 3. 関係者への配慮不足
- 原因:
- 自社作業のみの計画: 顧客や他チームなど、利害関係者の状況を考慮せずにスケジュールを立てる。
- 認識のずれ: 相手側のレビューや確認にかかる時間が考慮されていないため、後から大幅な遅延が発生する。
- 対策:
- 巻き込み時期の考慮: 相手側の繁忙期や都合を事前に確認し、いつ、どれくらいの時間を取ってもらう必要があるかを計画に盛り込む。
- リスクの考慮: 依頼した作業がスケジュール通りに進まない可能性を考慮し、バッファ(余裕時間)を設ける。
■ 4. 遅延の認識不足
- 原因:
- 進捗管理の不足: 作業量を定量的に把握しておらず、漠然と「順調」と判断している。
- 比較対象の欠如: そもそも具体的な予定を立てていないため、進捗が「遅れている」という事実を把握できない。
- 対策:
- 作業内容の定量化: 「完了すべき作業数」や「作業ステップ数」など、客観的に数えられる単位で進捗を管理する。
- 予定と実績の管理: 具体的な数値で立てた予定と、実際の進捗を比較し、遅れを早期に認識する。
■ 5. 遅れをごまかそうとする行動
- 原因:
- 報告への抵抗感: 遅れていることを報告しづらいため、スケジュールをサイレント修正したり、先行着手タスクやバッファを理由に遅れを隠蔽する。
- 対策:
- クリティカルシンキングの活用: 報告が事実に基づいているか、疑いの目を持って確認する。
- 目的の共有: 進捗報告の目的は、遅れのリスクを早期に発見し、対策を打つことであることを、チーム全体で共有する。
■ 6. コミュニケーション不足
- 原因:
- 利害関係者への遠慮: 顧客などへの依頼に遠慮が生じ、調整が後回しになる。
- フォローアップ不足: 依頼した作業の進捗を適切にフォローアップしないため、気づかないうちに遅延が発生する。
- 対策:
- プロジェクトの一体感形成: 依頼された作業を「やらされ感」ではなく、主体的に取り組んでもらえるように配慮する。
- 目的と期日の共有: 依頼する際は、その作業の目的と期日を必ずセットで伝える。
- 頻繁なコミュニケーション: 定期的なフォローアップを行い、進捗や課題を共有する。
■ 1. 計画段階での失敗
- スコープの曖昧さ: プロジェクトの作業範囲を明確にせずに開始する。
- 問題点: どこまでやるのかという境界線が不明確なため、後から理不尽な作業が追加され、チームが混乱する。
- 対策:
- WBS (Work Breakdown Structure) の活用: WBSを使って、プロジェクトの作業を階層的に細分化する。
- 成果物の明確化: 各作業がどのような成果物(アウトプット)を生み出すのかを明確にする。
- 想定の明記: 未確定な要素については、その前提や作成根拠を備考欄などに記載する。
- 合意形成: チームや顧客と作業範囲について合意を得ておく。
■ 2. スケジュールの見積もり不足
- 楽観的な見積もり: 実際にかかる時間よりも短い期間で作業を見積もってしまう。
- 問題点:
- 見え方と実作業のギャップ: 「関係者に確認するだけ」のように、一見簡単に見える作業も、実際には多くの付随作業(調整、資料作成など)が発生する。
- 担当者とのギャップ: 担当者のスキルや現在の状況(並行して抱えているタスクなど)を考慮せず、非現実的なスケジュールを立ててしまう。
- 対策:
- バッファの設定: 担当者のスキルや状況に応じて、余裕を持たせたスケジュールを設定する。
■ 3. 実行段階での失敗
- 根拠のない状況管理: 定量的な根拠のない進捗報告を行う。
- 問題点: 「だいたい7割」といった感覚的な報告では、正確な状況を把握できない。
- 対策:
- 分母・分子の明確化: 作業状況を、完了したタスク数やページ数など、客観的に数えられる単位で管理する。
- 定量的報告の徹底: 「16個中12個完了で75%」のように、根拠を説明できる形で進捗を報告する。
■ 4. マネージャーの視野の狭さ
- リスクの見逃し: 自分の作業に忙殺され、プロジェクト全体のリスクを見過ごしてしまう。
- 問題点: 小さな問題の兆候を早期に発見できず、問題が大きくなってから対応に追われる「後手後手」の対応となり、手遅れになる。
- 対策:
- リスクマネジメント: プロジェクト全体のリスクを常に監視し、兆候を早期に察知する。
- 早期対応: 小さな火種のうちに手を打ち、メンバーが疲弊するのを防ぐ。
- 心に余裕を持つ: 視野を広く保ち、客観的に全体を把握する。
■ 結論
- プロジェクト管理ができないマネージャーは、計画や実行段階で「曖昧さ」を放置している。
- メリハリのある管理が必要である。締めるところはしっかり締め、プロジェクトの成功とメンバーの負担軽減の両立を目指す必要がある。
- 本稿で挙げられた4つの失敗例以外にも、プロジェクトを効率的に管理するための要素は多数存在する。
■ 1.システム化の目的が明確でない
- リスク事象:要件の増大、もしくは絞り込みの不全が発生し、プロジェクトが統制できなくなる
- 把握観点
- システム化の目的が文書化されているか
- 定量的な達成指標が文書化されているか
■ 2. 現行機能の調査・確認が不足している
- リスク事象:受け入れテスト時に不具合指摘が多発しプロジェクトの中断または大量の仕様変更が発生してコストが超過する
- 把握観点
- 業務要求と現行システムの関係を説明できるメンバーの有無
- 現行システムの設計書が最新化されているか
- 要件定義書に「現行どおり」という記載があるか
■ 3. 現行システムとそのドキュメントが整合していない
- リスク事象:現行システムから引き継ぐべき要件に漏れが発生する
- 把握観点
- 現行システムに関する各種ドキュメントが存在するか
- サンプルチェックによる網羅性・整合性の度合いが一定以上か
■ 4. パッケージ選定に関する検討が十分でない
- リスク事象:機能の要求を満たせないことや性能が出ないことにより、大きな手戻りが発生し稼働不能になる
- 把握観点
- 選定における機能条件、非機能条件、運用条件が明確に文書化されているか
- 検討経緯が明確か
■ 5. 性能の検討が十分でない
- リスク事象:利用に供する性能が出ないため、稼働不能や大規模改修に繋がる
- 把握観点
- 性能見積りの前提となるデータ量に関する資料の有無
- 実装過程における性能に関する進め方について、妥当性があるか
■ 6. 可用性の検討が十分でない
- リスク事象:安定稼働の保証がないため、稼働不能や大規模改修に繋がる
- 把握観点
- 目標とする稼働率、可用性確保の方式が明確か
- 稼働率の見積り方法は妥当か
■ 7. 運用要件の検討が十分でない
- リスク事象:実現できない、矛盾を含んだ要求仕様ができる(運用要件)
- 把握観点
- システム運用関連の検討が行われているか
- システム運用関連の成果物の作成が計画されているか
■ 8. 運用に向けての制約条件が明確でない
- リスク事象:期待された業務運用ができない
- 把握観点
- 運用担当者によるレビューが行われているか
- 業務視点でのウォークスルー、テストが計画されているか
■ 9. 要件を獲得すべきステークホルダーが網羅されていない
- リスク事象:要件の漏れが発生する(後になってステークホルダーから指摘される)
- 把握観点
- ステークホルダーのリストの有無
- ステークホルダー全員にヒアリングを実施しているか
■ 10. システム部門による要件とりまとめが十分でない
- リスク事象:要件がいつまでも確定しない、あるいは要件が想定以上に膨らむ
- 把握観点
- 要件の引き出しプロセスが明確になっているか
- 要件のとりまとめ様式が定義されているか
■ 11. ドキュメントの更新が管理されていない
- リスク事象:追加・改修開発時に、現行システムから引き継ぐべき要件に漏れが発生する
- 把握観点
- 変更管理手順が規定され、実践されているか
- 要件変更・ソースコード修正時にドキュメント修正およびレビューを実施しているか
■ 12. 仕様の変更管理ができていない
- リスク事象:規模の肥大化、費用に関するPJ の目標未達
- 把握観点
- 仕様変更一覧の有無
- 仕様変更に仕組み(フロー、会議体)が規定されているか
■ 13. ユーザーによる仕様の確認が十分でない
- リスク事象:要件の漏れや認識の齟齬が生じる
- 把握観点
- 現場ユーザによるドキュメントレビューが適切に行われているか
- 要件定義完了時点でステアリングコミッティが開催されたか
■ 14. 要求の優先度が曖昧になっている
- リスク事象:開発規模が膨張する
- 把握観点
- 要求に優先度付けを実施しているか
- 要求の優先度をお客様に確認しているか
■ 15. 業務要件の網羅性が検証できない
- リスク事象:画面、帳票等の形式的、定型的な情報はあるが、業務の全体にわたる要件や要望、今後の展望などがあいまいになる
- 把握観点
- 現行の画面や帳票以外から業務要件を把握するための人的な体制が準備されているか
- 業務視点でのウォークスルーがスケジュールされているか
■ 16. 設計と実業務の整合性が検証できていない
- リスク事象:業務に合わない情報システムになる(要件定義に漏れが発生する)
- 把握観点
- 業務面と情報システム面の双方から点検(ウォークスルー)し、業務に対する機能の解釈の誤りの有無について確認しているか
■ 17. 経営層によるプロジェクト運営の関与が十分でない
- リスク事象:要件定義を始めとする工程の節目や重要な意思決定場面で、優先順位やリソース配分に対する方向性が決まらないため、プロジェクトの意思決定が誤ったものとなる
- 把握観点
- プロジェクト憲章が作成されているか/承認されているか
- 経営層がプロジェクトに対し月次報告などを要求しているか
■ 18. 経営層によるスコープ決定への関与が十分でない
- リスク事象:調整の不調による費用の膨張や要件定義の誤り
- 把握観点
- 要件の変更時に、及ぼす影響に応じた責任者の承認を得るルールが存在するか
■ 19. 経営層がパッケージ導入の意図・目的を明示していない
- リスク事象:パッケージ導入でカスタマイズ仕様が膨張する
- 把握観点
- パッケージの採用方針(導入意図や、現行業務維持方針など)について、プロジェクト企画書などの公式文書に記載しているか
- カスタマイズに関する制約条件(コストや工数の上限など)について、プロジェクト企画書などの公式文書に記載しているか
■ 20. ステークホルダー間の力関係がアンバランスである
- リスク事象:全体最適が実現しないことによるQCD の乱れ
- 把握観点
- 納期折衝・スコープ調整の余地がない
- 異なる役割を持つステークホルダー間で指導・統括・評価関係がある
■ 21. 高次の調整・決定機関が機能していない
- リスク事象:重要事項の決定が遅れたり、調整できなかったりする
- 把握観点
- ステアリングコミッティにあたる機構が存在しない
- ステアリングコミッティの開催要件(定期開催サイクル、開催条件など)が定義されていない
■ 22. 十分なコミュニケーションがとれていない
- リスク事象:作業効率の悪化により工程の進捗が遅れる
- 把握観点
- 会議体が定義されているか
- 課題管理とエスカレーションに関するルールが規定されているか
■ 23. 業務用語が共有されていない
- リスク事象:要件定義・設計上の誤謬による手戻りや品質問題が発生する
- 把握観点
- (開発者向け)業務用語に関する注釈付きドキュメントの有無
- (ユーザ向け)システム用語に関する注釈付きドキュメントの有無
■ 24. 業務知識が不足している
- リスク事象:仕様変更、仕様追加の多発により、サービス開始の遅れや品質の極端な悪化を招く
- 把握観点
- ユーザ側:キーマンが明確であるか/要件定義に参画しているか
- ベンダー側:現行業務を現場レベルで調査しているか
■ 1. プロジェクト管理の課題と確率的予測の利点
- 確定的な納期の困難さ: ソフトウェア開発において、要件変更や技術的な問題など、予測不可能な要素が多いため、確定的な納期を提示することは難しい。
- 確率的予測の導入: 「いつ終わるか」という単一の納期ではなく、「この時期までに終わる確率」で考えるべきである。
- リスク共有と対応: 確率的な予測を用いることで、事前にリスクを関係者と共有し、遅延した場合の対処法を検討できる。
■ 2. 計画の明確化と視点の転換
- 3つの概念の分離:
- 見積もり(Estimate): エンジニアの個人的な「予想」であり、約束ではない。
- コミットメント(Commitment): チームが「達成する」と合意したライン。
- ターゲット(Target): ビジネス上の「必達目標」であり、最も厳格な期限。
- 「タスク中心」から「リスク中心」へ: 単にタスクを積み上げて計画を立てるのではなく、起こりうるリスクを考慮に入れることで、より現実的なスケジュールを作成できる。
■ 3. 予測精度向上のための手法
- リスクチェックリスト: 「要件の曖昧さ」や「情報共有不足」といったリスク要因をリストアップし、不確実性を可視化する。
- 過去の実績からの学習: アジャイル開発のスプリントを繰り返し、過去の作業実績データ(ベロシティ)を蓄積することで、将来の予測精度を高められる。
- ベロシティの安定化: チームの作業ペース(ベロシティ)を安定させることで、予測の信頼性を向上できる。
- スコープクリープの管理: 開発中の要件追加(スコープクリープ)を事前に見込むか、その発生を抑制するルールを設けることで、計画のブレを抑えられる。
■ 4. モンテカルロシミュレーションの活用
- 不確実性の考慮: モンテカルロシミュレーションを用いることで、不確実な要素を考慮した多数のシナリオをコンピュータ上で試行し、確率的な予測を算出できる。
- 直感的な理解: この手法により、「50%の確率でこの時期までに終わる」といった予測がグラフなどで可視化され、専門家でなくても直感的に理解できる。
- 共通認識の形成: シミュレーション結果を共有することで、関係者全員がプロジェクトの現実的な状況を把握し、納得のいく計画を立てられる。
■ 5. 結論
- リスクの可視化: ソフトウェア開発における不確実性は避けられないが、確率的なアプローチでリスクを可視化し、計画に組み込むことが重要である。
- 予測の正確性向上: ベロシティの安定とスコープクリープの管理により、予測はさらに正確になる。
- 共通理解の促進: モンテカルロシミュレーションなどのツールを使って結果を視覚化することで、ステークホルダー間の共通理解が促進され、現実的な計画運営が可能となる。
■ 1. プロジェクト管理の一般的な誤解
- タスク中心のアプローチ: プロジェクト管理は、タスクを洗い出し、スケジュールを綿密に組むことだという誤解がある。
- 不確実性への対応不足: 実際には、要件変更や予期せぬ問題など、不確実な要素が常に発生する。タスク消化だけを指標にすると、リスクの兆候が見過ごされ、問題が顕在化した際に手遅れになることが多い。
- 負のスパイラル: チームは過度なプレッシャーに晒され、リスクを報告することをためらうようになる。
■ 2. タスク中心とリスク中心の比較
- タスク中心アプローチ:
- 特徴: WBS(作業分解構成図)やガントチャートといった詳細な計画を重視する。進捗は「タスクの完了」で測る。
- 課題: 予期せぬ事象を「イレギュラー」として扱い、問題が顕在化してから後手に回る傾向がある。計画からの逸脱に抵抗感がある。
- リスク中心アプローチ:
- 特徴: プロジェクトの初期段階から、達成を妨げる潜在的なリスク要因を徹底的に洗い出す。
- 強み: スケジュールは常に最新の情報に基づいて調整され、リスクの状況に応じてタスクの優先順位を柔軟に変更する。進捗は「リスクの顕在化状況」や「新たな問題の発見」によって評価される。
- 根本的な違い:
- タスク中心は「どれだけ計画通りに作業を消化したか」に焦点を当てる。
- リスク中心は「計画を脅かす要因をどれだけ早く発見し対処できたか」に焦点を当てる。
■ 3. リスクの性質と分布
- 掛け算的に増殖する脅威: プロジェクトにおけるリスクは、単独で作用するのではなく、連鎖的に影響を及ぼし、問題が「掛け算的」に拡大する性質がある。
- 対数正規分布: プロジェクトの所要期間は、対数正規分布に近い形を示す。これは、発生確率は低いものの、極めて大きな遅延が発生しうることを示唆する。
■ 4. リスク管理の具体的な手法
- 早期警報システム: リスクを早期に捉え、先手を打つことが重要である。
- IPAのリスク事象ドライバー: IPA(情報処理推進機構)が公開する「ITプロジェクトのリスク予防への実践的アプローチ」では、問題発生の前触れとなる24種類のリスク事象ドライバーが提示されている。これをチェックリストとして活用し、潜在的なリスクを客観的に洗い出すことができる。
- 心理的安全性: チームメンバーが、失敗や懸念を安心して発言できる状態。リスクを早期に発見するためには、この心理的安全性が不可欠である。
- 実践方法: リーダーは、問題提起に対して感謝の意を示し、自らの失敗談を共有するなど、安心して発言できる環境を意識的に構築する。
- リスク=チャンス: リスクは単に避けるべきものではなく、新たな価値創出や成長の機会となる。リスクを特定し、チームで対処する過程そのものが、チームのスキル向上や結束力強化につながる。
■ 5. 日々の実践へのヒント
- キックオフでのリスク洗い出し: プロジェクト開始時に、チーム全員でリスクをリストアップし、担当者と対応策を明確にする。
- 定例ミーティングでの共有: 進捗報告に加え、必ず「リスク・懸念事項」を共有する時間を設ける。
- リスク対策タスクの計画への組み込み: 優先度の高いリスクには、具体的な対策タスクを立て、通常のタスクと同様に計画に含める。
- 振り返りによる学習: プロジェクト完了後やトラブル収束後に、リスクへの対応を振り返り、得られた知見を組織のナレッジとして蓄積する。
■ 1. レビュー疲れの背景と課題
- レビュー時間の急増: LLMの普及により、コードやドキュメントのアウトプット量と速度が大幅に増加した。しかし、必ずしも質が向上しているわけではなく、レビューに要する時間と疲労が増加している。
- 「他人を経由したプロンプティング」: 知識がないままLLMに生成を任せ、その結果をレビュー側に丸投げするケースが多い。レビュー側は、生成側より知識をつけた上でレビューする必要があり、非効率である。
- 自己レビューの欠如: 生成されたものを自己レビューしない、あるいはレビューしても見落とすケースが多発している。これは、自分の手で書いたコードではないため脳内キャッシュに乗らず、理解が追いつかないことが原因である。
- クソデカコミットの問題: LLMが試行錯誤を繰り返し、大きな単位でコードを上書きするため、既存の設計を無視した巨大なコミットが生まれやすい。適切なタスク単位への切り出しが困難である。
- インセンティブ構造の不一致: 生成側はLLMの利用でスループットを最大化しようとするが、レビュー側は質を担保する必要があり、レビューの速度は向上していない。このインセンティブ構造の違いが、レビュー疲れの主原因である。
■ 2. 対策と試行錯誤
- コーディングレビューでの対策:
- 1. 自己レビューの徹底: 生成したコードをGitHub上で他人のコードとしてレビューし、レビュアーとしてのマインドセットに切り替える。
- 2. ドキュメントドリブン開発: 要件定義、外部設計、作業計画書などをドキュメントとして実装と一緒にコミットする。これにより、コミットが大きくても意図が理解しやすくなり、不毛な議論を回避できる。
- 文章レビューでの対策:
- LLMが生成した文章をそのまま提出する人に対しては、LLMにエスカレーションの文言を作成させ、適宜マネージャーに報告することが有効である。
■ 3. 結論
- LLMの限界は人間の限界: LLMの能力はそれを使う人間の能力に規定される。
- 今後の展望: LLMを最大限に活用するためには、人間が主導してワークフローを構築し、LLMの限界を補完していく必要がある。現状はまだ手探りの状態が続いている。
■ 1. 移行前のシステムが抱える問題
- 根本原因: 業務ロジック自体は単純であるにもかかわらず、全体の見通しが悪く、運用が困難な状態にあった。
- 複雑さの正体: 問題の核心は、業務ロジックそのものではなく、「前処理」の複雑さである。
- 処理の分散: レガシーシステムとの連携に伴う「値の加工」や「区分値の変換」といった処理が、複数の層に分散して記述されていた。
- 結果の予測困難性: この処理の分散が、「入力に対する結果が予測しづらい」システムという状況を生み出していた。
■ 2. 移行時の対処と成果
- 構成の再整理: 一連の処理を整理し、「業務ロジック(ドメインロジック)」と「前処理(モデル変換装置/腐敗防止層)」の二層構造に再構成した。
- 可読性の向上: 業務ロジックで使用する値に関する処理が「モデル変換装置」に集約された結果、関連処理をシステム全体から探し出す手間がなくなり、可読性が大幅に向上した。
- コード量の削減: 全体的なコード量が驚くほど削減された。
■ 3. 移行作業における課題と考察
- 心理的抵抗: DBやSQLに慣れた開発者にとっては、「データの近くで加工する方が効率的」という感覚があり、処理の分散を避けるための徹底的な集約作業に心理的抵抗があった。
- コード量の逆転: 出来上がったシステムでは、「モデル変換装置」のコード量が「業務ロジック」のコード量を上回った。
- 本質的な複雑さの可視化: このコード量の差は、「データを整える部分」にこそ真の複雑さがあることを示唆している。最も重要な業務ロジックが簡潔に記述されているという結果は、慣れ親しんだシステム設計とは異なるため、違和感として感じられた。
「C# や SQL Server が Linux でも動かせる」というのはそうなんだけど「やろうと思えばできる」というのとLinux の上で動かすのが当たり前という物とでは話がちがう 後者なら全ての開発者がそれを前提にエコシステムを組むけど、前者ではそうならない
実際、SQL Server に関しては ODBC Driver を Mac にインストールしたりするところで躓く
そういう細かい yak shaving みたいなのがあちこちで発生する
Web 系システムのノウハウは、Linux などを中心としたオープンなエコシステムに支えられて蓄積されてきた
だとすれば、そこで動かすのが当たり前の前提になっているプラットフォームに乗っかるのがマクロにみれば最適だということは自明でしょう
○○でもやればできるよ、みたいなのは論点がずれてる
PostgreSQL や MySQL を使っていれば何の苦労もないものを、GCP や AWS で SQL Server を使おうとすると細かいところでノウハウが要る、みたいなのは実体験としてあります
基幹データベースは移管が難しいからそれでも SQL Server を使い続けるけど、そうでなければ好き好んでそんな苦労はしたくない
それなら Azure を使えばいい、というのはそう
でもその時点で使う物が限定される
そこを限定されてでも Microsoft のプラットフォームに乗っかるかアグノスティックにレイヤーごとに選択肢を豊富にもっていたいか、それは価値観次第だと思います
そういう大枠での判断基準で考えるものなので、C# は良い言語だとか、Linux でも動くとかそういう点の議論をしててもしょうがないですよ
結合でシステムの複雑性を管理!
「結合」とは、モジュール設計における基本概念の1つ。モジュール間の相互作用や依存関係の強さを表します。「結合」を適切に管理することで、ソフトウェアシステムの保守性や拡張性、進化性を向上させることができます。その重要性にも関わらず「結合」について深く理解されていないのが実情です。本書では、まず構造化設計やオブジェクト指向設計に用いられてきた「結合」に関するモデルや評価手法を包括的に解説。さらに、複雑性を管理し、モジュール性を高める設計ツールとして「結合」を使用する新たなアプローチを提案します。
■ 1. NScripter開発の背景と変遷
- 開発の動機: NScripterは、開発者である高橋直樹氏が自身の同人活動でノベルゲームを制作するために、自作のゲームエンジンシリーズ「Scripter」を発展させたものである。
- 簡易な言語仕様: 開発当初から、専門家ではないクリエイターでも扱いやすいように、プログラミング入門の定番であるBASIC言語の文法を参考にしている。これにより、ノベルゲーム制作の敷居を下げた。
- 拡張性の確保: エンジン本体はシンプルに保ちつつ、新しい命令文の追加や、プラグイン(例: 音源や画像形式の対応)による機能拡張を可能にした。
- 時代の要求に応じた進化: 2000年代後半に、ノベルゲームのUIやデータ構造が複雑化。それに伴い、より高度なロジックを扱えるよう、スクリプト言語「Lua」を拡張機能として導入した。
- 後継エンジン「NScripter2」の開発: PCの性能向上と描画速度の限界に対応するため、高速な描画処理が可能な「DirectX」を全面的に採用し、Luaをエンジンの中核に据えた「NScripter2」をゼロから開発した。
■ 2. NScripterの普及と開発者の視点
- 普及の要因:
- リリース当時は、手軽に使えるゲームエンジンが少なかった。
- 『月姫』や『ひぐらしのなく頃に』といった人気作品に採用されたことで、多くのクリエイターに存在が知られた。
- 非商用・同人活動での無料ライセンスモデルがクリエイターの裾野を広げた。
- 開発者のスタンス:
- 自身が開発したツールが文化に与えた影響については、「純粋に使ってもらえたのがありがたい」と謙虚な姿勢である。
- ユーザーが使い方を解説するウェブサイトを運営してくれたことに対し、特に感謝している。
■ 3. 現在の活動と今後の展望
- キャリアの変化: 2018年頃にノベルゲーム市場の縮小を感じ、一般企業のプログラマーに転職した。
- 「NScripter3」の開発:
- 今後も自身がゲーム開発を続けるために、新たな環境を求めて「NScripter3」を開発中である。
- これまでの自作エンジンとは異なり、オープンソースのゲームエンジン「Godot」にLuaのプラグインを組み合わせる設計を考えている。
- 開発のモチベーション: 25年以上続く開発の動機は、一貫して「自分で使うため」である。自分の創作活動が主軸にあり、そのツールを「ついでに」公開するというスタンスを貫いている。
- ジャンルの未来: ノベルゲーム市場は国内で落ち着いたものの、Steamでのインディーゲームのヒット事例があることから、今後も魅力的なジャンルであり続けると期待している。
■ 1. ADRの概要と重要性
- ADR(Architectural Decision Record)とは: ソフトウェアアーキテクチャの重要な決定を記録する文書である。単なる設計書ではなく、なぜその決定がなされたのかという理由に焦点を当てる。
- ADRの利点:
- 意思決定の質が向上し、学習効果が高まる。
- 意思決定の妥当性に自信を持ち、チームメンバーに説明しやすくなる。
- 開発組織の大規模化や生成AIの進化により、ドキュメントの重要性が高まっている。
- 生成AIの限界: 現在の生成AIは、コードベースに残らない「意思決定の理由」や「検討された別の選択肢」を創造できないため、ADRの作成には不向きである。
■ 2. ADRに記載すべき内容とアンチパターン
- 記述すべきタイミング: トレードオフを伴う重要な意思決定が必要な時に書くべきである。
- 主な目的:
- 意思決定の経緯や背景を正確に理解すること。
- 意思決定の妥当性に自信を持つこと。
- 将来の振り返りに役立てること。
- 記述すべき項目:
- 意思決定が必要になったコンテキスト
- 各選択肢のトレードオフ
- 意思決定で重視したポイント
- アンチパターン:
- 1. 「今必要な理由がわからない」: 意思決定の背景となるコンテキストが不明瞭な場合。
- 2. 「適切と考える理由がわからない」: 各選択肢のトレードオフを比較せず、決定理由が不明瞭な場合。
- 3. 「最善の選択肢を生み出そうとする」: 完璧な案を出そうとしてしまい、手が止まる場合。
■ 3. ADR作成の実践的ヒント
- コンテキストの共有: 執筆前に、なぜこの意思決定が必要かをチームとすり合わせることで、手戻りを防ぐ。
- 多様な視点での検討:
- 「多分違うだろう」と思う選択肢も含め、各案に「肩入れして」考えることで、潜在的なコンテキストや見落としに気づける。
- 生成AIを活用し、各案の強みを聞いてみることも有効である。
- 批判的思考: 結論を出した後、その決定理由が他の選択肢にも当てはまらないか批判的に考える。
- 表による可視化: トレードオフ分析の結果を表にまとめることで、一覧性が高まり、理解が促進される。
■ 4. ADR実践から得られる効果
- 「手癖」からの脱却: 意思決定の理由を言語化する過程で、自身が無意識に行っていた設計に気づく。
- 過去の意図の理解: 過去に書かれたADRを読むことで、設計の意図を理解し、手戻りを防ぐ。
- 「バランス」を見極める力: コンテキストを分析し、最適な意思決定を下す力が身につく。これは、生成AI時代に最も重要な「技術的卓越性」につながる力である。
Linuxカーネルのリソースノードのリライトに対する、たった1つの修正がことの発端だった。Linus Torvalds氏は、その修正を見れば見るほど当惑していった。なぜなら、その修正は「実際には何も修正していなかった」からだ。
同氏は「この無意味なコミットの理由を説明してくれることを期待して、『Link:』引数を確認した。しかし、いつものように、そのリンクはすでに存在するくだらない情報を指し示しているだけで、ただ時間を無駄にした」という。
その後、Torvalds氏は「もうこのゴミはやめろ」と語り、Linux Kernel Mailing List(LKML)での議論において、当惑から瞬く間に怒りへと変わった。同氏はさらにこう続ける。「私の最初の反応が間違っている理由を説明してくれるような、何か不具合報告などを指し示していることを期待していた」が、結局は期待外れに終わった。
Torvalds氏は「人の時間を無駄にする無意味なLink引数を追加するのはやめてくれ。“追加”の情報がある場合にのみリンクを追加してほしい」と宣言した。また、「この無意味なリンクは本当に嫌いだ。“役に立つ”リンクは大好きだが、実際に見るリンクの99%は、ただの愚かで役に立たないゴミを指しているだけで、私の時間をただただ無駄にしている。今回もだ!」といら立ちをあらわにした。
要するに、同氏は「もし私にプルすることを本当に期待しているなら、役に立たないリンクではなく、ちゃんとした説明が欲しい」と語っている。さらに、「そうだ、私は機嫌が悪い。私の主な仕事、いや、本当に唯一の仕事はプルリクエストを理解することだと感じており、だからこそ、自動的に追加され、私の仕事をより困難にするだけのこうしたものが、心底嫌いなのだ」と心情を吐露した。
他の人々もTorvalds氏の意見に同意している。あるRedditの投稿者は、「Linusの言うことは一理ある。あの元のパッチはAIが書いた要約のように見えたし、問題の説明へのリンクも同じ要約だった」と述べている。
仕様駆動開発(Specification-Driven Development)は、まず仕様を明確に作成し、その仕様を基に実装計画を立ててコーディングを行うという開発手法です。
Amazon Web Services(AWS)が7月に発表したコーディング支援ツール「AWS Kiro」がこの手法を採用しており、それがきっかけで注目されるようになりました。
参考:AWSがAIコードエディタ「Kiro」をプレビュー公開、VS Code互換。AIとチャットしながらプロダクトを開発
今回GitHubが公開したSpec Kitは、この仕様駆動開発のワークフローの実行を生成AIが支援してくれる仕組みを備えており、後述するようにGitHub CopilotやClaude Code、Gemini CLIで仕様駆動開発が容易に実現できます。
■ 1. PRDの3つの役割
- 成長・評価のツール:
- PRDを一人で書ききれることが、一人前のプロダクトマネージャー(PM)の分岐点である。
- 他の職種と対話しながらPRDを完成させることで、PMの企画、開発、検証ワークフローのコントロール能力を判断できる。
- PRDはPMの育成に活用できる。
- 思考のツール:
- PRDのフォーマットに沿って企画を考えることで、プロダクトのあるべき姿を再考し、見落としがちな上流工程の事項を押さえられる。
- PRDは、多様な解決策とトレードオフを記録する装置として有用である。
- コミュニケーションツール:
- PRDは「指示書」ではなく「対話書」である。
- 開発スタイルに関わらず、PRDを介して多職種が協働・協業できる。
- 新規メンバーがキャッチアップするための「知のベースキャンプ」となる。
■ 2. PRDの正しい使い方
- 書き方:
- パワーポイントやExcelは避け、マークダウン形式で書くべきである。図はMermaidの使用が推奨される。
- WHATやHOW(要求事項)から書くのは間違いである。
- WHY(前提条件)やCORE(中心概念)から、他職種と対話しながらPRDを埋めるべきである。
- 構成:
- デザイン思考のダブルダイヤモンド(発見・定義→解決策提供)に沿ってPRDを作成する。
- 課題と解決策は1対1ではないため、PRDにはソリューション案の検討過程を残しておくべきである。
- フローに沿って作成することで、思考の質とPRDの品質が一定に保たれる。
■ 3. AI時代のPRD
- 変わらない価値:
- 人と人がコラボレーションする限り、PRDは有用である。
- AIと人との共同作業においても、共通の思考フォーマットとして機能する可能性がある。
- 意思決定の記録として、人にもAIにもコンテキスト(文脈)を伝えるために有用である。
- プロトタイプとの関係:
- 良いプロトタイプを作れる人は、PRDを書くのが上手なPMである可能性が高い。
- プロトタイプ主導の開発を進めるためには、PRDを通じて個人や組織の思考力を鍛えるべきである。
- AIによる効率化:
- PRDの一次レビューはAIに任せることができる。
- AIにPRDを書いてもらうことも可能である。この場合、PRDフォーマットの上から順に、AIと対話しながら初稿を作成することが効率的である。
■ 4. 結論
- 未来のPRD: 将来的にPRDの執筆はAIが行うようになるかもしれない。しかし、予算執行を伴う意思決定は人間の役割として残る可能性が高い。
- 人間が磨くべき力:
- 「PRDをレビューできる力」、すなわち良し悪しを判断する力が重要になる。
- そのためには、対話力と思考力を鍛えるべきである。
- PRDの役割の再定義: PRDは単なるドキュメントではなく、思考力や対話力を通じて個人や組織を変革するための「道具」として活用すべきである。
■ 1. 課題の背景と現状
- 問題提起: 生成AIによってジュニアエンジニアが低品質な成果物を大量生産し、シニアエンジニアがそのチェックに工数を割かれ、全体の生産性が低下する事態が発生している。
- 想定外の共感: この問題はITエンジニア業界に限らず、翻訳、法律、教育など、他業界でも同様の課題が見られる。
- 生成AIの性質: 生成AIは「できないことをできるようにする」ツールではなく、「できることをより早くする」ツールである。
■ 2. ジュニアエンジニアが陥る問題点
- 粗悪品の量産: 経験の浅いジュニアエンジニアが生成AIを安易に使うと、非機能要件(可用性、性能、セキュリティなど)や、トレードオフとなる意思決定事項が考慮されない「クソコード」を恐ろしい速度で量産してしまう。
- 非機能要件の考慮不足: 企画側から明示的に伝えられない非機能要件について、ジュニアが考慮せずにプロンプトを書くため、考慮漏れが発生する。
- シニアエンジニアの負担増: ジュニアが量産した低品質な成果物のチェックにシニアエンジニアが追われ、本来の生産的な業務を妨げられる。
■ 3. 解決策と提言
- 思考の転換:
- 低品質なタスクの効率化: 形式的なメール返信やアイデア出しなど、100%のクオリティを必要としないタスクには生成AIを積極的に活用すべきである。
- 質と量のバランス: 「100点×1個」ではなく、「80点×100個」の成果が求められる場面を見極めることが重要である。
- ジュニアエンジニアへの提言:
- ノールックでの提出を避ける: 依頼内容をそのままAIに渡し、完成品として提出するのではなく、AIを相談相手として活用すべきである。
- 品質向上への注力: 同じ時間を使うのであれば、低品質なものを大量に作るのではなく、「一球入魂」の姿勢で、生成AIを活用しながら一つの成果物の品質を高めるべきである。
- 能動的な学習: AIを使う過程で、非機能要件やトレードオフといった、自身が不足している知識を補い、学びを深めることが重要である。
【ニューヨーク共同】生成人工知能(AI)の開発に著作を不正に使われたとして、作家らが米新興企業アンソロピックを訴え、15億ドル(約2200億円)を原告に支払う和解案で合意したことが5日、分かった。
JavaScriptランタイム「Bun」の最新バージョンとなる「Bun v1.2.21」がリリースされ、BunがMySQL/PostgreSQL/MySQLを単一のBun.SQL命令でサポートするユニバーサルなデータベースクライアントとなることが示されました。
Bunは、2023年に登場したバージョン1.0の時点でデータベース機能としてSQLiteを内蔵しており、今年(2025年)1月にリリースされたBun 1.2で、MySQLとPostgreSQLのクライアント機能を搭載しています。
本バージョンでBunが備えるデータベースクライアントライブラリのBun.SQL命令が、Bunに内蔵されたSQLiteをサポートしたことで、主要な3つのデータベースに対して単一のBun.SQLが利用可能になりました。
■ 1. 操作中心の思考の課題
- 操作中心の思考とは: インプットからアウトプットを計算したり、状態を変更する「操作」(関数定義)から先に考える思考法である。
- 問題点:
- 抜け・漏れの発生: 最初に最も可能性の高いケースを考え、それ以外の例外的なケースを後回しにする傾向がある。これにより、状態変更の考慮漏れが発生しやすくなる。
- コードの複雑化: 仕様の「ただし書き」や、考慮漏れを補うためのif文が増え、コードが不必要に複雑になる。
- 安易な仕様変更: コーディングを楽にするために、不自然な仕様や複雑な状態を生み出すことがある。
■ 2. 状態中心の思考への転換
- 状態中心の思考とは: 操作を考える前に、まず操作の前後で取りうる「状態」や「性質」を定義し、それを可能な限りシンプルに保つ思考法である。
- 実践方法(ユーザー登録の例):
- 操作前の状態を定義する: 該当メールアドレスのユーザーが「存在しない」「有効である」「無効である」の3パターンを定義する。
- 操作後の状態を定義する: 成功した場合、必ず「該当メールアドレスのユーザーが存在し、有効である」という単一の状態を保証する。
- 思考の順序:
- 1. 操作の前後に成り立ってほしい状態や性質を考える。
- 2. その状態や性質を満たすには、どのような操作が必要かを考える。
■ 3. 状態中心の思考の適用範囲
- コードレビュー: コードレビューでは、この思考順序がコードに如実に現れる。操作から考える傾向のあるコードは、後から追加されたif文などによって不必要に複雑になっていることが多い。
- 仕様定義: この考え方は、より大きなプロジェクトの仕様定義にも適用できる。
- ユーザーが抱える課題(事前条件)や、達成したい目標(事後条件)といった「状態」を先に定義する。
- その「状態」を満たすために必要な機能(操作)を次に考える。
- 問題解決全般: 解決方法(How)を先に考えるのではなく、「どういう状態になったら成功か」という問題を先に理解することで、より本質的な解決策を導き出せる。
■ 4. まとめ
- 思考の習慣の重要性: 多くのエンジニアが意識していないが、美しく堅牢なコードを書くためには「操作」よりも「状態・性質」に注目する習慣が不可欠である。
- 堅牢なコードの基盤: この思考順序で取り組むことで、複雑さを避け、美しく堅牢なコードの土台を築くことができる。
- 開発フローの「型」: 効果的な利用のためには、利用方法に「型」を決め、インクリメンタル(段階的)に進めることが重要だと述べられています。
- 具体的なコマンドとプロセス:
/design: 実装計画の作成/revise: 計画の修正/implement: 実装/ask、/instruct: 実装内容の修正/review: コードレビュー/recap: タスクの振り返り、ナレッジの蓄積- ツールの活用:
- Git: 細かくコミットを行い、
difitのようなツールでレビューを繰り返すことが推奨されています。- CLIツール: Neovimやtmuxなど、ターミナルを広く使うことで作業効率を高めています。
- Obsidian: 開発で得られたナレッジを管理するために使用しています。
- 公開されているリソース: 記事内で紹介されているスラッシュコマンドやサブエージェントは、Gistで公開されており、読者も利用可能です。
日本政府は8月27日、米国・韓国と共同で、身分および所在地を偽って業務を受注し、核や弾道ミサイル開発の資金源としている北朝鮮IT労働者に対して懸念を表明する「北朝鮮IT労働者に関する共同声明」を公表した。
北朝鮮IT労働者は、AIツールの活用や外国の仲介者との協力などのさまざまな手法により、偽の身分および所在地を活用して非北朝鮮IT労働者として偽装し、世界中の標的となる顧客からフリーランスの雇用契約を獲得するため、高度なITスキルへの需要を利用しているという。また、北朝鮮IT労働者自身も、悪意あるサイバー攻撃に関与している可能性が極めて高いといい、知的財産やデータ、資金の窃取など、深刻なリスクをもたらすとしている。
同声明では、これらの活動について懸念を表明するとともに、脅威を阻止するための連携について公表された。あわせて、日本では、2024年3月に公表した「北朝鮮IT労働者に関する企業等に対する注意喚起」を更新し、米国は、北朝鮮IT労働者に関する計画を促進する4つの団体および個人を関連措置の追加対象へ指定、韓国は、北朝鮮IT労働者の活動に関するアドバイザリを発出した。
3カ国は8月26日、サイバーセキュリティ企業のMandiantと連携し、北朝鮮の攻撃に対して官民の連携を向上させ、国際的な業界連携を支援するための行事を東京で主催した。今後、北朝鮮による悪意あるサイバー活動及び不法な資金調達に対処するため、3カ国間の連携を強化し、官民連携を強化する取り組みについて改めて確認するとした。
ITエンジニアが導入の必要もない超シンプルなサービスにk8sを導入して転職するムーブを「履歴書駆動開発」と評している人がいてワロタ
■ 1. Reactの歴史とエコシステムの変遷
- Reactの初期: 2013年にオープンソース化され、当初はUIに特化した最小限のライブラリ(「MVCのV」)と位置付けられた。
- エコシステムの爆発: Reactチームが「unopinionated(意見を持たない)」な姿勢を貫いた結果、状態管理、データフェッチ、ビルドツールなど、様々な分野で多様なライブラリが乱立した。この柔軟性は、同時に開発者の「決定疲れ」やプロジェクトの「コードベースのばらつき」を招いた。
- Create React App(CRA)の登場: この課題を解決するため、Reactチームはビルド設定をカプセル化したCLIツール「CRA」を開発し、プロジェクト開始の複雑さを軽減した。
- React Server Components (RSC) のプロトタイプ発表: 2020年後半、Reactチームはサーバー上でデータをフェッチし、コンポーネントをレンダリングするRSCのプロトタイプを発表した。これは、Reactの「クライアント上のビューだけ」という従来の立ち位置からの大きな転換となった。
■ 2. コミュニティの懸念と実態
- 懸念:VercelによるReactの乗っ取り: Reactチームの一部メンバーがNext.jsを開発するVercelに移籍し、RSCの実装をNext.js App Routerで進めたことから、「VercelがReactを乗っ取り、自社サービスにユーザーを誘導している」という見方が広まった。
- 実態: この見方は因果関係が逆であり、ほとんどがFUD(恐怖、不確実性、疑念)である。RSCはReactチームのビジョンであり、Metaのインフラではテストが困難だったため、Vercelがそのビジョンに賛同し、Next.jsを再設計して実装の場を提供した経緯がある。
- 懸念:ReactはNextでしか動かない: ReactのドキュメントがNext.jsを強く推奨したことから、「Reactは今やNextでしか使えない」という誤解が生まれた。
- 実態: これは完全な誤解である。Reactは依然として様々なフレームワークや純粋なSPAでも動作する。この混乱は、React、Next、フレームワーク間の境界線が不明瞭になったことに起因する。
- 懸念:Reactのクライアント機能がなくなる: サーバーサイド機能への注力が強まったため、「将来クライアントサイドの機能がなくなるのではないか」という不安が広がった。
- 実態: この懸念はあり得ない。Meta自身が膨大なクライアントサイドReactコードを保有しているため、クライアントレンダリング機能がなくなることはない。RSCなどのサーバー機能は付加的であり、オプションである。
■ 3. Reactチームのフレームワーク推奨の意図と課題
- 推奨の理由:
- フレームワークは、ルーティングやデータフェッチなど、多くの共通課題に対する統合されたソリューションを「箱から出してすぐに」提供する。
- これにより、開発者が独自のセットアップを構築する手間を省き、デフォルトでより良いパフォーマンスを実現できる。
- RSCの機能を正しく動作させるには、フレームワークとの密接な統合が必要である。
- ドキュメントの課題:
- ニュアンスの欠如: フレームワーク推奨が「フレームワークを使わないのは間違いだ」という過度に広範な処方箋となり、SPAのような一般的なユースケースを「珍しい制約」と表現した。
- コミュニティの軽視: 「私たちはあなたを止めることはできません」といった表現が、SPAユーザーを軽視していると受け止められた。
- 情報不足: RSCの重要な機能がReactに組み込まれたにもかかわらず、公式ドキュメントにRSCに関する情報が不足し、Next.jsのドキュメントに頼るしかなかった。この情報不足が混乱を助長した。
■ 4. 教訓と今後の展望
- 不信感の原因: Reactチームの行動と発言は善意から出たものであったが、コミュニケーション不足とドキュメントの問題が、コミュニティに不信感を与え、FUDを強化してしまった。
- 今後の課題:
- コミュニケーションの改善: Reactチームはコミュニティの懸念を読み取り、存在を認め、明確に答える姿勢を強化する必要がある。
- ドキュメントの改善: SPAのような一般的なユースケースを適切に評価し、RSCのコンセプトや使い方を包括的に説明する公式ドキュメントを充実させるべきである。
- 結論: 広く使われるライブラリの維持と多様なニーズへの対応は非常に難しい。Reactチームは全体として良い仕事をしているが、コミュニケーションとドキュメントの不足が多くの不満を生んでいる。
■ アーキテクチャ設計の基本と意義
- アーキテクトの定義: ITスキル標準や情報処理技術者試験(システムアーキテクト)によると、ビジネス・IT上の課題を分析し、情報システム化要件として再構成し、システムの構造設計や要件定義を主導する役割を担う。
- アーキテクチャの語源: 古代ギリシア語の「architectonice」に由来し、「始原、原理、首位」「職人」「制作」の3要素を含み、特に原理や抽象という概念が含まれている。
- アーキテクチャの定義(ソフトウェア): ISO/IEF/IEEE 42010:2011では、「環境におけるシステムの基本的な概念や特性が、その要素や関係、および設計と進化の原則に具体化されたもの」と定義される。
- アーキテクチャ不在のリスク: 全体的視点や長期的視点、秩序、戦略、方針が欠如し、部分最適化、サイロ化、巨大な泥団子(レガシーシステム)化を招く。
- アーキテクチャ設計の目的: 機能要求に加え、品質特性(非機能要求)という達成すべき目標がある。これらの特性達成の難易度やトレードオフを克服し、ソフトウェア制作の原理や方針を定めることが本質である。
- 品質特性とアーキテクチャ: 顧客やユーザーの文脈、ニーズにより重要視される品質特性(例:理解容易性、修正容易性、テスト容易性、スケーラビリティ、時間効率性)が決まり、それに応じて最適なアーキテクチャ(例:Map/Reduceパターン)が選択される。
■ アーキテクティングと価値・勝ちの設計
- アーキテクティングの概念: アーキテクチャを設計する一連の行為を指す。システムに上位目的を達成する能力を与えるため、ソフトウェアアーキテクチャを記述し、実現する活動である。
- アーキテクトの役割の拡張: ソフトウェアアーキテクチャに限定せず、システム(系)全体が上位目的を達成するための能力付与に拡張できる。
- 「価値」の設計: ビジネスサイドとの共創、顧客視点、仮説検証を通じて「正しいもの」を作り、ソフトウェアエンジニアリングや開発プロセス、組織設計により「正しく」作る活動を指す。
- 「勝ち」の設計: 勝ち筋を見出し戦略を立てる活動であり、ゴールを明確にし、取るもの/取らないものを決め、資源の配分を行うことを意味する。
- 戦略的設計の例: DDD(ドメイン駆動設計)では、サブドメインの種類(コア/支援/汎用)に応じて、内製、ローコードツールの活用、SaaSの利用といった実現手段を使い分ける戦略が重要である。
- 社内政治の重要性: ポジティブな意味での社内政治は、摩擦を軽減し組織全体の成長に繋がる。ステークホルダーマップの作成や、ナラティブアプローチ(対話)を通じて、各々の立場や行動原理を理解することが具体策となる。
■ アーキテクトとしての成長に必要な要素
- アーキテクトの人材像: アーキテクティングを柱とし、土台となるソフトウェアエンジニアリング、さらに業務知識やソフトスキルといった幅広い要素が必要となる。
- アーキテクチャの特殊解: アーキテクチャスタイルやパターンといった一般解を、特定の状況に適用・評価することで、目の前の課題に対する特殊解としてのアーキテクチャを導き出す。
- ソフトスキルの重要性: 技術力と同じくらい重要であり、ビジネスに技術で貢献するためにはソフトスキルが伴う必要がある。
- リーダーシップと動機づけ: 組織の一人ひとりがリーダーシップを持って自律的に行動するには、内発的動機づけが重要であり、そのためには組織のWHY、共通のゴール、ナラティブが必要である。
- 思考力の強化: アーキテクトとして鍛えるべき思考方法として、具体と抽象、推論(演繹法、帰納法、アブダクション)、メンタルモデル、仮説思考などが挙げられ、これらを鍛えることはレバレッジが効く。
- 推論の活用: 帰納法で事例から知識(ルール)を獲得し、演繹法で知識を応用した結果予測を行い、アブダクションで結果を説明できる仮説(例:AIの精度向上策)を立てることで問題解決を行う。
このエントリには直接書いてないのですが、このエントリでは要するに 名前について仮定を置くな と言っているのです。言い換えれば、 名前を入力するフィールドを「姓と名」に分けたり、長さとか文字の種類についてバリデーションするべきでない ということを主張しているのです。
とはいえ、実際にシステムを作るときには、次に3点だけは制約としてあっていい、と 個人的には 思っています。件のブログによるとこの仮定すら本当は間違っているのですが、流石にシステムを設計するときには、この3つの仮定くらいは設けないと、先に進めませんからね*1。
- 人の名前は Unicode 16.0 で表現できる。
- 人には1文字以上からなる名前がある。
- 人の名前は255文字以下である(あるいは100文字以下、ないし50文字以下。正確な値はシステムの要件に合わせて決めてください)
Googleは「信頼性を確保するために待機しているアイドル状態のマシンも考慮する」「GPUやTPUなどのAI処理用チップだけでなくCPUやDRAMも考慮する」「計算用マシンだけでなくデータセンターの冷却システムや配電システムも考慮する」といった条件を付加し、より実際の運用に近い値を算出しました。その結果、Geminiは電力消費量の中央値は1プロンプト当たり0.24Whで、二酸化炭素排出量は0.03g、水の消費量は0.26mlであることが明らかになりました。これは「テレビを9秒みた際の電力消費量」や「5滴の水」に相当します。
GoogleはGeminiの開発時にエネルギー効率の高いアルゴリズムを選択していることや、Google製AI処理チップ「TPU」の電力効率の高さが今回の結果をもたらしたとアピールしています。また、Googleは今後も電力および水の消費量削減に取り組んでいく姿勢を示しています。
フューチャー社内の有志メンバーでI/F設計ガイドラインを作成し、公開しました。
- I/F設計ガイドライン | Future Enterprise Arch Guidelines
システム開発、特にエンタープライズ領域においてシステム間のデータ連携は避けて通れません。
本ガイドラインは、クラウドネイティブな環境におけるモダンなシステム間連携の設計指針を提供することを目指しています。
アピールポイント
連携方式の選定といった上流のアーキテクチャ設計から、ファイル形式や冪等性といった下流の詳細設計、そして結合テスト計画の指針まで網羅されたガイドラインになっています。
■ まとめ
- POML (Prompt Orchestration Markup Language) はプロンプトを構造化された文書として管理するためのマークアップ言語
- VS Code 拡張機能や TypeScript, Python を通じて POML ドキュメントを解析しプレーンテキストに変換できる
- .poml 拡張子のファイルで POML ドキュメントを保存し、HTML タグに似た構文でプロンプトを定義
- ドキュメントのルートは <poml> タグで始まり、<role> や <task> といったセマンティックなコンポーネントを使用
- <img>, <table> などのコンポーネントを使用して、リッチなコンテンツを表現
- 変数の定義やループ、条件分岐を使用して動的なプロンプトを生成可能
- <meta> タグを使用して POML ドキュメントにバージョン要件やレスポンススキーマ、ツールスキーマを追加