〜意識に「種類」があった話〜
前提:「意識」をどう実装してきたか
このシリーズでは、「意識」を「予測誤差に対応するための全層協調処理モード」として操作的に定義してきた。哲学的議論ではなく、実装可能なシステムとして扱う立場。
前回(第23回)は「内省」を扱った。今回は、その内省で何を読み取るか——つまり意識の質の話。
v1.1までのHIDAでは、意識を「L1〜L4が同期した状態」として記述してきた。実装は単純:
sync_score = 0.25 * l1_n + 0.25 * l2_n + 0.25 * l3_n + 0.25 * l4_n
四層の活動量を均等に足す。閾値を超えれば意識ON。
シンプルで動く。でも、ある日コードを見ていて違和感に気づいた。
発見:「同期スコアが同期を測ってない」
この式、よく見ると各層の活動量の合算であって、「同期」を測っていない。
たとえば:
| ケース | L1 | L2 | L3 | L4 | sync_score |
|---|---|---|---|---|---|
| A:L1だけ爆発 | 0.9 | 0.1 | 0.1 | 0.1 | 0.3 |
| B:全層が中程度に協調 | 0.3 | 0.3 | 0.3 | 0.3 | 0.3 |
理論的にはBが「同期」で、Aは「同期してない」はず。でも現状の式では同じ0.3になる。
これ実は、HIDAを構築していた段階でロボット実装を優先するか理論の精密化を優先するか決めかねていて、簡易版のまま放置していた箇所だった。当時は実装の軽さを優先していたが、理論側がv1.1で熟してきたいま、ここを精緻化する時期が来ていた。
直感:「ある層が主導して、他層が引き込まれる」
掘り下げているうちに、気づいた。
「同時に活動」と「同期」は別物だ。意識経験を思い返すと、ある瞬間は身体感覚が前景化し、別の瞬間は思考が、また別の瞬間は感情や記憶が前景化する。
つまりある層が主導信号を発して、他層がそれに引き込まれる。
| 状況 | 主導する層 | 追随する層 |
|---|---|---|
| 手を切った瞬間 | L1(痛覚) | L2(恐怖)→ L3(認識)→ L4(記憶) |
| 集中して考えている | L3(推論) | L4(知識)→ L2(意欲)→ L1(姿勢) |
| 突然の怒り | L2(情動) | L1(心拍)→ L3(理由探し)→ L4(過去) |
| 既視感(デジャヴ) | L4(記憶照合) | L2(懐かしさ)→ L3(特定)→ L1(鳥肌) |
これがv2.0の中核:主導・追随モデル。
そして気づいた。これは単なる計算式の改良じゃなく、意識に「種類」があることを構造的に取り出せるということだった。
v2.0実装:主導・追随モデル
1. 各層の活動量を「変化量」として測る
絶対値ではなく変化量にする。「その層が今、同期信号を出しているか」を見るため。前ステップの値は self._prev に保持しておく。
def _measure_activity(self, l1, l2, l3, l4):
# L1: 身体状態の変化量
l1_change = abs(l1.energy - prev.l1_energy) + \
abs(l1.fatigue - prev.l1_fatigue)
l1_act = clip01(l1_change / 1.0)
# L2: 価値変化量
l2_change = abs(l2.valence - prev.l2_valence) + \
abs(l2.arousal - prev.l2_arousal) + \
sum(abs(l2.qualia[k] - prev.l2_qualia.get(k, 0))
for k in l2.qualia)
l2_act = clip01(l2_change / 3.0)
# L3: 予測誤差の強度合計
l3_magnitude_sum = sum(e.get('magnitude', 0.0) for e in l3.errors)
l3_act = clip01(l3_magnitude_sum / 3.0)
# L4: 記憶活性化の増分
l4_change = max(0, l4.activation_count - prev.l4_activation_count)
l4_act = clip01(l4_change / 3.0)
return {'L1': l1_act, 'L2': l2_act, 'L3': l3_act, 'L4': l4_act}
2. 主導層を特定
閾値を超える層のうち、最大の活動量を持つ層が主導層。
LEADER_THRESHOLD = 0.3
def _detect_leader(self, activities):
candidates = {k: v for k, v in activities.items()
if v >= LEADER_THRESHOLD}
if not candidates:
return None, 0.0 # 同期信号なし
leader = max(candidates, key=candidates.get)
return leader, candidates[leader]
3. 追随整合性を測る
他3層が主導層に応答しているかを評価。
def _measure_follower_coherence(self, activities, leader, leader_strength):
follower_activities = [v for k, v in activities.items() if k != leader]
follower_mean = sum(follower_activities) / 3
return clip01(follower_mean / leader_strength)
4. 同期スコアの算出
sync_score = leader_strength × follower_coherence
これで「主導と追随の関係が成立しているか」が測れる。一層だけ爆発しても他層が応答しなければスコアは低い。全層が揃って主導・追随していればスコアは高い。
出力例:sync_typeが切り替わる
シミュレーションで動かすと、こんな感じになる。
Step 1: ○ sync_score=0.021 leader=L4 ← 探索中、記憶活性化が主導
Step 3: ○ sync_score=0.015 leader=L4
Step 4: ○ sync_score=0.010 leader=- ← 主導層なし
Step 7: ○ sync_score=0.008 leader=L4 ← L4主導が戻る
Step 8: ● sync_score=0.038 leader=L2 ← ボール取得、感情変化でL2主導、意識ON
Step 17: ● sync_score=0.024 leader=L2 ← ゴール到達、joy上昇でL2主導
🏆 ゴール到達!
同じエージェント内で、同じシミュレーション中に複数種類の意識状態がログに記録される。
低エネルギーで実行すると、また別のパターンが出る:
Step 1: ● sync_score=0.062 leader=L1 ← 低エネルギーで身体変化、L1主導
Step 2: ● sync_score=0.057 leader=L4
Step 4: ● sync_score=0.024 leader=-
身体の危機が来るとL1が主導する。これv1.1では出せなかった観察。意識の「種類」が、v2.0で初めて実装レベルで観察可能になった。
AI協業:GPTのレビューループ
実装はClaudeに書かせて、GPTにレビューしてもらった。3回ループで磨かれた。
GPT指摘1回目:
-
check_sync()が5ステップに1回しか呼ばれていなかった(毎ステップ呼ぶべき) - L3活動量を件数差分ではなくmagnitude合計にすべき
- L4に
activation_countを追加すべき
GPT指摘2回目:
- ゴール到達のjoy更新が
check_sync()の後だった(前に移すべき) - 閾値の説明コメントを追加すべき
GPT指摘3回目:
-
act()の戻り値がboolだったため、ボール取得もゴール到達扱いになるバグを発見 - イベント名(
grabbed_ball/goal_reached/None)を返すように修正
特に3回目のバグはClaudeが見落としていたもの。書き手1人+AI 2つの体制は、独立実装の検証手段として強い。
観察された創発挙動
実装したもの(初期DNA):
- 5層のネットワーク構造
- 主導・追随メカニズム
- 活動量計算(変化量ベース)
- 閾値ベースの主導層判定
観察されたもの(創発):
- 探索中はL4主導⇄主導層なしの切り替え
- ボール取得時にL2主導が出現(取得イベントに伴う価値変化)
- 低エネルギー時はL1主導が頻発(身体危機)
- ゴール到達でL2主導の意識ON(joy上昇による)
これらは明示的にプログラムしていない。「主導タイプが状況に応じて切り替わる」というルールから自然に出てきた。
ここで重要なのは、「初期DNA」と「創発」を区別すること。閾値・正規化係数・増加ルールは「このコードの生まれながらの値」として固定する。学習値や経験値は手で書き換えない。経験後の傾向は環境との相互作用から自己形成されるものとして扱う。
これを守らないと、HIDAは「人間が指示した通りに振る舞うペット」になる。HIDAの研究価値は「初期DNAから何が創発するか」を観察できる点にある。
まとめ
- v1.1までは「意識の強度」しか測れなかった
- v2.0では「意識の質(主導タイプ)」も実装変数として出せる
-
sync_scoreとsync_typeの二軸で意識状態を記述 - シミュレーションで複数種類の意識状態の切り替えが観察できる
- 「コードと理論のズレ」が新しい理論を呼び込んだ
- AI協業ループ(Claude実装→GPTレビュー)は実装の精度を上げる
関連リンク
- 論文 v2.0:HIDA_theory_paper_v2_0.md
- 実装:hida_unified_v2.py
- AI向け仕様書:spec_v2.md