はじめに
ChatGPT用に書いたCustom InstructionsをClaudeにも貼る。Cursor用には少し短くする。ローカルLLMでは、さらに別の形式にする。
最初は手作業でも何とかなります。しかし、プロジェクトが増え、文体や制約や作業方針が増えてくると、プロンプトのコピペ運用はだんだんつらくなります。
問題は、プロンプト文字列を保存していないことではありません。
ローカルにProfileの正本を置き、targetごとにプロンプトを生成したい。
そのために作っているOSSが、Sayane(紗綾音)です。
https://github.com/zyx-corporation/sayane
この記事では、PyPIからSayaneをインストールし、sayane initでローカルProfile Storeを作り、サンプルProfileをChatGPT / Claude向けにcompileするところまでを扱います。
Sayaneとは
Sayaneは、LLM向けの人格設定・文脈・方針をローカルProfileとして保持し、ChatGPT / Claude / Gemini / DeepSeek / local-openwebui などのtarget向けにcompileするCLI/ツールキットです。
Sayaneは、単なるプロンプト集ではありません。
ひとつのProfileを正本として管理し、必要なtargetごとに出力を生成します。
この記事では、まずCLIでこの最小フローを確認します。
前提環境
この記事では、次の環境を前提にします。
Python 3.11+
pip
macOS / Linux / Windows
Sayane 1.0.3
Windowsでも利用できますが、本文中のコマンド例は主にmacOS / Linuxのシェルを想定しています。Windows PowerShellを使う場合は、パスや仮想環境の有効化コマンドを適宜読み替えてください。
インストール
PyPIからインストールします。
pip install 'sayane==1.0.3'
インストールできたか確認します。
sayane --version
macOS / Linuxでは、インストールスクリプトも使えます。
curl -fsSL https://raw.githubusercontent.com/zyx-corporation/sayane/main/scripts/install.sh | bash
Windows PowerShellの場合は、次のスクリプトを使えます。
irm https://raw.githubusercontent.com/zyx-corporation/sayane/main/scripts/install.ps1 | iex
ただし、この記事ではPyPIから入れる方法を中心に進めます。
ローカルProfile Storeを初期化する
まず、SayaneのローカルProfile Storeを作ります。
sayane init
通常、次のような構造が作られます。
~/.sayane/
profiles/
default/
sayane.profile.yaml
context/
candidates/
構造として見ると、sayane init はローカルにProfileの正本と、文脈メモ、更新候補の置き場を作ります。
sayane.profile.yaml がローカルProfileの正本です。
context/ は、Markdown形式の文脈メモを置くためのディレクトリです。
candidates/ は、会話やcaptureから得た更新候補を置くためのディレクトリです。
この時点で、Profileをローカルに置く準備ができました。
サンプルProfileをChatGPT向けにcompileする
サンプルProfileを使うため、リポジトリをcloneします。
git clone https://github.com/zyx-corporation/sayane.git
cd sayane
ChatGPT向けにcompileします。
sayane compile --target chatgpt --profile examples/profiles/minimal.yaml
標準出力に、ChatGPT向けの出力が表示されます。出力は環境やバージョンによって変わる可能性がありますが、概念的には次のような形式です。
{
"messages": [
{
"role": "system",
"content": "..."
}
]
}
ここで確認したいことは、サンプルProfileからChatGPT向けのプロンプト出力が生成されることです。
同じProfileをClaude向けにcompileする
次に、同じProfileをClaude向けにcompileします。
sayane compile --target claude --profile examples/profiles/minimal.yaml
ポイントは、Profileを変えていないことです。
変えたのは、--target だけです。
つまり、同じProfileから、targetごとに異なる出力を生成できます。
この構造により、ChatGPT用に書いた長いプロンプトをClaudeへそのまま貼るのではなく、Profileを正本として扱い、対象ごとに出力する形にできます。
Profile → Prompt IR → Adapter の考え方
Sayaneの内部構造をもう少しだけ説明します。
Sayane Profileは、ユーザーの文脈の正本です。
Prompt IRは、Prompt Intermediate Representationの略で、プロンプト中間表現です。特定のLLMに依存しない共通の構造として、Profileの内容をいったん整理します。
Adapterは、そのPrompt IRをtarget別の形式へ変換する層です。
この構造にすると、「ChatGPT用プロンプトをClaudeにそのまま貼る」のではなく、「同じProfileからそれぞれ向けに生成する」形になります。
同一人格 ≠ 同一プロンプト文字列
同一Profile → targetごとに最適化された出力
複数LLMを使う場合、この違いはだんだん効いてきます。
自分のProfileでcompileする
sayane init を実行した後は、デフォルトProfileを使ってcompileできます。
sayane compile --target chatgpt
Claude向けに出力する場合は、targetを変えます。
sayane compile --target claude
Markdownとして確認したい場合は、exportを使えます。
sayane export --format markdown --target chatgpt
これで、自分のローカルProfileをもとに、target別の出力を確認できます。
Markdown文脈を追加する
Sayaneでは、Profile配下のcontext/にMarkdown文脈を置くことができます。
たとえば、プロジェクト用の文脈を追加してみます。
cd ~/.sayane/profiles/default/context
cat > project.md <<'EOF'
# Project Context
- This project uses Python.
- Prefer small, testable modules.
- Avoid hidden global state.
EOF
新しいMarkdownを追加したら、indexを更新します。
sayane storage index
その後、compileします。
sayane compile --target chatgpt
流れとしては、Markdown文脈をProfile Storeへ置き、indexを更新し、compile時にtarget別の出力へ反映する形です。
これにより、ローカルのMarkdown文脈をProfile側の文脈として扱えるようになります。
ObsidianやGitと組み合わせる場合も、基本的な考え方は同じです。文脈をローカルに置き、必要なtarget向けに出力します。
Candidate / evaluate / lineage は何のためか
Sayaneは、取り込んだ文脈をいきなりProfileへmergeしない設計です。
LLMとの会話からは、便利そうな設定や方針が生まれます。しかし、それをそのまま正本に入れると、長期的にはノイズになることがあります。
コード変更をいきなりmainに入れず、Pull Requestや差分レビューを通すのに近いです。
文脈更新も同じで、一度候補として扱い、評価してから採用します。
この仕組みは、Profileを長期的に育てていくために必要になります。
第一回では詳しく扱いませんが、今後の記事でCandidate、evaluate、approve / reject、lineageの流れを掘り下げる予定です。
CLI以外の接続面
この記事ではCLIだけを扱いましたが、Sayaneには他にも接続面があります。
CLIで最小フローを確認した後、必要に応じてBridge、MCP、Extensionへ広げていく想定です。
できることと制限
Community Edition v1.0.3では、主に次の機能を利用できます。
CLIでinit / compile
ChatGPT / Claude / Gemini / DeepSeek / local-openwebui向けadapter
Markdown context
Storage index
Candidate evaluation
MCP / Bridge / Extension
一方で、制限もあります。
外部vaultとのリアルタイム双方向同期は未対応です。Chrome Extensionは別途buildが必要です。巨大なcontextを無制限に入れる用途ではありません。Commercial Edition相当の暗号化SQLiteなどは別製品として扱う予定です。
最新の状態はREADMEとロードマップを参照してください。
https://github.com/zyx-corporation/sayane/blob/main/README.md
https://github.com/zyx-corporation/sayane/blob/main/docs/roadmap.md
連載予告
この連載では、Sayaneの設計と使い方を、実装者向けに順番に整理していきます。
第1回である本記事では、Sayaneをインストールし、ローカルProfileからChatGPT / Claude向けプロンプトを生成する最小フローを扱いました。
第2回では、Sayane ProfileとPrompt IRの設計を扱います。なぜプロンプト文字列を直接正本にしないのか、Profileと中間表現を分けることで何が楽になるのかを整理します。
第3回では、Adapterの作り方を扱います。同じPrompt IRから、ChatGPT向け、Claude向け、local-openwebui向けの出力をどう分けるのかを見ます。
その後は、Candidate / evaluate / lineageによる文脈更新管理、MCP ServerとしてCursorから使う方法、Markdown / Obsidian / Gitを使った文脈運用、RDE的な評価をどのように実装へ落とすかを順に扱う予定です。
まとめ
複数LLM時代には、プロンプト文字列を保存するだけでは足りなくなります。
ローカルProfileを正本にし、targetごとにcompileすることで、文脈管理を少し扱いやすくできます。
Sayaneは、そのためのOSSです。
プロンプトをコピペで運ぶのではなく、文脈をProfileとして管理し、必要な形式へ生成する。
Sayaneは、そのための小さなCLIから始まります。