Skip to content

AI への頼み方 ​

hatake は AI が読み書きしやすいように作ってある(AI に書かせる)。それでもAI が決められないことが残る ── 業務の言葉と、業務の決めごとだ。

AI が決められる人が決める
画面の種別・キーの書き方・型・警告の直し方業務の言葉(項目名・画面名・ボタン名)
一覧に絞り込みを付ける、桁区切りを付ける(好みは advise が言う)業務の決めごと(上限件数・締めの規則・消させない・確認の文)
バックエンドが返すべき形(openapi / types)どこからデータが来るか(Repository の名前、無ければ「まだ無い」)
役割で出し分ける書き方役割の名前(manager なのか sales_manager なのか)

この4つを渡さないと、AI はそれらしい嘘を書く。「顧客名」で通ると思って書いたら現場は「先方名」だった、という類の嘘は、動くので気づけない。

案件の説明は、毎回書かなくていい ​

下に置いたテンプレは画面1枚ごとの頼み方だ。けれど「何のシステムで、何ができないか」 「その業務語をどう書くか」は画面ごとに変わらない。2枚目から毎回書くのは無駄だし、 書き忘れると AI は書ける方に倒す(直せないマスタに編集ボタンが付く)。

そこは1枚に置いて先に読ませる。定義の隣に hatake.project.yaml を置くと、道具は 渡さなくても読む。

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つ ​

急いでいるなら、これだけ書けば着手できる。

  1. 誰が・何のために使う画面か(「営業が、受注を探して状態を直す」)
  2. 扱う項目と、その業務の言葉(「受注番号・顧客名・受注日・状態・金額」)
  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 が「言ったのに入っていない・言っていないのに入っている・未定なのに決まっている」を突き合わせる。頼み方を決めておくと、設計書が副産物になる。

決まっていないことを洗い出す ​

上のテンプレで一番書けないのが**「決まっていないこと」だ。決まっていないことは、 たいてい思い出せない**(思い出せるなら決めてある)。

そこは書いた定義から出せる。

bash
npx -p @hatake-fw/api hatake ask order_entry.yaml
text
決めてください(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行足して印を付ける。次からその問いは 出ない。答えたら消えるので、同じことを二度聞かれない。

yaml
logic:
  - what: 受注は更新日時が変わっていたら弾いて、読み直させる(後勝ちにしない)
    where: server
    answers: [concurrency]

出なかった=決まっている、ではない(表に無いことは聞かない)。そこは道具が毎回自分で 言う。

決めたことは、二度聞かれない ​

答えを書くほどでもない(既定のままでよい)と決めることもある。それも残せる。

yaml
questions:
  decided:
    - id: notify
      why: 却下は同じ画面を見ている担当が拾うので、外へ知らせる口は要らない
      date: "2026-09-14"

理由は必須。理由の無い決定は、後から誰も直せない(「なぜ聞かれなくなったのか」が 消える)。消した件数は黙らずに出るので、聞かれなかったのか、決めたから消えたのかが 読み手に分かる。

この会社でしか出ない決めごとも足せる ​

組み込みの12種類は「業務システムで大抵決めていないこと」だ。稟議番号の採番規則・保存 期間のようなその会社の決めごとは、前書きに足せる。

yaml
questions:
  ask:
    - id: retention
      step: must
      where: outside
      trigger: saves
      ask: この画面で入れたものは何年残しますか。
      why: 保存期間は業務と法律の決めごとで、定義には書けない。
      ifNot: 消してよいものが分からず、結局ずっと残る。
      answer: logic に1行(受注は7年保存 / where outside)。

読み手は組み込みと同じなので、緩い問いは書けない(担当は「サーバ」か「枠組みの外」 だけ・聞く引き金は決まった9つ・印は組み込みとぶつけられない)。出るときは 「(この案件の決めごと)」と付くので、読む人は組み込みと区別できる。

触る前に聞く ​

「この項目もう要らないんだけど、消していい?」も同じ形で聞ける。

bash
npx -p @hatake-fw/api hatake ask order_entry.yaml --impact price
text
"price" を触ると、定義の 3 か所に響きます。
どうしますか(消す/名前を変える/残して画面から隠す)。

一覧の列です:  order_entry: …columns[2].field(単価)
**計算の元**です: order_entry: …computed.fields[1](金額)

辿るのはキー・列・絞り込み・入力欄・計算・条件・遷移のパラメータ・帳票の8つで、 明細の中まで開く。行を絞る条件(where)も計算の元として出る ── ここを見落とすと 合計が黙って変わるので。

定義に無い名前は「影響なし」と言わない(打ち間違いを見て消されると困るから、 「定義のどこにも出てきません」と言う)。辿るのはこの定義の中だけで、サーバやプラグインの 中身は見えない ── そこも毎回書いてある。

名前を変えると決めたら、変える先も出る ​

辿れるようになると、次に必ず来るのが**「じゃあ直して」**。そこは今まで人が10箇所を 手で書き換えていた ── 1つ忘れると、画面は出るのにそこだけ空になる(しかも落ちない)。

bash
npx -p @hatake-fw/api hatake ask order_entry.yaml --impact qty:orderedQty --out draft.yaml
text
"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 に貼る ​

決めていないことは、レビューの席でこそ答えが出る(その場に業務の人が居る)。

bash
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行ずつ読む必要はない(読めるように作ってあるが、読むのは大変だ)。読み返しを読む。

bash
npx -p @hatake-fw/api hatake explain order_search.yaml

「この画面は何ができて、何ができないか」が業務の言葉で出る。そこに書いてあることが意図と違えば、定義が違う。 逆に言えば、頼むときの文とこの出力を見比べられるように頼めばよい ── それが「終わりの判定」を書く意味だ。