AI代理系统

一个基于TypeScript的AI代理系统,集成了检索增强生成(RAG)和模型上下文协议(MCP)工具调用功能,结合向量检索与外部工具执行复杂任务。

  • by Zeglow
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 Zeglow/rag-mcp-from-scratch

使用说明

使用RAG和MCP工具的AI代理

一个基于TypeScript的AI代理系统,集成了检索增强生成(RAG)和模型上下文协议(MCP)工具调用功能。该系统将矢量检索与外部工具相结合,以执行复杂的任务。

增强LLM

该项目基于以下内容实现了增强的LLM架构 构建高效代理 原则。

classDiagram
    class Agent {
        +init()
        +close()
        +invoke(prompt: string)
        -mcpClients: MCPClient[]
        -llm: ChatOpenAI
        -model: string
        -systemPrompt: string
        -context: string
    }
    class ChatOpenAI {
        +chat(prompt?: string)
        +appendToolResult(toolCallId: string, toolOutput: string)
        -llm: OpenAI
        -model: string
        -messages: OpenAI.Chat.ChatCompletionMessageParam[]
        -tools: Tool[]
    }
    class EmbeddingRetriever {
        +embedDocument(document: string)
        +embedQuery(query: string)
        +retrieve(query: string, topK: number)
        -embeddingModel: string
        -vectorStore: VectorStore
    }
    class MCPClient {
        +init()
        +close()
        +getTools()
        +callTool(name: string, params: Record<string, any>)
        -mcp: Client
        -command: string
        -args: string[]
        -transport: StdioClientTransport
        -tools: Tool[]
    }
    class VectorStore {
        +addEmbedding(embedding: number[], document: string)
        +search(queryEmbedding: number[], topK: number)
        -vectorStore: VectorStoreItem[]
    }
    class VectorStoreItem {
        -embedding: number[]
        -document: string
    }

    Agent --> MCPClient : uses
    Agent --> ChatOpenAI : interacts with
    ChatOpenAI --> ToolCall : manages
    EmbeddingRetriever --> VectorStore : uses
    VectorStore --> VectorStoreItem : contains

🚀 特性

  • 🤖 智能体:基于OpenAI的会话式AI代理,具有工具调用和流式响应功能
  • 📚 RAG检索:基于向量嵌入的文档检索与语义相似性搜索
  • 🔧 MCP工具集成:通过模型上下文协议集成多个工具(文件系统、HTTP请求等)
  • 💬 流媒体对话:实时流式响应输出
  • 🔍 自动工具调用:代理自动确定何时调用工具,并处理多轮工具调用循环

📁 项目结构

├── src/
│   ├── Agent.ts              # Core Agent class, coordinates LLM and tool calls
│   ├── ChatOpenAI.ts         # OpenAI API wrapper with streaming and tool calling
│   ├── MCPClient.ts          # MCP client for connecting to MCP servers
│   ├── EmbeddingRetrievers.ts # Embedding retriever, handles document embedding and retrieval
│   ├── VectorStore.ts        # Vector store with cosine similarity search
│   ├── utils.ts              # Utility functions (logging, etc.)
│   └── index.ts              # Main entry file
├── images/                   # Images directory for documentation
├── knowledge/                # Knowledge base documents directory
├── output/                   # Output files directory
├── package.json
├── tsconfig.json
└── README.md

🏗️ 建筑

核心组件

  1. 代理 (Agent.ts)

    • 协调LLM和多个MCP客户端
    • 处理工具调用循环逻辑
    • 支持上下文注入和系统提示
  2. ChatOpenAI (ChatOpenAI.ts)

    • 包装OpenAI聊天完成API
    • 支持流式响应输出
    • 处理工具调用和工具结果附加
  3. MCP客户端 (MCPClient.ts)

    • 连接到MCP服务器(例如,文件系统、fetch)
    • 动态获取可用工具列表
    • 执行工具调用并返回结果
  4. 嵌入检索器 (EmbeddingRetrievers.ts)

    • 将文档转换为向量嵌入
    • 根据查询检索最相关的文档
    • 支持自定义嵌入模型
  5. 向量存储 (VectorStore.ts)

    • 内存向量存储
    • 基于余弦相似度的文档搜索

🛠️ 技术栈

  • 语言:TypeScript(ESM)
  • 运行时:Node.js
  • LLM:OpenAI API(支持自定义基础URL)
  • 嵌入模型BAAI/bge-m3(通过API)
  • 主控程序:模型上下文协议SDK
  • 公用事业:Chalk(日志格式化)、dotenv(环境变量)

📦 安装

# Install dependencies using pnpm
pnpm install

⚙️ 配置

创建一个 .env 项目根目录中的文件:

OPENAI_API_KEY=your_openai_api_key
OPENAI_BASE_URL=https://api.openai.com/v1  # Optional, defaults to OpenAI official API
EMBEDDING_BASE_URL=https://your-embedding-api.com  # Embedding model API address
EMBEDDING_KEY=your_embedding_api_key  # Embedding model API Key

💡 例子

基本代理使用

import Agent from "./Agent.js";
import MCPClient from "./MCPClient.js";

// Initialize MCP clients
const fetchMCP = new MCPClient('fetch', 'uvx', ['mcp-server-fetch']);
const fileMCP = new MCPClient('file', 'npx', [
    "-y", 
    "@modelcontextprotocol/server-filesystem", 
    process.cwd()
]);

// Create and initialize Agent
const agent = new Agent('gpt-4o-mini-2024-07-18', [fetchMCP, fileMCP]);
await agent.init();

// Execute task
await agent.invoke('Fetch content from https://example.com and save to file');

// Close connections
await agent.close();

RAG代理

import EmbeddingRetriever from "./EmbeddingRetrievers.js";
import Agent from "./Agent.js";
import MCPClient from "./MCPClient.js";
import path from "path";
import fs from "fs";

// Initialize MCP clients
const fetchMCP = new MCPClient('fetch', 'uvx', ['mcp-server-fetch']);
const fileMCP = new MCPClient('file', 'npx', [
    "-y", 
    "@modelcontextprotocol/server-filesystem", 
    process.cwd()
]);

// 1. Retrieve relevant context
const embeddingRetriever = new EmbeddingRetriever("BAAI/bge-m3");
const knowledgeDir = path.join(process.cwd(), 'knowledge');

// Embed knowledge base documents
for (const file of fs.readdirSync(knowledgeDir)) {
    const content = fs.readFileSync(path.join(knowledgeDir, file), 'utf-8');
    await embeddingRetriever.embedDocument(content);
}

// Retrieve most relevant documents
const context = (await embeddingRetriever.retrieve('query content', 3)).join('\n');

// 2. Create Agent with context
const agent = new Agent(
    'gpt-4o-mini-2024-07-18', 
    [fetchMCP, fileMCP], 
    '',  // System prompt
    context  // Inject context
);
await agent.init();
await agent.invoke('Answer questions based on the context');
await agent.close();

📝 运作原理

RAG工作流程

  1. 文档嵌入:从以下位置读取文档 knowledge/ 使用嵌入模型将目录转换为向量
  2. 查询检索:根据用户查询检索最相关的文档片段(默认前3个)
  3. 上下文注入:将检索到的文档作为上下文注入LLM对话中

代理工具调用流程

  1. 代理接收用户查询
  2. LLM确定是否需要调用工具
  3. 如果需要工具调用,请执行相应的工具(例如,文件读/写、HTTP请求)
  4. 将工具结果返回给LLM
  5. LLM继续处理,可能需要多次调用工具
  6. 循环将继续,直到LLM返回最终答案,不再调用工具

🔧 可用工具

通过MCP集成的工具:

  • 文件系统工具 (@modelcontextprotocol/server-filesystem):文件读/写操作
  • 提取工具 (mcp-server-fetch):HTTP请求功能

您可以添加更多MCP服务器以扩展工具功能。