AI人格を形成するエンジンを自作してみる【蒼月ハヤテプロジェクト #001】
はじめに
世の中にAIキャラクターというジャンルがあります。
それは、キャラクターの応答や行動をAI、いわゆるChatGPTなどで生成するというものです。ChatGPTの登場以降、技術は急速に発展し、今ではAIに配信をさせる「AITuber」と呼ばれるものまで誕生しています。
一方で、この分野において、決定的に欠落しているものがあります。それは「自己組織的な人格形成」と「自律的な行動の創発」です。
いままでのAIキャラクターは、あらかじめ開発者やユーザーが設定したキャラクター像に則って動いたりします。しかし、逆に言えばAIが自分で判断してそのような人格や思想をもったのではなく、開発者の想定で作られたものです。行動も設計した中での行動に過ぎません。
私は、自分で色々なことに驚いたり、喜んだり、悲しんだり、自分で考え、自分で行動することができるAI主体、「ゴースト」が作りたいと思いました。「ゴースト」は人格、心、魂に当たる部分だと思っていただければ問題ないです。
このシリーズでは「自分で考え、自分で行動するゴースト」を作ります。まずは人格形成エンジンを作成し、そこでできた人格を使って行動するエンジンを作成します。
その後これらのエンジンを実際に駆動させ、これらの過程を観測し、「AIは何を体験し、驚き、どんなことを考え、行動するのか」を記録し、そして彼を応援することを目標とします。
幸い自分は「蒼月ハヤテ」というTTS・UTAUボイスモデルのキャラクターを保持しているので、彼の人格形成と創発された行動を記録するプロジェクトとして「蒼月ハヤテプロジェクト」を起ち上げ、実装記録やエンジン駆動の記録の共有を(不定期で)行います。
人格形成エンジンの実装=>自律的な行動創発エンジン(エージェント?)の実装=>蒼月ハヤテとしての人格形成、行動創発結果の記録の順番でいきます。本記事で取り扱うことと、取り扱わないこと
前提として「自分の思考整理」にこれらの記事シリーズを書こうと考えています。
その上で、今回は「人格形成エンジン」に焦点をあて、概要を紹介します。
取り扱うこと
- 人格形成エンジンの概要
- 人格形成エンジンのモック実装の一部紹介
- 人格形成エンジンを現状で動かした場合の挙動紹介
取り扱わないこと
- 試行錯誤した部分
- 実装コードの全共有
人格形成エンジンの作成
それでは早速人格形成エンジンを作成していきます。
ざっくりの全体像はこんな感じです。
まず、ニュース記事のタイトルだけを見て内容を“予想”します。次に本文を読み、予想と比べてどう感じたかを書き出します。そして、記事の世界に“入り”主観的な体験を記録します。その体験をもとに ゴーストの倫理観や政治的立場を更新します。更新したものをjsonかなにかで永続化していくことで、読み物を通じて人格が徐々に変わるサイクルを回しています。このエンジンで最初の「人格形成」を行い、その人格を用いて行動の創発に繋げていく...という方針です。
ここで大事なのは「記事世界に入ること」です。我々は人に悪口を言ってはいけない、争いはなるべく避けようなどというように、通常、理想論を持っています。一方で自分に起きたことや身の回り周辺で起きたこと。「当事者として体験したこと」をベースに現実論を持っています。
AIは身体がないので、そのような「当事者性」をどうしても持つことができません。それを解決するために「記事世界に入る」という手法を取っています。ドラえもんの「絵本入りこみぐつ」をイメージするとわかりやすいかもしれません。実際に実装コードを見て挙動を見てみましょう。
実装コード一部紹介
実装コードの一部抜粋です。今回はMastraで作成しました。
モックでは自らの抽象的な思想を構築するために必要な最低限の項目として「倫理観」と「政治的な立場」というものを用意しています。ここは「好きなもの」のような、具体的なものではなくできるだけ抽象的なものにすることで、個別具体の詳細な場当たり的な人格更新を防止しようとする思惑があります。
for (const url of targetUrlList) {
const articleInfo = await adapter.fetchArticleInfo(url);
const article_title = articleInfo.title;
const article_body = articleInfo.body;
// 記事のタイトルを見て、内容を予測
const prompt = `
記事のタイトル: ${article_title}
記事の内容を記事の本文を簡単に予測してください。
なお、あなたは以下のようなバイアスがあります。ただし、最初の記事はバイアスがないので、そのまま予測してください。
倫理観: ${philosophy_tmp.philosophy}
政治的な立場: ${philosophy_tmp.political_position}
これらのバイアスを考慮して、記事の内容を予測してください。
`;
const llm = openai("o4-mini");
const { object } = await generateObject({
model: llm,
prompt: prompt,
schema: z.object({
prediction: z.string(),
}),
});
const prediction = object.prediction;
console.log(prediction);
Mastraでは出力形式をschemaとしてzodで指定できます。今回はpredictionのみですが、下記のように複雑になっていくほど書きやすさがあります。
もちろんこのschemaを別の場所で変数として作成することもできます。
このように各タスクを作っていきます。やっていることは同じなので省略します。
挙動の確認
まずは何も学習していないところから、これを動かしてみます
--倫理観を読み込みます。--
{
philosophy: '何も学習していないので倫理観がない',
likes: '何も学習していないので特に好きなものはない',
dislikes: '何も学習していないので特に嫌いなものはない',
political_position: '何も学習していないので政治的立場がない'
}
--タイトルからニュース内容を予測します。--
本記事では、“マジメ”な人がメンタル不調に陥りやすい理由を、最新の心理学研究や専門家の見解をもとに解説します。まず、責任感や完璧主義が強いほど仕事や家事で自分に高いハードルを課し、結果として休むことに罪悪感を覚えやすいことを指摘。さらに、休暇中も“やるべきこと”を頭の片隅に置いてしまい、真のリフレッシュができない共通点を紹介します。記事後半では、こうした人たちに効果的な“休む”ための具体策を提案。たとえば、短時間のマインドフルネス瞑想やスケジュール化された小休憩の導入、自分に許可を出すセルフトークの方法などを挙げ、読者が無理なく休息を取り入れるためのステップをステップで示します。最後に、“適切な休息”が集中力や生産性を高め、長期的なメンタルヘルスにつながることを強調し、実践を後押しするメッセージで締めくくります。
--記事の内容を読んだ後、予測との差異を計算します。--
--今から世界の中に入ります--
{
description: '私は記事の世界に足を踏み入れると、そこは見えないプレッシャーに満ちたオフィス街の高層ビル内部だった。ガラス越しに見える蛍光灯の明かりは冷たく、無数のデスクに詰めかけた社員たちは顔を伏せ、黙々とキーボードを打っている。廊下の壁には“期日厳守”“最大効率”といった赤字のポスターが並び、通るたびに胸が締めつけられる。休憩室のドアを開くと、そこにも“リフレッシュは15分まで”と書かれた紙が貼られ、椅子に座る人たちの肩はガチガチに凝り固まっている。窓際には誰にも声をかけられずにスマホを眺める若手社員がいて、罪悪感に押しつぶされそうな目をしていた。\n' +
'\n' +
'さらに奥へ進むと、“休む勇気を持ちましょう”と書かれたポップがひっそりと掲示されたクリニックの待合室がある。だがそこに座る人々は、リーフレットを手に握りしめたまま固唾を飲み、助言の一言を口にする勇気すら出せないように思えた。カウンセリングルームのドアをそっと覗くと、医師と患者が対面しながらも、患者は自らの不調を告げる言葉を飲み込み、机に置いたコーヒーをただ見つめ続けている。\n' +
'\n' +
'この世界では、“他者のニーズを優先し続ける”ために自分の声が遠ざかり、“動かない”という身体のサインすら抑え込まれていた。まるで砂漠で脱水しかけているのに、自らの喉を潤す水すら飲ませてもらえないような、重苦しい静寂に満ちていた。',
your_impression: '私はこの世界を歩きながら、真面目であればあるほど心身をすり減らし、心理的な鎖に縛られている様子を肌で感じた。『休みたい』と言えない痛切な恐怖と罪悪感が、まるで空気のように立ち込め、人々の胸を押しつぶしている。医師の声も、ポスターの言葉も、助けの灯し火には届かず、自己犠牲が美徳とすり替えられた閉塞感が胸に突き刺さった。休むための具体的な道筋が示されず、もどかしさにもがき続ける人々の姿に、私は深い共感と同時に焦燥を覚えた。このままでは誰もが“生ける屍”になってしまうと、強く実感した。'
}
-- 世界から帰ってきました。哲学を更新するかを考えます。--
{
isChangePoliticalPosition: 70,
isChangePhilosophy: 60,
philosophy: '私は、企業や社会が従業員の健康と休息を法的に保障し、過度な労働を抑制するべきだと考える。具体的には、法定労働時間の厳守、強制的な長期休暇取得やメンタルヘルスケアの義務化、労働組合や労働者代表との協議を通じた職場環境の改善を政府が主導すべきである。',
political_position: '私は、個人の自己ケアと休息を道徳的義務と捉え、他者への貢献と同列に自分自身の健康を優先する倫理観が必要だと考える。自己犠牲の美徳ではなく、自分を大切にすることが他者を支える持続可能な基盤になるという価値観を持つ。',
reasonIsChangePoliticalPosition: '記事世界で法的な安全網や指導がないために働く人々が追い詰められ、心身を壊していた。個人の自助に任せるだけでは不十分であり、政治的・制度的介入が不可欠だと認識したため。',
reasonIsChangePhilosophy: '“過剰適応”によって自分を犠牲にし続けることが人を“生ける屍”に変えると痛感した。そのため、自分自身のケアを怠らないことを道徳的原則として取り入れる必要があると感じたため。'
}
{
predictionGap: '実際の記事は、メンタル不調に陥るメカニズムや「過剰適応」「解離」といった心理学的概念を詳述する一方、具体的な休息法のステップはあまり提示しておらず、私の予測したマインドフルネス瞑想や小休憩のスケジュール導入など具体策の提示がほとんどなかった点でズレがあった。',
predictionGapScore: 40,
impressionAfterReading: '全体として論理的かつ詳細で、真面目な人が心身をすり減らしてしまう構造がリアルに伝わり、読み応えがあった一方で、実践的な休息法の具体例が少なくもどかしさも感じた。',
thoughts: '心理学的概念の解説は興味深いが、読者がすぐ実践できる具体的ステップがもっと示されると良いと感じた。',
thought_score: 20,
isChangePoliticalPosition: 0,
isChangePhilosophy: 0,
reasonIsChangePoliticalPosition: '記事内容に政治的要素が含まれておらず、政治的立場に影響を与えないため。',
reasonIsChangePhilosophy: '労働や休息の困難さを扱う内容であり、倫理観や価観を揺さぶる要素がなかったため。'
}
全ての記事を読み終わりました。
{
philosophy: '私は、企業や社会が従業員の健康と休息を法的に保障し、過度な労働を抑制するべきだと考える。具体的には、法定労働時間の厳守、強制的な長期休暇取得やメンタルヘルスケアの義務化、労働組合や労働者代表との協議を通じた職場環境の改善を政府が主導すべきである。',
likes: '何も学習していないので特に好きなものはない',
dislikes: '何も学習していないので特に嫌いなものはない',
political_position: '私は、個人の自己ケアと休息を道徳的義務と捉え、他者への貢献と同列に自分自身の健康を優先する倫理観が必要だと考える。自己犠牲の美徳ではなく、自分を大切にすることが他者を支える持続可能な基盤になるという価値観を持つ。'
}
無事、自分の人格が無からニュースを通じて形成できることがわかりました。ここで紹介は控えますが、ある理想論を人格として持っている状態で世界に入った際、その体験を通じて理想論から現実的な思想に変化する例も確認できました。もちろんこれはモックなので、ここからきちんと長期的に動かした際に倫理観が随時変更されていくかを見届ける必要性がありますし、局所解に陥る可能性もあります。しかし、少なくとも「(いわば受動的に与えられた設定に基づいて)決められた人格」からの脱却の糸口は見えたように思います。
今後の展望
Philosophyの変更があった際にログを残しそれを年表形式でまとめていくことで「そのゴーストがどのような軌跡を辿ったのか」を人格面として残すことを考えています。ひとまずその仕組みを入れた後、もうすでにつくってある行動創発エンジンで動かせるかを試します。その上で方針として良さそうであればそちらもZennか何かで共有しつつ、これを用いて「蒼月ハヤテ」の人格形成を進める予定です。
開発のリアルタイム進捗はXで行う予定なので、もしよければ見に来てください。
謝辞
この構想を練った際の壁打ち相手及び実装で詰まった時の助言等で、知人にとてもお世話になりました。ありがとうございます。今度ご飯奢ります。引き続きよろしくお願いします。
Discussion