0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

YouAndOrchestra ーClaude Codeで音楽制作するAIエージェントー

0
Last updated at Posted at 2026-05-06

Gemini_Generated_Image_3ggttt3ggttt3ggt.png

はじめに

私にとって音楽はやりたいけどできないものです。昔から音痴でリズム感もなく、楽器も全然うまくなりませんでした。楽器演奏やカラオケ、オタマトーン、鼻歌、作曲等々、色々挑戦しては上達しない日々で、いつしか音楽は自分には向いてないものだと思い、遠ざかっていました。

Claude Codeが登場して日々のソフトウェア開発作業が自動化される中で、ふと思いました。もしかしてClaude Codeは音楽も作れるのでは、と。思い立ったらすぐに試してみたくなり、YouAndOrchestra(以下YaO)というプロジェクトを立ち上げました。YaOはClaude Codeを使って音楽制作するAIエージェントのプロジェクトです。

作曲例

YaOではClaude Codeスキル/sketchで自然言語のプロンプトを指定して、/conductスキルで楽曲を生成できます。ジャンルや楽器構成、テンポ、曲の長さなどを指定するだけで、音楽理論に基づいた楽曲が自動生成されます。

以下にいくつかの作曲例を紹介します。

弦楽曲

プロンプト

/sketch String quartet in D minor. Violin, violin 2, viola, cello. 152 BPM. 80 bars. Classical sonata form with exposition, development, and recapitulation.

日本のアニメソング

プロンプト

/sketch J-Rock anime opening. Electric guitars, violin ensemble, cello, trumpet, french horn, synth pad, timpani. 165 BPM. 19 bars. Intense and heroic with unison melody climax.

静かなジャズ

プロンプト

/sketch Quiet jazz ballad. Tenor sax, piano, contrabass, drums, tubular bell. Bb minor, 80 BPM. 10 bars. Late night atmosphere, sparse and intimate.

パズルゲームのBGM

プロンプト

/sketch Puzzle game BGM. Glockenspiel, marimba, piano and drums. 90 BPM. 30 seconds. Minimal and looping.

その他作曲例

他にも以下のような楽曲が生成可能です。

YouAndOrchestraの仕組み

image.png

YaOは「Music-as-Code」という思想で設計されています。人間が作曲の意図をYAML仕様書として記述し、AIエージェントがそれを解釈して音楽理論に基づいた楽曲を生成します。生成された楽曲は自動評価され、フィードバックループによって品質が改善されていきます。

YaOのアーキテクチャは8層のレイヤー構造になっており、各層が独立したI/O契約を持っています。これにより、生成アルゴリズムを変更してもレンダリング層に影響を与えない、といった柔軟な拡張が可能です。

Layer 名前 役割
0 Constants(定数) MIDI範囲、音階定義、楽器レンジ、強弱記号マッピング
1 Specification(仕様定義) Pydanticモデル、YAML仕様、調性システム
2 Generation(生成戦略) ルールベース、確率的、ループ進化、マルコフ、12音技法
3 IR(中間表現) ScoreIR、Note、Motif、Harmony、Voicing
3.5 Sound Design(音色設計) シンセパッチ、エフェクトチェーン、サンプル管理
4 Perception(知覚代理) 参照曲マッチング、心理マッピング、サプライズモデル
5 Rendering(出力) MIDI書き出し、オーディオレンダリング、楽譜生成
6 Verification(検証・批評) 6次元品質評価、音楽リント、敵対的批評
7 Reflection(振り返り・学習) 決定の来歴記録、ユーザースタイル学習

横断的関心事:

  • Conductor(指揮者:生成→評価→適応→再生成のループ制御)
  • Provenance(来歴:全決定のappend-only記録)
  • CLI(コマンドラインインターフェース)

image.png

音楽理論

YaOは音楽理論をコードとして体系的に実装しています。人間の作曲家が暗黙に従っている理論的制約をプログラムで明示し、生成と評価の両方に活用します。

image.png

調性システム(Tonal System)

音楽生成AIの多くは西洋のメジャー/マイナースケールを前提にしています。しかし実際の音楽はジャズのモード、ブルースの♭3、アンビエントのドローンなど多様です。「長調/短調しか知らないAI」では作れるジャンルが限られてしまうため、調性システムを抽象化し、ジャンルに応じて動的にディスパッチする設計にしました。

YaOは西洋古典音楽の長調・短調だけでなく、多様な調性体系をサポートします。

  • 長調・短調(tonal_major_minor): クラシック、ポップス、ゲーム音楽など
  • モーダル(modal): ドリアン、ミクソリディアンなどの教会旋法を使ったジャズやケルト音楽
  • ペンタトニック(pentatonic): 日本音楽、ブルース、アジア音楽
  • ブルース(blues): ♭3や♭7を特徴とするブルーススケール
  • 無調(atonal): 十二音技法、現代音楽
  • ドローン(drone): アンビエント、持続音ベースの音楽

各調性システムに応じて、和声の実現方法や評価基準が動的に切り替わります。たとえば無調音楽に対して「協和度」を評価しても意味がないため、調性システムに応じてメトリクスが条件付きで有効化されます。

和声と進行

楽曲全体で同じコード進行を使い回すと単調になります。人間の作曲家はVerseとChorusで異なる進行パターンを使い分けますが、これをプログラムで再現するために、セクションごとにパターンプールを分離しました。これにより「Verseは穏やかにI-IV-V-I、Chorusは盛り上がるI-V-vi-IV」といった構造的なコントラストが自動生成されます。

コード進行はセクション(Verse、Chorus、Bridge等)ごとに異なるパターンプールから選択されます。

# セクションごとに異なるコード進行パターン
_SECTION_CHORD_PATTERNS = {
    "verse": [[0, 3, 4, 0], [0, 5, 3, 4], ...],   # I-IV-V-I, I-vi-IV-V...
    "chorus": [[0, 4, 5, 3], [0, 3, 0, 4], ...],   # I-V-vi-IV, I-IV-I-V...
    "bridge": [[5, 3, 4, 0], [1, 4, 5, 3], ...],   # vi-IV-V-I, ii-V-vi-IV...
}

メロディ生成

ランダムに音を並べても音楽にはなりません。人間が「メロディ」と感じるには、音の高低に方向性(上昇・下降・アーチなど)が必要です。YaOではメロディを「音の並び」ではなく「輪郭の形」として捉え、まず全体の形を決めてから個々の音を配置します。これにより、確率的生成でも自然で記憶に残るメロディラインが得られます。

メロディは音楽的な「輪郭(contour)」に基づいて生成されます。

  • アーチ型(arch): 上昇して頂点に達し、下降する
  • 上昇型(ascending): 徐々に音域が上がる
  • 下降型(descending): 徐々に音域が下がる
  • 波型(wave): 上昇と下降を繰り返す

さらに音程の選択では「順次進行(stepwise motion)」を優先し、跳躍進行は効果的に制限することで、歌いやすく自然なメロディラインを実現しています。

リズムとグルーヴ

同じ曲でもドラムパターンが変わるとジャンルが一変します。ジャズのスウィング、ロックのバックビート、EDMのフォー・オン・ザ・フロアなど、リズムはジャンルのアイデンティティそのものです。さらに人間の演奏には微小なタイミングのずれ(グルーヴ)があり、これが機械的な印象を避けるために重要です。YaOではドラムパターンのファミリーとヒューマナイズ量を独立に指定できるようにしました。

リズムパターンは楽器の役割(melody, harmony, bass, rhythm)に応じて異なるプールから選択されます。ドラムパターンは15種類のファミリー(ballad_brushed, jazz_swing_ride, rock_backbeat, four_on_the_floor, trap_half_time等)から選べ、スウィング量やヒューマナイズ(微小なタイミングずれ)も指定可能です。

制約システム

「自由に作って」と言われるより「ハ長調で、暗い和声は避けて、30秒ループで」と言われた方が良い曲が書けるのは人間もAIも同じです。制約はクリエイティビティの敵ではなく足場です。しかし全ての制約が同じ重みではありません。「絶対に守るべきルール」と「できれば従いたい好み」を区別するために、4段階の強度を持つ制約システムを設計しました。

楽曲生成には4種類の制約を指定できます。

種類 意味
must 必ず満たす 「グロッケンシュピールは2小節のモチーフを繰り返す」
must_not 絶対に避ける 「暗い和声は使わない」
prefer できれば従う 「順次進行を優先する」
avoid できれば避ける 「急激なダイナミクス変化を避ける」

これらの制約は自然言語で記述でき、生成と評価の両方で参照されます。

YouAndOrchestraプロジェクトの構成

YaOはClaude Codeの拡張機能(Skills, Agents, Commands)を活用して音楽制作ワークフローを構築しています。

Claude Codeとの統合

YaOはClaude Codeの以下の機能を活用しています。

機能 用途
スラッシュコマンド /sketch, /compose, /conduct, /render, /critique, /feedback 等の対話的ワークフロー
CLAUDE.md 音楽理論の制約、レイヤーアーキテクチャの規則、コーディング規約をClaude Codeに教示
エージェント Composer, Critic, Orchestrator等のサブエージェント定義
スキル ジャンルごとの作曲知識(cinematic, voice-leading, piano, tension-resolution等)

CLAUDE.mdの役割

CLAUDE.mdはYaOの開発において重要な役割を果たしています。700行以上のこのファイルには以下が記述されています。

  • 7つの不可侵ルール: レイヤー境界の厳守、来歴記録の必須化、サイレントフォールバック禁止など
  • レイヤーアーキテクチャ: どのモジュールが何をインポートできるかの厳密な規則
  • ジャンル普遍性テスト: 「この変更はブルースでも動くか?無調音楽でも?」という10項目チェックリスト
  • コードパターン: 正しいパターンと避けるべきアンチパターンの具体例

これにより、Claude Codeは音楽制作という特殊なドメインでも、一貫性のあるアーキテクチャに従ったコードを生成できるようになっています。

Claude Codeによる音楽制作の仕組み

YaOの中心は人間のプロンプトをベースに「Conductor(指揮者)」が楽曲を自動的に制作することです。人間が意図を伝え、AIが生成・評価・改善を繰り返す、まさにオーケストラのリハーサルのような反復プロセスで楽曲を磨き上げていきます。

生成→評価→適応→再生成のフィードバックループ

音楽制作は一発で完成することはほぼありません。プロの作曲家もデモを書き、聴き直し、修正を繰り返します。YaOではこの「書いて→聴いて→直す」サイクルをプログラムで自動化しました。人間が「良い/悪い」を判断する代わりに、定量的な評価メトリクスとルールベースの批評で品質を判定し、自動的に仕様を修正して再生成します。

┌──────────────┐
│ 人間の意図     │  intent.md + composition.yaml
└──────┬───────┘
       ▼
┌──────────────┐
│ 生成(Generate)│  stochastic / rule_based / loop_evolution
└──────┬───────┘
       ▼
┌──────────────┐
│ 評価(Evaluate)│  6次元×11+メトリクスでスコアリング
└──────┬───────┘
       ▼
┌──────────────┐
│ 批評(Critique)│  35+の敵対的ルールで問題検出
└──────┬───────┘
       ▼
┌──────────────┐     ┌──────────────┐
│ 適応(Adapt)  │────→│ 再生成        │──→ ループ
└──────────────┘     └──────────────┘
  1. Generate(生成): YAML仕様書に基づいてMIDIノートを生成します。生成戦略は複数あり、仕様書で指定できます。
  2. Evaluate(評価): 生成された楽曲を6次元(構造、メロディ、和声、美学、アレンジ、音響)で自動評価します。各メトリクスには目標値と許容範囲があり、合格率で品質を定量化します。
  3. Critique(批評): 35以上の敵対的ルールにより、クリシェ検出、構造的退屈さ、声部進行の誤り、スタイルの不一致などを検出します。
  4. Adapt(適応): 評価結果に基づいて仕様書を自動修正します。たとえば「音域活用率が低い」→「temperatureを上げる」、「セクションコントラストが不足」→「ブリッジのダイナミクスを変更」など。
  5. Regenerate(再生成): 修正された仕様書で再度生成し、品質が収束するまで繰り返します。

このループはClaude Codeスキルの /conduct コマンドで自動実行され、指定した反復回数内で最良の結果を返します。

image.png

6次元評価システム

「良い曲」とは何か?

この問いに単一のスコアで答えるのは不可能です。メロディが美しくても構造が破綻していれば曲として成立しません。逆にリズムが正確でもメロディが退屈なら聴く価値がありません。YaOでは音楽の品質を6つの独立した次元に分解し、それぞれに目標値と許容範囲を設けました。これにより「何が良くて何が悪いのか」を具体的に診断でき、適応フェーズで的確な修正が可能になります。

次元 重み 評価内容
Structure(構造) 20% セクションコントラスト、クライマックス位置、密度カーブ
Melody(旋律) 25% 音域活用、モチーフ想起強度、輪郭多様性、順次進行比率
Harmony(和声) 20% 協和度、和声機能適合、緊張-解決
Aesthetic(美学) 20% 参照曲距離、心理的覚醒度/感情価
Arrangement(編曲) 10% 楽器役割明確性、周波数衝突リスク
Acoustics(音響) 5% BPM精度、LUFS目標、スペクトルバランス

image.png

来歴追跡(Provenance)

AIが生成した音楽に対して「なぜこの音なの?」と聞かれたとき、「なんとなく」では困ります。人間の作曲家には「ここはドミナントモーションで解決感を出したかった」のような意図がありますが、AIの判断は通常ブラックボックスです。YaOでは全ての生成決定をappend-onlyのログに記録し、後から「この音が選ばれた理由」を遡れるようにしました。これにより人間が結果を理解し、的確なフィードバックを返せるようになります。

YaOでは「なぜその音が生成されたか」を全て記録します。全ての生成決定にはエージェント名、フェーズ、信頼度、代替案が付与され、append-onlyのログに保存されます。これにより、楽曲のどの部分がどの判断に基づいて作られたかを遡って説明できます。

provenance.record(
    layer="generator",
    operation="generate_melody",
    parameters={"section": "verse", "contour": "arch"},
    rationale="アーチ型輪郭でVerseの穏やかな上昇感を表現",
    agent="composer",
    phase="DETAILED_FILLING",
    confidence=0.85,
)

image.png

生成アルゴリズム

音楽のジャンルによって最適な生成手法は異なります。クラシックのソナタ形式には理論に忠実なルールベースが適していますが、ジャズの即興感にはマルコフ連鎖が、EDMのレイヤー構築にはループ進化が向いています。単一のアルゴリズムで全ジャンルをカバーするのは無理があるため、YaOでは戦略パターンで生成アルゴリズムを差し替え可能にし、仕様書のstrategyフィールドで選択できるようにしました。

YaOには5種類の生成アルゴリズムがあり、楽曲の特性に応じて使い分けます。

戦略 特徴 適したジャンル
rule_based 完全決定論的、再現性100% テスト用、シンプルな楽曲
stochastic シード+温度で制御された確率的生成 ほぼ全ジャンル(デフォルト)
loop_evolution コアループを段階的に進化させる EDM、lo-fi、アンビエント
markov マルコフ連鎖による確率的遷移 ジャズ即興風、実験的
twelve_tone 12音技法、行操作 現代音楽、無調

最も汎用的な stochastic 戦略では、seed(乱数シード)と temperature(冒険度: 0.0=保守的〜1.0=冒険的)の2パラメータで出力を制御します。同じseedと仕様書からは常に同じ結果が得られるため、再現性が保証されます。

image.png

実際に音楽を作ってみよう

YaOでの作曲は、Claude Codeのスラッシュコマンドを使った対話的なプロセスです。ここでは先ほどの「パズルゲームBGM」を例に、実際の作曲ワークフローを解説します。

image.png

ステップ1: スケッチ(/sketch)

/sketch コマンドは6ターンの対話で、曲のアイデアを完全な仕様書に変換します。まずは以下のようなシンプルなプロンプトから始めます。

> /sketch puzzle game BGM. Glockenspiel, marimba, piano and drums. 90 BPM. 30 seconds.

/sketch コマンドでは以下の6ターンで仕様が完成します。

ターン 内容
1 感情と目的の確認
2 参照スタイルとアンチリファレンス
3 楽器、構造、キー、テンポ
4 テンションとデンシティの時間軸カーブ
5 最終仕様の確認
6 生成と評価結果の提示

各ターンではAIが具体的な提案を行い、ユーザーは「yes」で承認するか、具体的な修正を伝えます。これにより音楽の専門知識がなくても、対話的に仕様を詰めていくことができます。

/sketchのやりとりのイメージは以下のようになります。

Claude Codeの対話例(クリックで展開)
 ▐▛███▜▌   Claude Code v2.1.91
▝▜█████▛▘  Opus 4.6 (1M context) · Claude Max
  ▘▘ ▝▝    ~/tmp/YaO

❯ /sketch puzzle game BGM. Glockenspiel, marimba,
piano and drums. 90 BPM. 30 seconds.

⏺ Turn 1: Core Emotion & Purpose

  Based on your description, I hear:

  - Core emotion: playful, curious, light-hearted
  - Purpose: background music for a puzzle game
  (looping during gameplay)
  - Listening context: game speakers/headphones,
  repeated listening, needs to stay unobtrusive
  while maintaining engagement

  Instruments confirmed: glockenspiel, marimba,
  piano, drums

  Constraints noted: 90 BPM, 30 seconds (short loop)

  The mallet-heavy palette (glockenspiel + marimba)
  gives a toy-like, crystalline quality — perfect
  for puzzle games. Piano provides harmonic
  grounding, drums keep gentle momentum.

  Is this right? Anything to adjust on the emotional
   feel — e.g., should it lean more
  whimsical/childlike, or more cerebral/minimalist?

❯ yes

⏺ Turn 2: References & Anti-References

  Draw inspiration from (style/feel):
  - Nintendo puzzle game soundtracks (Tetris Effect,
   Captain Toad, Picross)
  - Minimalist mallet patterns (Steve Reich-esque
  interlocking)
  - Bright, major-key xylophone/marimba textures

  Avoid:
  - Dark or tense harmony
  - Heavy/loud dynamics (it's background, not
  foreground)
  - Complex jazz chords (keep it simple and
  approachable)
  - Sudden changes or dramatic shifts (distracting
  during gameplay)

  Does this sound world fit? Any styles to add or
  remove?

❯ yes

⏺ Turn 3: Instruments, Duration, Structure

  Here's what I'd suggest:

  - Instruments:
    - Glockenspiel — melody (high, bell-like motifs)
    - Marimba — counter-melody / rhythmic ostinato
    - Piano — harmonic support (light chords,
  arpeggios)
    - Drums — soft kit, brushes or light
  shaker/hi-hat pattern
  - Duration: 30 seconds (~11 bars at 90 BPM)
  - Sections: A (4 bars) → B (4 bars) → A' (3 bars,
  slight variation for seamless loop)
  - Key: C major (bright, simple, toy-like)
  - Tempo: 90 BPM (confirmed)
  - Time signature: 4/4
  - Loopable: yes (A' tail connects seamlessly back
  to A)

  The short loop with ABA' gives enough variety to
  avoid fatigue while staying coherent over repeated
   plays. The glockenspiel carries a simple,
  memorable 2-bar motif that recurs.

  Adjust anything? I can shift to a different key (F
   major for warmth?), change structure, or tweak
  roles.

❯ yes

⏺ Turn 4: Trajectory (Emotional Arc)

  Here's the emotional arc for the 30-second loop:

  Tension:  ░░▓▓▓▓▓▓████████░░░░
  Density:  ░░▓▓▓▓▓▓████████▓▓░░
            A       B       A'

  - A (bars 1–4): Tension 0.3, density 0.4 —
  glockenspiel motif enters with light piano.
  Marimba joins bar 2. Gentle, inviting.
  - B (bars 5–8): Tension 0.5, density 0.6 — all
  four instruments active. Marimba plays a
  complementary counter-rhythm. Mild peak of energy.
  - A' (bars 9–11): Tension 0.25, density 0.35 —
  thins back out. Drums drop to just shaker. Piano
  simplifies. Prepares seamless return to A.

  Climax: middle of section B (bar 6–7) — the
  fullest moment, but still light and unobtrusive.

  The arc is intentionally gentle — no dramatic
  peaks or valleys. It breathes just enough to avoid
   monotony over repeated loops.

  Does this feel right? I can flatten it further
  (more ambient/static) or add a bit more contrast.

❯ yes

⏺ Turn 5: Final Spec Confirmation

  Here's your complete specification:

  title: Puzzle Light
  key: C major
  tempo_bpm: 90
  time_signature: 4/4
  duration_seconds: 30
  loopable: true
  instruments:
    - name: glockenspiel, role: melody
    - name: marimba, role: counter_melody
    - name: piano, role: harmony
    - name: drums, role: rhythm
  sections:
    - name: section_a, bars: 4, dynamics: mp
    - name: section_b, bars: 4, dynamics: mf
    - name: section_a_prime, bars: 3, dynamics: mp
  trajectory:
    - section: section_a, tension: 0.3, density: 0.4
    - section: section_b, tension: 0.5, density: 0.6
    - section: section_a_prime, tension: 0.25,
  density: 0.35
  generation:
    strategy: stochastic
    seed: 42
    temperature: 0.4

  intent.md:
  ▎ A playful, light-hearted 30-second loop for a
  puzzle game. Bright mallet instruments
  (glockenspiel, marimba) carry interlocking melodic
   patterns over gentle piano chords and soft drums.
   Minimalist, curious, unobtrusive — designed for
  repeated listening without fatigue. Inspired by
  Nintendo puzzle game aesthetics and Steve
  Reich-style mallet textures.

  Ready to create? I'll write the project files and
  generate.

❯ yes

  Read 1 file, listed 3 directories (ctrl+o to
  expand)

⏺ Good, I have the structure. Now let me create the
  project files for puzzle-light.

⏺ Bash(mkdir -p /Users/shibuiyusuke/tmp/YaO/specs/pr
      ojects/puzzle-light)
  ⎿  Done

⏺ Write(specs/projects/puzzle-light/composition.yaml
       )
  ⎿  Wrote 102 lines to specs/projects/puzzle-l
     ight/composition.yaml
       1 title: "Puzzle Light"
       2 genre: "game"
       3 tonal_system:
       4   kind: tonal_major_minor
       5   key: "C"
       6   mode: "major"
       7
       8 tempo_bpm: 90
       9 time_signature: "4/4"
      10 total_bars: 11
     … +92 lines (ctrl+o to expand)

⏺ Write(specs/projects/puzzle-light/trajectory.yaml)
  ⎿  Wrote 34 lines to specs/projects/puzzle-li
     ght/trajectory.yaml
       1 title: "Puzzle Light"
       2 description: "Gentle arc for a puzzl
         e game loop — mild peak in section B
         , seamless return"
       3
       4 waypoints:
       5   - section: section_a
       6     bar: 1
       7     tension: 0.3
       8     density: 0.4
       9     energy: 0.35
      10     description: "Glockenspiel motif
          enters with light piano. Marimba jo
         ins bar 2."
     … +24 lines (ctrl+o to expand)

⏺ Write(specs/projects/puzzle-light/intent.md)
  ⎿  Wrote 19 lines to
     specs/projects/puzzle-light/intent.md
       1 # Intent: Puzzle Light
       2
       3 A playful, light-hearted 30-second l
         oop for a puzzle game. Bright mallet
          instruments (glockenspiel, marimba)
          carry interlocking melodic patterns
          over gentle piano chords and soft d
         rums. Minimalist, curious, unobtrusi
         ve — designed for repeated listening
          without fatigue. Inspired by Ninten
         do puzzle game aesthetics and Steve
         Reich-style mallet textures.
       4
       5 ## Emotional Core
       6 - Playful, curious, light-hearted
       7 - Never tense or dark
       8 - Maintains engagement without deman
         ding attention
       9
      10 ## Listening Context
     … +9 lines (ctrl+o to expand)

⏺ Write(specs/projects/puzzle-light/sketch_state.jso
       n)
  ⎿  Wrote 27 lines to specs/projects/puzzle-li
     ght/sketch_state.json
       1 {
       2   "turn": 6,
       3   "project_name": "puzzle-light",
       4   "intent": {
       5     "emotion": "playful, curious, li
         ght-hearted",
       6     "purpose": "puzzle game BGM",
       7     "context": "game speakers/headph
         ones, repeated listening"
       8   },
       9   "references": {
      10     "like": ["Nintendo puzzle games"
         , "Steve Reich mallet patterns", "mi
         nimalist interlocking"],
     … +17 lines (ctrl+o to expand)

⏺ Now let me generate the piece.

⏺ Bash(python -m yao conduct --spec
      specs/projects/puzzle-light/composition.yaml
      --project puzzle-light --iterations 3 2>&1 |
      head -100)
  ⎿  /Users/shibuiyusuke/tmp/YaO/.venv/bin/pyth
     on: No module named yao.__main__; 'yao' is
      a package and cannot be directly executed

⏺ Bash(python -m yao.cli conduct --spec
      specs/projects/puzzle-light/composition.yaml
      --project puzzle-light --iterations 3 2>&1 |
      head -100)
  ⎿  /Users/shibuiyusuke/tmp/YaO/.venv/bin/pyth
     on: No module named yao.cli

⏺ Bash(which yao 2>/dev/null; pip show yao
      2>/dev/null | head -5; ls src/yao/cli*
      2>/dev/null || find src/yao -name "cli*" -o
      -name "__main__*" 2>/dev/null)
  ⎿  /Users/shibuiyusuke/tmp/YaO/.venv/bin/yao
     Name: yao
     Version: 0.1.0
     … +5 lines (ctrl+o to expand)

⏺ Bash(yao conduct --spec
      specs/projects/puzzle-light/composition.yaml
      --project puzzle-light --iterations 3 2>&1)
  ⎿  Error: Exit code 1
     Conducting: Puzzle Light (C major, 90.0 BPM,
     max 3 iterations)
     Error: Drum pattern 'light' not found.
     Available: ['ballad_brushed', 'bartok_7_8',
     'bulgarian_7_8', 'chiptune', 'compound_6_8',
     'four_on_the_floor', 'game_drive_16bit',
     'jazz_swing_ride', 'lofi_laidback',
     'orchestral', 'pop_8beat', 'rock_backbeat',
     'take_five_5_4', 'trap_half_time', 'waltz_3_4']

⏺ Update(specs/projects/puzzle-light/composition.yam
        l)
  ⎿  Added 1 line, removed 1 line
      46      time_signature: "4/4"
      47
      48  drums:
      49 -  pattern_family: "light"
      49 +  pattern_family: "ballad_brushed"
      50    swing: 0.1
      51    humanize_ms: 5.0
      52    ghost_notes_density: 0.05

⏺ Bash(yao conduct --spec
      specs/projects/puzzle-light/composition.yaml
      --project puzzle-light --iterations 3 2>&1)
  ⎿  Conducting: Puzzle Light (C major, 90.0 BP
     M, max 3 iterations)
     2026-05-06 07:31:27 [info     ] conductor_
     … +164 lines (ctrl+o to expand)

⏺ Turn 6: Generation Complete!

  Project: puzzle-light — generated successfully.

  Results:
  - Duration: 29.3s | Bars: 11 | Notes: 229
  - Quality Score: 6.6/10 | Pass Rate: 91% (10/11
  metrics pass)
  - Output:
  outputs/projects/puzzle-light/iterations/v004

  Evaluation highlights:

  ┌────────────────────┬───────┬─────────────────┐
  │       Metric       │ Score │     Status      │
  ├────────────────────┼───────┼─────────────────┤
  │ Section contrast   │ 0.55  │ PASS            │
  ├────────────────────┼───────┼─────────────────┤
  │ Bar count accuracy │ 1.00  │ PASS            │
  ├────────────────────┼───────┼─────────────────┤
  │ Consonance ratio   │ 0.81  │ PASS            │
  ├────────────────────┼───────┼─────────────────┤
  │ Stepwise motion    │ 0.41  │ PASS            │
  ├────────────────────┼───────┼─────────────────┤
  │ Motif recall       │ 0.26  │ FAIL (target    │
  │ strength           │       │ 0.55)           │
  └────────────────────┴───────┴─────────────────┘

  Critic notes (no critical issues):
  - 2 major: tension contrast is low (intentional
  for puzzle BGM — we want gentle, not dramatic)
  - 11 minor: mostly marimba note overlaps and
  missing cadences

  The one failing metric (motif_recall_strength) is
  because the glockenspiel motif isn't repeating as
  strongly as the evaluator expects. This could be
  improved with /regenerate-section if you want more
   repetition.

  Next steps:
  - /render puzzle-light — render to audio
  - /critique puzzle-light — get detailed
  adversarial feedback
  - /regenerate-section puzzle-light section_a — if
  you want to strengthen the motif

  Would you like to render it or refine further?

✻ Crunched for 1m 30s

ステップ2: 作曲と指揮(/compose, /conduct

/sketch の最終ターンで自動的に /conduct が実行されますが、仕様書を直接編集して再生成することもできます。

❯ /compose specs/projects/puzzle-light/composition.yaml

❯ /conduct puzzle-light

/conduct スキルは指定した回数だけ「生成→評価→適応」ループを回し、最良の結果を保存します。

ステップ3: レンダリング(/render

生成されたMIDIをオーディオに変換します。

❯ /render puzzle-light

ステップ4: 批評と改善(/critique, /regenerate-section

生成結果に不満がある場合、批評スキルで詳細なフィードバックを得られます。

❯ /critique puzzle-light

❯ /regenerate-section puzzle-light section_a

/regenerate-section はセクション単位の部分的再生成を行います。全体を作り直すのではなく、問題のあるセクションだけを改善できるため、すでに良い部分を保持したまま品質を向上させられます。

ステップ5: フィードバック(/feedback

人間の感想を自然言語で伝えると、仕様書の修正提案に変換されます。

❯ /feedback puzzle-light グロッケンシュピールのモチーフをもっと繰り返してほしい。ドラムがもう少し控えめでもよい。

YouAndOrchestraによる楽曲制作の詳細

楽曲プロジェクトの3つのファイル

YaOでは1つの楽曲プロジェクトが3つのファイルで構成されます。これらは /sketch コマンドの6ターン対話で自動生成されます。

ファイル 役割 生成タイミング
intent.md 楽曲の創作意図(なぜ作るのか) Turn 1–2で感情・目的・参照スタイルから生成
composition.yaml 楽曲の技術仕様(何を使って作るか) Turn 3, 5で楽器・構造・制約から生成
trajectory.yaml 感情の時間変化(どう変化するか) Turn 4でテンション・密度カーブから生成

image.png

この3ファイル分離には明確な理由があります。intent.md は「なぜ」、composition.yaml は「何を」、trajectory.yaml は「どのように変化するか」をそれぞれ記述します。分離することで、同じ意図(パズルゲームBGM)でも楽器構成を変えたり、同じ楽器構成でも感情カーブを変えたりといった組み合わせの自由度が生まれます。

intent.md(意図の記述)

楽曲の「魂」にあたるドキュメントです。技術的パラメータでは表現しきれない創作意図を自然言語で記述します。

フィードバックループで適応を行うとき、「この曲は何を目指しているのか」という原点に立ち返る必要があります。intent.md はその判断基準です。たとえばCriticが「テンションコントラストが低い」と指摘しても、intent.md に「穏やかでループ向き」と書かれていればそれは許容される、という判断ができます。

以下はパズルゲームBGMの例です。

# Intent: Puzzle Light

A playful, light-hearted 30-second loop for a puzzle game.
Bright mallet instruments (glockenspiel, marimba) carry
interlocking melodic patterns over gentle piano chords and
soft drums. Minimalist, curious, unobtrusive — designed for
repeated listening without fatigue.

## Emotional Core
- Playful, curious, light-hearted
- Never tense or dark
- Maintains engagement without demanding attention

## Listening Context
- Puzzle game background music
- Repeated listening over extended play sessions
- Must not become annoying or fatiguing

## Sound World
- Toy-like, crystalline mallet timbres
- Bright, major-key harmony
- Minimalist interlocking patterns
- Soft, brushed percussion

composition.yaml(楽曲仕様書)

楽曲の技術的な仕様を定義するファイルです。このファイルを自然言語のプロンプトではなくYAMLにした理由は3つあります。

  1. 再現性: 同じYAMLからは常に同じ楽曲が生成されます。自然言語プロンプトはLLMの解釈に揺れがありますが、YAMLは曖昧さがありません。
  2. 差分管理: YAMLはgit diffで変更箇所が明確にわかります。「前回からテンポだけ変えた」「制約を1つ追加した」といった変更が追跡可能で、楽曲の進化過程がバージョン管理できます。
  3. バリデーション: PydanticモデルでYAMLを読み込むことで、不正な値(テンポが0以下、存在しない楽器名、矛盾する制約など)を生成前に即座に検出できます。

仕様書の構造自体も意図的に設計しています。tonal_systemを独立させたのはジャンルごとに和声実現を切り替えるため、instrumentsroleを持たせたのは楽器の機能的な関係(melody/harmony/bass/rhythm)から生成パターンを選択するため、constraintsを自然言語で書けるようにしたのは音楽的な意図を技術的パラメータに還元しきれない場合に対応するためです。

以下はパズルゲームBGMの例です。

title: "Puzzle Light"
genre: "game"
tonal_system:
  kind: tonal_major_minor
  key: "C"
  mode: "major"

tempo_bpm: 90
time_signature: "4/4"
total_bars: 11
loopable: true

instruments:
  - name: glockenspiel
    role: melody
    density_factor: 0.6
    techniques: [staccato, bell_tone]
  - name: marimba
    role: counter_melody
    density_factor: 0.5
    techniques: [ostinato, arpeggiated]
  - name: piano
    role: harmony
    density_factor: 0.4
    techniques: [arpeggiated, block_chord]
  - name: drums
    role: rhythm
    density_factor: 0.3
    techniques: [brushes, light_shaker]

sections:
  - name: section_a
    bars: 4
    dynamics: "mp"
  - name: section_b
    bars: 4
    dynamics: "mf"
  - name: section_a_prime
    bars: 3
    dynamics: "mp"

constraints:
  - type: must
    scope: global
    rule: "glockenspiel carries a simple 2-bar melodic motif"
  - type: must_not
    scope: global
    rule: "dark or tense harmonies"
  - type: prefer
    scope: global
    rule: "stepwise melodic motion in glockenspiel"

generation:
  strategy: stochastic
  seed: 42
  temperature: 0.4

trajectory.yaml(感情の時間軸設計)

音楽は時間芸術です。「最初から最後まで同じテンション」の曲は退屈ですし、「ずっとクライマックス」の曲は疲れます。trajectory.yaml は楽曲の感情的な起伏を時間軸に沿って定義するファイルです。

image.png

composition.yaml と別ファイルにしたのは、「何を使って作るか」と「時間とともにどう変化するか」は独立した関心事だからです。この分離により、同じ楽器構成でも「穏やかなアーチ」と「急激なビルドアップ」で全く異なる曲を生成できます。テンション(緊張度)、デンシティ(音の密度)、エネルギーの3軸をウェイポイント形式で指定し、生成器はこのカーブに沿って各セクションのノート密度やダイナミクスを調整します。

以下はパズルゲームBGMの例です。

title: "Puzzle Light"
description: "Gentle arc for a puzzle game loop  mild peak in section B, seamless return"

waypoints:
  - section: section_a
    bar: 1
    tension: 0.3
    density: 0.4
    energy: 0.35
    description: "Glockenspiel motif enters with light piano. Marimba joins bar 2."

  - section: section_b
    bar: 5
    tension: 0.5
    density: 0.6
    energy: 0.55
    description: "All four instruments active. Marimba counter-rhythm. Mild peak."

  - section: section_a_prime
    bar: 9
    tension: 0.25
    density: 0.35
    energy: 0.3
    description: "Thins out. Drums to shaker only. Piano simplifies. Prepares loop return."

climax:
  section: section_b
  bar: 6
  description: "Fullest moment  all instruments active, but still light and unobtrusive"

loop_point:
  enabled: true
  crossfade_bars: 0.5
  description: "section_a_prime tail connects seamlessly back to section_a"

各ウェイポイントでテンション・密度・エネルギーを0.0〜1.0で指定し、クライマックスの位置やループ接続点も明示します。生成器はウェイポイント間をベジェ曲線で補間し、小節ごとの目標値を算出します。

生成結果(outputs/)

/conduct を実行すると、フィードバックループの各イテレーションごとに成果物が outputs/projects/<name>/iterations/ に保存されます。以下はパズルゲームBGMの最終イテレーション(v004)の例です。

outputs/projects/puzzle-light/iterations/
├── v002/
│   ├── full.mid              # 全楽器統合MIDI
│   ├── stems/                # 楽器ごとの個別MIDI
│   │   ├── glockenspiel.mid
│   │   ├── marimba.mid
│   │   ├── piano.mid
│   │   └── drums.mid
│   ├── analysis.json         # 構造分析結果
│   └── evaluation.json       # 6次元評価スコア
├── v003/                     # 適応後の再生成
│   └── (同じ構造)
└── v004/                     # 最終イテレーション
    ├── full.mid
    ├── stems/
    │   ├── glockenspiel.mid
    │   ├── marimba.mid
    │   ├── piano.mid
    │   └── drums.mid
    ├── analysis.json
    ├── evaluation.json
    └── provenance.json       # 全決定の来歴記録

各ファイルの役割:

ファイル 内容
full.mid 全楽器を含む完成MIDIファイル。DAWに読み込んで編集可能
stems/*.mid 楽器ごとに分離されたMIDI。個別に音色を変えたり、特定パートだけ差し替えたりできる
analysis.json 楽曲の構造的分析(総ノート数、音域、楽器別ノート数、セクション一覧など)
evaluation.json 6次元の品質評価スコア。各メトリクスの値・目標・合否が記録される
provenance.json 全ての生成決定の来歴。どのエージェントが、どのフェーズで、なぜその判断をしたかが追跡可能

イテレーションが複数残るのは意図的です。v002よりv003の方が評価スコアが高いとは限らず、「v002のメロディは良かったがv003でリズムが改善された」といった比較ができます。最終的にどのイテレーションを採用するかは人間が決めます。

analysis.json の例(抜粋):

{
  "title": "Puzzle Light",
  "total_notes": 229,
  "duration_seconds": 29.3,
  "pitch_range_names": ["A2", "C8"],
  "instruments_used": ["drums", "glockenspiel", "marimba", "piano"],
  "sections": ["section_a", "section_b", "section_a_prime"],
  "tempo_bpm": 90.0,
  "key": "C major",
  "notes_per_instrument": {
    "drums": 60,
    "glockenspiel": 48,
    "marimba": 85,
    "piano": 36
  }
}

evaluation.json の例(抜粋):

{
  "title": "Puzzle Light",
  "scores": [
    {
      "dimension": "structure",
      "metric": "section_contrast",
      "score": 0.549,
      "target": 0.5,
      "tolerance": 0.4,
      "detail": "0.549 within [0.100, 0.900]"
    },
    {
      "dimension": "melody",
      "metric": "pitch_range_utilization",
      "score": 0.823,
      "target": 0.65,
      "tolerance": 0.35,
      "detail": "0.823 within [0.300, 1.000]"
    }
  ]
}

このように、生成プロセス全体が透明で再現可能な形で保存されます。MIDIファイルは音楽としての成果物、JSONファイルは「なぜこの楽曲がこうなったか」の説明責任を果たす記録です。

これらの過程を通して、以下のような楽曲が制作されます。

今後の展望

今後は以下の方向で開発を進めていきます。

  • 音色の制御: 現在はMIDI出力が中心ですが、シンセパッチやエフェクトチェーンを仕様書で指定し、音色まで含めた楽曲生成を目指します
  • DAW統合: MCP経由でDAWと双方向通信し、YaOで生成した楽曲をそのままDAWで編集できるようにします
  • ボーカル対応: 歌唱性制約やブレス位置を考慮したメロディ生成で、歌モノの作曲を可能にします

image.png

まとめ

YaOの目標は「音楽制作をやりたいけど音楽が苦手な人」のための創作環境です。音楽理論の知識がなくても、感情や目的を言葉にできれば、AIが音楽理論的な裏付けを持った楽曲を生成してくれます。人間はクリエイティブな判断(「もっと明るく」「ここは静かに」)に集中し、技術的な実装はAIに任せる。そんな「You and Orchestra」—あなたとともにあるオーケストラ—の世界を目指しています。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?