RAG を使用した研究論文 assistant の構築
このガイドでは、Retrieval Augmented Generation(RAG)を使用して学術論文を分析し、その内容に関する具体的な質問へ回答できる AI research assistant を作成します。
例として、Transformer の原論文 「Attention Is All You Need」を使用します。データベースにはローカルの libSQL データベースを使用します。
前提条件前提条件への直接リンク
- Node.js
v22.13.0以降がインストールされていること - サポートされている Model Provider の API キー
- 既存の Mastra プロジェクト(新しいプロジェクトをセットアップするには、インストールガイドに従ってください)
RAG の仕組みRAG の仕組みへの直接リンク
RAG の仕組みと、各コンポーネントの実装方法を確認します。
Knowledge Store/IndexKnowledge Store/Indexへの直接リンク
- テキストをベクトル表現に変換する
- コンテンツの数値表現を作成する
- 実装:OpenAI の
text-embedding-3-smallで埋め込みを作成し、LibSQLVector に保存します
RetrieverRetrieverへの直接リンク
- similarity search で関連コンテンツを見つける
- クエリ埋め込みと保存済みベクトルを照合する
- 実装:LibSQLVector を使用し、保存済み埋め込みに対して similarity search を行います
GeneratorGeneratorへの直接リンク
- 取得したコンテンツを LLM で処理する
- コンテキストに基づいた応答を生成する
- 実装:OpenAI モデルを使用し、取得したコンテンツに基づいて回答を生成します
この実装では次を行います。
- Transformer 論文を処理して埋め込みに変換する
- すばやく取得できるよう LibSQLVector に保存する
- similarity search で関連セクションを見つける
- 取得したコンテキストを使って正確な応答を生成する
Agent の作成Agent の作成への直接リンク
Agent の動作を定義して Mastra プロジェクトに接続し、ベクトル store を作成します。
追加の依存関係をインストールします
インストールガイドの手順を実行した後、追加の依存関係をインストールします。
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/rag@latest aipnpm add @mastra/rag@latest aiyarn add @mastra/rag@latest aibun add @mastra/rag@latest ai次に、RAG を利用する research assistant を作成します。この Agent は次を使用します。
- 論文内の関連コンテンツを見つけるため、ベクトル store に対して semantic search を行う Vector Query Tool
- クエリを理解して応答を生成する OpenAI モデル
- 論文の分析、取得したコンテンツの効果的な使用、制限事項の明示について Agent を導くカスタム instructions
新しいファイル
src/mastra/agents/researchAgent.tsを作成し、Agent を定義します。src/mastra/agents/researchAgent.tsimport { Agent } from '@mastra/core/agent'import { ModelRouterEmbeddingModel } from '@mastra/core/llm'import { createVectorQueryTool } from '@mastra/rag'// Create a tool for semantic search over the paper embeddingsconst vectorQueryTool = createVectorQueryTool({vectorStoreName: 'libSqlVector',indexName: 'papers',model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),})export const researchAgent = new Agent({id: 'research-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-5.6-sol',tools: {vectorQueryTool,},})プロジェクトルートで
pwdコマンドを実行し、absolute path を取得します。path は次のようになります。> pwd/Users/your-name/guides/research-assistant既存の
src/mastra/index.tsファイルと設定に、次を追加します。src/mastra/index.tsimport { Mastra } from '@mastra/core'import { LibSQLVector } from '@mastra/libsql'const libSqlVector = new LibSQLVector({id: 'research-vectors',url: 'file:/Users/your-name/guides/research-assistant/vector.db',})export const mastra = new Mastra({vectors: { libSqlVector },})urlには、pwdコマンドで取得した absolute path を使用します。これにより、プロジェクトルートにvector.dbファイルが作成されます。注記このガイドではローカルの libSQL ファイルへの absolute path をハードコードしていますが、本番環境では機能しません。本番環境では、remote の永続データベースを使用してください。
src/mastra/index.tsファイルで Agent を Mastra に追加します。src/mastra/index.tsimport { Mastra } from '@mastra/core'import { LibSQLVector } from '@mastra/libsql'import { researchAgent } from './agents/researchAgent'const libSqlVector = new LibSQLVector({id: 'research-vectors',url: 'file:/Users/your-name/guides/research-assistant/vector.db',})export const mastra = new Mastra({agents: { researchAgent },vectors: { libSqlVector },})
ドキュメントの処理ドキュメントの処理への直接リンク
次の手順では、研究論文を取得して小さな chunk に分割します。その後、埋め込みを生成し、chunk をベクトルデータベースに保存します。
このステップでは URL を指定して研究論文を取得し、document object に変換して、扱いやすい小さな chunk に分割します。chunk に分割することで、より高速かつ効率的に処理できます。
新しいファイル
src/store.tsを作成し、次を追加します。src/store.tsimport { MDocument } from '@mastra/rag'// Load the paperconst paperUrl = 'https://arxiv.org/html/1706.03762'const response = await fetch(paperUrl)const paperText = await response.text()// Create document and chunk itconst doc = MDocument.fromText(paperText)const chunks = await doc.chunk({strategy: 'recursive',maxSize: 512,overlap: 50,separators: ['\n\n', '\n', ' '],})console.log('Number of chunks:', chunks.length)ターミナルでファイルを実行します。
npx bun src/store.ts次の応答が返されます。
Number of chunks: 892最後に、次の手順で RAG 用のコンテンツを準備します。
- テキストの各 chunk に対して埋め込みを生成する
- 埋め込みを保持するベクトル store インデックスを作成する
- 埋め込みとメタデータ(元のテキストとソース情報)の両方をベクトルデータベースに保存する
注記このメタデータは、ベクトル store が関連する一致を見つけたときに、実際のコンテンツを返せるようにするため重要です。
Agent はベクトルインデックスを使用して、関連情報を検索、取得します。
src/store.tsファイルを開き、次を追加します。src/store.tsimport { MDocument } from '@mastra/rag'import { embedMany } from 'ai'import { mastra } from './mastra'// Load the paperconst paperUrl = 'https://arxiv.org/html/1706.03762'const response = await fetch(paperUrl)const paperText = await response.text()// Create document and chunk itconst doc = MDocument.fromText(paperText)const chunks = await doc.chunk({strategy: 'recursive',maxSize: 512,overlap: 50,separators: ['\n\n', '\n', ' '],})// Generate embeddingsconst { embeddings } = await embedMany({model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),values: chunks.map(chunk => chunk.text),})// Get the vector store instance from Mastraconst vectorStore = mastra.getVector('libSqlVector')// Create an index for paper chunksawait vectorStore.createIndex({indexName: 'papers',dimension: 1536,})// Store embeddingsawait vectorStore.upsert({indexName: 'papers',vectors: embeddings,metadata: chunks.map(chunk => ({text: chunk.text,source: 'transformer-paper',})),})最後に、スクリプトをもう一度実行して埋め込みを保存します。
npx bun src/store.ts操作が成功した場合、ターミナルには出力もエラーも表示されません。
Assistant のテストAssistant のテストへの直接リンク
すべての埋め込みがベクトルデータベースに保存されたので、さまざまな種類のクエリで research assistant をテストできます。
新しいファイル src/ask-agent.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/ask-agent.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
別の質問も試します。
import { mastra } from './mastra'
const agent = mastra.getAgent('researchAgent')
// 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.
Application の提供Application の提供への直接リンク
Mastra サーバーを起動し、research assistant を API として公開します。
mastra dev
research assistant は次の 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 の例への直接リンク
より高度な RAG 手法については、次の例を参照してください。
- メタデータを使用して結果をフィルターする Filter RAG
- 情報密度を最適化する Cleanup RAG
- Workflow を使って複雑な reasoning クエリを処理する Chain of Thought RAG
- 結果の関連性を向上させる Rerank RAG