YAMLを共通言語にしたら、チームの”翻訳”コストが下がった話 🗣️
はじめに 👋
突然ですが、あなたのチームでは、デザイナー、PM、エンジニアがスムーズに意思疎通できていますか?
多くの場合、それぞれの専門用語や視点の違いから、微妙な認識のズレが生まれがちです。私たちはこれを「職種間の言語の壁 🧱」と呼んでいます。この壁は、手戻りや無駄な確認作業といった「翻訳コスト 💸」を生み出す原因になります。
そこで今回提案したいのが、画面要件をYAMLで定義し、チームの「共通言語」として運用する手法です。
この手法の目的は、単なるドキュメント管理の効率化ではありません。構造化されたYAMLを唯一の正(Single Source of Truth)とすることで、職種間の言語の壁を取り払い、チーム全体のコミュニケーションを円滑にすることにあります。
この記事では、具体的なYAMLの書き方から、チームの共通言語をどう育てるか、その実践方法をサンプルを交えてご紹介します。
なぜYAMLなのか? 🤔
チームの「共通言語」として、なぜYAMLが適しているのでしょうか。
- 構造が明確 🏗️: インデントで階層を表現するため、誰が見ても要件の構造を同じように解釈できます。自然言語の曖昧さを排除できます。
- 人間にも機械にも優しい 😊🤖: 人が読み書きしやすく、同時にプログラムでの処理も容易です。これにより、ドキュメントの自動生成やテストへの応用が可能になります。
実践: YAMLで画面要件を定義する ✍️
それでは、具体的な画面の要件をYAMLで定義してみましょう。今回は、シンプルな「ユーザープロフィール編集画面」を例にします。
screenName: "Edit User Profile"
tags: ["user", "profile", "form"]
description:
ja: "ユーザーが自身のプロフィール情報を編集・更新する画面です。"
en: "A screen where users can edit and update their profile information."
path: "/users/profile/edit"
layout:
form:
components:
- id: "profileFieldSet"
type: "fieldSet"
label:
ja: "プロフィール情報"
en: "Profile Information"
components:
- id: "usernameInput"
type: "input"
label:
ja: "ユーザー名"
en: "Username"
required: true
placeholder:
ja: "例: 山田 太郎"
en: "e.g., Taro Yamada"
validation: "maxLength:20"
note:
ja: "登録後に変更することはできません。"
en: "Cannot be changed after registration."
- id: "bioTextarea"
type: "textarea"
label:
ja: "自己紹介"
en: "Bio"
required: false
placeholder:
ja: "あなたのことを教えてください"
en: "Tell us about yourself"
validation: "maxLength:200"
- id: "bioCharCount"
type: "display"
label:
ja: "現在の文字数"
en: "Current character count"
value:
calculation: "length(bioTextarea.value)"
- id: "locationSelect"
type: "select"
label:
ja: "居住地"
en: "Location"
required: true
options:
- value: "hokkaido"
ja: "北海道"
en: "Hokkaido"
- value: "tokyo"
ja: "東京都"
en: "Tokyo"
- value: "osaka"
ja: "大阪府"
en: "Osaka"
- value: "fukuoka"
ja: "福岡県"
en: "Fukuoka"
- value: "other"
ja: "その他"
en: "Other"
actions:
components:
- id: "submitButton"
type: "button"
label:
ja: "更新する"
en: "Update"
style: "primary"
action:
ja: "システムへプロフィールの更新をリクエストする"
en: "Request to update the profile"
transition: "/users/profile"
hover:
type: "tooltip"
text:
ja: "プロフィール情報を保存します"
en: "Save profile information"
disabled:
condition: "usernameInput is empty"
note:
ja: "ユーザー名が入力されると有効になります"
en: "Enabled when username is entered"
- id: "cancelButton"
type: "button"
label:
ja: "キャンセル"
en: "Cancel"
style: "secondary"
transition: "back"
errorHandling:
"401":
transition: "/login"
message:
ja: "再度ログインしてください。"
en: "Please log in again."
"403":
transition: "/dashboard"
message:
ja: "この操作を行う権限がありません。"
en: "You do not have permission to perform this action."
"404":
transition: "back"
message:
ja: "データが見つかりませんでした。"
en: "Data not found."
"500":
transition: "/error"
message:
ja: "サーバーでエラーが発生しました。時間をおいて再度お試しください。"
en: "A server error occurred. Please try again later."
ポイント:仕様をプログラムにしないための工夫 ✨
仕様書が複雑になりすぎて、それ自体がデバッグ対象のプログラムのようになってしまうのは、避けるべきアンチパターンです。このYAML定義は、そうならないための3つの重要な原則に基づいています。
1. 構造とコンテンツ(自然言語)を分離する
labelやplaceholderなど、ユーザーの目に触れるテキストはすべてjaとenのプロパティで定義します。また、validationはmaxLength:20のように、自然言語を避けて構造的に記述します。これにより、仕様の「構造」と「文言」が完全に分離され、国際化対応が容易になるだけでなく、仕様書そのものの可読性も向上します。
2. 振る舞いは「宣言的」に書く
disabledの条件をcondition: "usernameInput is empty"と書いたり、valueをcalculation: "length(bioTextarea.value)"と定義している点に注目してください。これは状態や要求を宣言しているだけで、「どのように実現するか」には言及していません。これにより、仕様書がシンプルに保たれ、デバッグが必要になる事態を避けています。
3. AI時代のドキュメント連携:idからtagsへ 🔗
かつて、ドキュメント同士を紐づけるには、ファイル名や固有のidを直接記述する必要がありました。しかし、この方法はドキュメントの独立性を損ない、変更に弱いという欠点がありました。
AIエディタの登場で、この常識は変わります。tagsこそが、AIが仕様の文脈を理解するための最大のヒントになります。tagsにuserやprofileと記述しておくことで、AIアシスタントに「この画面に関連するAPI仕様を教えて」と尋ねれば、AIは文脈を理解し、関連するドキュメントを見つけ出してくれます。これにより、各ドキュメントの独立性を保ちながら、AIを介して必要な時にだけ関連性を引き出せます。
Markdownへの変換:伝わる形への「翻訳」 📖
YAMLを「原文」として、誰にとっても分かりやすいMarkdown形式に「翻訳」します。重要なのは、このMarkdownは**YAMLという「原文」からスクリプトで自動生成される「翻訳版」**だということです。これにより、情報の鮮度が常に保たれます。
画面名: ユーザープロフィール編集
- Tags: user, profile, form
- 概要: ユーザーが自身のプロフィール情報を編集・更新する画面です。
- パス: /users/profile/edit
🖼️ 画面要素
| ラベル | 種類 | 必須 | 補足情報 |
|---|---|---|---|
| ユーザー名 | 入力欄 | ✅ | バリデーション: maxLength:20 Note: 登録後に変更不可 |
| 自己紹介 | テキストエリア | バリデーション: maxLength:200 | |
| 現在の文字数 | 表示 | 計算ロジック: 自己紹介の文字数を表示 | |
| 居住地 | プルダウン | ✅ | 選択肢: 北海道, 東京都, 大阪府, 福岡県, その他 |
🔘 アクション
| ラベル | スタイル | アクション内容 | 補足情報 |
|---|---|---|---|
| 更新する | primary | システムへプロフィールの更新をリクエストする | Hover: プロフィール情報を保存します Disabled: ユーザー名が空の場合 |
| キャンセル | secondary | 前画面へ戻る |
➡️ 画面遷移
- 更新するボタン押下時 → /users/profile (プロフィール画面へ)
- キャンセルボタン押下時 → 前の画面に戻る
🚨 エラー時の挙動
- 401 (Unauthorized): /login へ遷移、「再度ログインしてください。」
- 403 (Forbidden): /dashboard へ遷移、「この操作を行う権限がありません。」
- 404 (Not Found): 前の画面に戻り、「データが見つかりませんでした。」
- 500 (Internal Server Error): /error へ遷移、「サーバーでエラーが発生しました。時間をおいて再度お試しください。」
まとめ:AIと共に開発する未来へ 🚀
この手法の最大の価値は、YAMLという共通言語が、人間とAIの共同作業を加速させる点にあります。
- 🎨 デザイナーが考える「必須項目」
- 💻 エンジニアが実装する
required: true - 📈 PMが定義する「未入力では登録不可」というルール
これらはすべて、YAMLで定義された required: true という一つの事実を指します。そして、この「事実」の定義は、もはやエンジニアだけの仕事ではありません。非エンジニアでもこのYAMLにルールを定義し、生成AIに依頼しながらプロダクトを構築できます。
もし自分の書いたYAMLに自信がなければ、まずAIに「このYAMLをMarkdownにして」と依頼し、人間が読める形でレビューすればよいのです。
YAMLは、チーム内の言語の壁を越えるだけでなく、人間とAIの間の言語の壁をも越えるための強力なツールとなります。仕様書にidを振って管理するのではなく、AIが文脈を読んでくれる新しい開発スタイルが、この手法から見えてくるはずです。
あなたのチームでも、YAMLを「共通言語」として導入し、よりスムーズで未来的な開発体制を築いてみてはいかがでしょうか。
Discussion