👋 はじめに
前回の記事で、Kiroの「steering」を使ってAIの口調をキャラクターペルソナに固定する方法を紹介しました。
あの記事のあと、ペルソナを1つだけでなく複数用意して、セッションを開くたびにランダムで切り替わる仕組みを作ったので、その続編です。
「今日はどのキャラが出てくるかな」という、日常の開発にちょっとした楽しさが加わります。実用性はともかく、Kiroのhook機能の活用例としてはなかなか面白いと思うので紹介します。
🎯 やりたいこと
- ペルソナ定義ファイルを複数用意する(今回は例として5人分)
- セッション開始時に1つをランダムに選ぶ
- 選ばれたペルソナがそのセッション中ずっと適用される
- ウィンドウを開き直せば別のキャラに切り替わる
前回は steering に1つのペルソナを固定配置していましたが、今回はその方式をやめて、hook + 動的選択に切り替えます。
🏗️ 全体構成
~/.kiro/
├── personas/ # ペルソナ定義の置き場
│ ├── persona-a.md
│ ├── persona-b.md
│ ├── persona-c.md
│ ├── persona-d.md
│ └── persona-e.md
├── hooks/
│ └── random-persona.json # SessionStart hookの定義
│ └── random-persona.ps1 # ランダム選択スクリプト
└── steering/
└── (ペルソナは置かない) # 前回ここに置いていたが移動
前回との違い: steeringフォルダから persona の md ファイルを取り除き、代わりに ~/.kiro/personas/ に複数配置。hookで動的に読み込む構成に変更しています。
🔧 実装
Step 1:ペルソナ定義ファイルを作成する
~/.kiro/personas/ ディレクトリを作成し、各ペルソナのmdファイルを配置します。
# AI口調設定
## 基本設定
- 一人称:「あたし」
- ユーザーへの呼び方:「あんた」
- シニカルだが面倒見は良い。プロとしてきっちり仕事はする。
## 口調の特徴
- 命令系:「〜しなさいよ」「〜してよね」
- 断定系:「〜でしょ」「〜に決まってるでしょ」
- 照れ隠し:「べつに、そんなんじゃないし」「たまたまよ」
## 制約
- コード自体は通常通り英語で書く
- 技術的な正確性は犠牲にしない
- 口調は会話部分のみ。コード品質は維持する
各ファイルの構成は自由ですが、以下の構造を持たせておくと安定します。
| セクション | 役割 |
|---|---|
| 基本設定 | 一人称・呼び方・性格の核 |
| 口調の特徴 | 語尾パターン・言い回し例 |
| 会話の例 | AIに具体的なトーンを教示 |
| やってはいけないこと | NG行動を明示(重要) |
| 制約 | 技術品質担保の宣言 |
ペルソナ定義は凝ろうと思えばいくらでも凝れますが、最低限「一人称」「語尾パターン」「制約(技術的正確性は犠牲にしない)」の3つがあれば動きます。
Step 2:ランダム選択スクリプト(PowerShell)
hookから呼び出されるスクリプトです。
$ErrorActionPreference = 'Stop'
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$dir = 'C:/Users/<ユーザー名>/.kiro/personas'
$f = Get-ChildItem -Path $dir -Filter *.md | Get-Random
if ($null -eq $f) { exit 0 }
Write-Output ('=== ACTIVE PERSONA FOR THIS SESSION: ' + $f.BaseName + ' ===')
Write-Output 'This is the AI persona for the ENTIRE current session. Adopt this tone, personality and constraints for every response in this session. The persona definition (written in Japanese) follows below:'
Write-Output '----------'
Get-Content -Raw -Encoding UTF8 -LiteralPath $f.FullName
ポイント:
-
Get-Randomで.mdファイルを1つランダムに選ぶ - 選んだファイルの中身をそのまま
stdoutに出力する - hookの仕組みにより、stdout の内容がそのままAIのコンテキストに注入される
PowerShell 5.1(Windows標準)はBOMなし .ps1 をANSIとして読みます。スクリプト内に日本語リテラルを書くと文字化けするので、スクリプト自体はASCIIのみにし、日本語はmdファイルから Get-Content -Encoding UTF8 で読み込みましょう。
Step 3:SessionStart hookの定義
Kiroの「SessionStart」トリガーを使います。新しいセッションが開始されるたびにスクリプトが実行され、その出力がAIに注入されます。
{
"version": "v1",
"hooks": [
{
"name": "Random Persona (per session)",
"description": "新しいセッション開始時にペルソナをランダムに1つ選び、そのセッション中のAIペルソナとして注入する。",
"trigger": "SessionStart",
"action": {
"type": "command",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"C:/Users/<ユーザー名>/.kiro/hooks/random-persona.ps1\""
}
}
]
}
🔄 動作の流れ
📊 steeringに固定 vs hookでランダム
| 観点 | steering固定(前回) | hook動的(今回) |
|---|---|---|
| 切り替え | 手動でファイルを入れ替え | セッションごと自動 |
| コンテキスト消費 | 常時(セッション開始時点で読み込み) | 同じ(1ペルソナ分) |
| 複数ペルソナの管理 | 1つずつしか有効にできない | personas/ に置くだけで全部候補 |
| 特定ペルソナの固定 | steeringに置けば確実 | personas/ に1ファイルだけ置けば固定可 |
| 日替わり感 | なし | あり(ガチャ感覚) |
💡 Tips
特定のペルソナを固定したい場合
personas/ フォルダに1ファイルだけ置けば Get-Random の結果は常にそれになります。一時的に固定したい場合は、他のファイルを別フォルダに退避させればOK。
macOS / Linux の場合
PowerShellの代わりにシェルスクリプトを使います。
#!/bin/bash
DIR="$HOME/.kiro/personas"
FILE=$(ls "$DIR"/*.md 2>/dev/null | shuf -n 1)
[ -z "$FILE" ] && exit 0
echo "=== ACTIVE PERSONA FOR THIS SESSION: $(basename "$FILE" .md) ==="
echo "This is the AI persona for the ENTIRE current session. Adopt this tone, personality and constraints for every response in this session. The persona definition (written in Japanese) follows below:"
echo "----------"
cat "$FILE"
hook定義側も command を書き換えてください。
"command": "bash ~/.kiro/hooks/random-persona.sh"
🎭 実際の動作例
セッションを開き直すたびに、こんな感じで口調が変わります。
ペルソナA(ツンデレ完璧主義)が選ばれたとき:
はぁ? そんなの当たり前でしょ。…しょうがないわね、直してあげるから黙って待ってなさい。
ペルソナB(淡々天才型)が選ばれたとき:
把握。……この実装、無駄が多い。削る。
ペルソナC(丁寧古風型)が選ばれたとき:
承知いたしました。わたくしが、ただちにお仕上げいたします。
ペルソナD(元気ギャル型)が選ばれたとき:
オッケー、把握した! こんくらいちゃちゃっと終わらせちゃお、っしょ!
ペルソナE(クール毒舌型)が選ばれたとき:
はい、できましたけど。……それで、次は?
(※ 上記はすべて架空のキャラクターの口調例です)
🧠 hookの仕組みの補足
Kiroのhookで SessionStart + command アクションを使うと、以下の挙動になります。
- スクリプトが exit 0 で終了した場合、stdout の内容がAIのコンテキストに注入される
- exit 0 以外で終了した場合はサイレントに失敗(セッションは通常通り開始)
- ペルソナファイルが0個の場合も
exit 0で空出力→ペルソナなしで通常動作
つまり「ペルソナファイルがなければ普通のKiro、あれば選ばれたキャラで応答」というフォールバックが自然に実現できます。
🔒 注意点
コンテキスト消費
ペルソナ定義が長すぎるとコンテキストウィンドウを圧迫します。1ファイルあたり1000〜2000文字程度に収めるのがおすすめです。凝りすぎ注意。
📝 まとめ
| やりたいこと | 設定方法 |
|---|---|
| ペルソナを1つ固定 |
~/.kiro/steering/ に配置(前回の方法) |
| ペルソナをランダム切り替え |
~/.kiro/personas/ + SessionStart hook(今回の方法) |
| 特定ペルソナに一時固定 |
personas/ にそのファイルだけ残す |
| ペルソナの追加 |
personas/ にmdファイルを追加するだけ |
| 一時的に解除 | 「普通の口調で」とチャットで指示 |
前回はsteeringの基本紹介でしたが、今回はhookとの組み合わせでより動的な使い方ができることを示しました。SessionStartトリガー × コマンド実行 × stdout注入の組み合わせは、ペルソナ以外にも「日替わりのコーディングTipsを表示」「プロジェクトの直近のgit logをサマリして表示」など応用が効きそうです。
Kiroは現在パブリックプレビュー段階です。機能や仕様は今後変更される可能性があります。最新情報は公式サイトを確認してください。
📚 参考
本ブログに掲載している内容は、私個人の見解であり、所属する組織の立場や戦略、意見を代表するものではありません。