RAGを使ったリサーチペーパーアシスタントの構築
このガイドでは、Retrieval Augmented Generation(RAG)を活用して、学術論文を分析し、その内容に関する具体的な質問に答えるAIリサーチアシスタントを作成します。
例として、基礎的なTransformer論文であるAttention Is All You Need を使用します。
RAGコンポーネントの理解
RAGがどのように機能するか、そして各コンポーネントをどのように実装するかを理解しましょう。
-
ナレッジストア/インデックス
- テキストをベクトル表現に変換する
- コンテンツの数値表現を作成する
- 実装方法:OpenAIのtext-embedding-3-smallを使って埋め込みを作成し、PgVectorに保存します
-
リトリーバー
- 類似度検索によって関連するコンテンツを見つける
- クエリの埋め込みと保存されたベクトルをマッチングする
- 実装方法:PgVectorを使って保存された埋め込みに対して類似度検索を行います
-
ジェネレーター
- 取得したコンテンツをLLMで処理する
- 文脈に基づいた応答を生成する
- 実装方法:GPT-4o-miniを使い、取得したコンテンツに基づいて回答を生成します
私たちの実装では、以下のことを行います:
- Transformer論文を埋め込みに変換する
- それらをPgVectorに保存し、素早く取得できるようにする
- 類似度検索を使って関連するセクションを見つける
- 取得した文脈を使って正確な応答を生成する
プロジェクト構成
research-assistant/
├── src/
│ ├── mastra/
│ │ ├── agents/
│ │ │ └── researchAgent.ts
│ │ └── index.ts
│ ├── index.ts
│ └── store.ts
├── package.json
└── .env
プロジェクトの初期化と依存関係のインストール
まず、プロジェクト用の新しいディレクトリを作成し、そこに移動します:
mkdir research-assistant
cd research-assistant
新しいNode.jsプロジェクトを初期化し、必要な依存関係をインストールします:
npm init -y
npm install @mastra/core@latest @mastra/rag@latest @mastra/pg@latest @ai-sdk/openai@latest ai@latest zod@latest
APIアクセスとデータベース接続のための環境変数を設定します:
OPENAI_API_KEY=your_openai_api_key
POSTGRES_CONNECTION_STRING=your_connection_string
プロジェクトに必要なファイルを作成します:
mkdir -p src/mastra/agents
touch src/mastra/agents/researchAgent.ts
touch src/mastra/index.ts src/store.ts src/index.ts
リサーチアシスタントエージェントの作成
次に、RAG対応のリサーチアシスタントを作成します。このエージェントは以下を使用します:
- Vector Query Tool:ベクトルストア上でセマンティック検索を実行し、論文から関連コンテンツを見つけるためのツール
- GPT-4o-mini:クエリを理解し、応答を生成するため
- カスタム指示:論文の分析方法、検索されたコンテンツの効果的な使用方法、制限の認識方法についてエージェントを導くもの
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { createVectorQueryTool } from "@mastra/rag";
// Create a tool for semantic search over our paper embeddings
const vectorQueryTool = createVectorQueryTool({
vectorStoreName: "pgVector",
indexName: "papers",
model: openai.embedding("text-embedding-3-small"),
});
export const researchAgent = new Agent({
name: "Research Assistant",
instructions: `You are a helpful research assistant that analyzes academic papers and technical documents.
Use the provided vector query tool to find relevant information from your knowledge base,
and provide accurate, well-supported answers based on the retrieved content.
Focus on the specific content available in the tool and acknowledge if you cannot find sufficient information to answer a question.
Base your responses only on the content provided, not on general knowledge.`,
model: openai("gpt-4o-mini"),
tools: {
vectorQueryTool,
},
});
Mastraインスタンスとベクトルストアの設定
import { Mastra } from "@mastra/core";
import { PgVector } from "@mastra/pg";
import { researchAgent } from "./agents/researchAgent";
// Initialize Mastra instance
const pgVector = new PgVector({ connectionString: process.env.POSTGRES_CONNECTION_STRING! });
export const mastra = new Mastra({
agents: { researchAgent },
vectors: { pgVector },
});
論文の読み込みと処理
このステップでは、初期ドキュメント処理を行います。以下の手順で進めます:
- 研究論文をURLから取得
- ドキュメントオブジェクトに変換
- より良い処理のために、小さく管理しやすいチャンクに分割
import { openai } from "@ai-sdk/openai";
import { MDocument } from "@mastra/rag";
import { embedMany } from "ai";
import { mastra } from "./mastra";
// Load the paper
const paperUrl = "https://arxiv.org/html/1706.03762";
const response = await fetch(paperUrl);
const paperText = await response.text();
// Create document and chunk it
const doc = MDocument.fromText(paperText);
const chunks = await doc.chunk({
strategy: "recursive",
size: 512,
overlap: 50,
separator: "\n",
});
console.log("Number of chunks:", chunks.length);
// Number of chunks: 893
埋め込みの作成と保存
最後に、RAG用にコンテンツを準備します:
- テキストの各チャンクの埋め込みを生成
- 埋め込みを保持するベクトルストアインデックスを作成
- 埋め込みとメタデータ(元のテキストとソース情報)をベクトルデータベースに保存
注意:このメタデータは重要です。ベクトルストアが関連する一致を見つけたときに実際のコンテンツを返すことができるようになります。
これにより、エージェントは効率的に情報を検索して取得できるようになります。
// Generate embeddings
const { embeddings } = await embedMany({
model: openai.embedding("text-embedding-3-small"),
values: chunks.map((chunk) => chunk.text),
});
// Get the vector store instance from Mastra
const vectorStore = mastra.getVector("pgVector");
// Create an index for our paper chunks
await vectorStore.createIndex({
indexName: "papers",
dimension: 1536,
});
// Store embeddings
await vectorStore.upsert({
indexName: "papers",
vectors: embeddings,
metadata: chunks.map((chunk) => ({
text: chunk.text,
source: "transformer-paper",
})),
});
これにより以下が実行されます:
- URLから論文を読み込む
- 管理しやすいチャンクに分割する
- 各チャンクの埋め込みを生成する
- 埋め込みとテキストの両方をベクトルデータベースに保存する
スクリプトを実行して埋め込みを保存するには:
npx bun src/store.ts
アシスタントをテストする
異なるタイプのクエリで研究アシスタントをテストしてみましょう:
import { mastra } from "./mastra";
const agent = mastra.getAgent("researchAgent");
// Basic query about concepts
const query1 =
"What problems does sequence modeling face with neural networks?";
const response1 = await agent.generate(query1);
console.log("\nQuery:", query1);
console.log("Response:", response1.text);
スクリプトを実行します:
npx bun src/index.ts
次のような出力が表示されるはずです:
Query: What problems does sequence modeling face with neural networks?
Response: Sequence modeling with neural networks faces several key challenges:
1. Vanishing and exploding gradients during training, especially with long sequences
2. Difficulty handling long-term dependencies in the input
3. Limited computational efficiency due to sequential processing
4. Challenges in parallelizing computations, resulting in longer training times
別の質問を試してみましょう:
// Query about specific findings
const query2 = "What improvements were achieved in translation quality?";
const response2 = await agent.generate(query2);
console.log("\nQuery:", query2);
console.log("Response:", response2.text);
出力:
Query: What improvements were achieved in translation quality?
Response: The model showed significant improvements in translation quality, achieving more than 2.0
BLEU points improvement over previously reported models on the WMT 2014 English-to-German translation
task, while also reducing training costs.
アプリケーションを提供する
Mastraサーバーを起動して、研究アシスタントをAPI経由で公開します:
mastra dev
研究アシスタントは以下のURLで利用可能になります:
http://localhost:4111/api/agents/researchAgent/generate
curlでテストします:
curl -X POST http://localhost:4111/api/agents/researchAgent/generate \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "user", "content": "What were the main findings about model parallelization?" }
]
}'
高度なRAGの例
より高度なRAG技術の例を以下でご覧ください:
- メタデータを使って結果をフィルタリングするFilter RAG
- 情報密度を最適化するCleanup RAG
- ワークフローを用いた複雑な推論クエリのためのChain of Thought RAG
- 結果の関連性を向上させるRerank RAG