はじめに
コーディングエージェントを継続利用していると、次のような情報を次回以降にも使いたくなります。
- この設計を選んだ理由
- 過去の障害原因と有効だった回避策
- 自分固有の、継続して適用してほしい方針
一方で、会話・ソースコード・READMEを何でも自動保存すると、情報が重複し、古い実装を正しいものとして参照してしまう危険があります。そこで今回は、OpenViking を「私が明示的に保存を頼んだ情報」の永続ストアとして構成しました。
この記事では、Windows + RTX 3060 12GB 環境で実施した、ローカル OpenViking 導入を紹介します。
目標:コード検索と長期記憶を混ぜない
この構成での役割分担は次のとおりです。
Codex
├─ Repository / tests / config : 現在の事実の Source of Truth
├─ Serena : symbol、参照、実装、リファクタリング
├─ Archify : 必要な場合だけ現在のアーキテクチャを可視化
└─ OpenViking : 明示保存された過去の判断・経験・理由
重要なのは、OpenViking を「現在のコードを探す検索エンジン」にしないことです。
-
この関数はどこから呼ばれる?→ Repository / Serena -
現在の実装は?→ Repository / Serena -
以前なぜこの方式を選んだ?→ OpenViking を必要な場合だけ検索 -
この判断を次回以降も覚えておいて→ OpenViking に明示保存
矛盾した場合は、現在のコード、テスト、設定、プロジェクト文書、現在のユーザー指示を優先し、過去のメモリは助言として扱います。
なぜ「明示保存型」なのか
OpenViking の Codex 専用プラグインには、プロンプトごとの recall と会話 capture を行う構成があります。しかし今回の目的は会話ログの全自動アーカイブではありません。
そこで、フックを含まない公式の Agent Plugins 向け MCP プロキシを使用します。この形では、remember を明示的に呼んだときだけ長期メモリが作られます。通常の会話、コード編集、テスト結果は自動保存されません。
保存対象は、例えば次のような「現在のリポジトリから復元しにくい理由」です。
DB migration を方式 A ではなく方式 B にした。方式 A は過去の本番ロールバックで失敗したため、以後同種の変更では方式 B を優先する。
逆に、README・AGENTS.md・現在のコード・設定・テストから分かる内容は保存しません。
ローカル構成
今回は VLM と embedding を別プロセスにしました。
Codex
│ MCP (on demand)
▼
OpenViking :127.0.0.1:1933
├─ VLM endpoint :127.0.0.1:8081
│ └─ Gemma 4 E4B Q4_K_XL
└─ Embedding endpoint :127.0.0.1:8082
└─ Qwen3-Embedding-0.6B Q8_0
VLM:Gemma 4 E4B
VLM には、私の環境で余裕を持って動作する gemma-4-E4B-it-qat-UD-Q4_K_XL.gguf を使いました。OpenViking における役割は、保存・取り込み時の意味抽出です。
Embedding:Qwen3-Embedding-0.6B
embedding には、公式 GGUF の Qwen3-Embedding-0.6B-Q8_0.gguf を採用しました。
- 0.6B parameters、約639 MB
- 1024 次元
- 100超の言語とコード検索に対応
- Apache-2.0
12GB VRAM で Gemma と同居しても余裕を残しやすく、日本語・英語・コードが混在する開発メモリに適しています。詳細は 公式モデルカード を参照してください。
導入手順
1. OpenViking をインストールする
uv tool install openviking --upgrade
インストール後、openviking-server と ov が利用可能になります。
2. llama.cpp の Windows CUDA バイナリを配置する
NVIDIA GPU を使う場合は、llama.cpp Releases から Windows x64 / CUDA 12.4 の公式バイナリを取得します。
今回使用した b10763 では、展開後の llama-server.exe をプロジェクトの bin/ に置きました。
C:\Users\<user>\openviking-local-runtime\
├─ bin\llama-server.exe
├─ models\
│ ├─ gemma-4-E4B-it-qat-UD-Q4_K_XL.gguf
│ └─ Qwen3-Embedding-0.6B-Q8_0.gguf
└─ .env
ダウンロードしたアーカイブは、必ずリリースに掲載された SHA-256 と照合してから展開してください。
3. Python ランタイム・プロジェクトを作る
Python プロジェクトは、モデル別の起動、ヘルスチェック、OpenViking 設定生成を担います。アプリケーションコードに OpenViking の認証情報を埋め込まない点も重要です。
.env の例です。
LLAMA_SERVER_PATH=bin/llama-server.exe
VLM_MODEL_PATH=models/gemma-4-E4B-it-qat-UD-Q4_K_XL.gguf
VLM_PORT=8081
VLM_CONTEXT_SIZE=8192
VLM_GPU_LAYERS=999
EMBEDDING_MODEL_PATH=models/Qwen3-Embedding-0.6B-Q8_0.gguf
EMBEDDING_MODEL_NAME=Qwen3-Embedding-0.6B-Q8_0.gguf
EMBEDDING_DIMENSION=1024
EMBEDDING_PORT=8082
EMBEDDING_GPU_LAYERS=999
OPENVIKING_PORT=1933
VLM と embedding は別モデルです。Gemma を embedding 用に流用しないようにします。
4. 2つの llama-server を起動する
プロジェクトのランチャーから起動します。
uv run ov-local-runtime doctor
uv run ov-local-runtime serve-vlm
uv run ov-local-runtime serve-embedding
実体としては、VLM は --jinja、embedding は --embedding --pooling last を使い、両方とも loopback (127.0.0.1) にだけバインドします。
llama.cpp は OpenAI 互換の HTTP API を公開するため、確認は次で行えます。
Invoke-WebRequest http://127.0.0.1:8081/health
Invoke-WebRequest http://127.0.0.1:8082/health
embedding の確認例です。
$body = @{
model = 'Qwen3-Embedding-0.6B-Q8_0.gguf'
input = @('OpenViking explicit memory policy', '明示的に保存した過去の判断を検索する')
} | ConvertTo-Json
Invoke-RestMethod http://127.0.0.1:8082/v1/embeddings `
-Method Post -ContentType 'application/json' -Body $body
今回の環境では日英2件とも 1024 次元ベクトルを返しました。
5. OpenViking 設定を生成・検証・起動する
設定ファイルは、VLM と embedding の OpenAI 互換 endpoint を分けて指定します。
{
"embedding": {
"dense": {
"provider": "openai",
"api_base": "http://127.0.0.1:8082/v1",
"api_key": "local",
"model": "Qwen3-Embedding-0.6B-Q8_0.gguf",
"dimension": 1024,
"encoding_format": "float"
}
},
"vlm": {
"provider": "openai",
"api_base": "http://127.0.0.1:8081/v1",
"api_key": "local",
"model": "gemma-4-E4B-it-qat-UD-Q4_K_XL.gguf",
"timeout": 600
},
"server": {
"host": "127.0.0.1",
"port": 1933
}
}
api_key: "local" は loopback の llama.cpp endpoint に要求形式を合わせるためのダミー値です。外部サービスの API キーではありません。
uv run ov-local-runtime render-openviking-config
openviking-server doctor --config generated/ov.conf
openviking-server --config generated/ov.conf
readiness は次で確認します。
Invoke-WebRequest http://127.0.0.1:1933/ready
embedding: ok、vectordb: ok が返れば、ローカル OpenViking の基盤は起動完了です。
Codex からの利用方法
Codex には、公式の stdio MCP プロキシを接続します。ただし、毎ターンの自動 recall / capture を行うフック型プラグインは有効化しません。
Codex を再起動後、必要な場合だけ過去メモリを検索します。保存はユーザーが明示的に依頼した場合だけ remember を呼びます。
ユーザー: この判断を今後も覚えておいて
↓
Codex: 現在のリポジトリに重複しない理由・適用範囲へ要約
↓
OpenViking remember
↓
Codex: 記憶に保存しました。
この構成の利点
1. 現在のコードと過去の経験を混同しない
コードの真実はリポジトリにあります。OpenViking は「なぜその判断をしたか」「以前の障害をどう避けたか」の補助情報だけを担当します。
2. 会話ログを無差別に蓄積しない
通常会話を自動 capture しないため、不要なコンテキスト膨張や、偶発的な発言の長期保存を避けられます。
3. ローカル完結で運用できる
VLM、embedding、OpenViking を 127.0.0.1 で動かすため、外部 API キーやクラウド推論を必須にしません。
4. 12GB VRAMでも役割ごとに最適化できる
4GB級の Gemma E4B と 0.6B embedding を分離することで、重い単一モデルに依存せず、用途に合わせた更新・停止・性能調整ができます。
運用上の注意
-
rememberの前に、現在のコードやドキュメントと重複していないかを確認する - APIキー、トークン、秘密情報、会話全文は保存しない
- 過去メモリは現在の実装より優先しない
-
forgetは永続削除なので、ユーザーから明示的な削除依頼がある場合だけ実行する - embedding モデルを差し替える場合は、次元数が変わるため既存のベクトルDBを再作成・再indexする
まとめ
OpenViking を「何でも覚える仕組み」ではなく、「明示保存した判断・経験を必要なときだけ取り出す仕組み」として使うと、Codex の通常のコード作業を邪魔せずに長期的な文脈を補えます。
今回の構成では、Gemma 4 E4B を意味抽出、Qwen3-Embedding-0.6B を検索ベクトルに分離し、12GB VRAM でもローカル完結の長期メモリ基盤を作れました。
