Upgrade to Pro — share decks privately, control downloads, hide ads and more …

命名から始めるSpec Driven

Avatar for Kurowi Kurowi
November 27, 2025

命名から始めるSpec Driven

Avatar for Kurowi

Kurowi

November 27, 2025
Tweet

Other Decks in Technology

Transcript

  1. ©2025 Kyash Inc. ©2025 Kyash Inc. 命名から始めるSpec Driven AIとの対話で用語を固める設計プロセス Hiroto

    Kuroiwa / 株式会社Kyash Nov. 27th, 2025 - 生成AIの実践知 〜 試行錯誤から組織への定着まで 〜 【Finatext × Kyash】
  2. ©2025 Kyash Inc. Spec Drivenのつらみ 仕様書の肥大化 大量のMarkdownファイル 過剰な設計プロセス 要件, 設計,

    タスクの重複 終わりのないエッジケースの考慮 二重メンテナンス 仕様書をレビュー コードもレビュー 現実とのズレ 既存コードや実際の要件との乖離
  3. ©2025 Kyash Inc. 進め方 アイデアを書き出す CONCEPT.md 煮詰まっていなくていいのでまずは設計方針を立てる 定義を生成し、曖昧さを炙り出す アイデアから定義となるコードを生成してもらう テーブル定義、構造体、オブジェクトなどやりやすい形式。

    「この型でいい?」「この制約で足りる?」を考える 重要なのは各要素が何を表すかをコメントまで書くこと 違和感を見つける 一貫性のない命名, 曖昧な表現, 増えすぎたENUMなど AIとの対話で違和感を解消 「この単語は適切?」「別の事象と混同しない?」「増えすぎているので分けるべきでは?」 アイデアがなくても「〜すべきでは?」と投げかける 設計の軸は自分で持ち、AIの引き出しを活用する 1 2 3 4 何度も往復する
  4. ©2025 Kyash Inc. 進め方 設計ドキュメントを更新 CONCEPT.md → DESIGN.md ブラッシュアップしたアイデアとコードに落とし込んだ定義を踏まえて作成 曖昧だったコンセプトを洗練された設計に昇華する

    ドメインモデルを作成 設計ドキュメントに基づいたドメインモデルの実装を依頼する 「貧血症にならないようモデルの振る舞いを意識して」と明示的に指示 5 6
  5. ©2025 Kyash Inc. 違和感の見つけ方(一例) 一貫性のある用語を使用しているか? 文脈が揃っていない用語はロジックも歪む 例: billing ↔ refund

    … 一見対称に見えるが文脈が違う 増えすぎていないか? 登場人物が増えるときはまず疑ってみる カラムが増える … 別のエンティティの責務ではないか? 区分値が増える … 別の概念を混ぜていないか? テーブルが増える … ドメイン境界を誤っていないか? ひとことで説明できるか? 説明が長くなったらブラッシュアップの余地がないか考える 定義にコメントを付けておくとコメントの肥大化で気づきやすい
  6. ©2025 Kyash Inc. 例1: 同じ文脈の言葉を使っているか? 初期設計の用語 ユーザーが支払うべき額 … billing_amount ユーザーに支払うべき額

    … refund_amount ユーザーが支払った額 … paid_amount ユーザーに返金した額 … refunded_amount 初期設計の違和感 違和感 billing ↔ refund: 対称的でない refund ↔ refunded: 違いが分かりづらい refund: お金が動いていないことが表現できていない paid: ユーザー, 会社, 誰が払った?
  7. ©2025 Kyash Inc. 例1: 同じ文脈の言葉を使っているか? AIとの対話 billing ↔ refund が対称的でなくて気持ち悪い。何

    か良い単語はない? いいですね。テーブル定義に落とし込んでください 会計用語で debit / credit があります。 debit は借方、credit は貸方で完全に対称です debited_amount: 請求権の発生額 credited_amount: 返金義務の発生額 collected_amount: 実際に回収した額 refunded_amount: 実際に返金した額
  8. ©2025 Kyash Inc. 例1: 同じ文脈の言葉を使っているか? 債権債務の発生 debited_amount 借方:請求権 credited_amount 貸方:返金義務

    ↔ ↔ 実際のお金の動き collected_amount 回収した額 refunded_amount 返金した額 ✓ 用語が対称的 → ロジックも対称的に ✓ 「発生」と「実際の動き」が明確に分離 結果 2層構造への整理
  9. ©2025 Kyash Inc. 例2: 増えすぎていないか 問題の発生 初期設計の決済集約がもつステータス REQUIRES_REFUND REQUIRES_COLLECTION COMPLETED

    新たな要件 「要対応の取引」を抽出するクエリが複雑化 Before : WHERE status <> 'COMPLETED' After : WHERE status NOT IN ('COMPLETED', 'REFUNDED', ...) COMPLETEDのうち「返金取引」を区別したい statusにREFUNDEDを追加します
  10. ©2025 Kyash Inc. 例2: 増えすぎていないか AIとの対話 COMPLETEDでない取引を抽出するケースが複 雑化しています。Statusに追加すべきでない可能 性はありませんか? おっしゃるとおり運用状態と最終結果は別の関心事で

    す (言語化) final_statusの追加を提案します _statusが増えていく未来が見えてイケていないで す。適切な一単語はありませんか? outcome, conclusion, verdict... outcomeにしましょう
  11. ©2025 Kyash Inc. 例2: 増えすぎていないか 結果 statusとoutcomeの分離 status … 現在の状態

    collection_due ↔ ↔ refund_due balanced requires_action outcome … 最終的にどうなったか collected / refunded reversed / voided written_off / escheated → 要対応 … status <> ‘balanced’ だけでシンプル → statusがbalancedになったときに確定 ✓ 関心事が分離されシンプルに
  12. ©2025 Kyash Inc. いろいろつきつめた結果 全usecaseがこれだけ func(uc *HandleEventUseCase) Execute( ctx context.Context,

    event PaymentEvent, ) error { nexus := repository.FindByOrigin(...) nexus.Apply(event) repository.Save(nexus) return nil } 10種類のイベントすべてがこのパターンに収束 言葉を詰めた結果、スペック駆動ツールが不要なほどシンプルに
  13. ©2025 Kyash Inc. なぜこうなったか 用語が対称 ↓ ロジックも対称 ↓ 複雑なロジックが減る 概念が明確

    ↓ モデルが「自分の状態を どう更新すべきか」を知っている 責務が整理 ↓ usecaseは 調整役に徹することができた
  14. ©2025 Kyash Inc. 既存システムへの適用 一見具体的な指示で始めても 記事にいいね機能を追加してください。 - likesテーブルを作成 (user_id, article_id,

    created_at) - POST /articles/:id/likes でいいね - DELETE /articles/:id/likes で取消 - いいね数はarticles.likes_countで管理
  15. ©2025 Kyash Inc. 既存システムへの適用 指示は具体的でも、用語と責務が曖昧なまま進むと継ぎ足しの設計に 追加要件でテーブルが増殖 自分:コメントにもいいねしたい AI:comment_likesテーブルを作成します (article_likesと別になった…) →

    抽象化(Likeable)を検討しなかった 振る舞いの置き場所がバラバラ 自分:いいねのロジックを共通化して AI:LikeService.execute(user, article)を作成します (さっきはUser.like(article)だったのに…) → 「誰がいいねする責務を持つか」を決めなかった 用語の衝突 自分:ブックマーク機能も追加して AI:Favoriteモデルを作成します (LikeとFavorite、何が違うの…?) → 「Likeとは何か」を定義しなかった
  16. ©2025 Kyash Inc. 命名から始めるアプローチ Step 1:用語を決める いいねする → like いいね取り消し

    → unlike (cancel? remove?) いいね済み → liked Step 2:ドメイン層の責務を考える Like(Entity) user_id, target_type, target_id Likeable(Interface) いいねされる対象が実装 Article, Comment などさまざまなものが対象になる LikeService 重複いいね防止 いいね数の集計ロジック Step 3:ここでスペック駆動 「LikeServiceを実装して。 Likeエンティティを作成し、 対象のlikesCountを インクリメントする」 用語と責務が決まっているので AIの実装が一貫する
  17. ©2025 Kyash Inc. DDDっぽいけどDDDではない やったことを振り返ると ・使う用語を統一した ・曖昧な概念を明確にした(statusとoutcomeの分離) ・モデルに振る舞いを持たせた DDDで言う「ユビキタス言語」と 「ドメインモデル」に近い

    ただし、本来の DDDとは違う DDDは 「ドメインエキスパートと開発者の協働」が核心 AIはドメインエキスパートではない AIは広く浅い知識を持っているだけ ビジネス上の正解はAIにはわからない それを決めるのは人間