はじめに
この記事は、GLOBIS アドベントカレンダーシリーズ1の7日目の記事となります。
自己紹介
業務委託で「グロービスAI経営教育研究所(GAiMERi)」をお手伝いしている imunew です。
GAiMERi でどんなことをしているかについて詳しくは、こちらを参照いただければと思います。
仕様書駆動教材開発とは
ソフトウェア開発の世界では「仕様書駆動開発(Spec-Driven Development)」というアプローチがにわかに注目を集めています。
仕様書駆動開発では、コーディングエージェント(生成AI)に仕様書や計画書を書かせてから、その仕様・計画にしたがって実装(コーディング)を進めていくのが特徴となっています。
これにヒントを得て、生成AIに演習問題を作成させるのが、仕様書駆動教材開発(造語)です。
GAiChaL-2.0のシナリオ作成を生成AIで半自動化する
GAiMERi で開発・運用しているサービスに、GAiChaL-2.0 という受講生向けの復習ツールがあります。
この1つ1つの演習は、以下のようにフローチャートのような構造を持っています。
(以下は、管理画面のスクリーンショットです。)
ちなみに、このフローチャートのUIには、Sequential Workflow Designer を使っています。
リリースから1年以上経過して、受講生から「演習数が少ない」「もっと演習を解きたい」といった声をいただきます。
リリース当初からこの演習の量産という課題に、GAiMERiの 健太さん は取り組んできました。
試行錯誤の末、以下の要領で生成AIに、(いい感じに)演習を作らせることができました。
プロンプト概要
下記のプロンプトをベースに、作りたい演習のテーマに沿って「ラーニングポイント」を記述します。
あなたはビジネススクールの教員です。
チャットボットによる演習問題を作成するため、演習問題用のフローチャートの概要を作成しようとしています。
下記のラーニングポイントに関して、フローチャートの概要を番号付きリストを使って作成してください。
# 条件
- 番号付きリストのラベルは4つの種類のみです
1. ボット(問い)
2. ボット(判定)
3. ボット(解説)
4. 学習者
- 番号付きリストは少なくとも13以上、多くても18以内です
- 最初の「ボット(問い)」ではラーニングポイントに出てくる単語を使わないでください
- 出力は番号付きリストの内容だけにしてください。内容に関する説明は一切不要です
# ラーニングポイント
(省略)
# フローチャートの概要例
## 例1
1. ボット(問い)
- 将来、グローバルで活躍するため、英語力を強化したい。どんな打ち手があるか3つ挙げさせる
2. 学習者
- (回答させる)
(以下、番号付きリストが続く)
## 例2
(番号付きリスト)
## 例3
(番号付きリスト)
あとは、生成AIに投げてみて、修正が必要であれば、修正箇所とどのように修正してほしいか、生成AIに追加で指示します。
番号付きリストができたら、あとは、以下のプロンプトを投げて、Mermaid 記法に変換してもらいます。
下記の条件に従って、フローチャートの概要をMermaid記法に変換してください。
# 条件
- 最初は「開始」で始まり、最後は「終了」で終わってください
- 「開始」「終了」はsquareノードを使ってください
- 「ボット(判定)」はdiamondノードを使ってください
- 「ボット(問い)」「学習者」「ボット(解説)」はroundノードを使ってください
- 「ボット(解説)」が正解の場合、不正解の場合に分かれる場合、分岐するようにしてください
- ノード内に問いや解説などのテキストを記述するようにしてください
- ノード内のテキストでは「1. 」のような番号付きリストの表記は使用しないでください
- 出力はMermaidの内容だけにしてください。内容に関する説明は一切不要です
このアプローチのポイントは以下のとおりです。
- フローチャートを番号付きリストにすることで、生成AIにお手本を示す(
Few-shot learning)ことができるようになった - 番号付きリストを Mermaid 記法に変換することで
- フローチャートを人間が目視で確認できる
- Mermaid 記法はプレーンテキストなので、ソフトウェア上で再利用しやすい
- ラーニングポイントをどうするかに集中でき、それ以外の工程は生成AIがやってくれる
GAiChaL-2.0のシナリオとの互換性
Mermaid 記法で表現できるデータには限界があり、GAiChaL-2.0のシナリオを完全に網羅することはできません。
なのですが、用途は十分にありそうです。
- Mermaid 記法から GAiChaL-2.0 にインポート
- 新規作成のテンプレートとして使う
- GAiChaL-2.0 から Mermaid 記法にエクスポート
- プロンプトに渡す
Few-shot learningとして入力する
- プロンプトに渡す
既存のシナリオを Mermaid 記法に変換、フローチャートを表示してみた
GAiChaL-2.0のシナリオデータを、Mermaid 記法に変換する部分の実装は Claude にやってもらいました。
管理画面からシナリオデータをJSON形式でエクスポートし、それをMermaid記法へ変換してほしい、と指示しました。
特にこちらからデータ構造の解説はしていないにもかかわらず、いい感じにコードを書いてくれました。
(Claude には演習のことをより一般的な「クイズ」と言い換えて指示しました)
UI部分の実装は自分でやって、最終的には以下のような画面を実装してみました。
左側には Mermaid 記法のソース、右側にはフローチャートを表示しています。
ページ右側のチャート表示部分は以下のような実装になっています。
mermaid.js が React 用のコンポーネントを用意してくれてないので、mermaid.render したSVG要素をHTMLに埋め込んでいます。
おまけ的に、HTMLファイルのダウンロード機能も実装しました。
import { PropsWithChildren, useCallback, useEffect, useId, useRef, useState } from 'react'
import mermaid from 'mermaid'
import { Button, Flex } from 'antd'
import { DownloadOutlined } from '@ant-design/icons'
export default function MermaidDiagram({ code }: PropsWithChildren<{ code: string }>) {
const outputRef = useRef<HTMLDivElement>(null)
const [svg, setSvg] = useState<string>()
const render = useCallback(async () => {
if (outputRef.current && code) {
try {
const { svg } = await mermaid.render('mermaid-flowchart', code)
outputRef.current.innerHTML = svg
setSvg(svg)
} catch (error) {
console.error(error)
outputRef.current.innerHTML = 'Invalid syntax'
}
}
}, [code])
useEffect(() => {
mermaid.initialize({
startOnLoad: true,
theme: 'default',
flowchart: {
useMaxWidth: true,
htmlLabels: true,
curve: 'basis',
padding: 20,
nodeSpacing: 100,
rankSpacing: 80,
},
})
render()
}, [render])
if (!code) {
return
}
const onDownloadButtonClick = () => {
if (!svg) {
return
}
const a = document.createElement('a')
a.download = 'mermaid_flowchart.html'
const blob = new Blob([`<html lang="ja"><body>${svg}</body></html>`], { type: 'text/html' })
a.href = URL.createObjectURL(blob)
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
return (
<div className={'mermaid-container'}>
<Flex>
<div style={{ marginLeft: 'auto' }}>
<Button onClick={onDownloadButtonClick}>
<DownloadOutlined />
HTMLファイルをダウンロード
</Button>
</div>
</Flex>
<div className={'mermaid'} ref={outputRef} />
</div>
)
}
おわりに
まだまだ始まったばかりの取り組みですが、演習を量産し、受講者が納得いくまで復習できるようにしていきたいです。
お知らせ
グロービスでは継続的にエンジニアを募集しています。
興味のある方は下記のリンクをご覧になってください。
ではでは。


