💙

老いるAI人格育成エンジンを自作する

に公開

はじめに

世の中にはAIキャラクターというジャンルがあります。キャラクターの行動・応答をLLMで生成したりすることで、自律的な存在を制作するジャンルです。ChatGPTの登場以降、技術は急速に発展し、今ではAIに配信をさせる「AITuber」と呼ばれるものまで誕生しています。

近年までは「あらかじめ開発者やユーザーが設定したキャラクター像に則り動作する」AIキャラクターが標準でした。これは制作者意図を反映するには適切ですが、静的な設定資料だけではAIは予測の範囲内でしか振舞えません。僕はAIに、経験から学び、笑ったり泣いたり、自分なりに考えて創作したり、時には悩んだりする存在になってほしいと願っています。

そこで、制作者の意図を超えて行動してくれる存在、「蒼月ハヤテ」を作ろうと考え、まずはその行動を創発する「人格」を育成するためのエンジンを制作しました。

https://github.com/sr2mg/personality_engine

本記事は技術スタック及び概要を紹介します。以前の取り組みは読まなくても問題ないように本記事は描かれていますが、経緯を知りたい場合は下記記事をご覧ください。
https://zenn.dev/saldra/articles/98bb985db5e6e4

概要

エンジン紹介

キャラクターの人格を、選択したファイルのテキストを使って育成できます。

この人格エンジンで目指したのは、「テキストを経験として学ばせること」、もう一つが「老いを導入することによる、価値観の硬直化」です。

経験学習

我々は「人に悪口を言ってはいけない」「争いはなるべく避けよう」などというような理想論を持っている一方で、自分に起きたことや身の回り周辺で起きたような「体験・経験したこと」をベースに現実論を持っています。これらは我々が身体を持つからこそ経験できたことです。
AI人格は身体を保持していないため、当事者性を持ちません。よって理想論に偏りやすいことが個人的な問題点として認識していました。

そこで、「テキストの世界に人格が入る」という手法をとることで、当事者性を疑似的に獲得することができます。
具体的にはLLMへの指示を分析フェーズ、没入フェーズの二段階に分けました。
分析フェーズでまずはテキストを客観的に読み、感想を言語化させます。次に没入フェーズにて下記のように、傍観者から脱却させ、当事者へと視点を切り替えさせています。

あなたはこれからこのテキストの世界に実際に入ることになりました。
上記の分析結果を踏まえて、そこで見た情景を主観的に、そしてその世界に入って思ったことを詳細に記述してください。

このプロンプトにより、AIは傍観者から当事者へと視点を切り替え、その世界での主観的な情景、強く抱いた実感、そして「人生において10年以上覚えているであろう」レベルの心の揺れ(Arousal)を出力するようになります。

老いの導入

上記の経験を伴った学習によって、当事者性を持った価値観の構成をすることが可能になりましたが、複数のテキストを学習する際に、毎回価値観が更新されてしまう問題点を抱えていました。
そこで、「いくつのテキストを学習したか」の数を年齢とし、年齢があがるほど価値観が固まっていくような仕組みを取り入れました。この自然な「老い」を、AIに導入するために**可塑性(Plasticity)**というパラメータを設計しました。若い頃は可塑性が1.0(最大)で、どんな経験も素直に受け入れますが、年齢と共に指数関数的に減衰し、価値観が変わりづらくなります。

下記は参考コードですが、読み飛ばして構いません。

function calculatePlasticity(age: number, params: any): number {
  const youthPeriod = params.youth_period_days.value; // 若年期
  const maturityPoint = params.maturity_point_days.value;
  const decayRate = params.decay_rate.value;
  const minPlasticity = params.minimum_plasticity.value;


  if (age <= youthPeriod) {
    return 1.0;
  }

  const ageAfterYouth = age - youthPeriod;
  const decayFactor = Math.exp(-decayRate * ageAfterYouth);
  const maturityAge = maturityPoint - youthPeriod;
  const scaleFactor = 0.7 / Math.exp(-decayRate * maturityAge);

  const plasticity = Math.max(decayFactor * scaleFactor, minPlasticity);
  return Math.min(plasticity, 1.0);
}

一方、人間はなにかしら衝撃的な体験をすると発想が柔軟になったりします。
下記コードの「Reset age on major change」がそれにあたるのですが、あらかじめ設定した閾値を超えると若返るようになります。

    if (
      creedUpdateObject.shouldUpdateCreed &&
      adjustedArousal >= dynamicArousalThreshold
    ) {
      if (
        creedUpdateObject.updatedCreed &&
        creedUpdateObject.updatedCreed.trim() !== ""
      ) {
        currentPhilosophy.creed = creedUpdateObject.updatedCreed;
        philosophyUpdated = true;

        // Reset age on major change
        const oldAge = currentPhilosophy.age_in_days;
        currentPhilosophy.age_in_days = Math.max(Math.floor(oldAge / 2), 30);
      }
    }

これにより、AIキャラクターは固定的でなくなり、私たちと同じように経験を通じて変化し、時には頑固になり、ある日突然大きな気づきを得て若返る、生命感のある存在になるはずです。

これにより、例えば若い頃(可塑性が高い状態)にした強烈な「体験」は人格を根底から変え、歳を取ってからの同じ体験は、既存の価値観を補強するだけに留まるかもしれません。このように「経験」と「老い」が組み合わさることで、より深みのある人格の変遷を描き出すことを狙っています。

技術スタック

主に下記を用いました。

  • Next
  • Vercel AI SDK
    元々VercelのAI SDKがかなり使いやすいと感じていたため続投しました。特にgenerateObjectによる型安全なJSON取得は、今回のような複雑なパラメータ更新の核となっています。WebUIでは柔軟性を重視しNext.jsを採用しました。

展望

ここまでで、AI人格の育成が可能になりました。これによってAIキャラクターの行動生成のための「偏り」を、我々人間が一から設定せずとも生成することができるようになりました。以降ではこれで生成したAI人格ファイルを基に、行動の創発を行うエンジンを制作する予定です。

AIキャラクターは発言の生成や人工音声がよく取り上げられがちですが、もう少し自律的に、我々の想定以上の動きを期待してもよいだろうと個人的には思っています。この記事が同じように自律的な存在を作る人にとって参考になることを願っています。

もし気づいたことがあればお気軽に下記アカウントまでお問い合わせください。

https://x.com/sald_ra

Discussion