🛡️

AIエージェント×スキーマバリデーションでドキュメント生成を堅牢にする

に公開

概要

AIエージェントにドキュメントを生成させたら「思い通りのフォーマットにならない」ということがあります。ここでは Markdown → YAML → CUE の 3 段階でバリデーション強度を高めながら、同一のアウトプット品質 を実現する方法を紹介します。

  • 1️⃣ まず“テンプレのみ”の Markdown 生成の弱点を確認
  • 2️⃣ YAML スキーマで最小限の保証をかけ、Markdown へ変換
  • 3️⃣ CUE で 検証と Markdown 出力を 1 ファイルで完結 させる方法を紹介

それぞれサンプルコード付きで解説します。

1. Markdown(バリデーションなし)

説明

  • 自然言語テンプレ×AI でそのまま Markdown を生成する最短手段。
  • 速いものの揺らぎ・抜け漏れが頻発し、CI で検知できない。
  • ユースケース: ワンショットメモ・軽量ドキュメント。

プロンプト

以下のフォーマットで Markdown を生成してください
ファイル名は `YYYY-MM-DD-todo.md` としてください
タグは最低2つ、タスクは最低3つ必要です

```markdown
# YYYY-MM-DD の ToDo

[[YYYY-MM-DD]]
#tag1 #tag2

- 朝会で進捗共有
- PRレビュー
- スキーマバリデーション記事執筆
```

簡易的なものであれば成功率は高いですが、複雑になってくると抜けてくる項目が目立ってきます。()

2. YAML スキーマ

説明

  • YAML Schema + ajv で必須項目と型を厳密保証。
  • Markdown への整形は別スクリプトで行う 2 ステップ構成。
  • 利点: コマンド実行時に型不整合を弾ける。
  • 課題: 変換スクリプト維持コスト。

サンプルコード

schema.yaml

$schema: "http://json-schema.org/draft-07/schema#"
title: "Daily ToDo Schema"
type: "object"
required:
  - title
  - date
  - tags
  - tasks
additionalProperties: false
properties:
  title:
    type: "string"
  date:
    type: "string"
    pattern: "^\\d{4}-\\d{2}-\\d{2}$"
  tags:
    type: "array"
    minItems: 2
    items:
      type: "string"
  tasks:
    type: "array"
    minItems: 3
    items:
      type: "string"

todo.yaml(中間生成物)

title: "Daily Work Tasks"
date: "2024-06-21"
tags:
  - "work"
  - "urgent"
tasks:
  - "Reply to client emails"
  - "Prepare project report"
  - "Team meeting at 15:00"

コマンド

バリデーション (ajv 使用)

npx ajv validate -s schema.yaml -d todo.yaml --strict=true

YAML → Markdown 変換は別途スクリプトを用意

プロンプト

以下の YAML Schema を満たす `todo.yaml` を生成してください。
以下のコマンドでスキーマを検証します。

```sh
npx ajv validate -s schema.yaml -d todo.yaml
```

3. CUE ― 検証と生成を 1 ファイルで

説明

  • CUE は「スキーマ+データ+テンプレート」を 1 ファイルに統合できる宣言的 DSL。cuelang.org
  • cue cmd … gen検証&Markdown 生成をワンショット
  • YAML Schema では煩雑な条件・計算ロジックをシンプルに表現可能。

サンプルコード(note_tool.cue)

cue cmd を使う時は、*tool.cue のようにファイル名を指定する必要があります。

import (
	"strings"
	"text/template"
	"tool/file"
)

// ------------------------------
// To‑Do データ + バリデーション
// ------------------------------
item: {
	title: string                       @tag(title)
	date:  =~"^\\d{4}-\\d{2}-\\d{2}.*$" @tag(date)

	rawTags: string @tag(tags)
	tagList: strings.Split(rawTags, ",")
	taglistLength: {len(tagList) >= 2}
	tags: tagList

	rawTasks: string @tag(tasks)
	taskList: strings.Split(rawTasks, ",")
	taskListLength: {len(taskList) >= 1}
	tasks: taskList
}

// ------------------------------
// Markdown テンプレート
// ------------------------------
mdTmpl: """
	# {{ .title }}

	[[{{ .date }}]]
	{{ range .tags }}#{{ . }} {{ end }}

	{{ range .tasks }}- {{ . }}
	{{ end }}
	"""

// ------------------------------
// Markdown 生成コマンド
// ------------------------------
command: gen: {
	write: file.Create & {
		filename: "\(item.date)_todo.md"
		contents: template.Execute(mdTmpl, item)
	}
}

コマンド

cue cmd \
  --inject title="2025-05-06 の ToDo" \
  --inject date="2025-05-06" \
  --inject tags="work,ai,validation" \
  --inject tasks="朝会で進捗共有,PRレビュー,スキーマバリデーション記事執筆" \
  gen note_tool.cue


プロンプト

`cue cmd` を使って TODOファイルを生成してください
以下例

```sh
cue cmd \
  --inject title="2025-05-06 の ToDo" \
  ...
```

まとめ

手法 構造保証 変換ステップ 運用コスト おすすめ用途
Markdownのみ なし 0 メモ・ドラフト
YAML Schema 必須 & 型 1 (検証) + 1 (変換) ★★ 中規模ドキュメント
CUE 必須 & 型 & 高度ロジック 1 (検証+生成) ★★★ 継続運用する記事生成

Takeaway: “AI だから壊れる”はもう古い。CUE まで踏み込めば、指示→検証→完成 を 1 コマンドで自動化し、エージェントドリブンなドキュメント生成を安全にスケールできます。

Discussion