AI への頼み方
hatake は AI が読み書きしやすいように作ってある(AI に書かせる)。それでもAI が決められないことが残る ── 業務の言葉と、業務の決めごとだ。
| AI が決められる | 人が決める |
|---|---|
| 画面の種別・キーの書き方・型・警告の直し方 | 業務の言葉(項目名・画面名・ボタン名) |
一覧に絞り込みを付ける、桁区切りを付ける(好みは advise が言う) | 業務の決めごと(上限件数・締めの規則・消させない・確認の文) |
バックエンドが返すべき形(openapi / types) | どこからデータが来るか(Repository の名前、無ければ「まだ無い」) |
| 役割で出し分ける書き方 | 役割の名前(manager なのか sales_manager なのか) |
この4つを渡さないと、AI はそれらしい嘘を書く。「顧客名」で通ると思って書いたら現場は「先方名」だった、という類の嘘は、動くので気づけない。
案件の説明は、毎回書かなくていい
下に置いたテンプレは画面1枚ごとの頼み方だ。けれど「何のシステムで、何ができないか」 「その業務語をどう書くか」は画面ごとに変わらない。2枚目から毎回書くのは無駄だし、 書き忘れると AI は書ける方に倒す(直せないマスタに編集ボタンが付く)。
そこは1枚に置いて先に読ませる。定義の隣に hatake.project.yaml を置くと、道具は 渡さなくても読む。
project_version: "1.0"
system:
what: 卸売の受注。営業が電話で受けた注文を入れて、出荷指示まで出す。
users:
- 営業(10人・事務所の PC)
- 出荷担当(倉庫のタブレット。手袋のまま触る)
premises:
- 商品マスタは購買部の別システムが正。こちらからは直せない(照会だけ)。
- 締めは月末。締めたあとの受注は直せない。
glossary:
- term: 取引先
field: partnerCode
avoid: [顧客, 得意先]
note: 社内の帳票が全部「取引先」なので、画面もそう呼ぶ
naming:
page: snake_case
field: camelCase
role: snake_case読み返しは npx -p @hatake-fw/api hatake project。MCP を繋いでいれば hatake_project が最初に読む。
ここで大事なのは、縛れているものと縛れていないものを分けて見ること。用語と名前は 機械が定義と突き合わせられる(npx -p @hatake-fw/api hatake advise page.yaml --project hatake.project.yaml が「ラベル『顧客コード』に『顧客』が入っています」と言う)。けれど業務の前提は 誰も突き合わせていない ── 人と AI が読むだけだ。読み返しはそれを毎回言う。 「前提を書いたから守られる」ではなく、「前提を渡したから読まれる」まで。
ブランチ名やコミット規約はここに書かない。定義に現れないものは機械が見られないので、 書いても腐る(そちらは AGENTS.md の担当)。
何を決めておくか・どう1枚に落とすかは 先に決めること。キーの意味は 案件の前書き。
最低限の3つ
急いでいるなら、これだけ書けば着手できる。
- 誰が・何のために使う画面か(「営業が、受注を探して状態を直す」)
- 扱う項目と、その業務の言葉(「受注番号・顧客名・受注日・状態・金額」)
- 守る決めごと(「出荷済は直せない」「一括では消させない」)
決まっていないものは「決まっていない」と書く。空白で渡すと AI が埋めてしまうが、「決まっていない」と書けば、AI はそこを TODO にして聞き返す。
埋めるだけのテンプレ
## やること
(1文。例: 受注を探して、状態を直せる画面を作る)
## 使う人
(役割の名前 / 例: sales(営業), manager(承認者)。役割で出し分けるなら、アプリが配っている名前そのまま)
## 画面でやること
- 探す:(何で絞れるか。例: 受注番号・顧客名・受注日の範囲・状態)
- 見る:(一覧に出す列。例: 受注番号・顧客名・受注日・状態・金額)
- 直す:(何を直せるか。例: 状態だけ / 全部 / 直せない)
- 押す:(ボタンと、押したら何が起きるか。例: 一括承認=選んだ行をまとめて承認)
## データの出どころ
(Repository の名前 / 例: orderRepository。まだ無ければ「まだ無い(形はそちらで出して)」)
## 業務の決めごと
- (例: 出荷済の受注は直せない)
- (例: 一括承認は1回 20 件まで)
- (例: 削除は使わない。取消の印を立てる)
## 決まっていないこと
- (例: 却下の理由の選択肢は未定)
## 終わりの判定
(例: validate が警告ゼロ・run のシナリオが通る・explain を読んで意図と合っている)「終わりの判定」を書くのが一番効く。 これが無いと AI は「動いたつもり」で止まる。hatake なら判定が道具で書ける ── それが次の節。
終わりの判定に使えるもの
| 言い方 | AI が回す道具 | 何が保証されるか |
|---|---|---|
「validate を警告ゼロで通して」 | hatake validate --warn-as-error | 書いたのに効かない書き方が無い |
「run のシナリオを通して」 | hatake run --scenario(試す) | その値でその答えになる(計算・必須・押せる) |
「explain を貼って」 | hatake explain | 人が定義を読まずに意図を確かめられる |
「advise を1回かけて、当てるものは相談して」 | hatake advise | 書いていない所(好み)を見落とさない |
「diff で壊していないことを見せて」 | hatake diff(改修のとき) | 既存の呼び出し側を壊していない |
「動きました」ではなく「この5件のシナリオが通りました」で報告させる。定義ファーストの値打ちは、判定が定義から作れることにある。
このテンプレは、そのまま残せる(言ったことを残す)。asked / decisions / undecided / acceptance に落として定義の隣に置くと、hatake trace が「言ったのに入っていない・言っていないのに入っている・未定なのに決まっている」を突き合わせる。頼み方を決めておくと、設計書が副産物になる。
決まっていないことを洗い出す
上のテンプレで一番書けないのが**「決まっていないこと」だ。決まっていないことは、 たいてい思い出せない**(思い出せるなら決めてある)。
そこは書いた定義から出せる。
npx -p @hatake-fw/api hatake ask order_entry.yaml決めてください(2件)。
必ず決めること(2件)
1. [concurrency] 同じ1件を2人が同時に直したら、どちらの入力を残しますか。
決めないと: 先に保存した人の入力が黙って消える。しかも画面には両方とも「保存しました」と出る。
誰の担当か: サーバの担当
この定義で聞いた理由: order_entry: 保存できる画面(type: form)聞かれるのは定義に書けないことだけ。書けることは検証(validate)と助言 (advise)の担当で、そっちは既にある。抜けるのはいつも「定義に書けないので、 誰も気づかない決めごと」のほうだ。
| 聞かれること | 聞かれる理由(画面の事実) |
|---|---|
| 同時に直したらどうするか | 保存できる画面が在る |
| 新しい1件の番号は誰が付けるか | 新規のボタンが在る |
| 消したものを残すか/誰が消したかを残すか | 削除が在る |
| 一括が途中で落ちたら | 選んだ行にまとめて実行するボタンが在る |
| 同じ検証をサーバでも見るか | 必須や検証が書いてある |
| 隠したものをサーバでも止めるか/役割はどこから来るか | roles が書いてある |
| 端数をどう扱うか | 平均や掛け算で計算している |
| その状態は誰が動かすか | 条件で出し分けている |
全部で12種類。定義が無くても npx -p @hatake-fw/api hatake ask --kinds で読めるので、書く前に 何を聞かれるか分かる。
問いは人に返る(AI が埋めない)
hatake_ask は MCP の道具にもなっているが、返ってきた問いを AI が当ててはいけない と道具の説明に書いてある。答えは業務の判断なので、推測で埋めると「決まっているように 見える嘘の設計」ができる。これがいちばん質が悪い(空欄なら誰かが気づくが、埋まって いると誰も見ない)。
答えが決まったら前書きの logic に1行足して印を付ける。次からその問いは 出ない。答えたら消えるので、同じことを二度聞かれない。
logic:
- what: 受注は更新日時が変わっていたら弾いて、読み直させる(後勝ちにしない)
where: server
answers: [concurrency]出なかった=決まっている、ではない(表に無いことは聞かない)。そこは道具が毎回自分で 言う。
決めたことは、二度聞かれない
答えを書くほどでもない(既定のままでよい)と決めることもある。それも残せる。
questions:
decided:
- id: notify
why: 却下は同じ画面を見ている担当が拾うので、外へ知らせる口は要らない
date: "2026-09-14"理由は必須。理由の無い決定は、後から誰も直せない(「なぜ聞かれなくなったのか」が 消える)。消した件数は黙らずに出るので、聞かれなかったのか、決めたから消えたのかが 読み手に分かる。
この会社でしか出ない決めごとも足せる
組み込みの12種類は「業務システムで大抵決めていないこと」だ。稟議番号の採番規則・保存 期間のようなその会社の決めごとは、前書きに足せる。
questions:
ask:
- id: retention
step: must
where: outside
trigger: saves
ask: この画面で入れたものは何年残しますか。
why: 保存期間は業務と法律の決めごとで、定義には書けない。
ifNot: 消してよいものが分からず、結局ずっと残る。
answer: logic に1行(受注は7年保存 / where outside)。読み手は組み込みと同じなので、緩い問いは書けない(担当は「サーバ」か「枠組みの外」 だけ・聞く引き金は決まった9つ・印は組み込みとぶつけられない)。出るときは 「(この案件の決めごと)」と付くので、読む人は組み込みと区別できる。
触る前に聞く
「この項目もう要らないんだけど、消していい?」も同じ形で聞ける。
npx -p @hatake-fw/api hatake ask order_entry.yaml --impact price"price" を触ると、定義の 3 か所に響きます。
どうしますか(消す/名前を変える/残して画面から隠す)。
一覧の列です: order_entry: …columns[2].field(単価)
**計算の元**です: order_entry: …computed.fields[1](金額)辿るのはキー・列・絞り込み・入力欄・計算・条件・遷移のパラメータ・帳票の8つで、 明細の中まで開く。行を絞る条件(where)も計算の元として出る ── ここを見落とすと 合計が黙って変わるので。
定義に無い名前は「影響なし」と言わない(打ち間違いを見て消されると困るから、 「定義のどこにも出てきません」と言う)。辿るのはこの定義の中だけで、サーバやプラグインの 中身は見えない ── そこも毎回書いてある。
名前を変えると決めたら、変える先も出る
辿れるようになると、次に必ず来るのが**「じゃあ直して」**。そこは今まで人が10箇所を 手で書き換えていた ── 1つ忘れると、画面は出るのにそこだけ空になる(しかも落ちない)。
npx -p @hatake-fw/api hatake ask order_entry.yaml --impact qty:orderedQty --out draft.yaml"qty" → "orderedQty" の下書きを作りました(5 か所)。
order_entry: page.form.sections[0].fields[3].columns[1].field … orderedQty
order_entry: page.form.sections[0].fields[3].fields[1].field … orderedQty
order_entry: page.form.sections[0].fields[3].fields[3].computed.fields[0] … orderedQty
…書き換えるのは項目名として書いてある所だけ。ラベル「数量」や確認の文に同じ言葉が 出てきても触らない ── あちらは業務の言葉で、項目名とは別物。差し込み($row.<項目名>)は 項目名なので直す。
当てるのは人。 既定は標準出力に下書きを出すだけで、上書きは --write を渡したとき だけ(fix と同じ立場)。元の文字列を切り貼りしているので、コメントも並びも空白も そのまま残る=差分が読める。
新しい名前がもう使われていたら落ちる。 衝突を黙って作ると2つの項目が1つに潰れて、 どちらの値が出るか定義から読めなくなる(気づくのは動かしたあと)。
そして定義の外は直していない ── サーバがその名前で返している項目・アプリ側の ハンドラ・試験は見えないので、そこは人が一緒に直す。これも毎回書いてある。
決めていないことを PR に貼る
決めていないことは、レビューの席でこそ答えが出る(その場に業務の人が居る)。
npx -p @hatake-fw/api hatake ask app.yaml --markdown表と <details> で出るので、そのまま PR のコメントに貼れる。答えが前書きに入れば その問いは次から出ないので、同じ問いが増え続けない。
会社の決めごと(保存期間・稟議番号の採番規則)は案件をまたぐので、1枚にして --questions team.json で渡せる。並びは組み込み → 会社 → 案件で、印がぶつかったら 落ちる(どちらが正かは道具が決めない)。
ケース別の型
A. 新しい画面を作る
上のテンプレそのまま。加えて近い画面があれば必ず言う(「顧客マスタと同じ作りで」)。AI は例を写して直すのが一番速く、一番外れない。
受注照会の画面を作って。顧客マスタと同じ作りで。
探すのは受注番号(部分一致)・顧客名(部分一致)・受注日(範囲)・状態(未出荷/出荷済)。
一覧は受注番号・顧客名・受注日・状態・金額(¥ 桁区切り)。
行から明細を開く。明細は直せる(出荷済は直せない)。
Repository は orderRepository。
終わりの判定: validate 警告ゼロ・run の下書きを作って通す・explain を貼る。B. 既にある画面を直す(改修)
変える前と後を書く。 「良くして」ではなく「いまこうで、こうしたい」。
order_search(受注照会)を直して。
いま: 一覧に金額が出ていない。
こうしたい: 金額を出す(¥ 桁区切り・右寄せ)。合計は出さない。
決めごと: 列は増やすが、絞り込みは増やさない(画面を広げたくない)。
終わりの判定: diff で「壊す変更なし」・explain --diff で変化を1行で貼る。改修では diff と explain --diff を必ず要求する。前者は「API を壊したか」、後者は「画面がどう変わったか」を言う ── 別の道具なので両方。
C. 不具合を直す
「期待」と「実際」を分けて書く。 hatake ではこれがそのままシナリオになる。
order_entry の小計が合わない。
実際: 取消の行も足されて 1,000 円になる。
期待: 取消の行は外して 200 円。
再現: 明細2行(鉛筆 2×100、ノート 1×800 で取消)。
終わりの判定: この形を run のシナリオに入れて、通ることを見せて。再現手順を値で書くと、AI はまず失敗するシナリオを書き、直してから通す(テストファースト)。「たまに変」だけでは何も始まらない。
D. アプリに繋ぐ・バックエンドの形が要る
order_search を実際に動かしたい。
Repository は REST(/api/orders)。認証はヘッダに Bearer。
バックエンドはまだ無いので、返すべき形を出して。
終わりの判定: refs で要る登録を全部並べて・wire で配線の下書き・openapi を出す。「まだ無い」を言うのが大事。定義から契約が出るので、サーバ側の実装が後でも進められる。
E. DSL に無いことをやりたい
消費税の計算を項目に入れたい(税率は案件で変わる)。
DSL に無いなら、プラグインで足す形を提案して。フレームワーク本体は直さない。
終わりの判定: 定義側の書き方(op の名前と引数)と、登録するコードの両方を出して。hatake の原則は本体を直すよりプラグイン。頼むときにそう言えば、AI は正しい側に寄る(AI に書かせる の原則もそうなっている)。
F. レビュー・棚卸し
この定義(貼る)をレビューして。
見てほしいのは: 誰が何を開けるか・押しても何も起きないボタン・一括の安全(確認と上限)。
終わりの判定: explain --review を貼って、直すべきものは理由付きで挙げて(直すかは相談)。頼み方のアンチパターン
| 言い方 | 何が起きるか | 代わりに |
|---|---|---|
| 「Flutter で受注画面を書いて」 | Widget を書き始める(この枠組みの意味が消える) | 「定義で受注画面を書いて」 |
| 「いい感じにして」 | それらしい嘘(現場に無い項目名)が混ざる | 業務の言葉を渡す。無ければ「決まっていない」 |
| 「テーブル定義を渡すから作って」 | DB の列がそのまま画面になる(業務の画面にならない) | 誰が何をするかを先に書く |
| 「全部の画面を作って」 | どれも半分になる | 1画面ずつ。近い画面を「同じ作りで」と言う |
| 「テストも書いて」(丸投げ) | 通ることしか確かめないテストが生える | 「期待をこう書いたシナリオを通して」 |
| 「役割は適当に」 | 画面は出るのに誰にも見えない | アプリが配っている役割名そのまま渡す |
人が最後に見るもの
AI が書いた YAML を1行ずつ読む必要はない(読めるように作ってあるが、読むのは大変だ)。読み返しを読む。
npx -p @hatake-fw/api hatake explain order_search.yaml「この画面は何ができて、何ができないか」が業務の言葉で出る。そこに書いてあることが意図と違えば、定義が違う。 逆に言えば、頼むときの文とこの出力を見比べられるように頼めばよい ── それが「終わりの判定」を書く意味だ。