前言概览
在很多 LLM 应用中,常见的智能体框架包括 LangChain、AutoGPT、CrewAI 等。
我们尝试不依赖任何 Agent 框架,而是用 TypeScript 亲手实现了一套简单的 Agent 逻辑,盘一下Agent各组件之间的关系,打通了如下能力链条:
✅ 调用RAG(检索增强生成)接口为LLM注入上下文知识
✅ 调用 OpenAI LLM(如 GPT-4o)流式生成对话
✅ 调用外部工具在写文件/抓网页等
✅ 使用 MCP 协议启动多个“工具智能体”进行协同
可以理解为一个极简的多工具智能体原型,也是学习 Agent 系统简单切入点。
学习参考视频:
名词解释:
一、项目运行效果展示
该项目有三个功能测试:
调用 LLM 接口实现流式问答:支持边生成边输出的对话体验;每次生成不依赖上下文,体现出一次性交互的特性。
通过 MCPClient 调用外部工具的agent:可接入网页爬取工具与本地文件系统,实现网页信息抓取与文件写入等能力。
通过 RAG 接口实现知识库注入:将本地文件夹中的文本向量化,Agent 基于检索出的知识内容进行创作,并将生成的故事写入本地文件。
注意:都是命令行运行,没有图形化界面。
1. 流式问答功能实现
调用 LLM 接口实现流式问答效果如下图:
问题:

回答:

2. 可以调用外部工具的agent功能实现
可接入网页爬取工具与本地文件系统,实现网页信息抓取与文件写入,效果如图:

生成的文件:

总结的文件中,新闻链接都可以访问。
3. 通过 RAG 接口实现知识库向量化
将本地文件夹中的文本向量化,Agent 基于检索出的知识内容进行创作,并将生成的故事写入本地文件。这是最后完成的效果体现:

本地文件展示:

二、如何本地运行项目?
默认电脑安装了node.js环境
执行以下命令,配置好环境:
git clone git@github.com:likerhood/llm-mcp-rag.git npm install npm add dotenv openai @modelcontextprotocol/sdk chalk配置请求网址和apikey:
llm的请求网址和api-key
rag的请求网址和api-key
这里选择很多,可以选择deepseek的和硅基流动的,具体可以自己搜索<如何使用api调用大语言模型>

进入项目的src目录,执行
npm run dev
三、模块协作逻辑:LLM、RAG、MCP、Agent 如何协同?
1. 理解智能体:LLM 只是“大脑皮层”,不是全部
我们可以把“智能体(Agent)”理解为一个模仿人类思维行为模式的最小智能单元,它具备以下能力模块:
🧠 记忆:存储知识和经验,例如通过向量数据库或 RAG 技术实现记忆检索;
👁️ 感知:通过语音、图像等模态获取环境信息,比如语音识别、图像识别;
💡 决策:基于当前任务、历史上下文和外部知识做出选择——这通常由 LLM(大语言模型)完成;
⚙️ 行动:执行任务,调用工具,比如保存文件、爬取网页、生成图片等。

🧩 RAG、LLM、MCP、工具之间的联系:
模块
对应图中角色
说明
LLM(大语言模型)
大脑皮层
决策与语言生成的核心,用于思考和输出
RAG(检索增强生成)
海马体(记忆)
通过向量化知识库,实现外部记忆的调用
MCP(工具协议)
动作接口(行动)
统一协议,让 LLM 能够“调用”外部工具
工具(Tool)
行动模块
执行实际任务,如写文件、抓网页、发邮件等
Agent
统筹全局,有很多框架
串联 LLM、RAG、MCP 的控制中枢,是一个“思考 + 行动”的统一体
智能体不是单一模块,而是一个具备“记忆 → 感知 → 决策 → 行动”能力的组合体。
在我们实现的项目中,Agent 通过 RAG 记住知识、用 LLM 思考问题、借助 MCP 工具完成任务,才构成了一个完整的智能行为闭环。
2. LLM、RAG、MCP、Agent 如何协同工作
2.1 协作图
在本项目中,LLM(大语言模型)、RAG(检索增强生成)、MCP 工具协议与 Agent 的协作流程如下图所示:

2.2 整体流程总结:
用户请求发起:
用户通过一个自然语言任务或指令向 Agent 发起请求,例如:“请根据知识库内容写一篇关于 Antonette 的故事”。
RAG 检索上下文(可选步骤):
Agent 会使用 RAG(EmbeddingRetriever)模块将用户请求向量化,并在本地知识库中检索相关内容。
返回相似度最高的上下文(context)作为输入,交由 LLM 使用,从而提升回答的准确性和上下文性。
Agent 初始化 LLM 并传入上下文和工具:
Agent 使用
ChatOpenAI封装的大语言模型(如 GPT-4)开始对话。同时将 MCP 提供的工具注册给 LLM,使其具备使用外部工具的能力(function call)。
LLM 决策是否使用工具:
LLM 接收上下文和用户问题后判断是否需要调用工具,例如:
是否需要访问网页(fetch 工具)
是否需要保存文件(file 工具)
如果需要调用工具,会返回 tool_call 请求。
Agent 识别 tool_call 并委托 MCPClient 调用对应工具:
Agent 查找哪个 MCPClient 实例提供了该工具(例如 fetch 工具)。
调用 MCPClient 的
callTool方法,底层通过stdio与 MCP Server 通信,实现真正的系统操作。
MCP 工具服务完成操作并返回结果:
MCP Server 是运行在本地的服务(如
uvx mcp-fetch、npx mcp-file),完成任务后通过 MCP 协议返回结果。
LLM 接收结果并继续生成回复:
Agent 将工具返回的结果通过
appendToolResult方法再次发送给 LLM。LLM 使用最新的上下文继续回复,可能再次调用工具,直到任务完成。
最终输出:
Agent 返回最终的自然语言结果(如 Markdown 文件内容、写入文件路径等),任务结束。
ai生成的流程图,忍受一下哈

四、源码讲解
1. 类图
2. 各模块职责解析
1. Agent:智能代理核心
主控类,负责:
初始化 LLM 模型(
ChatOpenAI)注册 MCP 工具客户端(
MCPClient)执行主流程:接收 Prompt → 判断是否调用工具 → 调用工具 → 追加结果 → 再生成回答
关键函数:
init():初始化 LLM 和 MCP 工具invoke(prompt):执行一轮对话close():资源回收
2. ChatOpenAI:封装 OpenAI 聊天逻辑
对
OpenAI.Chat的封装,支持:提供消息历史与上下文
支持注册 ToolCalls(function calling)
接收并管理 Tool 返回结果
核心方法:
chat(prompt):发送 prompt,接收 LLM 响应appendToolResult(...):将工具调用结果注入对话上下文
3. MCPClient:MCP 工具客户端
封装 MCP 协议客户端逻辑,负责连接某一个 MCP 工具服务(如
fetch、file)每个 MCPClient 实例代表一个 MCP 工具,Agent 会统一管理多个 MCPClient
核心方法:
init():连接 MCP Server,注册工具callTool():调用 MCP 工具实际执行操作(通过stdio通信)
4. EmbeddingRetriever:RAG 检索模块
用于将文本嵌入向量,插入向量库,并进行语义相似度检索
支持三种操作:
embedDocument():插入知识文档embedQuery():将查询语句向量化retrieve():返回与查询语义最接近的文档(上下文)
5. VectorStore:向量存储模块
内存中存储向量和对应文档,支持余弦相似度计算
是检索模块的底层依赖组件
核心功能:
addEmbedding():添加一条向量文档search():根据向量找 topK 最相似文档
6. VectorStoreItem
一个简单的数据结构,记录一条向量和对应文档内容
3. 模块协作流程回顾:
Agent 统一调度 → LLM 判断是否用工具 → 工具由 MCPClient 调用 → 工具服务执行 → 结果传回 LLM → 输出最终响应;
可选:RAG 模块作为前置上下文注入机制,为 Agent 和 LLM 提供语义支持。
总结
主要内容
在这个项目中,我们构建了一个能够自主响应简单请求的 Agent ,它背后的核心是四个关键组件的协同工作:
LLM(大语言模型):就像是大脑,能够理解用户的问题并生成自然语言回答,但它本身不具备“访问网页”或“写入文件”这样的能力。
RAG(检索增强生成):提供了“知识记忆”,能从本地知识库中找到相关信息,补充 LLM 原本不掌握的内容,让回答更贴合实际、更有依据。
MCP(工具协议):就像是“手脚”,通过 MCPClient 连接各种工具(如爬网页、写文件等),让 LLM 具备动手能力。
Agent(智能体):是整个系统的“指挥官”。它接收用户请求,调用 RAG 检索背景知识,调度 LLM 进行思考和判断,如果需要用工具就调用 MCP,再把整个流程协调好并返回给用户答案。
整个系统的协作过程是这样的:用户提出请求 → RAG 检索知识 → Agent 初始化 LLM → LLM 判断是否调用工具 → Agent 执行工具操作 → LLM 得到结果继续生成回复 → 最终输出答案。
评论区