给搜索 Agent 装上 RAG 和记忆系统
上一篇文章的结尾我立了个 flag:搜索 Agent 的”搜索 → 抓取 → 基于内容回答”和 RAG 的”检索 → 取文档 → 基于文档回答”在逻辑上几乎同构,Agent Loop、trace、规则引擎应该都能直接复用。这两周(roadmap 的第四、五周)把 RAG 和记忆系统做完了,flag 基本成立。这篇文章分两部分:第一部分讲 agentic RAG 怎么落地,第二部分讲记忆系统的分层设计——后者是这两周真正的重头戏,会展开讲。照例,完整代码和实验数据在文末的仓库里。 先交代节奏:第四周 RAG 原计划单独一周,实际和第五周压进了同一周做。不是赶进度,而是动手前发现这两块不是并列关系,而是地基与上层: flowchart TD W4["第四周 RAG<br/>造出「向量检索器」retriever"] W5["第五周记忆<br/>长期事实的「语义召回」就是再调一次它"] W4 -->|直接复用| W5 记忆系统里”按语义找回相关事实”这个能力...
动手写一个搜索 Agent:从能跑通到受控运行
上一篇文章把 Chatbot/Workflow/RAG/Agent 四个概念的边界理清楚了。按照我的 roadmap,接下来两周正式上手写代码:先学 tool calling,做一个”网页搜索 + 总结”的最小 Agent;再做 prompt 约束、结构化输出和控制循环,把它从”能跑通”升级到”受控运行”。这篇文章就是这两周的完整记录——一个搜索 Agent 从 v1 到 v2 的演进过程,完整代码在文末的仓库里。 Tool Calling:Agent 的行动能力从哪来上篇文章说过,Agent 的”行动能力”来自工具。LLM 本身只能生成文本,是 tool calling 机制让它能搜索、调 API、读写文件。这个机制的核心流程在任何模型上都一样: 1定义工具(JSON Schema)→ 模型决策 → 开发者执行 → 结果回传 → 模型综合 写第一个 tool calling 示例时,有个分界线让我印象很深:模型不执行工具,它只决定调用什么。 模型返回 tool_calls 之后,所有的执行权都在我的代码手中——参数校验、权限检查、危险操作确认,都...
再聊 Chatbot/Workflow/RAG/Agent
为什么又重新聊这几个概念? 最近在系统性学习 AI Agent 的构建和落地,喂给了 GPT 一批资料,让它给我整理了一份详细的 roadmap,第一步便是应该先弄清楚这几个概念,GPT 建议我输出一份文档,于是便有了这个文章(但其实这篇文章也是我列好大纲让 AI 写的)。 一、为什么要区分这四个概念学 AI Agent 的第一步不是写代码,而是搞清楚边界。很多项目失败不是因为技术不行,而是用错了模式——该用 Workflow 的地方强上 Agent,该用 Agent 的地方只做了 RAG。理解这四个概念的区别和关系,是后续所有工程决策的基础。 二、一句话定义 Chatbot:基于 LLM 的对话系统,用户问一句答一句,不主动行动,不调用外部工具。 Workflow:预定义的固定流程,每一步做什么、调什么工具、输出什么格式都是开发者写死的。 RAG(Retrieval-Augmented Generation):在生成回答前,先从外部知识库检索相关内容注入上下文,让模型基于检索结果回答。 Agent:具备自主决策循环的系统,能根据当前状态动态选择下一步行动,包括调用工具、检索信...
RAG(下)
上一篇文章是关于 RAG 的一些基本介绍,这篇主要是根据上篇的流程来实现一个简易的 RAG 系统,进一步加深对 RAG 工作流程的理解。本文所列举的示例代码非常简单,完全是按照上篇文章中所划分的三个阶段来的,但是包含了 RAG 系统所有的必要步骤。 数据源加载与分块1234567891011from typing import Listdef split_into_chunks(doc_file: str) -> List[str]: with open(doc_file, 'r') as file: content = file.read() return [chunk for chunk in content.split("\n\n")]chunks = split_into_chunks("doc.md")for i, chunk in enumerate(chunks): print(f"[{i}] {chunk}\n&quo...
RAG(上)
基础原理RAG(Retrieval-Augmented Generation)中文叫做检索增强生成,它是一种将外部知识库与大语言模型(LLM)相结合的技术。其核心思想是在大模型生成回答之前,先检索文档将检索到内容作为上下文输入给模型,从而提高回答的准确性和时效性。 在一个典型的 RAG 系统中,首先会对外部文档进行预处理并向量化存储形成知识库,当用户提出问题,系统会将问题转化成向量,并且计算出向量相似度,在知识库中找出与用户问题相近的片段,然后将用户问题和相似片段一起丢给大模型(prompt),大模型在此基础上生成答案。 总结上述过程,大致可以分为三个阶段: 准备阶段:分片、索引 检索阶段:召回、重排 生成阶段:生成 使用场景通过上述的介绍不难发现,RAG 适合用做智能客服或者企业内部知识库等私有化数据的场景。一般来说,传统的 LLM 通常都有上下文的限制(即使 Gemini 有百万的上下文),这就导致大模型在工作时始终有上下文局限,我们不可能把大量的私有数据一下子全部喂给大模型,而 RAG 通过分片、向量化存储和向量相似性等手段解决了 LLM 根本局限性。 总结一下,可以归...
聊聊MCP
模型上下文协议(MCP)是一个开放协议,用于标准化应用程序向大语言模型提供上下文的方式,由 Anthropic 于 2024 年 11 月推出。在 MCP 出现之前,将 AI 模型连接到各种数据源通常需要为每个源开发定制化的集成方案,导致系统碎片化、难以扩展且开发成本高昂,MCP 则通过提供一个通用的、标准化的协议来解决这个问题。 MCP 架构MCP 的核心架构遵循客户端-服务器模型,主要包含三个组件: MCP 主机(MCP Host):指的是希望通过 MCP 利用外部数据或工具的应用程序。例如 AI 助手(如 Claude Desktop)、集成开发环境(IDE)、或其他 AI 工具。MCP Host 负责管理 MCP 客户端实例,并控制权限和安全策略。 MCP 客户端(MCP Client):嵌入在主机应用程序中,是实现 MCP 协议客户端逻辑的部分。它负责与一个或多个 MCP 建立并维护安全、一对一的连接,管理通信、状态和能力协商。 MCP 服务器(MCP Server):是实现协议服务器端逻辑的程序。它连接到具体的数据源(本地文件、数据库等)或远程服务(API),并通过...
Paxos
Paxos 背景和介绍进入正文之前先来简单说一下几个概念和 Paxos 的由来。 分布式一致性问题在分布式计算领域,一个核心且基础的挑战是如何让一组独立的计算机(或称为节点、进程)在可能发生故障(如节点崩溃、网络消息丢失或延迟)的环境下,就某个值或状态达成一致 。这个问题被称为共识(Consensus)。达成共识的能力对于构建可靠的分布式系统至关重要,这些系统需要在多个副本之间维护数据一致性,例如分布式数据库、分布式锁服务、以及实现状态机复制(State Machine Replication)等场景 。状态机复制是一种强大的技术,它允许将任何单机上的确定性算法转化为一个容错的、分布式的实现,确保即使部分副本发生故障,整个系统对外也能表现得像一个永不宕机的单体服务 。 一个健壮的共识算法通常需要满足几个关键属性: 有效性(Validity):最终被选定的值必须是某个进程实际提议过的值。 一致性(Agreement/Consistency):所有做出决定的正常进程必须对同一个值达成一致 。这是共识最核心的保证。 完整性(Integrity):每个进程最多只能决定一个值。...
KV Server
MIT 6.824 课程的第二个 lab 是实现一个 key/value server,这里是官网的 实验说明。本篇文章是关于 key/value server 实验设计思路及实现过程。 实验概述本实验要求实现一个单机版的 kv server,支持 Put、Append 和 Get 三种操作。该服务保证所有的操作都必须是线性化(linearizable)的,确保操作顺序符合实时顺序,并且能够处理网络故障(例如消息丢失),保证操作只执行一次。实验目标是能够满足不同客户端以及不可靠网络等场景,确保服务器在并发和故障情况下都能够正常工作。 设计 线性化:通过使用 Go 的互斥锁(mutex)保护共享数据,确保并发访问时操作顺序一致。 网络故障处理:客户端为每个请求分配唯一序列号(sequence number),服务器通过客户端唯一标识(Client ID)和请求序列号检测重复请求,确保幂等性。 操作定义: Put(key, value): 将键 key 的值设置为 value,覆盖原有值。需确保线程安全,并记录序列号以防重复。 Append(key, arg): ...
MapReduce
MapReduce 是一种处理大量数据的编程模型以及实现,它使用 Map 和 Reduce 两个函数对于海量数据计算做了一次抽象,用于在集群上使用分布式算法处理和生成大数据集。MapReduce 最先由 Google 在 2004 年提出,并且在内部得到了大量的实践,简单说来,MapReduce 模型由一个 Map 函数处理一个基于 key/value pair 的数据集合,输出中间的基于 key/value pair 的数据集合,然后再由一个 Reduce 函数用来合并所有的具有相同中间 key 值的中间 value 值。 仔细分析发现,现实世界中有很多满足上述处理模型的例子,关于 MapReduce 的产生背景和详细的介绍本文不再详细叙述,强烈建议阅读 Google 的论文,一定会对 MapReduce 模型有更进一步的理解。 说起分布式系统,大家应该都知道 MIT 有一个明星课程 6.824,它是专门讲解分布式系统的,这个课程还设置了一系列非常有难度的实验来检验你对课程的掌握。为了进一步加深我对分布式系统的理解,前段时间我便开始完成 2024 年春季 6...
基于 WebRTC 实现一个文件传输工具(二)- 信令服务器的实现
上篇文章,详细介绍了 WebRTC 技术。我们知道,WebRTC 标准中并没有规定信令服务器的实现,它把这部分的实现交给了程序开发者本身,一方面基于 WebRTC 的应用形态和技术栈可能是多种多样的,这样不但保持了技术中立性,还最大限度的确保了技术的灵活性和开放性;另外一方面,协议的设计是极其复杂的,要兼顾的场景很多,这样也保证了技术标准的简洁性。因此,只要符合 WebRTC 的通信流程和架构设计理念,信令服务器的实现方案应该是非常灵活的。 本文是此系列文章的第二篇,介绍 WebRTC 中信令服务器的设计。 信令介绍在 WebRTC 的技术栈里,详细定义了一整套的规范,例如它的接口设计,使用 SDP 进行媒体协商、使用 ICE 收集网络地址并进行联通性检测等,这些规范使得客户端与客户端之间的数据交换变得非常容易和方便,但是我们发现 WebRTC 并没有对客户端建立点对点连接之前的过程定义规范,“空缺”的这部分,其实就是信令服务器在发挥作用的地方。 概括来说,WebRTC 信令是设备通信和交换点对点连接所需的信息的方式,包括交换应用程序之间的网络信息、协商媒体格式并处理通信会话的各...









