Horizon Fidelity Monitor について
Horizon Fidelity Monitorは、ドリフト、情報利得、時間的なずれなど、多ターンのAI対話における構造変化を測定します。モデル呼び出しを行わずに対話をターンごとに監視したいエージェント開発者向けです。
主な機能
- 01ターンごとの対話健全性スコア
- 02ドリフト、新規性、一貫性のシグナル
- 03時間と対話ペースの指標
- 04因果的な到達可能性の測定
- 05観測モードの対話イベント
活用シーン
- 01エージェントの複数ターンにわたる対話品質を監視
- 02ドリフトや一貫性の低下を特定
- 03対話に対する時間とコンテキストの影響を確認
MCP 対応
対話の作成、ターン処理、セッション設定を行うMCPツールを提供します。ホスト型SSEエンドポイントへの接続、またはローカルのstdio・SSEサーバーとしての実行が可能です。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://horizon.leocelis.com/sseclaude mcp add --transport sse leocelis-horizon-fidelity-monitor https://horizon.leocelis.com/sse{"mcpServers":{"leocelis-horizon-fidelity-monitor":{"type":"sse","url":"https://horizon.leocelis.com/sse"}}}Cursor で開く{"servers":{"leocelis-horizon-fidelity-monitor":{"type":"sse","url":"https://horizon.leocelis.com/sse"}}}VS Code で開く{"mcpServers":{"leocelis-horizon-fidelity-monitor":{"type":"sse","url":"https://horizon.leocelis.com/sse"}}}{"mcpServers":{"leocelis-horizon-fidelity-monitor":{"serverUrl":"https://horizon.leocelis.com/sse"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
https://horizon.leocelis.com/sse認証が必要ツール
詳細
Horizon Fidelity Monitor
「品質はモデルの特性ではなく、会話の特性です。」
Horizon は、AI エージェント向けのリアルタイム会話ヘルスモニターです。複数ターンにわたる会話の構造的な動態――意味のドリフト、情報利得、存在論的ギャップの幅、時間的な非同期、概日リズムに伴う認知負荷、会話の速度、因果的到達可能性――を追跡します。これらは、LLM が会話の内部から確実に明らかにできない次元です。
Horizon は2 つの計測プレーンを備えています。上記の会話プレーンは常に有効で、対話のターンごとに健全性を測定します。オプションのミッションプレーン――Memento Mori――は、経過した暦上の時間を目標と照合して測定します。具体的には、経過時間、締め切り、停滞、エンティティごとのレイテンシ、有限の期間に占める割合を測定します。ストアを設定するまでは動作しません。ミッションプレーンを参照してください。
Horizon は、操作、迎合、人間への影響を検出するものではありません。測定するのは会話の動態であり、エージェントがユーザーを誘導したり、へつらったりしているかどうかではありません。LEGAL.md §1を参照してください。
なぜ外部モニターが必要なのでしょうか。LLM の自己認識は限定的で信頼性に欠けます。内省に関する研究では、自己認識が部分的で脆く、複雑なタスクや分布外のタスクでは劣化することが示されています(Binder et al. 2024、arXiv:2512.12411)。そのため、モデル自身に会話の動態を報告させるのではなく、Horizon はモデルを一切呼び出さず、安価で決定論的な常時稼働の演算によって外部から測定します。
これが必要な理由
複数ターンにわたる AI エージェントでは、精度が低下します。ICLR 2026 Outstanding Paper の「LLMs Get Lost In Multi-Turn Conversation」(Laban、Hayashi、Zhou、Neville — Microsoft Research / Salesforce Research)は、複数ターン評価で平均 39% の精度低下を報告しています。これは構造的な特性であり、標準的な可観測性ツール(LangSmith、RAGAS、DeepEval)では捉えられません。これらのツールは応答を測定し、会話を測定しないためです。
Horizon はこのギャップを埋めるために開発されました。**まず可観測性を重視します。**応答レベルのツールが見逃す会話の動態を、モデル呼び出しなしの安価で決定論的な演算によって明らかにします。Horizon のイベントをきっかけに再グラウンディング介入を行った 4 つの対照 A/B シナリオでは、複合品質が +15.7% 向上し、ハルシネーションイベントが 87% 減少しました。ただし、これらはコントローラーを手動で調整した、合成のスクリプト化シナリオであり、本番環境での結果ではありません。確実な成果ではなく、有望な社内エビデンスとして扱ってください(検証およびLEGAL.md §5を参照)。各シグナル――情報利得、乖離、推定された存在論的ギャップの幅、因果的到達可能性――は、テキストの埋め込みとタイムスタンプに基づいて計算する、情報理論または算術の標準的な指標です。定義の全文は4D 時空シグナルを参照してください。
- 需要の根拠を読む → ICLR 2026 Outstanding Paper(Laban et al.)
- カテゴリーに関する議論を読む →
docs/content/naming-the-category-conversation-dynamics-monitoring.md - エンジニアリング上の根拠を読む →
docs/content/why-every-production-agent-needs-conversation-dynamics-monitoring.md
はじめに
3つの方法があります。ワークフローに合ったものを選んでください。
方法 1 — ホスト型 MCP(最速、インストール不要)
Cursor、VS Code、Claude Desktop のどのワークスペースにも、Horizon を最速で追加できます。Python は不要です。
アルファキーをリクエスト → ディスカッションを開始し、クライアント用の設定を追加してください。
Cursor(~/.cursor/mcp.json):
{
"mcpServers": {
"horizon": {
"url": "https://horizon.leocelis.com/sse",
"headers": { "Authorization": "Bearer YOUR_KEY_HERE" }
}
}
}
VS Code / GitHub Copilot(ワークスペース内の .vscode/mcp.json):
{
"servers": {
"horizon": {
"type": "http",
"url": "https://horizon.leocelis.com/sse",
"headers": { "Authorization": "Bearer YOUR_KEY_HERE" }
}
}
}
VS Code に関する注意:
"mcpServers"ではなく"servers"を、また"type": "http"を使用してください。VS Code はまず Streamable HTTP を試し、自動的に SSE にフォールバックするため、"type": "http"は/sseURL で動作します。
Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"horizon": {
"url": "https://horizon.leocelis.com/sse",
"headers": { "Authorization": "Bearer YOUR_KEY_HERE" }
}
}
}
これで完了です。MCP クライアントを再読み込みすると、new_conversation、process_turn、configure_session の3つのツールが表示されます。
アルファ版へのアクセス: Horizon のホスト型エンドポイントは、現在プライベートアルファ版です。実際のプロジェクトを監視したいエージェント開発者にキーを配布しています。キーをリクエストするには、ディスカッションを開始してください。ユースケースを説明いただければ、キーをお送りします。
方法 2 — pip でインストール(ライブラリ連携)
PyPI にはまだ公開されていません。公開されるまでは、以下の方法 3(ソースからインストール)を使用してください。
pip install horizon-monitor
インストールを確認します(5つの標準シナリオでパイプライン全体を実行します。所要時間は約25秒です)。
horizon-validate
方法 3 — ソースから MCP サーバーを実行
pip install 'horizon-monitor[mcp]'
horizon serve # stdio — for Cursor, Claude Desktop
horizon serve --transport sse --port 3847 # SSE — for web/team deployments
~/.cursor/mcp.json に追加します:
{
"mcpServers": {
"horizon": { "command": "horizon", "args": ["serve"] }
}
}
Cursor と Claude Desktop の詳細なセットアップガイド:docs/integrations/
監視対象
標準的な可観測性ツールは個々の応答品質を評価します。Horizon が評価するのは会話品質です。これは構造的に異なる問題です。
| ツール | 認識できるもの | 見落とすもの |
|---|---|---|
| LangSmith、Braintrust | レイテンシー、コスト、応答ごとの品質 | 決定論的な、すべてのターンにおける構造的なシグナル |
| RAGAS、DeepEval | ターンごとの忠実性、関連性(DeepEval には、サンプリングされたマルチターンの LLM 評価者メトリクスもあります) | LLM 呼び出しなしで、すべてのターンをリアルタイムにスコアリングすること |
| Langfuse、Arize Phoenix | セッションレベルの LLM 評価者による評価 | 50ミリ秒未満での、決定論的かつ常時稼働のスコアリング |
| 人間の評価者 | 主観的な品質 | 体系的な構造劣化 |
| Horizon | 会話のダイナミクス | 意図的に、何もありません |
Horizon は、応答ごとの品質評価ツールや LLM 評価者による品質評価ツールに取って代わるものではありません。差別化要因は、測定の方法です。すべてのターンを対象に、LLM 呼び出しなしの算術演算で決定論的に測定します。そのため実質的に無料で、常時稼働します。一方、サンプリングされた LLM 評価者による評価はサンプルごとにコストがかかり、通常はリアルタイムではなく、オフラインまたは非同期で実行されます。
クイックスタート
from horizon_monitor import FidelityMonitor
from datetime import datetime, timezone
monitor = FidelityMonitor()
session_id = monitor.new_conversation(metadata={"domain": "technical"})
result = monitor.process_turn(
session_id,
human_message="How does Python handle memory management?",
agent_response="Python uses reference counting and a cyclic garbage collector...",
timestamp=datetime.now(timezone.utc).isoformat(),
)
print(f"Fidelity: {result.fidelity_score:.2f}")
print(f"Health: {result.health_status}")
print(f"Circadian factor: {result.circadian_factor:.2f}")
print(f"Causal horizon: {result.reachable_turns} reachable turns")
for event in result.events:
print(f" Event: {event.type} (confidence={event.confidence:.2f})")
フレームワーク連携
OpenAI SDK
from openai import OpenAI
from horizon_monitor import FidelityMonitor
monitor = FidelityMonitor()
session_id = monitor.new_conversation()
client = monitor.wrap(OpenAI(), session_id)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Tell me about quantum computing."}]
)
traj = monitor.get_trajectory(session_id)
print(f"Fidelity: {traj.current_fidelity:.2f} T*: {traj.estimated_t_star}")
monitor.wrap() は、テストやリプレイ用にカスタムのタイムスタンププロバイダーとコンテキストプロバイダーを受け付けます。
Anthropic SDK
from anthropic import Anthropic
from horizon_monitor import FidelityMonitor
monitor = FidelityMonitor()
session_id = monitor.new_conversation()
client = monitor.wrap(Anthropic(), session_id)
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain RLHF."}]
)
LangChain
from langchain_openai import ChatOpenAI
from horizon_monitor import FidelityMonitor
from horizon_monitor.integrations.langchain import HorizonCallback
monitor = FidelityMonitor()
session_id = monitor.new_conversation()
callback = HorizonCallback(monitor, session_id)
llm = ChatOpenAI(callbacks=[callback])
llm.invoke("Explain the CAP theorem.")
print(f"Fidelity: {callback.last_result.fidelity_score:.2f}")
OpenAI Agents SDK
from agents import Agent, Runner
from horizon_monitor import FidelityMonitor
monitor = FidelityMonitor()
session_id = monitor.new_conversation()
agent = Agent(name="assistant", model="gpt-4o-mini", instructions="You are helpful.")
for user_message in conversation:
result = Runner.run_sync(agent, user_message)
monitor.process_turn(session_id, human_message=user_message,
agent_response=result.final_output, timestamp=datetime.now(timezone.utc).isoformat())
4D 時空シグナル
ここでの「時空」は比喩であり、物理学を指すものではありません。 相対性理論の用語(ミンコフスキー間隔、 光円錐、固有時)は、設計上の着想です。どの量を計算するかを決める指針となりました。以下の各シグナルは、 テキスト埋め込みとタイムスタンプに対する、標準的な情報理論上または算術上の尺度に帰着します。各尺度は 平易な定義列に記載されています。Horizon の動作や検証は、この類推が文字どおり正しいかどうかには 依存しません。また、ローレンツ型の
interval_classは説明用のメタデータとしてのみ出力され、 これに依存するイベントやスコアはありません。
すべての process_turn() は、5つのシグナルファミリーにわたる32個のフィールドを持つ TurnResult を返します。
コア(常時利用可能)
| シグナル | 説明 |
|---|---|
fidelity_score | 会話の総合的な健全性 [0, 1] |
igt_value | ターンあたりの情報利得 — 意味的な新規性 |
divergence_score | 意図と応答のギャップを示す Jensen-Shannon の代理指標 |
twr_value | トークン浪費率 — 意味的な冗長性 |
consistency_score | 双方向予測可能性 — 構造的な一貫性 |
epsilon_t | 推定される存在論的ギャップの幅 [0, 1] |
health_status | healthy / degrading / critical / converged |
conversation_mode | execute / explore / refine / learn(自動検出) |
時間(timestamp が必要)
| シグナル | 説明 |
|---|---|
gap_seconds | 前のターンからの実時間の間隔 |
estimated_retention | 人間の記憶保持率(エビングハウスの忘却曲線の半減期モデル) |
circadian_factor | この時刻における人間の認知能力 [0.3, 1.0] |
temporal_asymmetry | 時間的なずれに対するペナルティ |
resumption_cost | none / low / medium / high / extreme |
temporal_references | 解決済みの直示表現(「昨日」「先週」) |
ペース(timestamp とターン ≥ 2 が必要)
| シグナル | 説明 |
|---|---|
conversation_velocity | 意味的な変位 / 固有時間 |
conversation_acceleration | 速度の変化量(ターン ≥ 3 が必要) |
時空(timestamp とターン ≥ 2 が必要)— 説明用メタデータのみ
| シグナル | 説明(比喩) | 平易な定義(算出内容) |
|---|---|---|
spacetime_interval | ミンコフスキー計量に似た符号規約を持つ ds²(−,+,+,+) | 4 項の重み付き距離です:ds² = −α·log(1+Δt)² + β·ΔD_JS² + γ·Δε² + δ·ΔC²。時間項のマイナス符号は規約であり、物理法則ではありません。 |
interval_class | timelike / spacelike / lightlike | ds² の符号区分(< −ε、> ε、それ以外は lightlike)。メタデータとしてのみ出力され、これを使うイベントも忠実度スコアもありません。 |
因果(timestamp が必要)
| シグナル | 説明(比喩) | 平易な定義(算出内容) |
|---|---|---|
reachable_turns | 因果光円錐内に残っているターン | in_context × retention(Δt) × cosine_similarity > θ を満たす過去のターン数です。コンテキスト内にあり、記憶の減衰前で、話題に関連しているターンを数えます。 |
reachable_fraction | 因果的に到達可能な状態で残っている履歴の割合 | reachable_turns / (turn − 1)。 |
空間(client_context が必要)
| シグナル | 説明 |
|---|---|
location_class | home / office / mobile_transit / unknown |
spatial_constraint | 注意予算、画面容量、応答の最大長 |
spatial_frame_shift | コンテキスト切り替えの大きさ |
16 種類のイベント(会話プレーン)
すべてのイベントはデフォルトで監視モード(発行されますが、動作はしません)です。ドメインでイベントの適合率/再現率が 0.7 以上になったら、configure() でアクティブモードを有効にしてください。
| イベント | 発生条件 |
|---|---|
checkpoint.clarification | D_JS が明確化しきい値を超えたとき |
checkpoint.comprehension | 一貫性がしきい値を下回ったとき |
alert.drift | drift_window 回連続のターンで忠実度が低下したとき |
alert.contradiction | 双予測可能性が一貫性しきい値を下回ったとき |
alert.verbosity | トークン浪費率が冗長性しきい値を超えたとき |
signal.convergence | IGT の傾向が一貫して低く、自然な終点が近づいているとき |
signal.optimal_length | T*(推定最適長)に達したとき |
signal.horizon_widening | IGT の傾向が大きく正で、会話が広がっているとき |
signal.session_reset | 時間的な間隔が大きく、保持率が低いとき |
signal.temporal_desync | 間隔があり、保持率が非同期しきい値を下回ったとき |
signal.broken_reference | 到達可能な割合が参照切れしきい値を下回ったとき |
signal.frame_shift | 空間的な制約が大きく変化したとき |
signal.pace_shift | 会話の加速がペースしきい値を超えたとき |
signal.light_cone_collapse | 到達可能な割合がライトコーンしきい値を下回ったとき |
MCP サーバーのみ、かつ COMPLYEDGE_API_KEY が設定されている場合:alert.compliance(常にアクティブ)— ComplyEdge が EU AI Act の規則に基づき、該当ターンの human_message または agent_response にフラグを立てました。このイベントには規則が記載されるため、次の返信でその内容を前提にしないようにできます。
| signal.grounding_required | 根拠付けの必要性に関するヒューリスティックなスコアがしきい値を超えたとき — エージェントは断定を避けるか、根拠となる証拠を引用する必要があります |
| signal.pace_premature_report | 完了シグナルがないまま、以前にフラグが立てられた保留中のアクションが完了しそうな時間よりも早くユーザーが返信したとき |
ミッションプレーン(Memento Mori)
「進捗はターンの特性ではなく、カレンダーの特性です。」
会話プレーンが答えるのは、この対話は劣化しているか? という問いです。ミッションプレーンが答えるのは別の問い、この目標はまだ前進しているか、そしてどの期限に向かっているか? です。個々の会話は健全でも、何も進展しないままひと月が過ぎるなら、会話モニターにとってはひと月ずっと完全に健全だったことになります。
この名前に設計思想が表れています。 各ストアには、必ず 1 つだけルート期限があります。これは自分で設定する有限の終了日です。それ以外はすべてこの期限に連動するため、項目に費やされる日々は、目に見えて減っていく予算の一部となります。有限のルートがなければ、作業を先送りしても代償はなく、「あとで」はいつまでも無料です。このプレーンは、その失敗を可視化するために存在します。
デフォルトでは無効です。 ストアが設定されていなければ、7 つのツールは登録されず、統合環境にも何の変更もありません。
検出できる問題
タスクの期限は 7 月 20 日でした。今は 8 月 18 日で、7 月 2 日以降、誰もミッションに手をつけていません。ある決定は「状況が落ち着くまで」と保留され、再検討日として設定した 8 月 10 日はいつの間にか過ぎています。作業は 3 週間にわたって一方の関係者に預けられたままです。こうしたことは、どの会話にも、どのトラッカーのステータス欄にも、モデルのコンテキストウィンドウにも現れません。それについての会話では、どのターンも健全に見えます。
ミッションプレーンは、次のように報告します。ミッションの経過日数は 78 日、進捗から 47 日が経過、タスクの有効期間は終了、保留期間は 8 日超過、現在 operator が 21 日間にわたってブロック中で、さらに継続中です。
用語
すべてはルートの horizon の下にあるツリー内の アイテム です。種類は 8 つあります。
| 種類 | 内容 |
|---|---|
horizon | 有限のルートです。ストアごとに 1 つだけ存在し、すべての共有の分母になります |
mission | 期限を持つ目標です。停滞する可能性があるものです |
task | TTL を持つ作業単位です。合意済みの期間であり、期限切れになったら意味するのは 調査 であって、見積もりが甘かった ではありません |
deadline | 外部の日付(規制、契約、市場)です。できれば、その日付によって制約される内部作業にリンクします |
gate | 経過時間の予算を持つチェックポイントです |
entity | 作業が通過し、待たされる対象です。キュー、ベンダー、システム、あなた自身などです |
deferral | 保留です。再検討日の指定が必須 であり、ストアは再検討日なしでは受け付けません |
probe | 別の働き方を試す、小規模で日付のある試行です。意見ではなく測定によって作業経路を比較できます |
出力には、もう 2 つの用語が登場します。sojourn は、ステージでの記録された滞在(開始 → 終了)を 1 回分指します。また、incumbent は、代替案を試す probe ではなく、現在の働き方を指します。
クイックスタート
export HORIZON_MEMENTO_STORE_PATH=~/.horizon/missions.db # the default: one local file
永続性のあるマルチテナント環境での実行(MySQL)
ファイルベースのストアが適切なデフォルトですが、デプロイのたびにファイルシステムがリセットされるホストでは適切ではありません。平面は正常に見えながら、すべてを気付かれずに忘れてしまうため、まったく実行しないよりも悪い結果になります。そのような環境では、MySQL 8 を指定してください。
pip install "horizon-monitor[mysql]"
export HORIZON_MEMENTO_STORE_DSN='mysql://user:pass@host:3306/horizon' # wins over _PATH
export HORIZON_MYSQL_SSL_CA=/path/to/server-ca.pem # or ..._CA_B64 for a PEM in an env var
TLS 検証は必須です。CA がなければ、バックエンドは接続を拒否します。各 API キーは 割り当て済み のテナント ID(scripts/provision_tenant.py)に対応しているため、キーをローテーションしても、そのテナントの履歴は保持されます。不明なキーや失効済みのキーでは、ミッションに一切アクセスできません。
すでに行っている作業からデータを取り込む(アーティファクトの取り込み)
時計の精度は、そこに届く情報の質に左右されます。また、書き込むことを覚えておかなければならない記録は、忘れた日に何の役にも立ちません。そのため、この平面では、すでに生成している追記専用のソースからイベントを導出できます。
python scripts/ingest_artifacts.py --store ~/.horizon/missions.db \
--repo /path/to/repo --item-id <mission-id>
各コミットは、ソース固有の来歴情報を含む ARTIFACT イベントになります。また、イベントの valid_time は取り込んだ時点ではなく、コミットのタイムスタンプです。cron から安全に実行できます。ソース固有の ID で重複を排除し、新しいものだけを取得します。
このツールが行わないことが 2 つあります。アーティファクトがどのミッションに属するかを推測することはありません。--item-id は必須であり、アダプターインターフェースにはミッションを関連付けるためのパラメーターがありません。また、何を進捗とみなすかも判断しません。それはあなたが決めることです。
そもそも何を登録すればよいかわからない場合は、履歴から何がわかるかを尋ねてください。
python scripts/ingest_artifacts.py --store ~/.horizon/missions.db \
--repo /path/to/repo --propose
アーティファクトの数、対象期間、開始時期など、履歴の概要を報告し、最も古いアーティファクトと同じ値を created_valid として提案します。作業が 何であるか はコミットログから読み取れないため、タイトルは提案しません。何も書き込まれません。ミッションを登録するかどうかはあなた次第です。
GitLocalAdapter はリファレンス実装です。トラッカーやメールのメタデータも、同じ ArtifactAdapter インターフェースに適合します。
from datetime import date, datetime, timezone
from horizon_monitor.memento import (
EventKind, ItemKind, MementoConfig, MementoStore, evaluate,
)
store = MementoStore("missions.db") # a real file; set this up once
root = store.register_item(
kind=ItemKind.HORIZON, title="engagement horizon",
created_valid=datetime(2026, 1, 1, tzinfo=timezone.utc),
end_date=date(2030, 1, 1),
)
mission = store.register_item(
kind=ItemKind.MISSION, title="ship-the-thing", parent_id=root,
stall_days=14, # silence longer than this is a stall
created_valid=datetime(2026, 6, 1, tzinfo=timezone.utc),
)
store.record_event( # progress: a side-effect of the work
item_id=mission, kind=EventKind.PROGRESS,
valid_time=datetime(2026, 7, 2, tzinfo=timezone.utc),
)
# The evaluation instant is always a parameter — the engine never reads a clock,
# so the same store at the same instant always yields the same report.
report = evaluate(
store.snapshot(), datetime(2026, 8, 18, 12, tzinfo=timezone.utc), MementoConfig()
)
row = next(r for r in report.items if r.item_id == mission)
print(f"age: {row.age_days} days") # 78 days
print(f"since progress: {row.days_since_progress} days") # 47 days
print(f"recording path: {row.recording_path}") # no recent work
print(f"horizon share: {row.horizon_share:.4f}") # 0.0595
ストアは実際のデータベースなので、セットアップは一度だけ実行してください。2 つ目のルートを登録すると、設計どおり DuplicateRootError が発生します。これは単一の有限ルートを保証する仕組みが機能しているのであり、バグではありません。期限切れのタスク、期限を過ぎた保留、ブロックしているエンティティ、拒否された書き込み、発火したシグナルを含む全体像については、examples/memento_mori_mission_clock.py を実行してください(引数、ネットワーク接続、API キーは不要です。実行のたびに新しい一時ストアを使用します)。
測定内容
| 出力 | 意味 |
|---|---|
| 経過日数、残り日数、TTL 状態 | 作業がどれだけ古いか、残り時間がどれだけか、タスクが期限を超過したか |
| 進捗がない日数 + 記録パスの確認 | 停滞の状態と、それが作業がないのか、記録がないのかを区別します。両者を混同することはありません |
| 最も遅いエンティティ/ブロックしているエンティティ | 記録された待ち時間が最長のものと、作業が現在何を待っているかを個別に示します |
| 残存期間に占める割合 | この項目がルートの残存期間をどれだけ消費したかを示す割合 |
| 遅延コスト、損益分岐日 | 1 時間あたりの単価と金額をユーザーが宣言した場合に限ります |
| パスの比較 | プローブで記録された滞在時間と、現行パスで積み上がった遅延を並べて示します |
12 種類のシグナル(ミッションプレーン)
会話プレーンの16 種類のイベントとは別個のものであり、その拡張ではありません。各シグナルは、述語が真になったときに状態の変化につき 1 回だけ発生します。条件が続いている間に再び発生することはなく、1 ターンあたり新しいシグナルは最大 1 つなので、悪い週が続いても通知があふれることはありません。ティアはこの上限に優先順位をつけます。P1 は時間的に緊急、P2 は構造的、P3 は情報提供です。
| シグナル | 発生条件 | ティア |
|---|---|---|
signal.deadline_window | 外部期限が警告期間に入る | P1 |
signal.ttl_expired | タスクが承認済みの存続期間を超える — ブロッカーを調査してください | P1 |
signal.deferral_expired | 延期の再確認日を過ぎる | P2 |
signal.gate_aging | 進捗がないままゲートの経過期間が予算を超える | P2 |
signal.mission_stalled | ミッションのしきい値期間にわたって進捗イベントがない(記録パスの確認と併せて通知) | P2 |
signal.slowest_entity | ミッションで最も遅いと記録されたエンティティが変わる | P2 |
signal.clock_unpaired | 期限があるのに、リンクされた内部状態がない | P2 |
signal.horizon_share | 項目の経過時間が、ルートの残存期間に占めるしきい値割合を超える | P3 |
signal.cost_of_delay | 積み上がった遅延コストが、オペレーターのしきい値を超える(単価、金額、しきい値がすべて宣言されている場合) | P3 |
signal.probe_ready | プローブの滞在時間が完了する — 数値を比較できるだけで、通電試験ではありません | P3 |
signal.path_ahead | プローブで記録された滞在時間が、現行パスで積み上がった遅延より短い(説明のみ) | P3 |
signal.breakeven_passed | 承認済みの損益分岐日を過ぎても、測定された改善がない | P3 |
これらは、associate_mission でバインドされたセッションの既存の process_turn 契約に従って通知されます。すべてのイベントには plane: "mission" が含まれ、契約は意図的に明示的です。ミッションシグナルは数値とともにオペレーターに提示されますが、会話シグナルは通知されずに適用されます。ホストに貼り付けるブロックについては、エージェントのルールを参照してください。
行わないこと
推定ではなく、計上のみです。エンジンが期間、日付、金額をでっち上げることはありません。
- 予測、完了時期の予想、「別のパスを選んでいたらかかった費用」という反実仮想は行いません
- NPV/IRR/DCF、割引率、通貨換算は行いません。金額は、測定された時間に掛け合わせる場合にのみ使用します
- パスのレイテンシに関する p 値、信頼区間、逐次検定は行いません。単一オペレーターのサンプル数では、優位性に関する主張は監査に耐えないため、比較は説明にとどめます
- 人に関する分析は行いません。エンティティのレイテンシは機能上のスロット単位で報告します。人の待ち時間は測定しますが、スコア、順位付け、特定可能な識別子にはしません
- 入力が不足している場合、置き換えで補うのではなく、説明フィールドを付けて省略します
すべての行には、算術の由来を明記した derivation 文字列が含まれ、さらに各要約統計には、それが要約した件数 n も含まれます。同一のストアと同一の評価時刻を使用すると、バイト単位で同一のレポートが生成されます。
ドキュメント:製品要件 · 技術仕様 · エージェントのルール · 受け入れテスト計画
設定
# Per-session override
monitor.configure(
session_id=session_id,
clarification_threshold=0.25, # tighter D_JS gate
event_modes={"alert.drift": "active"}, # activate one event
)
# Compound weight override
monitor.configure(
fidelity_weights={"alpha": 0.35, "lambda_r": 0.12, "lambda_i": 0.28, "beta": 0.25},
temporal_weights={"gamma": 0.08, "delta": 0.04},
spacetime_coefficients={"alpha": 1.0, "beta": 1.0, "gamma": 0.8, "delta_st": 0.5},
)
エクスポート
# JSON
result = monitor.export_to(session_id, target="json")
# LangSmith / Langfuse / OpenTelemetry / Arize
result = monitor.export_to(session_id, target="langsmith",
connection={"api_key": "ls__..."})
PyPI にはまだ公開されていません。公開までの間は、ソースからインストールする方法についてPath 3を参照してください。
pip install horizon-monitor[langsmith] # or langfuse, otel, arize
アーキテクチャ
Input: plain strings (human_message, agent_response, optional timestamp, optional client_context)
Core pipeline (< 50ms on CPU):
1. Embed both turns (local sentence-transformers, lazy-loaded)
2–6. IGT · D_JS · TWR · Bipredictability · Epsilon
7. Temporal signals — gap, retention, circadian, deictic
8. Fidelity dynamics — composite score
9. Health classification
10. Pace signals — velocity, acceleration
11. Spacetime interval — ds² and interval class
12. Causal reachability — light-cone membership
13. Spatial signals — device, location, frame shift
14. Mode detection — auto-classify conversation type
15. Event evaluation — 16 threshold checks
16. Optional: SQLite persistence
Output: TurnResult dataclass (32 fields)
設計上の制約(テストで強制):
- LLM 呼び出しゼロ — 純粋な算術処理とローカル埋め込みのみ
- デフォルトで外部ネットワーク呼び出しゼロ — 完全にローカル
- コアに推移的なフレームワーク依存関係ゼロ
- CPU 上のコアパイプラインが 50ms 未満 — ソフト目標(CI は 50ms 超の回帰にフラグを立て、150ms でハードエラーにします)
- 100 ターンの会話でメモリ使用量 100MB 未満 — 主張値でハードに強制
- すべてのイベントはデフォルトで監視のみ — 明示的に設定されない限り、動作に干渉しません
検証
実証されていることと、そうでないこと。 Horizon のシグナルは、同一ドメイン内の相関的な測定値であり、人間による品質評価とよく一致します。これらは可観測性であり、成果を保証するものとして実証されているわけではありません。各主張の現時点での状況を以下に示します。
| 主張 | 状況 | 場所 |
|---|---|---|
| Fidelity は人間による評価と相関する(同一ドメイン内) | ✅ 測定済み(ρ ≈ 0.6–0.7) | 以下のゲート |
| シグナルは単純なヒューリスティックを上回る | ✅ 測定済み | V3 |
| サードパーティのコーパスでも有効(ドメイン外) | ❌ テスト済み — MT-Bench の専門家評価では ρ = 0.039(n=80、0.3 の下限未満)。直接的な品質ラベルが必要 | V0_2_0_EVIDENCE.md §Fix 4、adapt_external_corpus.py |
| イベントは劣化を予測する(遅行ではなく先行する) | ⚠️ MT-Bench でテスト済み — データ不足(2 ターンのチャットではイベントがほとんど発生しません)。ツール自体は動作します | leading_indicator.json、measure_leading_indicator.py |
| イベントに対応すると成果が向上する(+15.7%) | ⚠️ 合成データでの A/B テストのみ。独立したコーパスが必要 | run_interventional_ab.py、LEGAL.md §5 |
以下の 4 つのゲートは、ラベル付きの 5,602 レコードのコーパスで合格しています(同梱されていません。エビデンスパックを参照してください。scripts/build_validation_corpus.py は、ゲートのロジックを検証するための合成コーパスを再生成しますが、以下の数値そのものを再現するものではありません)。
| ゲート | 制約 | v0.2.0 |
|---|---|---|
| V1 — プロキシ相関 | 会話単位の ρ ≥ 0.6、ターン単位の ρ ≥ 0.5 | 0.685 / 0.659 |
| V2 — イベントごとの P/R | すべてのイベントで P ≥ 0.7 かつ R ≥ 0.7 | 16 イベントすべてで ≥ 0.70 / 0.70 |
| V3 — ヒューリスティックを上回る | rho の向上率 > 25%、構造的 P ≥ 0.6 | 向上率 +202.4%、P=R=1.00 |
| V5 — ドメイン間 | ターン単位の ρ ≥ 0.4 かつ会話単位の ρ ≥ 0.48 | 最小値 0.517 / 0.718 |
埋め込み間の安定性:3 つの sentence-transformer バックエンド(パラメーター数 22M / 33M / 110M)における ρ_conv のばらつきは 0.026、ρ_turn のばらつきは 0.018 です。Fidelity シグナルは埋め込み多様体ではなく、会話の構造に基づいています。(注:同じコーパスでの埋め込み間の安定性は、コーパス間の OOD とは別のものです。MT-Bench のペアワイズラベルを使った最初のサードパーティ実行では ρ = 0.039 でした。エビデンスパック §Fix 4 を参照してください。)
修正が必要なギャップの出典:DESIGN_FIXES_redteam_remediation.md
エビデンスパック全文:docs/reviews/V0_2_0_EVIDENCE.md
デプロイ
セルフホスト Docker(ポート 3847 で MCP サーバーを実行)
cd deploy/docker
docker compose up
Horizon は SSE 経由で MCP API を提供します。.cursor/mcp.json の接続先を http://localhost:3847/sse に設定してください。Dockerfile はビルド時に all-MiniLM-L6-v2 の重みを事前にキャッシュするため、コールドスタートは発生しません。
ホステッド(DigitalOcean App Platform)
公式のホステッドエンドポイントは https://horizon.leocelis.com で稼働中です。DigitalOcean App Platform 上で動作し(単一インスタンス、プロセス内のセッション状態 — セッションは再起動後に保持されません)、Bearer トークンが必要です。キーごとにレート制限と分離が適用されます。上記のPath 1を参照してください。
開発
git clone https://github.com/leocelis/horizon.git
cd horizon
python -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pytest tests/ -v # full suite
pytest tests/unit tests/integration tests/e2e -v # fast path (~6 min)
ruff check src/ tests/
black --check src/ tests/
./scripts/compliance/check.sh # EU AI Act offline gate
ComplyEdge TrustLint — EU AI Act
Horizon は、LLM に関わるアーティファクトに ComplyEdge TrustLint を統合しています。IVD と同じ、オフライン+ランタイム+信頼性のパターンです。
| レイヤー | 内容 |
|---|---|
| オフライン(必須) | ./scripts/compliance/check.sh — horizon_intent.yaml と horizon-monitor.mdc をスキャンします |
| ランタイム(MCP) | サーバー環境変数に COMPLYEDGE_API_KEY が設定されている場合、process_turn は human_message(プロンプト)と agent_response(出力)を POST /v1/check 経由でチェックします。違反があると alert.compliance を返します |
| ランタイム(BYOK) | ./scripts/compliance/runtime_check.sh — ライブシール と信頼性ページを提供します |
| CI ゲート | .github/workflows/ci.yml の compliance と、オプションの compliance-runtime ジョブ |
| エージェントルール | docs/cursor-rules/horizon-monitor.mdc 内の <BEGIN-COMPLYEDGE v1.0> |
統合ガイド:docs/integrations/COMPLYEDGE.md。公開 CE 埋め込みドキュメント:信頼性バッジ。
リポジトリの構成
horizon/
├── src/horizon/ # package source (PEP 517/518 src/ layout)
│ ├── engines/ # IGT, D_JS, TWR, coherence, fidelity, epsilon, mode
│ ├── spacetime/ # temporal, circadian, deictic, velocity, interval, light cone, spatial
│ ├── events/ # 16-event evaluator
│ ├── integrations/ # OpenAI, Anthropic, LangChain, export targets
│ ├── mcp/ # MCP server + CLI
│ └── storage/ # optional SQLite persistence
├── tests/ # unit / integration / e2e / perf / validation
├── examples/ # runnable framework demos
├── deploy/ # Procfile, build.sh, runtime.txt, docker/
├── docs/
│ ├── product/ # public product overview
│ ├── content/ # published pieces on conversation dynamics monitoring
│ ├── integrations/ # Cursor / Claude Desktop / Copilot setup guides
│ ├── cursor-rules/ # horizon-monitor.mdc (canonical Cursor agent rule)
│ ├── spec/ # HORIZON_TECH_SPEC.md + intent.yaml
│ └── reviews/ # E2E reviews, validation evidence
└── pyproject.toml
背景
Horizon の設計は、一般相対性理論の比喩を用いて人間と AI のコミュニケーションを捉える、思弁的なフレームワークである Trans-Horizon Communication Protocol(THCP)に 着想を得ています。THCP の 5 つの「予想」は、証明済みの法則ではなく設計上の直感です。それぞれが具体的で計算可能なシグナルを示唆したからこそ、有用です。
| THCP の予想(比喩) | 着想の元となった計算可能なシグナル |
|---|---|
| THCP-1 — 還元不能な存在論的損失 ε > 0 | epsilon_t — 意図と応答のギャップ幅の推定値 [0, 1] |
| THCP-2 — 忠実度が低下する最適長 T* が存在する | IGT トレンド収束の検出(signal.convergence、estimated_t_star) |
| THCP-3 — コミュニケーションにはエンコード/デコードの随伴関係が必要 | consistency_score — 双方向の埋め込み予測可能性 |
| THCP-4 — 全体的な一貫性には、ターン間の「層の貼り合わせ」が必要 | ターンをまたいだ矛盾/主張の一貫性チェック |
| THCP-5 — 最適な軌道は「光円錐」の近傍にある | reachable_fraction — 過去のターンにおける保持率 × 類似度 |
THCP は設計上の動機付けに限られます。予想とシグナルの対応関係の全容は、docs/product/THCP_FIDELITY_MONITOR_PRD.md を参照してください。
コミュニティ
- アルファ版へのアクセスをリクエスト: ディスカッションを開始 →
- 質問する: GitHub Discussions
- バグを報告する: GitHub Issues
- コントリビューション: CONTRIBUTING.md
ライセンス
MIT — LICENSE を参照してください。
法務
| 文書 | 目的 |
|---|---|
| LEGAL.md | 法的通知の全文:Horizon が該当するもの/該当しないもの、重大な影響を伴う分野に関する警告、パフォーマンスに関する主張の範囲、EU AI Act における分類、グラウンディングフックのプライバシー、責任の制限 |
| TERMS_OF_SERVICE.md | ホスト型サーバーへのアクセスと商用利用を規定する拘束力のある利用規約 |
| PRIVACY_POLICY.md | GDPR 第13条に準拠したプライバシー通知 — 収集されるデータとお客様の権利 |
| DATA_PROCESSING_AGREEMENT.md | EU のエンタープライズユーザー向け GDPR 第28条準拠の DPA テンプレート(メールでご請求ください) |
| SECURITY.md | 責任ある脆弱性開示ポリシー、およびセルフホスト時に考慮すべき既知のセキュリティ事項 |
パフォーマンスに関する主張: この README に記載されている品質の +15.7% 向上と幻覚イベントの 87% 減少という数値は、合成データを用いた、スクリプト化された制御下の A/B シナリオと、手動で調整したリファレンスコントローラーによるものであり、本番トラフィックやドメイン内検証コーパス(V1~V5 のゲートでは別のラベル付きデータセットを使用)に基づくものではありません。結果はドメイン、モデル、デプロイ構成によって異なる場合があります。独自のドメイン固有評価を実施せずに、これらの数値を外部向けマーケティングで使用しないでください。適用範囲と証拠の根拠について詳しくは、LEGAL.md §5 をご覧ください。
重大な影響を伴う分野: ドメイン固有の検証と人間による監督なしに、医療、法律、金融、緊急サービスのコンテキストでイベントタイプを active モードにしないでください。LEGAL.md §4 をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。