前回は、AIにMarkdownモデルを生成させたときに、見た目は自然でも構造として壊れているケースがあることを書きました。
今回は、その対策として、Model WeaveのDogfoodで作った「Markdownモデルを安全に書くためのルール」を整理します。
Markdownは自由に書けることが強みです。
人間が読みやすく、Gitで管理しやすく、Obsidianでも扱いやすい。
一方で、AIが生成し、ツールが解析し、人間がレビューする設計モデルとして使う場合、その自由さがそのままリスクにもなります。
特に壊れやすかったのは、次のような部分でした。
- Markdownテーブル
- Wikilink
- frontmatter
- 型表記
- 定義外情報の書き場所
Model Weaveは、Markdownを正本として、図・プレビュー・診断・PNG出力などを生成するObsidianプラグインです。
そのため、Markdownは単なるメモではなく、設計モデルとして解析される構造データでもあります。
だからこそ、AIに自由に書かせるだけではなく、どこに、どの形式で書かせるかを決める必要がありました。
テーブルヘッダーはFORMATに合わせる
最初に重要なのは、Markdownテーブルのヘッダーです。
人間が読むだけのMarkdownであれば、列を少し増やしても大きな問題にはなりません。
しかし、Model Weaveのようにテーブルをモデルとして解析する場合、ヘッダーは文章表現ではなくスキーマです。
たとえば、あるセクションで次の列構成が期待されているとします。
| id | data | source | required | notes |
|---|---|---|---|---|
ここにAIが「参照先もあった方が便利そう」と判断して、次のように ref 列を追加すると問題になります。
| id | data | source | required | ref | notes |
|---|---|---|---|---|---|
見た目には自然です。
むしろ、人間には親切に見えるかもしれません。
しかし、FORMATで定義されていない列を追加すると、パーサーが期待する構造と一致しなくなります。
今回のDogfoodで分かったのは、AIは「それっぽく便利な列」を自然に足してしまうということです。
特に危なかったのは、次のような列です。
refruledescriptionnotessourcetarget
どれも設計情報としては自然な名前です。
だからこそ、AIが勝手に追加しやすい。
しかし、Markdownモデルでは、列の追加は単なるメモの追記ではありません。
FORMATの変更に近い行為です。
そのため、AI生成時の基本ルールは次のようにしました。
定義外の情報はnotesか任意セクションに逃がす
ただし、AIが追加しようとする情報自体が無価値というわけではありません。
たとえば、ある項目に補足説明を入れたい。
関連するソースファイルを書きたい。
将来の改善メモを残したい。
こうした情報は、設計モデルとして有用です。
問題は、それを定義済みテーブルに勝手な列として追加してしまうことです。
そこで、定義外の情報は次のような場所に逃がす方針にしました。
- 既存の
notes列 ## Notes## Source Links## Design Notes- TODO管理ファイル
- 将来構想用の別モデル・別セクション
たとえば、notes 列があるなら、補足説明はそこに集約します。
| id | data | source | required | notes |
|---|---|---|---|---|
| IN-001 | [[DATA-USER]] | request body | yes | User registration input. Related validation rule is described separately. |
一方で、ソースコードとの対応関係のように、テーブルの物理定義とは性質が違う情報は、別セクションに出します。
## Source Links
| path | notes |
|---|---|
| src/parsers/user-parser.ts | Parses user-related Markdown sections. |
大事なのは、AIの補足を禁止することではありません。
この考え方が重要でした。
テーブルセル内でパイプを使わない
Markdownテーブルで特に危険なのが、セル内の | です。
Markdownでは | が列区切りとして使われます。
そのため、セルの中に | を入れると、テーブル構造が崩れる原因になります。
AIは、ソースコードや型情報を読むと、次のような表記を自然に使います。
string | null
プログラムの型表記としては普通です。
しかし、Markdownテーブル内では危険です。
たとえば、次のような表を書いた場合、
| name | type | notes |
|---|---|---|
| email | string | null | optional email |
人間は string | null のつもりで読めても、Markdownとしては列が増えたように解釈されます。
技術的には \| とエスケープすれば書ける場合もあります。
| email | string \| null | optional email |
ただ、AI生成や他ツールとの連携を考えると、エスケープに頼る運用は不安定になりがちです。
可読性も下がります。
そのため、Dogfoodでは原則として、テーブルセル内に | を含む表記を避ける方針にしました。
任意性を表したいなら、型に詰め込むのではなく、required や not_null、または notes で表現します。
| name | type | required | notes |
|---|---|---|---|
| email | string | no | Optional email address. |
つまり、型表記だけで全てを表そうとしない。
これがかなり大事です。
Wikilinkエイリアスをテーブル内で使わない
Obsidianでは、Wikilinkエイリアスが便利です。
[[DATA-USER|User]]
これは、DATA-USER にリンクしつつ、表示上は User と見せる書き方です。
Markdown本文で使う分には自然です。
しかし、Markdownテーブル内では | を含むため危険です。
| id | data | notes |
|---|---|---|
| IN-001 | [[DATA-USER|User]] | Input data. |
この書き方は、テーブルの列区切りと衝突する可能性があります。
そのため、テーブル内ではエイリアスを使わず、シンプルなWikilinkに寄せます。
| id | data | notes |
|---|---|---|
| IN-001 | [[DATA-USER]] | Input data. |
表示名はリンク先の name や label に任せます。
または、必要なら別列や notes で補足します。
Obsidianでは自然な記法でも、構造化テーブル内では安全とは限らない。
これは今回のDogfoodで強く感じた点です。
frontmatter内のWikilinkはクォートする
次に、frontmatterです。
Markdown本文の中では、Wikilinkはそのまま書けます。
[[DATA-MW-DFD-FLOW-ENTRY]]
しかし、frontmatterはMarkdown本文ではなくYAMLです。
そのため、frontmatter内でWikilinkを書く場合は、ダブルクォートで囲む方が安全です。
避けたい書き方はこれです。
source: [[DATA-MW-DFD-FLOW-ENTRY]]
安全な書き方はこうです。
source: "[[DATA-MW-DFD-FLOW-ENTRY]]"
リンクとして扱う必要がない場合は、Wikilink形式を使わず、ID文字列だけにしてもよいです。
source: DATA-MW-DFD-FLOW-ENTRY
ここで重要なのは、Markdown本文とfrontmatterを同じものとして扱わないことです。
本文はMarkdown。
frontmatterはYAML。
同じ [[...]] でも、安全な書き方は場所によって変わります。
AIにモデルを生成させる場合、この違いを明示しておかないと、自然に未クォートのWikilinkを書いてしまいます。
型表記は単純型を優先する
AIにソースコードを読ませると、プログラム寄りの型表記を使いたがります。
たとえば、次のような表記です。
string[]
Array<string>
Optional<string>
string | null
コードの説明としては自然です。
しかし、Markdownモデルとして安全とは限りません。
string | null は | を含むためテーブルを壊す可能性があります。Array<string> や Optional<string> は、MarkdownレンダラーやHTML解釈と相性が悪い場合があります。string[] も、FORMAT側で想定していない場合は警告対象にした方が安全です。
そのため、Model WeaveのDogfoodでは、型表記はできるだけ単純型に寄せました。
string
number
boolean
datetime
配列性や任意性は、型に詰め込まず、別の列や notes で表現します。
| name | data_type | not_null | notes |
|---|---|---|---|
| tags | string | no | Multiple values. |
この場合、プログラムとしての厳密な型表記からは少し離れます。
しかし、Markdownモデルとしての安定性は上がります。
今回の考え方はこうです。
Markdownモデルでは、型は単純にし、補足情報は補足欄に逃がす。
これがAI生成時には扱いやすいと感じました。
補助ファイルにtypeを付けない
もう一つ、Dogfoodで気づいたのがfrontmatterの type です。
Model Weaveでは、正式なモデルファイルには type を付けます。
たとえば、rule、data_object、mapping のようなモデル種別です。
一方で、運用ガイドやTODO、補足メモのようなファイルは、正式なモデルではありません。
そのような補助ファイルに、
type: note
や、
type: todo
のような値を付けると、Model Weave側が不明なモデル種別として扱い、診断エラーの原因になる可能性があります。
そのため、補助ファイルには type を付けない方針にしました。
---
id: GUIDE-MW-AI-GENERATION-RULES
name: Model Weave AI生成運用ガイド
tags:
- Guide
- AI
---
id、name、tags は付けてもよい。
しかし、正式なModel Weaveモデルではないなら、type は付けない。
これも、AIに明示しておかないと間違えやすいポイントでした。
AIはファイルを分類したがるので、自然に type: guide や type: note を足したくなります。
しかし、その親切さが診断エラーにつながることがあります。
実装済みと将来構想を混ぜない
Dogfoodモデルには、現在の実装だけでなく、将来構想も含まれることがあります。
たとえば、今後作りたいViewerやExplorer、改善案などです。
これ自体は悪いことではありません。
むしろ、設計メモとしては有用です。
ただし、AIに書かせる場合は注意が必要です。
AIは、将来構想をあたかも実装済みのようにDogfoodモデル上に書いてしまう事がありました。
こうした方がいい、こうなっているべき。
という事を常に考えているためかもしれません。
実に人間っぽい誤りをします。
また、読ませるときにも、しっかりと区別しないと実装済みの機能として扱ってしまうことがあります。
そのため、次のような区別を用意しました。
- implemented
- experimental
- future
- design idea
- note
この話は、次回の「AIに渡す情報源をどう整えるか」で詳しく扱う予定ですが、Markdown安全記述の観点でも重要です。
これも、AI生成を実務で使うなら避けて通れない点だと思います。
AI生成用のルールはプロンプトだけでは足りない
ここまでの話を見ると、「プロンプトで注意すればよい」と思うかもしれません。
もちろん、プロンプトは重要です。
しかし、Dogfoodを進めて感じたのは、プロンプトだけでは不十分だということです。
AIに毎回長い注意事項を渡すだけでは、抜けや漏れが出ます。
モデルの種類が増えるほど、守るべきルールも増えます。
人間もAIも、何を優先すべきか分からなくなります。
そのため、次のような形でルールをファイル化しました。
- AI生成運用ガイド
- frontmatter内Wikilink安全記述ガイド
- Markdownテーブルセル安全記述ガイド
これらを情報源としてAIに渡すことで、都度プロンプトだけで説明するよりも安定します。
Model WeaveはMarkdownを正本にするツールです。
だからこそ、Markdownの書き方そのものも、設計資産の一部として管理する必要があると感じました。
おわりに
AIにMarkdownモデルを書かせるときは、「何を書かせるか」だけでは不十分です。
どこに書くか。
どの形式で書くか。
どの情報はテーブルに入れ、どの情報はnotesや別セクションに逃がすか。
どの記法は安全で、どの記法は壊れやすいか。
そこまで決めておく必要があります。
今回のDogfoodで分かったのは、Markdownを設計モデルとして使うなら、自由さと構造のバランスが重要だということです。
Markdownは自由に書けるから便利です。
しかし、AIが生成し、ツールが解析し、人間がレビューするなら、壊してはいけない構造を守る必要があります。
そのために、テーブルヘッダー、Wikilink、frontmatter、型表記、補足情報の逃がし先をルール化しました。
AI生成Markdownを安定させるには、プロンプトの工夫だけでは足りません。
FORMAT、記法ルール、診断、人間レビューをセットで整える必要があります。
次回は、AIに渡す情報源をどう整えるか、実装済みと将来構想をどう分けるかについて書いていきます。
Model Weave Dogfoodサンプルはこちらから
今回紹介している初回公開版ソースベースDogfood を公開しています。
ご興味のある方は是非ご覧ください。


コメント