🎯Single Source of Truth(SSoT)
4リポ共通の確定事項(正)。ターゲット OS / Asterisk 版 / ポート / verdict 経路など。各リポはここを参照する。
🕒 最終更新: 2026-07-04(JST)
このページは Aegis 全体(aegis-platform / aegis-sip-bridge / voice-edge / aegis-docs)の 唯一の正(Single Source of Truth) です。ターゲット OS や Asterisk 版などが各リポで食い違う (cross-repo drift)のを防ぐため、確定事項はここに一本化します。
- 正はここ。 各リポの README / docs / コード内コメントは、値を直書きせずこのページを参照する。
- 値を変えるときは まずこのページを更新 し、その後で各リポへ反映する(逆順は禁止)。
- 「実機確認中」の項目は確定扱いしない(下の ⚠️ 注記を参照)。
確定事項(正)
| 項目 | 確定値 | 備考 / 決定の背景 |
|---|---|---|
| ターゲット OS | Raspberry Pi OS Bookworm Lite 64bit (aarch64) | Chris 選択。aarch64 で統一 |
| Asterisk | 22 LTS(ソースビルド) | パッケージ版ではなくソースビルド |
| Python(Pi 本体) | 3.11(Bookworm 標準) | OS 標準をそのまま使用 |
| Python(bridge) | 3.12 想定 ⚠️ | 実機確認中(下記注記参照) |
| 本命の音声経路 | Route C(OpenAI Realtime GA / gpt-realtime) | AI 応答の本命。voice-edge A22 はその telephony 土台(下記) |
| 本命の telephony 土台 | voice-edge A22 | メインライン。下の比較表を参照 |
| AudioSocket ポート | 9092 | Asterisk ↔ bridge.py |
| 通話後データ記録 | POST /api/realtime/transcript-final(通話終了後 1 回) | 会話全文 + LLM 判定を call_logs に保存。学習データの本線 |
| spam_score の判定源 | call_logs.score_source = rules / llm | 同じ score 列に 2 種の判定が入り得る。列で区別(verdict 二重化への対処) |
| verdict 遮断(通話中) | bridge の AMI Hangup(D-1)で能動切断 | AstDB DBPut 経路は不採用(ADR-0001 B案) |
| 切断安全弁 | AEGIS_TERMINATE_MIN_SCORE=0.8 | LLM が should_terminate=true でも spam_score<0.8 なら切断却下→人へ(fail-open) |
| route-decision(通話前) | curl(別レイヤ) | 着信時のルート判定。verdict 経路とは別物 |
bridge の Python 3.12 想定 は実機での動作確認が未完了です。確定するまでは 「3.12 を目標、実機検証中」の扱いとし、各リポに 3.12 を断定で書かないこと。 (Pi 本体側の 3.11 は Bookworm 標準のため確定。)
本命(A22)と 凍結された設計
A22 と Route C の関係: voice-edge A22 は telephony(回線・Asterisk・AudioSocket)の土台、
Route C(OpenAI Realtime GA / gpt-realtime)は AI 応答の本命。両者は別レイヤで、A22 の上で Route C が動く。
v2 standalone(Ubuntu 24.04 / Asterisk 20)は凍結 です。過去資料として残しますが、 新規の実装・ドキュメント・見積りの根拠には使いません。今後の「正」は voice-edge A22 のみ。
verdict の流れ(経路を取り違えない)
判定値(verdict)の戻し経路と、通話前のルート判定(route-decision)は 別レイヤ です。混同しないこと。
- 通話前 — route-decision: 着信時にどのルートで処理するかを決める。curl(HTTP)で問い合わせる。
- 通話中 — 遮断(verdict): spam の切断は bridge が AMI Hangup(D-1)で能動的に行う。
OpenAI Realtime の
classify_call(should_terminate=true)を受け、締めの発話完了後にAEGIS_UUIDを AMIStatusで逆引きして対象チャンネルをHangup(cause=21)。 旧A案(bridge が AMIDBPutで AstDB に verdict を書き、dialplan がDB()で読む)は不採用 (ADR-0001 B案を採用)。bridge は DBPut しないため、dialplan 側の DB read も撤去済み。 - 切断安全弁(fail-open):
should_terminate=trueでもspam_score < AEGIS_TERMINATE_MIN_SCORE(既定 0.8) または数値でなければ 切断を却下し AI 継続 → 人へ。LLM 単独判定だけで実チャンネルを切らない。 (whitelist 再照合はcaller_number配線後の将来分。)
通話後データ記録(学習データの本線)
通話中の「遮断」とは別に、通話が終わったら会話全文と判定を残すレイヤがある。これが moat(データ資産)と 分類器改善(eval)の土台になる本線。
- 経路: bridge(Route C)が通話終了時に
POST /api/realtime/transcript-finalへ 1 回だけ 送る。 中身は 会話全文(caller:/ai:の順序付き) + 通話中classify_callの直近 LLM 判定(spam_score/detected_category)。 - fail-safe: 送信失敗でも通話終了処理は止めない。文字起こしが 0 件でも判定があれば送る(判定欠落を防ぐ)。
- 保存先:
call_logsに upsert(キー = 通話 UUID)。ここに溜まった行を 人手レビュー → 学習 → eval で回すのが本線。 - 通話中の遮断(AMI Hangup)とは独立。遮断されなかった通話も含めて全通話ぶん記録するのが狙い。
score_source(どの脳の score か)
call_logs.spam_score には 2 種類の判定源が入り得るため、score_source 列で必ず区別する(verdict 二重化への対処)。
score_source | 判定源 | 経路 |
|---|---|---|
rules | ルールベース Scorer(キーワード加点・カテゴリ) | transcript-tick が書く |
llm | LLM の classify_call(gpt-realtime) | transcript-final が書く |
null | スコア未付与 / 旧データ | — |
- どちらを「正」とするかは未確定。実データが溜まってから eval(
scripts/eval_scorer.py --source rules|llm)で両層を同一 gold で比較して決める。 - 初期観測: ルール層は言い換え・STT 誤りに弱く見逃しが多い / LLM 層は捕捉するがコスト・レイテンシがかかる。名札があるので後から公平に測れる、が現時点の確定事項。
src の共有方針
| 共有相手 | 渡す範囲 | 備考 |
|---|---|---|
| Chris(Namzak Labs) | リポジトリ全体 | OS など基盤の選定は Chris 判断 |
| ChatVoice | configs ・ scripts のみ | 設置・運用に必要な範囲に限定 |
更新履歴
- 2026-07-04: verdict 経路を実装事実に更新(AMI Hangup(D-1)で能動切断・AstDB DBPut 経路は不採用/撤去)+切断安全弁
AEGIS_TERMINATE_MIN_SCORE=0.8を追記。ADR-0001(B案採用)に整合。 - 2026-07-04: 「通話後データ記録(transcript-final・学習データの本線)」節と
score_source(rules/llm 区別) 節を新設。Route C(gpt-realtime)を本命の音声経路として位置づけ(A22=telephony 土台)。 - 2026-06-18: 初版。本日の決定事項(OS / Asterisk 22 / ポート 9092 / verdict 経路 / A22 本命・standalone 凍結 / src 共有方針)を確定として記載。