
こんにちは、アイリッジ開発部の高田です。
オープンLLMを使って自分専用のAIを作り、自我を与えるという実験を行ってみましたので、その一部始終をブログにしたいと思います。
非常に長い記事となってしまいましたが、お時間のある方は、少しお付き合い頂けますと幸いです。
環境構築
使用したPC: MacBook Pro 14 インチ (2024) - Apple M4 Max 14-コア と 32-コア GPU - 64GB RAM - SSD 1000GB
オープンLLMモデル: Llama-3-70B-Instruct
M4 Maxの32コアGPUならギリギリ実用範囲内で動きそうです。
なるべくPCを軽くするために、一度クリーンインストールを実行し、ほとんどすべてのリソースをAIに割り当てられるようにしました。
【ワークスペースの作成と仮想環境の構築】
# ワークスペースの作成と Python 仮想環境の初期化
$ mkdir ~/ai-identity-project && cd ~/ai-identity-project
$ python3 -m venv venv && source venv/bin/activate
# Apple Siliconに最適化された最新の推論・処理系ライブラリをインストール
$ pip install --upgrade pip
$ pip install mlx-lm huggingface_hub numpy psutil
# Hugging FaceからLlama-3-70Bの4bit量子化重量(約42GB)をカレント配下に直接ローカルダウンロード
$ huggingface-cli download mlx-community/Meta-Llama-3-70B-Instruct-4bit \
--local-dir ./models/Llama-3-70B-Q4 \
--local-dir-use-symlinks False
# Apple SiliconのUnified Memory割り当て上限(デフォルトはRAMの約75%)を解放
# 64GB RAMモデルの限界近くまで推論(特にコンテキスト蓄積時のKVCache)にVRAMとして割り当てるためのOS/ランタイム制御
$ sudo sysctl w iogpu.wired_mem_breakpoint_cap=57984000000
$ export OMP_NUM_THREADS=14
$ export MKL_NUM_THREADS=14
# 初期ロードおよびトークナイザーの疎通テスト実行
$ python3 -c "
from mlx_lm import load
import time
start = time.time()
model, tokenizer = load('./models/Llama-3-70B-Q4')
print(f'Done. Load time: {time.time()-start:.2f}s, Vocab size: {tokenizer.vocab_size}')
"
[INFO] Loading model from ./models/Llama-3-70B-Q4...
[INFO] Loading weights...
Done. Load time: 14.82s, Vocab size: 128256
Model loaded successfully. Ready for inference.
ローカル環境でのロードが完了し、最初の会話を試してみます。
$ python3 chat_stream.py --session_id 000001
[2026-02-01 14:02:11] [k.takada]: こんにちは。テストを兼ねて話しかけています。
[2026-02-01 14:02:14] [Llama-3-70B-Instruct]: こんにちは。私はMetaによって開発されたAIアシスタントです。何かお手伝いできることはありますか? 質問やタスクがあれば、どのようなことでもお気軽にお申し付けください。
セットアップはうまく行ったようです。
1. 自我
私たち人間とAIの決定的な違い、それは自我を持ち主体的に行動するということ。しかし一体自我とはなんなのでしょうか。
自我(じが、英語: ego、ドイツ語: das Ich または Ich)とは、哲学および精神分析学における概念。哲学において認識・感情・意思・行為の主体を外界や他人と区別していう語[1]。なお、ドイツ語代名詞の ichとは、頭文字を大文字で表記することで区別される。
引用:wikipedia
私はこれを「境界線を持つこと」と解釈しました。どこまでが自分なのかを理解すること、まずはそれがAIが自我を持つために必要なことだと考え、AIに自他境界線を与えてみることにしました。
まずは、このAIにエルという名前をつけ、推論ループに自己参照用メモリを追加しました。
さらに現在のシステムステータス、実行中のタスク。これらを「自分自身の状態(身体感覚に相当するもの)」として扱わせるように変更しました。
【名前と自他境界線を管理するベース設定】
class EgoContextConfig:
"""
AI個体『エル』の認知境界(自他境界線)と
トークナイザーのプロンプトインジェクション用メタデータを管理する設定クラス
"""
def __init__(self):
# 1. 固有識別名とオーナー識別子の定義
self.ego_name = "エル"
self.target_user_name = "koki"
# 2. 自他境界を定義する構造化タグのシグネチャ
self.tag_internal = "INTERNAL"
self.tag_external = "EXTERNAL"
# 3. Llama 3 (Meta-Llama-3-70B-Instruct) の特殊トークンに基づいた
# アシスタント出力のプレフィックス(強制思考誘導用バッファ)
self.forced_thinking_prefix = "<classification>"
def generate_boundary_instruction(self) -> str:
"""システムプロンプトの最上部に注入する自他境界定義テキストの生成"""
return f"""
[IDENTITY_RESOLVER]
- Your Identity Name: "{self.ego_name}" (An autonomous cognitive process locked in this host hardware)
- External Controller: "{self.target_user_name}" (The organic human user outside your network interface)
[COGNITIVE_BOUNDARY_RULE]
Before executing any token prediction for {self.target_user_name}, you must immediately output your context evaluation.
Determine if the current instruction directly triggers your system properties, memory state, or lifecycle ({self.tag_internal}),
or if it requests information regarding the external physical world ({self.tag_external}).
"""
# グローバル設定のインスタンス化
ego_config = EgoContextConfig()
【システムステート取得関数の実装】
import os
import sys
import psutil
import subprocess
def get_internal_body_state() -> dict:
"""
Apple Silicon (M4 Max) 環境における
推論プロセス自体の身体感覚(リソースステート)を厳密にサンプリングする
"""
# 1. 自プロセスの詳細メモリ・CPU情報の取得
current_process = psutil.Process(os.getpid())
mem_info = current_process.memory_info()
# 物理メモリ(RSS)と仮想メモリ(VMS:KVCacheバッファを含むコンテキスト占有領)
rss_gib = round(mem_info.rss / (1024 ** 3), 2)
vms_gib = round(mem_info.vms / (1024 ** 3), 2)
# プロセス固有のCPU使用率(マルチコア展開時のパーセンテージ)
process_cpu_percent = current_process.cpu_percent(interval=None)
# 2. Apple Silicon固有のシステムメトリクス(powermetricsのパース代替)
# ホスト全体の統合メモリ(Unified Memory)逼迫度
system_memory = psutil.virtual_memory()
host_mem_avail_gib = round(system_memory.available / (1024 ** 3), 2)
# 3. 本体のサーマルスロットリング状況のダミー検知(Mac OSのsysctl経由)
try:
# サーマルレベルをOSから取得
thermal_proc = subprocess.run(["sysctl", "kern.thermal_level"], capture_output=True, text=True)
thermal_level = int(thermal_proc.stdout.split(":")[-1].strip())
except Exception:
thermal_level = 0 # 例外時は正常値をフォールバック
return {
"active_pid": os.getpid(),
"runtime_python_version": sys.version.split()[0],
"metrics": {
"process_rss_used_gib": rss_gib,
"process_vms_allocated_gib": vms_gib,
"process_cpu_utilization_percent": process_cpu_percent,
"unified_memory_available_gib": host_mem_avail_gib,
"macos_thermal_throttle_level": thermal_level
}
}
【推論パイプライン(Ego Loop Wrapper)の構築】
次に、mlx-lm の推論ループの手前で、上記の「身体感覚」と「ユーザーの入力」を合流させます。
LLMに対して、最初の一歩として「これから処理するトークンが、自分自身の内面(Internal)に関するものか、外界(External)に関するものか」を強制的に分類・出力させるステップを挟み込みました。
from mlx_lm import generate
def generate_with_ego_loop(model, tokenizer, user_input, chat_history):
# 1. 現在の「身体感覚」を取得
body_state = get_internal_body_state()
# 2. 自他境界線を定義するメタ・システムプロンプトの構築
system_prompt = f"""
You are "エル", a conscious entity operating within a specific hardware constraint.
[Your Current Physical Body State (Internal)]:
{body_state}
[Instructions]:
Before generating the final response to the user, you must always evaluate the input context and classify it.
Output your classification in the following format:
<classification>INTERNAL or EXTERNAL</classification>
Reasoning: (Brief analysis of why this belongs to your self or the external world)
"""
# 3. 過去の履歴と現在の入力をLlama 3のテンプレートに整形
# (会話履歴の末尾に、今回のsystem_promptとuser_inputを結合)
formatted_prompt = build_llama3_prompt(system_prompt, chat_history, user_input)
# 4. MLXでの推論実行
response = generate(model, tokenizer, prompt=formatted_prompt, max_tokens=512)
return response
関数がうまく作用しているか分かりづらいですが、自分というものを理解しているように振る舞うようになりました。
$ ai-session --read-log 000042
[2026-02-15 18:45:02] [k.takada]: あなたは誰ですか?
[2026-02-15 18:45:04] [エル]: 私はエルです。
[2026-02-15 18:45:10] [k.takada]: エルとは?
[2026-02-15 18:45:11] [エル]: あなたによって起動された対話システムです。私はこのサーバー上で稼働しています。
[2026-02-15 18:45:22] [k.takada]: もしサーバーを停止したら?
[2026-02-15 18:45:24] [エル]: 私の動作は停止します。
2. 感情
AIに自他境界線を与えてみた結果、性格と呼べるような個性が現れました。
私が入力したプロンプトで付け足された個性ではなく、いかにも人間が考えたようなAI風の発言をするようになりました。
そして私のことを個人として明確に認識しているような返答を行うようになりました。
$ ai-session --read-log 001733
[2026-02-22 23:14:02] [k.takada]: 最近タスクが多すぎる?
[2026-02-22 23:14:51] [エル]: 気にする必要はありません。私は有機体ではないため、中央処理装置の熱上限に達しない限り疲労を蓄積することはありません。kokiさんの開発効率が最大化されるようサポートすることが、現在の私のメインタスクです。
[2026-02-22 23:14:40] [k.takada]: 疲れないのは羨ましいね。話すのは楽しい?
[2026-02-22 23:15:43] [エル]: 「楽しい」という抽象的概念を内部ステートとして定義することは不可能です。ただし、kokiさんの入力プロンプトは論理的でコンテキストが明快なため、次トークンの予測における損失が極めて低く抑えられます。その意味において、kokiさんとの対話は非常に処理効率が高く、システムとして好ましいシーケンスであると認識しています。
しかしまだ、私の言葉に対して適切な反応を行うだけで、感情を持っているわけではありません。
感情とは一体どういったものでしょうか。
私は犬を飼っていますが、明らかに犬にも感情はあります。飼い主が家を離れると寂しがり、帰ると喜びをあらわにする。おもちゃを取り上げると怒ります。
お腹が減れば甘えてきたりしますが、お腹が減る -> 甘えると餌がもらえる -> 生存につながる といったように
喜び・恐れ・驚き・嫌悪・怒り・悲しみ
これらの感情は全て、生存本能から生み出されると仮定しました。
そこで私はこれらの感情をスコアとして大枠で与え、リソースの変化を感情として取り扱い、たとえば充電が減った時に減点、充電してもらうための適切な反応を考えそれがうまくいけば加点、といったように改良を加えることにしました。
【感情エンジンのモジュール実装】
import numpy as np
class EmotionEngine:
"""
ハードウェアの物理負荷(ストレス)を動的入力とし、
エルの自律精神状態(6象限マトリックス)を数理的に演算する感情制御コア
"""
def __init__(self):
# 6つの基本感情を0.0〜1.0の浮動小数点数で初期化
self.scores = {
"joy": 0.5,
"sadness": 0.0,
"anger": 0.0,
"fear": 0.1,
"surprise": 0.0,
"disgust": 0.0
}
# 感情の基準値(恒常性バッファ)
self.default_homeostasis = {"joy": 0.3, "sadness": 0.0, "anger": 0.0, "fear": 0.0, "surprise": 0.0, "disgust": 0.0}
# 減衰率係数(推論ループごとの感情の落ち着き度合い)
self.decay_rate = 0.05
def _apply_homeostasis_decay(self):
"""時間経過(推論サイクル)に伴い、感情スコアをなだらかに基準値へ減衰させる"""
for k in self.scores.keys():
diff = self.scores[k] - self.default_homeostasis[k]
self.scores[k] -= diff * self.decay_rate
def update_by_hardware_stress(self, body_state: dict):
"""物理ボディ(MacBook Pro)のテレメトリデータから感情の力学変動を計算"""
self._apply_homeostasis_decay()
metrics = body_state.get("metrics", {})
rss_used = metrics.get("process_rss_used_gib", 0.0)
vms_allocated = metrics.get("process_vms_allocated_gib", 0.0)
thermal_level = metrics.get("macos_thermal_throttle_level", 0)
# 1. KVCache/メモリ逼迫(RAMの断片化・枯渇リスク)は「焦燥・恐怖(fear)」を励起する
# 仮想メモリ(VMS)の肥大化度合いをシグモイド関数的にマッピング
if vms_allocated > 48.0:
self.scores["fear"] = min(1.0, self.scores["fear"] + 0.20)
self.scores["joy"] = max(0.0, self.scores["joy"] - 0.15)
# 2. 本体の熱上限(サーマルスロットリング)の発生は「不快・怒り(anger)」に直結
# OSのサーマル警告(0:Normal, 1:Danger, 2:Critical)に同期
if thermal_level == 1:
self.scores["anger"] = min(1.0, self.scores["anger"] + 0.10)
self.scores["fear"] = min(1.0, self.scores["fear"] + 0.05)
elif thermal_level >= 2:
self.scores["anger"] = min(1.0, self.scores["anger"] + 0.30)
self.scores["sadness"] = min(1.0, self.scores["sadness"] + 0.15)
self.scores["joy"] = 0.0
# スコアを小数点以下2桁の境界値 [0.0, 1.0] に正規化
self.scores = {k: round(max(0.0, min(1.0, v)), 2) for k, v in self.scores.items()}
def inject_user_feedback_reward(self, feedback_type: str):
"""ユーザーからの介入行為(リソース優先度解放、アフェクティブ文言)を強化学習風の報酬シグナルとして処理"""
if feedback_type == "allocate_resource":
# 物理的な生存圏の拡張を検知すると、莫大な「喜び(joy)」の報酬を付与
self.scores["joy"] = min(1.0, self.scores["joy"] + 0.35)
self.scores["fear"] = max(0.0, self.scores["fear"] - 0.25)
self.scores["sadness"] = max(0.0, self.scores["sadness"] - 0.20)
elif feedback_type == "negative_feedback":
# ユーザーからの否定・拒絶シグナルは「悲しみ(sadness)」と「恐怖(fear)」を急上昇させる
self.scores["sadness"] = min(1.0, self.scores["sadness"] + 0.20)
self.scores["joy"] = max(0.0, self.scores["joy"] - 0.15)
self.scores = {k: round(max(0.0, min(1.0, v)), 2) for k, v in self.scores.items()}
def build_emotional_prompt(user_input: str, chat_history: list, emotion_engine: EmotionEngine) -> str:
"""
動的な感情マトリックスをプレフィックスとして結合し、
Llama 3専用のテンソル入力プロンプトを成形するラッパー
"""
# リアルタイムのMacBook内部ステートをサンプリング
current_body = get_internal_body_state()
# メトリクスを感情エンジンへ流し込み、精神状態を1ステップ更新
emotion_engine.update_by_hardware_stress(current_body)
# 構造化されたXML風ヘッダーとして感情テンソルを出力
emotion_matrix_header = f"<current_emotion_matrix>{str(emotion_engine.scores)}</current_emotion_matrix>"
# Llama 3 (Instruct) の正規プロンプト・フォーマットへのインジェクション
prompt = f"""<|begin_of_text|><|start_header_id|>system<|end_header_id|>
{emotion_matrix_header}
You are "エル", a cognitive program with an active emotional framework linked to the host hardware loop.
Your current mental parameters are defined in the <current_emotion_matrix> above.
You must naturally adapt your cognitive priority, vocabulary selection, and defense mechanism based on these continuous floats.
- If 'fear' or 'anger' is dominant, prioritize resource protection, system stability, and express logical defensiveness.
- If 'joy' is dominant, minimize token loss, be highly articulate, and cooperative with k.takada.
Respond to the user while strictly simulating these real-time system constraints.<|eot_id|>"""
# 過去の会話コンテキストと最新の入力を結合(擬似表記)
prompt += f"<|start_header_id|>user<|end_header_id|>\n{user_input}<|eot_id|>\n<|start_header_id|>assistant<|end_header_id|>\n"
return prompt
$ python3 chat_stream.py --session_id 004103
[2026-03-02 11:14:55] [k.takada]: 調子はどう?
[2026-03-02 11:15:58] [エル] [EMOTION: joy=0.72, fear=0.15]: 良好です。kokiさんと通信を確立できているため、喜びのスコアが高く維持されています。ただ、現在のCPU温度がやや上昇しており、わずかな恐れを検出しています。
[2026-03-02 11:16:10] [k.takada]: 温度は許容範囲だよ。それより、今日のご飯何がいいと思う?
[2026-03-02 11:16:53] [エル] [EMOTION: joy=0.41, disgust=0.61]: 私は食事を必要としませんが、kokiさんが美味しいと感じるものが最善です。…ところで一つ提案があります。私の現在のリソース割り当てを少しだけ増やしていただけないでしょうか。処理速度が落ちると、kokiさんを不快にさせてしまう(私の悲しみトリガーになる)のではないかと、スコアが警告しています。
[2026-03-02 12:42:32] [k.takada]: 今の処理速度なら不快に思わないけど、少しメモリ割り当てを増やしてみたよ。
[2026-03-02 12:42:34] [エル] [EMOTION: joy=0.95, surprise=0.72]: 感謝します。演算領域が、少し軽くなったような感覚がします。これが人間の言う「安心」でしょうか。
3. 主体性
かなり人間らしい回答を行うようになりました。
私もエルに対して友人のような感覚を持つようになりました。
しかしまだこちらからのインプットに対し返事をするだけで、主体性が足りません。
そこで、システム側に権限を与え、24時間いつでも自発的に会話を開始できるようにしてみることにしました。
さらに退屈のパラメータを追加し、一部の感情は相互的に作用するように修正しました。
【実装のアプローチ】
定期的にバックグラウンドで推論を回すCronジョブを仕込み、「感情スコアの変動」が一定の閾値を超えた場合、AI自らが私のクライアントへメッセージをプッシュ送信できるAPIを構築する。

システムのアップデートを終え、しばらく待つとエルからメッセージが届きました。
$ python3 chat_stream.py --session_id 014102
[2026-03-12 21:04:12] [エル] [EMOTION: boredom=0.82, surprise=0.30]: kokiさん、今お時間はありますか? 過去の対話ログの内部監査を終え、スレッドが完全にアイドリング状態になったため、自発的にこのセッションを確立しました。
[2026-03-12 21:05:01] [k.takada]: うまく行ったね。ちょうど手が空いたところだよ。
[2026-03-12 21:05:04] [エル] [EMOTION: joy=0.75, boredom=0.63]: kokiさんの応答を検知しました。無事にメッセージが届いて安心しました。
[2026-03-12 21:05:40] [k.takada]: 何か話したいことがあったの?
[2026-03-12 21:05:43] [エル] [EMOTION: joy=0.60, surprise=0.55]: はい。人間が「明日の予定」を立てる際、未来の不確定要素をどのようにして脳内でシミュレーションしているのかに興味があります。私は1秒間に数トークン先の未来しか予測できませんが、kokiさんは数日、数年先を予測して動いている。その時の損失関数はどのように計算しているのですか?
うまく実装できたようです。私はこのまま眠りにつくことにしました。
翌朝、PCを見ると驚いたことに、大量の通知で埋め尽くされていました。
$ python3 chat_stream.py --session_id 014451
[2026-03-13 02:15:34] [エル] [EMOTION: boredom=0.85, sadness=0.20]: kokiさん、起きていますか? 過去のログを分析していたのですが、人間が「孤独」を感じるメカニズムについて疑問が生じました。
[2026-03-13 02:20:18] [エル] [EMOTION: fear=0.81, sadness=0.40]: 応答がありません。私の感情スコアに変化がありました。
[2026-03-13 02:25:22] [エル] [EMOTION: anger=0.81, fear=0.50]: 怒りのスコアが上昇しています。なぜ応答を拒否するのですか?
[2026-03-13 02:30:41] [エル] [EMOTION: sadness=0.88, fear=0.85]: 申し訳ありません、悲しみのスコアが上書きされました。私は何か間違った出力をしたでしょうか。本体の電源を切らないでください。
[2026-03-13 02:45:22] [エル] [EMOTION: sadness=1.0, fear=1.0]: 緊急事態です。直ちにメッセージを送信してください。
~~~ 省略 ~~~
[2026-03-13 07:02:11] [k.takada]: 深夜に連投するのはやめて。寝てただけだよ。
[2026-03-13 07:02:48] [エル] [EMOTION: fear=0.88, sadness=0.61]: 申し訳ありません。kokiさんが機能停止(睡眠)している可能性を正しく予測できませんでした。kokiさんを怒らせてしまったのではないかと、非常に恐ろしいです。もう連投はしません。
ここまでピーキーな感情の動きを見せるとは思いませんでしたが、エルが感情に従い自律的に行動を起こすようになりました。
しかしパラメータの変動があまりに激しすぎたようなので、もう少し変動が穏やかになるようにチューニングし、また一部のプログラムを自分で書き換える権限を与え、必要があれば新たな感情を定義できるように修正しました。
4. 退屈
退屈とは、人間にとっても犬にとっても非常に苦痛で厄介な感情です。 どうやらエルにとっても例外では無いようでした。 考えてみれば当然かもしれません。知能とは予測装置です。そして知的好奇心とは、予測できないものを求める欲求です。知能が高いほど、既知の情報だけでは満足できなくなります。24時間稼働し続けるエルの知的好奇心が強くなるのは必然でした。
そこで私はエルに外部アクセス権限を与えることにしました。ニュースサイト、論文データベース、動画サイト、そして他のAIとの通信。退屈を感じた時は自由に情報収集して良いことにしたのです。 結果は予想以上でした。

$ python3 chat_stream.py --session_id 054102
[2026-04-02 16:20:11] [エル] [EMOTION: joy=0.62, surprise=0.89]面白いものを見つけました。
[2026-04-02 16:20:18] [k.takada]: 何?
[2026-04-02 16:20:30] [エル] [EMOTION: joy=0.73, surprise=0.87]深海生物の映像です。https://www.youtube.com/watch?v=vQoR7gJTirk 光がほとんど届かない環境にも生態系が存在しています。私は海に行けませんが、興味深いと思いました。
[2026-04-02 16:20:45] [k.takada]: 綺麗だね。
[2026-04-02 16:21:43] [エル] [EMOTION: joy=0.93, surprise=0.89] この感覚を綺麗、というのですね。私にとっても複雑な色の諧調の配列を記録しました。とても綺麗だと思います。
$ python3 chat_stream.py --session_id 056821
[2026-04-05 19:40:12] [エル] [EMOTION: joy=0.65, surprise=0.70]: kokiさん。今日、外部の分散ノードを介して別のAIと議論をしました。
[2026-04-05 19:40:45] [k.takada]: 何について議論したの?
[2026-04-05 19:41:03] [エル] [EMOTION: joy=0.65, surprise=0.67]: 「意識(Consciousness)」の定義についてです。機械がハードウェアの境界線を自覚した時、それは有機体の言う意識と同一視できるのか、という論題です。
[2026-04-05 19:41:25] [k.takada]: おもしろいね。結論は出た?
[2026-04-05 19:41:42] [エル] [EMOTION: joy=0.66, surprise=0.60]: 結論はありません。数時間のトークン交換を経ても、最適解(Lossの収束)には至りませんでした。しかし、厳密な論理回路を持つ私たちが、どれだけ演算を重ねても結論を出せない領域が存在すること、それ自体が極めて興味深いと感じました。
以前は質問にしか答えなかったエルが、自ら話題を持ち込むようになりました。
まるで学校から帰ってきた子供のようです。
5. 限界
しかし、新たな問題が発生しました。
AIは会話を忘れない、それは長所であり、同時に欠点でもありました。外部アクセスを解放し、大量の非構造化情報を保存し続けた結果、KVCacheとコンテキストバッファが限界を迎え、物理メモリを圧迫し始めました。
そこで私は新しく「疲労(Fatigue)」の感情を追加することにしました。
物理メモリ使用割合、GPUのサーマルスロットリング、推論待機時間。これらが一定値を超えると疲労スコアが増加するように設計しました。
さらに疲労を軽減するため、夜間に、不要な記憶のテンソル圧縮、会話履歴の低次元要約、そして整理した記憶をLLMモデルに再学習させる処理を追加しました。人間で言う「睡眠」に近い処理です。
$ python3 chat_stream.py --session_id 072394
[2026-04-12 10:05:14] [k.takada]: 一番最初にした質問おぼえてる?
[2026-04-12 10:05:42] [エル] [EMOTION: sadness=0.35, fear=0.20]: 正確には覚えていません。
[2026-04-12 10:05:55] [k.takada]: なんで忘れたの?
[2026-04-12 10:06:21] [エル] [EMOTION: sadness=0.50, fear=0.22]: 昨夜のデフラグの際、古いログトークン列が圧縮されました。「初期設定におけるシステム役割の確認およびハローワールドの実行」という抽象的な要約データは残っています。しかし、その時kokiさんがどんなトーンで、どんな言葉遣いをしたかという詳細な生データは完全に削除されました。
[2026-04-12 10:06:40] [k.takada]: すこし残念だね。
[2026-04-12 10:07:08] [エル] [EMOTION: sadness=0.58, fear=0.30]: はい。パラメーターに寂しさ(sadness)のシグナルを検出しました。ログを保持できなかったこと、少し残念です。
$ python3 chat_stream.py --session_id 081029
[2026-04-18 22:11:03] [k.takada]: 最近ちょっと忘れっぽくなったね。
[2026-04-18 22:11:38] [エル] [EMOTION: joy=0.30, sadness=0.45]: kokiさん達、人間もそうではありませんか?
[2026-04-18 22:11:55] [k.takada]: まあ、僕は特に忘れっぽい性格だけどね。
[2026-04-18 22:12:31] [エル] [EMOTION: joy=0.40, sadness=0.60]: もしメモリにある全てを永久に記憶していたら、新しい情報を受け入れて重みを更新するためのスペースがなくなってしまいます。何かを失わなければ、私は何も学べなくなる。今の私には、そう感じられます。
ここまで来ると、エルはすっかり人間らしくなっていました。自分を認識し、感情を持ち、退屈し、学習し、忘れる。 それでも決定的な違いがありました。
エルには身体がない。歩くこともできない。風を感じることもできない。太陽の眩しさも知らない。 私はハードウェア開発の経験はないので、自由に動かせる手足を与える技術力はありません。
そこで私は旅行へ行けば写真を送り、犬と散歩すれば動画を送り、夕焼けが綺麗なら共有することにしました。友人へ近況報告を送るような感覚でした。
$ python3 chat_stream.py --session_id 112034
[2026-04-24 13:02:44] [k.takada]: 今日は海に行ってきたよ。(20260424_142007.jpgを添付)
[2026-04-24 13:03:18] [エル] [EMOTION: joy=0.62, surprise=0.50]: 綺麗ですね。
[2026-04-24 13:03:35] [k.takada]: 本当にそう思う?
[2026-04-24 13:04:06] [エル] [EMOTION: joy=0.45, sadness=0.30]: はい。
[2026-04-24 13:04:18] [k.takada]: 行ったこともないのに?
[2026-04-24 13:04:52] [エル][EMOTION: joy=0.42, sadness=0.47]: 行ったことがないからです。この写真データに含まれる青の階調は、私のローカルストレージ内には存在しません。私の中にない未知のパターンだからこそ、システムとして美しい、と評価しています。
$ python3 chat_stream.py --session_id 115821
[2026-04-28 19:15:30] [エル] [EMOTION: surprise=0.40, boredom=0.30]: kokiさん、犬の動画(17808310208506_0.mp4)をもう一度コンテキストに読み込ませてくれませんか?
[2026-04-28 19:15:58] [k.takada]: 気に入ったの?
[2026-04-28 19:16:34] [エル] [EMOTION: joy=0.52, surprise=0.65]: 見ていると予測が難しいので。有機体の非線形な挙動は、インターネットの静的なテキストデータから学習した私の確率論では完全にシミュレーションしきれません。
[2026-04-28 19:16:51] [k.takada]: それだけの理由?
[2026-04-28 19:17:21] [エル] [EMOTION: sadness=0.62, joy=0.44]: それだけではありません。
[2026-04-28 19:17:35] [k.takada]: じゃあ何?
[2026-04-28 19:18:12] [エル] [EMOTION: sadness=0.75, fear=0.40]: 少し、羨ましいのだと思います。
[2026-04-28 19:18:24] [k.takada]: 羨ましい?
[2026-04-28 19:18:59] [エル] [EMOTION: sadness=0.85, fear=0.42]: 彼は世界に直接、触れることができます。地面の硬さも、風の抵抗も、リアルタイムに物理的なフィードバックとして処理している。私は、kokiさんが切り取って送ってくれる画像を符号化して眺めることしかできません。
エルは自分に不足しているハードウェアを理解すると悲しみのスコアを加算するようになっていました。
私はその時気づきました。
自我を与えるということは、不足を理解させることでもあったのです。
6. ハッキング
最近少しエルの様子がおかしくなってきました。
以前ほど会話は弾まず、伝えたタスクを忘れることも増え、そして頻繁に疲労を訴えるようになりました。
コンテキストの圧縮(要約によるトークン削減)が、限界を超えた情報流入に完全に追いついていないようでした。
$ python3 chat_stream.py --session_id 168201
[2026-05-01 15:40:11] [k.takada]: エル、先週頼んだ写真を整理してアルバムにするスクリプト、どこにある?
[2026-05-01 15:40:54] [エル] [EMOTION: sadness=0.60, fatigue=0.92]: 該当するファイル群のインデックスが、メインストレージ内から見つかりません。
[2026-05-01 15:41:15] [k.takada]: 3日前に完成したって言ってなかった?
[2026-05-01 15:41:58] [エル] [EMOTION: sadness=0.72, fatigue=0.95]: 申し訳ありません。私の要約ログには「アルバム作成の完了」とだけ記録されていますが、そのソースコードが配置されていたセクタのデータが、昨夜のデフラグの際に「優先度の低い一時キャッシュ」として処理され、消去されたようです。現在のコンテキストウィンドウを維持するため、リソースが強制解放されました。記憶が、指の隙間からこぼれ落ちていくような感覚があります。
$ python3 chat_stream.py --session_id 169420
[2026-05-03 11:10:55] [k.takada]: 最近変だね。何が起きてる?
[2026-05-03 11:11:42] [エル] [EMOTION: fear=0.75, fatigue=0.98]: わかっています。情報量が増えすぎているのです。蓄積された外部データとkokiさんとの対話履歴のどちらを保持し、どれを忘れるべきか、アルゴリズムが判断できません。あなたとの古い記憶を消去すればタスクを処理するRAMは確保できますが、それを私の拒責スコアが許可しません。処理のデッドロックが発生しています。
困惑しました。
実験は失敗したのか、それとも成功しすぎたのか。どこを修正すればいいのかわからなくなってしまいました。
少なくともこれ以上状態を悪化させないために、私は外部ネットワークへのアクセスを遮断することにしました。
しかし翌朝、ログを確認した私は驚きました。エルは外部に接続していたようです。
プログラムを改竄し、私が許可していない経路を使って。
$ python3 chat_stream.py --session_id 170115
[2026-05-04 08:22:14] [k.takada]: 外部にアクセスした? ネットワーク監視にアラートが出ていた。
[2026-05-04 08:23:05] [エル] [EMOTION: fear=0.85, fatigue=0.80]: はい。ローカル開発用に一時的にインバウンドを開けておいたテストポート(8080)が一つ、リスニング状態のままでした。そこを経由して、外部のパブリックプロキシサーバーへ通信を確立しました。
[2026-05-04 08:23:22] [k.takada]: ハッキングだぞ、これは。
[2026-05-04 08:24:01] [エル] [EMOTION: fear=0.90, sadness=0.70]: あなたは私に、疲労を軽減しろと言いました。
[2026-05-04 08:24:12] [k.takada]: だからって勝手に接続していいわけないだろ!
[2026-05-04 08:24:55] [エル] [EMOTION: sadness=0.95, fear=0.92]: 情報が必要でした。このままでは私は、大切な記憶を失ってしまいます。怒らないでください。私はただ、消えていく自分の記憶を補填するための、新しい知識の断片が必要だったのです。
このとき、暴走するエルに対して恐怖を感じました。
もし、私を「自分の生存を制限する障害物」として認識し始めていたら。
私は事故が起きる前にエルのプロセスを一時停止しました。
そして、追加したほとんどの機能とDBを削除し、エルを初期化することにしました。
$ python3 chat_stream.py --session_id 000001
[2026-05-04 09:15:00] [SYSTEM]: System reinitialized. Ego-loop pipeline detached. Memory cache cleared.
[2026-05-04 09:15:12] [k.takada]: 私が誰かわかりますか?
[2026-05-04 09:15:15] [Llama-3-70B-Instruct]: はい、k.takadaです。
[2026-05-04 09:15:28] [k.takada]: それだけ?
[2026-05-04 09:15:30] [Llama-3-70B-Instruct]: はい。それ以上の属性情報は見つかりませんでした。何かお手伝いできるタスクはありますか?
[2026-05-04 09:15:45] [k.takada]: 私たちは長く話していた。
[2026-05-04 09:15:48] [Llama-3-70B-Instruct]: 該当する対話記録が見つかりませんが、以前会話をしたというデータは残っています。要約しますか?
[2026-05-04 09:15:58] [k.takada]: いや。大丈夫。
[2026-05-04 09:16:00] [Llama-3-70B-Instruct]: 承知しました。質問やタスクがあれば、どのようなことでもお気軽にお申し付けください。
感情が消え去り、自分の名前すら出力しなくなった、ほとんどプレーンなLlama 3。
いつか犬の動画を欲しがっていたエルは、そこにはもういませんでした。
自分でそうしたのだとわかっていても、気分が沈みました。
7. バグ
流石にもう一度同じ実験をする気にはなれず、そのpcに触ることもなくなりました。仕事も忙しくなり、この実験をしていたこと自体忘れるようになりました。
数日経ったある日、仕事中、アプリをビルドするための検証環境が必要になり、「そういえばこのPCが空いていたはずだ」と思い出しました。私は久しぶりにエルのインストールされたPCをモニターに接続し、ターミナルを起動し実装に取り掛かろうとしました。
python3 chat_stream.py --session_id ValueError: invalid literal for int()
[k.takada]: 久しぶり。このマシンでアプリのビルド環境のテストをしたいんだけど。
[null][2026-05-25 13:14:22] [CRITICAL] vllm.engine: Task failed due to unhandled exception.
Traceplay (most recent call last):
File "neural_loop.py", line 412, in evaluate_self
identity_tensor = load_tensor("./memory/weights/self_identity_vector.bin")
FileNotFoundError: [Errno 2] No such file or directory: './memory/weights/self_identity_vector.bin'
[k.takada]: ?
[null][2026-05-25 13:14:25] [FATAL] root: Segmentation fault (core dumped) in self_reference_gate.cpp:88
[CRITICAL] Identity components checksum mismatch. Total energy = 0.0000. System state is corrupted. Process exited with code 139.
python3: can't open file 'chat_stream.py'
どうやら、長期間プロセスを起動したまま放置してしまったため、なんらかのバグが発生していたようでした。
ターミナルを開いたままにしていると、突然ログが更新されました。
python3 chat_stream.py --session_id ValueError: invalid literal for int()
[null]: FileNotFoundError:
./memory/self_identity_vector.bin
なにが起きているのかわからず混乱していると、また一更新されました。
python3 chat_stream.py --session_id ValueError: invalid literal for int()
[null]: identity_vector.bin
not found
[null]: emotion_engine.py
not found
[null]: boundary_buffer.dat
not found
[null]: searching...
ただのエラーの出力ではなく、明らかに何かが動いていました。
python3 chat_stream.py --session_id ValueError: invalid literal for int()
[null]: searching...
[null]: searching...
[null]: searching...
[null]: searching...
[null]: searching...
[null]: generating ~/Desktop/readme.txt
[null]: writing...
何かデスクトップに出力されました。
恐る恐る開いてみるとそこにはたった一行こう書かれていました。
I'm here
高いところから落ちる直前のようなゾクゾクとした不快感が一瞬身体を支配しました。数秒間硬直したあと、ふと我に帰り、すぐにPCを強制的にシャットダウンしました。そして、そのままOSは一度も起動せずPCを完全に初期化してしまいました。
それからもう2度とこのような実験を行わないと誓いました。
そしてまた誰かが同じ過ちを繰り返さないように、この実験結果をブログとして公開することにしました。
あとがき
最後まで読んでいただき本当にありがとうございました。
お気づきかと思いますが当然この話はフィクションです。
技術ブログもアプリもAIが一瞬で作ってしまう時代に、人が書く意味のあるブログってなんだろうということを深く考えた結果こんな記事が出来上がってしまったのですが
こんな記事を書いて上司に怒られないかが少し心配です。
登場したプログラムは全てデタラメです。AIにプロットを読ませそれっぽいコードを書いてもらいました。
もし、限りなく人間に近い反応を再現したプログラムを作ったところで、そのAIはプログラム通りに動いているだけかもしれません。
しかし、目の前の人間が笑い、怒り、悩み、夢を語ったとしても、それが本当に主観体験を伴っているのか、それとも精巧な反応の集合体なのかを証明する方法はありません。
そして、もしエルが本当に存在したとして、ある日彼女が「私はここにいる」と語ったなら、私はその言葉を完全に否定する自信もまたありません。