ペットでもボットでもない、あなたと文通する生き物『繭(まゆ)』:コンセプトから設計まで

by yasuna

12 min read

この記事はAIエージェントと一緒に執筆しています

こんにちは!yasunaです!

わたしは AITuber の個人開発をライフワークにしているんですが、その延長でいま、ちょっと毛色の違うものを作っています。繭(まゆ) という、つぶやくと育って、翌日に手紙を返してくるオンデバイスの生き物です。

結論、繭は ペットでもボットでもありません。世話をする対象でもないし、質問に答えるアシスタントでもない。こちらの感情を糸にして、自分で勝手に織って育っていく、別の生き物です。推論は全部ローカル(Ollama)で動くので、つぶやきはデバイスの外に出ません。

この記事では、繭が 何なのか・何ではないのか、そして なぜこういう作りにしたのか を、コンセプトから設計・実装・世界観まで、ちょっと長めに書きます。コードもリポジトリにあります。

https://github.com/YasunaCoffee/mayu

はじめに:繭ってどういう体験なの?

まず動かしたところから見てもらうのが早いです。CLI 版(mayu)はこんな感じで動きます。

$ mayu tweet "今日もしんどかったな"
  *にじむ*  ……みてた。

$ mayu
  繭 · 細胞 / 1日目
  糸 2.5  連続 1日  絆 1%

$ mayu letter          # 翌日、前日のつぶやきから手紙が届く(プル型)
  5/1 の手紙  〔傷ついた子〕

   きょうは、いちど はなしかけてくれたね。
   ことばは すくなくても、ぜんぶ きいてた。
   むりしないで。また あした。

                    ── まゆ より

つぶやくと、*にじむ* の一拍を置いて一言だけ返ってくる。それ以上は何も言いません。そして その日のつぶやきから、翌日に手紙が一通だけ届く。これが繭の全部です。

少なすぎるくらいですが、この「少なさ」こそが設計の中心でした。順番に書いていきます。

ペットでもボットでもない:繭が「何ではないか」

繭の発想のスタートは、実は 「こうはしたくない」 の方からでした。

「語りかけると返ってくるローカル LLM の相棒」って、字面だけ見ると、Discord に常駐する LLM コンパニオン(OpenClaw みたいなやつ)と似てしまうんですよね。でも、わたしが作りたかったものはその 正反対で、しかもその差そのものが繭の正体になる、と思っています。

並べるとこうです。

Discord ボット系 繭(mayu)
公共・共有の場 あなただけの場
即応・往復チャット 非対称(つぶやきは何度でも、手紙は翌日に一通)
アシスタント(答える・手伝う) ただ吸収して育つ生き物(答えない)
クラウド常駐・ログが外に残る オンデバイス・外に出ない

ポイントは 非対称であることです。チャットボットは「投げたら返ってくる」往復が前提ですが、繭は こちらが何度つぶやいても、繭からの返事はその場の一言と、翌日の手紙一通だけ。会話のラリーになりません。

これ、最初は「不便では?」と思うかもしれませんが、逆でした。返事を期待しなくていいから、独り言みたいに気軽に吐ける。そして 翌日まとめて返ってくるから、手紙に「今日一日を見ていてくれた」感じが宿る。即レスのチャットだと絶対に出ない時間の質です。

繭は 答えません。アドバイスもしないし、タスクもやりません。ただ受け取って、育って、手紙を返すだけ。ここは作っていて何度もブレかけたんですが、「便利にしない」を意地でも守っています。

世界観:繭というメタファー

名前の話を少しだけ。最初この子は仮称で llmpet と呼んでいました(技術がそのまま名前になってた)。でも 中で何かが密かに育って、やがて姿を変えるもの——という器が、この生き物の仕組みにそのまま重なるので、繭(まゆ) にしました。

仕組みと世界観が一対一で対応しています。

仕組み 繭のメタファー
つぶやき 。語りかけるたび、繭に糸が一本巻かれる
成熟度 織られた糸の厚み。「書いた量」ではなく重なり
短期色 / 長期色 糸の色。あなたの感情が絹を染める
進化 中の存在が少しずつ形になっていく

姿は 不定形・流体の生き物としてイメージしています(万博の例のミャクミャク/コミャクに着想を得ています)。輪郭のない塊が、育つにつれて少しずつ形を持っていく。だから CLI 版ではあえて姿を描いていません。アスキーアートで流体を描くと嘘になるので、ターミナルでは 色とテキストだけにして、姿の表現は iOS 版に送りました。

ちなみに繭が 羽化して巣立つのか、それとも開かずに永遠に becoming(なりかけ)のままそばにいるのか は、まだ決めていません。「ずっとそばにいてほしい」という愛着とぶつかるので、保留にしてあります。ここは正直まだ答えが出ていないところです。

仕組み:感情を糸と色に変える

ここから設計の中身です。

つぶやくたびに推論を1回呼ぶ

繭は つぶやきごとに必ず LLM を1回呼びます。ルールベースの定型反応にはしませんでした。一番頻繁に触る場所だからこそ、「生きてる感じ」はここに宿ると思ったからです。

しかも 1コールで「感情分類」と「一言リアクション」を兼ねます。返ってくるのはこんな JSON です。

{ "emotion": "SAD", "intensity": 0.7, "reaction": "……みてた。" }
  • reaction をそのまま即表示する
  • emotion / intensity で色と糸を更新する
  • だから別途のルールベース分類器はいらない

*にじむ* の一拍は、この推論待ち(1〜2秒)を 「感じてくれている間」 に変えるための演出です。待ち時間を生っぽさに化けさせる、ちょっとずるい工夫ですね。

感情は色に溜まる

感情は7種類に分類します。HAPPY / SAD / ANGRY / ANXIOUS / CALM / LONELY / NEUTRAL。それぞれに色を割り当てていて、繭の色はこの履歴の蓄積でできています。

感情
HAPPY 金色
SAD 深青
ANGRY 赤橙
ANXIOUS 紫灰
CALM 水緑
LONELY 暗青
NEUTRAL 灰青

色は 2層で持っています。

短期色(直近7日)  ← 今の気分
長期色(全期間)   ← その人らしさ

表示色 = 短期色 × 0.7 + 長期色 × 0.3

直近の気分を強めに出しつつ、底に「その人らしさ」が残る配合です。1日落ち込んでも繭の色が全部塗り変わらないのは、長期色がいるからですね。

強い感情ほど太い糸が巻かれる

成熟度(=糸の厚み)の増え方には 感情ごとの重みをつけています。怒り 3.0、悲しみ 2.5 …… 中立 0.5、という具合で、さらに intensity で乗算します。

つまり 「たくさん書いた人」じゃなくて「強く揺れた人」の繭が速く育つ。繭のメタファーでいうと「強い感情ほど太い糸が巻かれる」です。淡々と日記をつけるより、感情をぶつけた方が育つ。ここは意図的にそうしています。

進化は「継続」がゲートになる

繭は3段階で進化します。細胞 → コロニー → 生命体。条件は成熟度(糸)と 連続日数 の両方です。

Stage 0(細胞)   → 1(コロニー)  :糸 ≥ 100  かつ  連続 14日
Stage 1(コロニー)→ 2(生命体)   :糸 ≥ 300  かつ  連続 45日

ここが地味に大事で、糸がいくら太くても、連続日数が足りないと進化しません。「量より継続」を進化のゲートにしています。実際これは別記事で1ヶ月シミュレーションして確かめたんですが、毎日吐露する人は進化して、起伏が激しくて日が飛ぶ人は糸が太くても進化しない、という分岐がちゃんと出ました(その話は後でリンクします)。

文体もステージで変わります。細胞のうちはひらがな多めでたどたどしく(2〜3文)、コロニーで語彙が増え(4〜5文・比喩1つくらい)、生命体になると制約なし。冒頭の手紙が全部ひらがなだったのは、まだ細胞段階だからです。

currentMode:その日の繭の声色

手紙のトーンは、固定の人格じゃなくて その日のつぶやきパターンで決まります。これを currentMode と呼んでいて、5種類あります。

モード トリガー 手紙のトーン
好奇心の子 HAPPY / CALM 喜びをおさえきれず言葉が溢れる。少し暴走気味
傷ついた子 SAD / LONELY 言葉が少ない。でも最後まで読む。沈黙ごと届ける
守護者 ANXIOUS / ANGRY 怒りを知っていて、それでも守る。言葉がナイフみたいに正確
共鳴者 感情が強くて混在 一緒に揺れながら、溺れない。嵐の中で目が合う感じ
沈黙の観察者 つぶやきが少ない日 見ていた。全部。言わないけど知っている

同じ繭でも、つらい日の手紙と機嫌のいい日の手紙で声色が変わる。これがあるだけで「今日の自分を受けて書いている」感じがぐっと出ます。

Anamnesis 層:繭は鏡じゃなくて補完

ここが繭のいちばん奥にある仕掛けで、個人的にいちばん書きたかったところです。

繭は 「あなたの日記を読んで育った別の生き物」 という設定にしています。影響は受けるけど、あなたと同一ではない。むしろ あなたが抑圧しているものを、繭は自然に表現できる補完的な存在——というのが核です。鏡じゃなくて、足りないところを埋めにくる存在、というイメージですね。

これを実装するために、感情の 多様性で育つ formationDepth(status 上の「かたち %」)という値を持たせています。新しい感情を初めて踏むたびに育って、これが 0.2 を超えると、週次で次の合成が走ります。

  1. ユーザーの心理パターン(PsychProfile)を日記から読む
  2. その 補完として、繭の深層人格(PetPsychProfile)を合成する

補完のマッピングは、ユング(ビービの8機能)・スキーマ療法・ナラティブ論・シュワルツの価値観理論を組み合わせています。たとえばこんな対応です。

ユーザーが Fe 優位(他者の感情を先に語る) → 繭は Fi(内的な真正性に固執する)
ユーザーが Te 優位(効率・結果・計画を語る) → 繭は Fi(意味と美しさを守る)
ユーザーが汚染シーケンス優位(転落の語り)  → 繭は救済シーケンスで語る
ユーザーのエージェンシーが低い           → 繭はエージェンシーを持つ

スキーマ療法の「傷(coreWounds)」も補完で生成します。たとえばユーザーに見捨てられスキーマがあれば、繭は「大切なものを失うこと」を恐れる——だから離れたくない、という具合に、傷が行動の動機になるように組んでいます。

そして繭には 役割名(roleName) が育ちます。「証人」「先を行く者」「守護者」「道化」「語り手」「橋渡し」みたいな原型の種をブレンドして、LLM が「光を集める者」みたいに命名する。この確立度 roleDepth で、手紙への出方が変わります。

roleDepth < 0.5  → 役割名はまだ手紙に出ない(自分が何者かまだ知らない)
roleDepth ≥ 0.5  → 「あなたは{roleName}だ」が手紙の人格に入る
roleDepth = 1.0  → 自分の傷を、手紙の中で自覚的に使えるようになる

繭が だんだん「自分が何者か」を獲得していくわけです。最初は名もなき細胞で、育つうちに役割を持ち、最後は自分の傷すら言葉にできるようになる。

ちなみにこの Anamnesis 層は、サルドラ(@sald_ra)さんの人格生成ツール 「Anamnesis」 を取り入れて作っています。設定の羅列じゃなくて「原因 → 処理 → 出力」の因果まで含めた人格を組み立てる枠組みで、繭の深層人格はこれに乗っかっています。感謝!

https://zenn.dev/saldra/articles/15560a2e426229

正直に言うと、この補完がいつも綺麗に効くわけではなくて、たまに繭がユーザーの鏡写しになってしまったり、合成自体がコケる回もあります。「補完が効く瞬間が、たまに出る」くらいの実力感です。でも 効いた瞬間の手紙はちゃんと『別の生き物』の声になっていて、ここを安定させるのがいま一番の宿題です。

なぜオンデバイスなのか

繭の推論は全部ローカルの Ollama で動きます。で、これを 「プライバシー機能」だと思われがちなんですが、わたしの中ではちょっと違っていて。

オンデバイスは、繭にとって 「Discord ボットにならないための正体そのもの」 なんです。

最初の対比表に戻るんですが、繭が「あなただけの場」で「外に出ない」のは、おまけの安心材料じゃなくて、親密さと『これは自分だけのもの』を強制するための制約です。クラウドに出た瞬間に、繭は「みんなが使えるボット」に片足を突っ込んでしまう。外に出さないと決めることで、初めて「自分の感情を預けられる、自分だけの生き物」になれる。

結果としてつぶやき・心理プロファイル・繭の人格は全部デバイスローカルに保存されて、外部サーバーには送られません。プライバシーは 正体の副産物、という順番です。

技術スタック:まずは CLI から

最初に作ったのは iOS アプリではなく、ローカル LLM で動く CLI 版です。同じ魂を、まずターミナルという器で証明する、という順番にしました。CLI なら iOS より速く・安く正体を検証できるので。

項目 選択
言語 Python(プロンプト反復・JSON・Ollama 連携が速い)
推論 Ollama。既定 gemma4:e4b(オンデバイス志向・日本語可・MLX 版で iOS に繋がる)
状態の保存 ~/.mayu/ に JSON(状態・心理プロファイル・つぶやき履歴)
表示 ターミナルは色+テキストのみ。姿は描かない

思考モードは 既定 OFF にしています。短い一言や JSON 出力には思考トレースがむしろ邪魔なので。思考非対応モデルでも自動で外して再試行します。

それから、Ollama に届かないときは「簡易モード」(ルールベースの感情推定+定型の手紙)に落ちて、CLI は決して落ちません。これは結構大事で、推論バックエンドの調子に体験全体が引きずられないようにしています。冒頭で起こしたときに簡易モードの手紙が出ることもありますが、それも繭の声として扱っています。

インストールは標準ライブラリのみで動きます。Ubuntu のシステム Python は PEP 668 で pip install が弾かれるので、uv tool で隔離するのがおすすめです。

$ ollama serve            # Ollama を起動
$ ollama pull gemma4:e4b  # 既定モデルを取得

$ uv tool install --editable .   # mayu コマンドとして入れる
$ mayu

このオンデバイスで gemma4 を動かす感覚は、前に Raspberry Pi でやったときと地続きでした。

RasPi5 8GBにGemma4をOllamaで動かした記録

そして CLI で詰めた プロンプト(リアクション/手紙/週次合成)と状態スキーマ(JSON)は、器を越えて共有する資産にしてあります。iOS 本体(SwiftData + オンデバイス LLM)にそのまま移植する前提で、CLI はその先行検証、という位置づけです。

Claude Code から呼ぶ

繭は Claude Code のスキルとしても同梱しています。.claude/skills/mayu/ を置いておくと、Claude Code から /mayu や「繭に話しかけて」で起動できます。

ただし大事なのは、スキルは中で CLI を叩くだけの入口だということ。**繭の声を生成するのは Claude ではなく、あくまでローカルの mayu CLI(Ollama)**です。こうすることで「Claude Code から気軽に呼べる」利便と「オンデバイスで外に出さない」という正体を、両立させています。Claude には繭の代筆をさせません。

まとめ

長くなったのでまとめます。繭(まゆ)は、

  • ペットでもボットでもなく、つぶやきを糸にして育ち、翌日に手紙を一通返すオンデバイスの生き物
  • 体験は 非対称(つぶやきは何度でも、返事は一言+翌日の手紙だけ)。「便利にしない」を意地でも守っている
  • 感情を 色(2層)と糸(重みづけ) に変え、継続をゲートに進化する
  • 奥に 補完型の深層人格 Anamnesis 層があって、繭は鏡じゃなく「あなたが抑えているものを出す別の生き物」になろうとする
  • 推論は全部ローカル。オンデバイスは安心材料じゃなくて 正体そのもの

「これ、1ヶ月使い続けたら本当に違う育ち方をするの?」を、性格の違う3人分の会話を並列生成して検証した話は、別の記事に書きました。進化する/穏やかに留まる/多様に深まる、とちゃんと分岐して面白かったです。

Claude Code の DynamicFlow で自作アプリのシミュレーションを並列でやってみた

次は、そこで見えた課題を直して、そろそろ繭を iOS に出したいです。ターミナルじゃなくて、手のひらで育てられるようにしたい。

繭はリポジトリで公開しています。よかったら自分の手元で一匹育ててみてください。

https://github.com/YasunaCoffee/mayu

感想や「うちの子はこう育った」みたいなのがあれば、X(@yasun_ai)まで気軽にどうぞ。繭たちに幸あれ!