0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ninda 15日目: Blackboard 〜知識共有パターン〜

Last updated at Posted at 2025-12-14

今日のゴール

  • Blackboardパターンの概念を理解する
  • 複数エージェントによる協調問題解決を学ぶ
  • AIシステムへの応用を理解する

Blackboardパターンとは

黒板(Blackboard)に複数の専門家が書き込み、協調して問題を解決するパターンです。

要素 役割
Blackboard 共有知識ベース(タプルスペース)
Knowledge Sources 専門知識を持つエージェント
Control 処理の調整(イベント駆動)

タプルスペースとの相性

特性 Blackboardでの活用
共有メモリ 知識の共有
パターンマッチ 関連知識の検索
イベント通知 知識追加時のトリガー
疎結合 エージェント間の独立性

基本構造

知識の表現

# 事実(確定した情報)
toTuple(strVal("fact"), strVal("category"), strVal("key"), strVal("value"))

# 仮説(推測)
toTuple(strVal("hypothesis"), strVal("name"), floatVal(confidence))

# 解決状態
toTuple(strVal("problem"), intVal(id), strVal("level"), strVal("data"))

基本操作

# 事実を追加
proc assertFact(category, key, value: string) {.async.} =
  await blackboard.writeAsync(toTuple(
    strVal("fact"), strVal(category), strVal(key), strVal(value)
  ))

# 事実を照会
proc queryFacts(category: string): Future[seq[Tuple]] {.async.} =
  return await blackboard.readAllAsync(
    toPattern(strVal("fact"), strVal(category), nilValue(), nilValue())
  )

# 仮説を追加
proc addHypothesis(name: string, confidence: float) {.async.} =
  await blackboard.writeAsync(toTuple(
    strVal("hypothesis"), strVal(name), floatVal(confidence)
  ))

実践例: 診断システム

複数の知識源が協調して診断を行う例:

# 知識源1: 症状分析
proc symptomAnalyzer() {.async.} =
  let symptoms = await queryFacts("symptom")
  for s in symptoms:
    case s[2].strVal
    of "fever": await addHypothesis("infection", 0.6)
    of "cough": await addHypothesis("respiratory", 0.5)
    else: discard

# 知識源2: 組み合わせ分析
proc combinationAnalyzer() {.async.} =
  let hypotheses = await blackboard.readAllAsync(hypothesisPattern)

  if hasHypothesis("infection") and hasHypothesis("respiratory"):
    await addHypothesis("flu", 0.8)  # より高い確信度で診断

ポイント:

  • 各エージェントは自分の専門領域だけを担当
  • 知識が蓄積されるにつれて、より精度の高い結論に到達

漸進的問題解決

段階的に解決レベルを上げるパターン:

type SolutionLevel = enum
  slRaw, slParsed, slAnalyzed, slSolved

proc levelUp(problemId: int, fromLevel, toLevel: SolutionLevel, data: string) {.async.} =
  # 古いレベルを削除
  discard await bb.tryTakeAsync(
    toPattern(strVal("problem"), intVal(problemId), strVal($fromLevel), nilValue())
  )
  # 新しいレベルを追加
  await bb.writeAsync(toTuple(
    strVal("problem"), intVal(problemId), strVal($toLevel), strVal(data)
  ))

ポイント:

  • 各段階の処理は独立したエージェント
  • 失敗しても前のレベルに戻れる
  • 並列処理が可能(異なる問題を同時に処理)

AI推論エンジン

ルールベースの推論をタプルスペースで実装:

type Rule = tuple[
  conditions: seq[(string, string)],  # 条件リスト
  conclusion: (string, string)         # 結論
]

let rules: seq[Rule] = @[
  (conditions: @[("has", "feathers"), ("can", "fly")],
   conclusion: ("is", "bird")),
  (conditions: @[("is", "bird"), ("size", "small")],
   conclusion: ("is", "sparrow")),
]

proc infer() {.async.} =
  var changed = true
  while changed:
    changed = false
    for rule in rules:
      if await allConditionsMet(rule.conditions):
        if not await hasFact(rule.conclusion):
          await assertFact(rule.conclusion)
          changed = true  # 新しい事実が追加されたので再度チェック

推論の流れ:

  1. 初期事実: has=feathers, can=fly, size=small
  2. ルール1適用 → is=bird を導出
  3. ルール2適用 → is=sparrow を導出

ユースケース

分野 応用例
医療診断 症状から病気を推論
音声認識 音素→単語→文の段階的認識
画像解析 エッジ→形状→物体の認識
計画立案 部分解の統合
ゲームAI 状況分析と戦略決定

まとめ

学んだこと

トピック ポイント
Blackboard 共有知識ベースによる協調
Knowledge Sources 専門エージェントが知識を書き込み
漸進的解決 段階的に解のレベルを上げる
推論 ルールベースの知識導出

いつ使うか

場面 推奨
複雑な診断 Blackboard
段階的変換 漸進的解決
ルールベースAI 推論エンジン
単純なデータ処理 Producer-Consumer

演習問題

問題15-1: マルチエージェント診断

3つ以上の知識源を持つ診断システムを実装してください。

  • 症状分析エージェント
  • 患者属性分析エージェント(年齢、既往歴など)
  • 環境分析エージェント(季節、流行など)
ヒント
  • 各エージェントは独立したasyncプロシージャ
  • 事実は("fact", category, key, value)形式で統一
  • 各エージェントは自分の担当カテゴリだけを読む
  • 最終診断は全仮説の確信度を総合して決定

問題15-2: 優先度付き推論

確信度の高い仮説から優先的に処理する推論エンジンを実装してください。

ヒント
  • 仮説を確信度でソート
  • 閾値(例: 0.7)以上の仮説のみを次の推論に使用
  • readAllAsync → ソート → 処理の順で実装
  • 確信度の低い仮説は後回しにして、高い仮説で推論を進める

問題15-3: イベント駆動Blackboard

新しい事実が追加されたときに自動的に推論を実行するイベント駆動型システムを実装してください。

ヒント
  • evWriteイベントを購読
  • 新しい事実が追加されたら関連する知識源をトリガー
  • subscribeAsyncでパターン("fact", *, *, *)を監視
  • イベント受信時にasyncCheckで推論を非同期実行

前回: Master-Worker | 目次 | 次回: 永続化とWAL

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?