メインコンテンツへスキップ
Memory APIは、クエリに対して最適なコンテキストを自動で組み立てます。セマンティック検索、グラフ探索、エピソード履歴を組み合わせて、LLMに渡すための情報を構築します。

概要

const client = new NdxClient({
  apiKey: process.env.NEURADEX_API_KEY,
  projectId: 'your-project-id',
});

// Memory APIにアクセス
const context = await client.memory.getContext('クエリ');
const related = await client.memory.exploreRelated('knowledge-id');

メソッド一覧

メソッド説明
getContext(query, options?)クエリに対するコンテキストを取得
exploreRelated(knowledgeId, options?)関連ナレッジを探索

getContext()

クエリに対して最適化されたコンテキストを組み立てます。

処理の流れ

  1. セマンティック検索: クエリに関連するナレッジを検索
  2. グラフ探索: 関連ナレッジを多段階で探索
  3. エピソード取得: 関連するQ&A履歴や変更履歴を取得
  4. 最適化: トークン予算内に収まるよう結果を調整
  5. フォーマット: LLMに渡せる形式に整形

パラメータ

query
string
必須
検索クエリ(自然言語)
options.tokenBudget
number
デフォルト:"8000"
コンテキストの最大トークン数
options.includeEpisodes
boolean
デフォルト:"true"
Q&A履歴などのエピソードを含めるか
関連ナレッジを含めるか
options.maxDepth
number
デフォルト:"2"
グラフ探索の最大深度

戻り値

interface Context {
  items: ContextItem[];     // コンテキストの構成要素
  totalTokens: number;      // 合計トークン数
  truncated: boolean;       // 予算超過で切り詰めたか
  formatted: string;        // LLMに渡せる形式の文字列
}

interface ContextItem {
  type: 'knowledge' | 'related' | 'episode';
  id: string;
  title?: string;
  content: string;
  score: number;
  tokens: number;
}

使用例

// 基本的な使用
const context = await client.memory.getContext('返品の手続きを教えて');

console.log(`トークン数: ${context.totalTokens}`);
console.log(`切り詰め: ${context.truncated}`);

// LLMプロンプトに組み込む
const prompt = `
以下の情報を参考に、ユーザーの質問に回答してください。

## 参考情報
${context.formatted}

## 質問
返品の手続きを教えて
`;

オプションの調整

// トークン予算を制限
const context = await client.memory.getContext('質問', {
  tokenBudget: 2000,  // 小さいモデル向け
});

// エピソードを除外(ナレッジのみ)
const context = await client.memory.getContext('質問', {
  includeEpisodes: false,
});

// 浅い探索(直接関連のみ)
const context = await client.memory.getContext('質問', {
  maxDepth: 1,
});

// 深い探索(より多くの関連情報)
const context = await client.memory.getContext('質問', {
  maxDepth: 3,
  tokenBudget: 16000,
});

コンテキストアイテムの確認

const context = await client.memory.getContext('質問');

// 種類別にアイテムを確認
const knowledge = context.items.filter(item => item.type === 'knowledge');
const related = context.items.filter(item => item.type === 'related');
const episodes = context.items.filter(item => item.type === 'episode');

console.log(`直接ヒット: ${knowledge.length}件`);
console.log(`関連ナレッジ: ${related.length}件`);
console.log(`エピソード: ${episodes.length}件`);

// スコア順に表示
for (const item of context.items.sort((a, b) => b.score - a.score)) {
  console.log(`[${item.type}] ${item.title ?? item.id} (${item.score.toFixed(2)})`);
}

exploreRelated()

指定したナレッジから関連するナレッジを探索します。Multi-hop探索(BFS)により、直接つながっていないナレッジも発見できます。

パラメータ

knowledgeId
string
必須
起点となるナレッジID
options.maxDepth
number
デフォルト:"2"
探索の最大深度

戻り値

interface ExploreResult {
  relatedNodes: RelatedKnowledge[];  // 発見したナレッジ
  paths: GraphPath[];                 // 発見した経路
  depth: number;                      // 実際の探索深度
}

interface RelatedKnowledge {
  id: string;
  title: string;
  content: string;
  path: GraphPath;  // このナレッジへの経路
}

interface GraphPath {
  nodeIds: string[];    // 経路上のナレッジID
  edgeIds: string[];    // 経路上のエッジID
  totalWeight: number;  // 経路の合計重み
}

使用例

// 関連ナレッジを探索
const result = await client.memory.exploreRelated('knowledge-id');

console.log(`発見したナレッジ: ${result.relatedNodes.length}件`);
console.log(`探索深度: ${result.depth}`);

// 発見したナレッジを表示
for (const node of result.relatedNodes) {
  const hops = node.path.nodeIds.length - 1;
  console.log(`${node.title} (${hops}ホップ)`);
}

深い探索

// より広範囲を探索
const result = await client.memory.exploreRelated('knowledge-id', {
  maxDepth: 3,
});

// ホップ数別に分類
const byHops = new Map<number, RelatedKnowledge[]>();
for (const node of result.relatedNodes) {
  const hops = node.path.nodeIds.length - 1;
  if (!byHops.has(hops)) byHops.set(hops, []);
  byHops.get(hops)!.push(node);
}

for (const [hops, nodes] of byHops) {
  console.log(`${hops}ホップ: ${nodes.length}件`);
}

ユースケース

RAGアプリケーション

import { NdxClient } from '@neuradex/sdk';
import OpenAI from 'openai';

const neuradex = new NdxClient({
  apiKey: process.env.NEURADEX_API_KEY,
  projectId: process.env.NEURADEX_PROJECT_ID,
});
const openai = new OpenAI();

async function askQuestion(question: string): Promise<string> {
  // コンテキストを取得
  const context = await neuradex.memory.getContext(question, {
    tokenBudget: 4000,
    includeEpisodes: true,
  });

  // LLMで回答を生成
  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      {
        role: 'system',
        content: `あなたはアシスタントです。以下の情報を参考に回答してください。

${context.formatted}`,
      },
      { role: 'user', content: question },
    ],
  });

  return response.choices[0].message.content ?? '';
}

ナレッジグラフの可視化

async function buildGraph(startId: string) {
  const result = await client.memory.exploreRelated(startId, {
    maxDepth: 2,
  });

  // グラフデータを構築
  const nodes = new Map<string, { id: string; title: string }>();
  const edges: Array<{ from: string; to: string }> = [];

  for (const related of result.relatedNodes) {
    nodes.set(related.id, { id: related.id, title: related.title });

    // 経路からエッジを抽出
    const path = related.path.nodeIds;
    for (let i = 0; i < path.length - 1; i++) {
      edges.push({ from: path[i], to: path[i + 1] });
    }
  }

  return {
    nodes: Array.from(nodes.values()),
    edges,
  };
}

次のステップ

Knowledge API

ナレッジの管理

Episodes API

イベント・履歴の記録