広告

開発者向けのローカル・ファーストAIナレッジベースを作った — 何が違うのか

Dev.to / 2026/4/2

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical Usage

要点

  • NoteCoreは、開発者向けのローカル・ファーストなAI「セカンドブレイン」で、コード、アーキテクチャ上の意思決定、学びを保存し、キーワード検索に頼らず自然言語でその知識を問い合せられます。
  • このアプリはVoyage AIの埋め込み(voyage-code-2)を用いてノートをインデックス化し、ローカルのベクターストア上でコサイン類似度によるセマンティック検索を行うことで、言い回しの異なる過去ノートから関連する文脈を復元します。
  • AIレイヤーはClaude(claude-sonnet-4-6)を使って、ローカルに保存された内容に基づき開発者の質問へ回答します。ノートは、ユーザーが明示的にクラウド同期を有効にしない限り、オンデバイスのままです。
  • NoteCoreのアーキテクチャは、デスクトップではElectron + React + Vite、バックエンドはローカルのNestJS + SQLiteで構成されており、検索・回答のワークフローはオンデバイスで実行されます。
  • 主要な差別化点として主張されているのは、月日をまたいだり反復を重ねたりする中でプロジェクトの文脈を保持・再利用し、過去の意思決定や解決策を改めて導き直すといった重複するエンジニアリング作業を減らすことです。

プロジェクト間でコンテキストを失わないでください。NoteCoreは、開発者のために作られたセカンドブレインです。

私が知っているすべての開発者が、同じ問題を抱えています。

あなたはプロジェクトを終えます。6か月後に、似たような何かを始めようとして、自分が同じ認証の問題を以前に解決していたことを知っています。その1つのアーキテクチャのドキュメントに、なぜシンプルなサービスレイヤーではなくCQRSを選んだのかを書き残したことを知っています。どこかに、ちょうどこのエッジケースを扱っていたスニペットがあったことも知っています

でも見つからない。Notionか、Obsidianか、あるいは名前をほとんど覚えていないリポジトリの中の適当な.mdファイルの奥に埋もれているのです。

だから結局、最初からやり直します。2時間かけて、すでに分かっていた何かを再構築してしまう。

NoteCoreが存在するのは、まさにこの問題を解決するためです。

NoteCoreとは?

NoteCoreは、開発者のために特別に作られたローカルファーストのAIナレッジベースです。単なる別のメモアプリではありません。問い合わせ可能なセカンドブレインで、コードスニペット、アーキテクチャ上の意思決定、ドキュメントの抜粋、学び、などを投入すると、自然言語で答えが返ってきます。

構成はこうです:デスクトップではElectron + React + Vite、アプリ内で動くローカルのNestJS + SQLiteバックエンド、埋め込みにはVoyage AI、AI層にはClaude(claude-sonnet-4-6)。すべてがあなたのマシン上で動作します。クラウド同期を明示的に有効にしない限り、ノートは外に出ません。

では、実際に何がうまく機能させているのかを見ていきましょう。

Semantic Search(Voyage AIの埋め込み)

全文検索は最低条件です。でも、それだけでは不十分です。

たとえば、「JWT refresh token rotation strategy」というタイトルのノートを書いておいて、後で「トークンの有効期限切れをどう扱っていたっけ?」と検索したとします。キーワード検索では何も返ってきません。単語が一致しないからです。ですが意味は一致しています。そこで解決するのがセマンティック検索です。

NoteCoreは保存するすべてのノートをVoyage AIのvoyage-code-2モデルを使って埋め込み(embedding)します。コードやテクニカルな内容に最適化されています。クエリを書くと、同じモデルで埋め込みが作られ、ローカルのベクトルストア全体に対してコサイン類似度の検索を実行します。

結果として、6か月前にたまたまそう書いた言葉に合わせるのではなく、あなたが実際に考える形で質問できます。

// すべての検索で起きていることを簡略化した例
const queryEmbedding = await voyageClient.embed({
  input: userQuery,
  model: 'voyage-code-2',
});

const results = await vectorStore.similaritySearch(
  queryEmbedding.embeddings[0],
  { topK: 10, threshold: 0.75 }
);

埋め込み(embeddings)は保存時にローカルで生成され、ノートの内容と一緒にSQLiteに保存されます。検索のたびにクラウドへ往復する必要はありません。だから高速です。

なぜOpenAIの埋め込みではなくVoyage AIなのか?

理由は2つ。まず、voyage-code-2はコードのために作られています。const handleAuth = async () => と、「authentication handler function」 が同じものを指していることを理解します。汎用のテキスト埋め込みモデルは、ここまでうまく扱えません。

次に、Voyage AIの料金体系が、ローカルファースト製品により理にかなっていたことです。SaaSのバックエンドに何千ものリクエストをまとめて投げるのではなく、保存されるたびにノートを1つずつ埋め込みます。

ノートの上でAIチャット(Claude)

検索は関連するノートを見つけてくれます。チャットは答えを返します。

大きな違いがあります。検索では、結果を読んで自分で筋道をつなげる必要があります。チャットではNoteCoreがそれをやってくれます。知識ベースからセマンティックに最も関連するチャンクを取り出し、コンテキストに注入し、Claudeが実際の答えを合成します。

流れはこうです:

  1. あなたが聞く:「あのReactプロジェクトで楽観的アップデートをどう扱ってたっけ?」
  2. NoteCoreがノートに対してセマンティック検索を行い、最も関連度の高い上位k個のチャンクを取得する
  3. そのチャンクがコンテキストとしてClaudeのプロンプトに注入される
  4. Claudeはあなたの実際のノートに基づいて回答する(一般的な知識に基づかない)

ここでの重要な設計判断は、Claudeを「根拠に基づいて」動かすことです。答えがノートに存在しない場合は、一般知識から答えないよう明確に指示します。あるトピックについてあなたが何も書いていないなら、それを伝えます。存在しない回答をでっち上げて、あたかもすでに理解していたかのようにあなたを誤解させることはありません。

const systemPrompt = `
あなたは個人用の知識アシスタントです。ユーザーの質問に
下記の「ノート」だけをコンテキストとして使い、それに基づいて回答してください。 

答えがノートに存在しない場合は、それを明確に言ってください。 
不足を埋めるために一般知識を使わないでください。

ノートのコンテキスト:
${relevantChunks.map(c => c.content).join('

---

')}
`;

この制約こそが、実はこの機能の中で最も重要な部分です。でたらめを作り上げるセカンドブレインは、役に立つどころか害になります。誤った自信を与えてしまうからです。

会話コンテキスト

NoteCoreはセッション内で会話履歴を維持するので、ノートを使った複数ターンの推論ができます:

「あのプロジェクトで認証はどういう方針だった?」
「なぜそれをセッションではなく選んだの?」
「これ、これから考えている新しいアーキテクチャでもまだ動く?」

各フォローアップは、前に何があったかを理解しています。会話履歴全体がターンごとにClaudeに渡されるため、コンテキストが自然に積み重なっていきます。

BYOK — Bring Your Own Key

この点は、NoteCoreを設計する際に私が絶対に譲れなかったものです。

LLMを埋め込む多くのAIツールは、主に2通りのやり方をします。すべてを自社のバックエンド経由でルーティングする(つまりノートが相手のサーバーに送られ、推論コストを相手が負担してあなたにマージンを上乗せする)か、特定のモデルにロックして柔軟性がないかです。

NoteCoreはそれをしません。BYOKでは、自分のAPIキーを接続します――ClaudeにはAnthropic、埋め込みにはVoyage AI――そしてNoteCoreはローカルのバックエンドから直接APIを呼び出します。私たちはあなたのリクエストも、ノートも、レスポンスも一切見ません。

利用者の観点ではシンプルです。設定でキーを貼り付けるだけで、electron-storeによりOSレベルの暗号化を使ってローカルに暗号化された形で保存され、それで終わりです。その後は、Anthropic/Voyageからあなたが使った分がそのまま標準料金で直接請求されます。マークアップも、仲介者もありません。

// キーは暗号化して保存し、平文では一切保存しない
await secureStore.set('anthropic_api_key', encrypted(apiKey));

// AIリクエストごとに取得して、そのまま使用
const key = decrypt(await secureStore.get('anthropic_api_key'));
const client = new Anthropic({apiKey: key});

なぜこれが重要なのでしょうか?いくつか理由があります:

プライバシー。 あなたのノートはあなたの考えです。設計上の意思決定、途中までのアイデア、整理しきれていないこと――それらが誰かの別のサーバーに置かれるべきではありません。

コストの透明性。 あなたはいま何にいくら使っているのかを正確に見られます。実際のAPIコストを曖昧にするような不透明な「AIクレジット」はありません。

モデルの柔軟性。 Anthropicが新しいモデルを出したら、すぐに切り替えられます。私たちがバックエンドを更新するのを待つ必要はありません。あなたが、どのモデルのバージョンを動かすかをコントロールします。

信頼。 正直に言うと、これは簡単です。開発者はデフォルトで、自分の機密コンテキストをSaaS製品に預けることを信頼しません。BYOKは、信頼という前提条件をそもそも不要にします。

NoteCoreが違う理由

この領域には他のツールもあります。Obsidian、Notion AI、Mem、Reflect。ここでは正直な比較をします:

Obsidianは素晴らしいですが、そのAI機能はプラグイン依存で、分断されており、意味検索の体験は十分な準備をしないと弱いです。また、汎用ツールであり――コードや技術コンテンツ向けに最適化されていません。

Notion AIは、あなたのノートをNotionのクラウドに置くことを要求します。以上です。もしそれで問題ないなら、素晴らしい。それは私には問題でした。

MemReflectはどちらもクラウド優先で、サブスクリプション制で、そしてどちらも特に開発者向けではありません。彼らは知識労働者向けに最適化されており、自分のコード断片をクエリしたいエンジニアには最適化されていません。

NoteCoreのこだわりは具体的に:

  • デフォルトでローカルファースト。 データはあなたのマシンにあります。クラウド同期はオプトインです。
  • 開発者向けの埋め込み。 voyage-code-2は、汎用モデルでは難しい形でコードを意味的に理解します。
  • BYOKを、後付けではなくファーストクラスの機能として。 あなたがAPIとの関係を所有します。
  • グラウンデッドAI。 チャット機能は、インターネットや一般的なLLM知識ではなく、あなたのノートから回答します。
  • 一回払い。 サブスクリプションなし。買って、所有して、ずっと使えます。

概要としてのアーキテクチャ

全体の仕組みを理解したい方のために:

┌─────────────────────────────────────┐
│           Electron Shell            │
│  ┌─────────────┐  ┌──────────────┐  │
│  │  React UI   │  │ ローカルNestJS │  │
│  │  (Vite)     │◄─►  + SQLite   │  │
│  └─────────────┘  └──────┬───────┘  │
└─────────────────────────┼───────────┘
                           │ BYOKキー
                    ┌──────▼────────┐
                    │  Voyage AI    │  (埋め込み)
                    │  Anthropic    │  (チャット)
                    └───────────────┘

ローカルのNestJSバックエンドはElectronの中で子プロセスとして動作します。ReactフロントエンドはローカルのHTTPポート経由でそれと通信します。SQLiteにはノートの内容とベクトル埋め込みの両方が保存されます。すべて単一テナント、単一マシンであることを設計上の前提にしています。

同期とWebダッシュボードのための任意のクラウドバックエンド(NestJS + Railway上のPostgres)もありますが、これも完全にオプトインです。アプリはクラウド依存ゼロで完全にオフライン動作します。

現在の状況

NoteCoreはベータに向けて進行中です。ローカルバックエンドは、ノート管理、埋め込みパイプライン、意味検索、AIチャット、BYOKといった主要フェーズすべてにわたって完成しています。現在取り組んでいるのは、オンボーディングの導線、Gatedlyによる機能フラグの制御、GitHub Releasesによるパッケージングです。

プロジェクト間で自分のコンテキストを失ってしまうつらさを感じた開発者の方へ――これをあなたのために作っています。

ウェイトリストはnotecore.appで公開中です。

メールアドレスを送ってください。ベータはまもなく提供開始予定で、早期アクセスは限定されます。

公開しながらNoteCoreを開発中。アップデートはXで追ってください。

広告