使用 RAG 建置研究論文助理
在本指南中,你將建立一個 AI 研究助理,使用 Retrieval Augmented Generation(RAG)分析學術論文,並回答與論文內容相關的特定問題。
你將以 Transformer 的原始論文 「Attention Is All You Need」作為範例,並使用本機 libSQL 資料庫。
先決條件「先決條件」的直接連結
- 已安裝 Node.js
v22.13.0或更新版本 - 具備支援的 Model Provider 所提供的 API key
- 已有 Mastra 專案(請依照安裝指南設定新專案)
RAG 的運作方式「RAG 的運作方式」的直接連結
以下說明 RAG 的運作方式,以及你將如何實作各個元件。
Knowledge Store/Index「Knowledge Store/Index」的直接連結
- 將文字轉換為向量表示法
- 建立內容的數值表示法
- 實作方式:使用 OpenAI 的
text-embedding-3-small建立 embeddings,並將它們儲存在 LibSQLVector 中
Retriever「Retriever」的直接連結
- 透過相似度搜尋尋找相關內容
- 將查詢 embeddings 與已儲存的向量配對
- 實作方式:使用 LibSQLVector 對已儲存的 embeddings 執行相似度搜尋
Generator「Generator」的直接連結
- 使用 LLM 處理擷取到的內容
- 建立包含情境資訊的回應
- 實作方式:使用 OpenAI model,根據擷取到的內容產生答案
你的實作將會:
- 將 Transformer 論文處理為 embeddings
- 將它們儲存在 LibSQLVector 中,以便快速擷取
- 使用相似度搜尋尋找相關段落
- 使用擷取到的情境產生準確回應
建立 Agent「建立 Agent」的直接連結
接下來將定義 Agent 的行為、將其連線至 Mastra 專案,並建立 vector 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 的研究助理。此 Agent 使用:
- Vector Query Tool,對 vector store 執行語意搜尋,以尋找論文中的相關內容
- OpenAI model,用於理解查詢並產生回應
- 自訂 instructions,用來引導 Agent 分析論文、有效使用擷取到的內容,並說明其限制
建立新檔案
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指令取得絕對路徑。路徑可能類似如下:> 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指令取得的絕對路徑。如此一來,vector.db檔案會建立在專案根目錄。備註本指南為了示範而使用寫死的絕對路徑來指向本機 libSQL 檔案,但這不適用於正式環境。正式使用時,應改用遠端持久性資料庫。
在
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 },})
處理文件「處理文件」的直接連結
在接下來的步驟中,你會擷取研究論文並將其分割成較小的 chunks,然後產生 embeddings,並將 chunks 儲存至 vector database。
在此步驟中,系統會透過 URL 擷取研究論文,接著將其轉換為 document object,再分割成較小且易於處理的 chunks。分割成 chunks 可讓處理作業更快速、更有效率。
建立新檔案
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 產生 embeddings
- 建立 vector store index 來保存 embeddings
- 將 embeddings 與 metadata(原始文字及來源資訊)儲存至 vector database
備註此 metadata 非常重要,因為 vector store 找到相關配對時,可透過它傳回實際內容。
Agent 會使用 vector index 搜尋並擷取相關資訊。
開啟
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',})),})最後,再次執行 script 以儲存 embeddings:
npx bun src/store.ts如果操作成功,終端機中應該不會顯示任何輸出或錯誤。
測試助理「測試助理」的直接連結
vector database 現在已包含所有 embeddings,你可以使用不同類型的查詢來測試研究助理。
建立新檔案 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)
執行 script:
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.
啟動應用程式「啟動應用程式」的直接連結
啟動 Mastra server,透過 API 提供研究助理:
mastra dev
你的研究助理可透過下列位置存取:
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:使用 metadata 篩選結果
- Cleanup RAG:最佳化資訊密度
- Chain of Thought RAG:使用 Workflows 處理複雜推理查詢
- Rerank RAG:改善結果相關性