← 返回文章列表
019 — AI · #RAG #Agent #LLM #架构 · 2026-08-18 · 6 MIN READ

我的博客助手是 RAG 还是 Agent?一条分界线讲清楚

「你博客上那个是 AI Agent 吗?」——项目上线后我被问到最多的问题就是这个。我一般都答「是 RAG 智能体」,但这个回答其实很含糊。这篇用我自己项目的代码当解剖样本,把分界线画清楚,顺便讲明白为什么这条界线对工程决策很重要。

先看解剖台上有什么

这个助手收到一次提问后,执行的完整流程是:

python
# blog-agent/app/routes/chat.py 的主线,去掉细节后
results = rag.search(body.query)          # ① 检索向量库
context = RAGService.build_context(results) # ② 组装上下文
messages = [SystemMessage(...)] + history + [question]  # ③ 拼提示词
async for chunk in llm.astream(messages):  # ④ 调 LLM 流式生成
    yield {"data": ...}                    # ⑤ 逐 token 推给前端

一次请求,五步走,一条直线。它有检索(RAGService + ChromaDB),有对话历史(HistoryManager 按 conversation_id 存轮次),有 LLM(DeepSeek)。看起来该有的都有。

但它没有的三样东西,恰好是 Agent 定义里最核心的部分。

分界线:Agent = LLM + 规划 + 工具 + 记忆 + 反馈循环

把这个圈子里比较公认的定义拆开,Agent 和普通 LLM 应用的区别不在「用了什么模型」,在控制流在谁手里

  1. 规划(Planning):面对一个目标,模型自己决定分几步走、每步做什么。我的助手没有规划层——流程是我写死的五步直线,模型只出现在第④步,老老实实把上下文变成回答。
  2. 工具调用(Tool Use):模型在生成过程中自主决定「我现在需要调搜索/查数据库/执行代码」,拿到结果后继续。我的助手只有一个「工具」——向量检索,而且是代码在第①步调用的,模型从头到尾不知道检索发生过,它只是收到了一段上下文。
  3. 环境反馈循环(Feedback Loop):行动 → 观察结果 → 调整下一步。我的助手跑完⑤就结束,没有「观察」这一说。

对照下来,这个系统的准确描述是:一条 RAG 增强的问答链(RAG-augmented QA chain)。控制流 100% 在代码里,模型的自由度只有「回答怎么措辞」。

那 RAG 在这个定义里是什么位置?它是「记忆/知识」这一环的工程化解法——模型参数记不住我博客的内容,就用检索把相关知识在每次请求时注入上下文。RAG 可以是 Agent 的一个器官(Agent 把检索当工具自主调用),但 RAG 本身不构成 Agent,就像记忆不构成完整的人。

为什么刻意不上 Agent

这不是能力问题,是算账问题。博客问答这个场景,用户的意图空间非常窄:问一个问题,得到一个基于站内文章的回答。行动空间只有一种——「回答」

给这个场景加规划层,得到的是:

  • 延迟翻倍。规划意味着多一轮甚至多轮 LLM 调用。现在首字延迟控制在 2 秒上下(代价是把模型思考模式都关了,见这篇),加一个「先想想该干什么」的环节,这个数字直接没法看。
  • 失败面变大。直线流程的失败点是可以枚举的:检索失败、LLM 失败、网络失败,每一种我都写了对应的降级路径(见降级四层防线)。引入自主规划后,失败模式变成组合爆炸——规划错、选错工具、工具返回了但模型误读,每一种都得兜底,而且很多失败从界面上看不出来,模型只是「悄悄答偏了」。
  • 行为不可预测。博客助手代表博主发言,我需要它的行为边界是可预期的。「仅基于检索上下文回答」这个约束,在直线流程里是硬约束;在 Agent 架构里,模型可能自己决定去「探索」,约束就变成了软建议。

收益端呢?规划能力在这个场景几乎没有用武之地——没有多步任务要分解,没有外部世界要操作。这是一笔收益为零、成本实付的买卖,所以是刻意的减法。

什么时候该跨过这条线

界线不是永远不动的。我在复盘时给自己列了触发条件,将来出现这些信号才考虑升级:

  • 用户需求出现多步结构:比如「帮我对比 A 和 B 两篇文章的观点,再汇总成表格」成为高频请求,单轮检索+回答开始明显答不好。
  • 行动空间扩大:助手需要做「回答」之外的事——订阅更新、执行搜索、操作书签。
  • 知识库大到单轮检索命中率撑不住,需要迭代式检索(查一次、发现不够、换关键词再查)。

到那时候,升级路径也不是推翻重写:把 RAGService 包成一个 tool,把五步直线换成一个 ReAct 循环,外层的 SSE 协议和前端基本不用动。当初把检索、历史、LLM 封装成独立模块(core/rag.pycore/history.pycore/llm.py),就是在为这个可能性留接口。

复盘

「RAG 还是 Agent」这个问题之所以总被问,是因为两个词在传播中都被稀释了——好像接了向量库就是 RAG,能对话就是 Agent。我的体会是,回答这个问题最好的方式是看控制流:谁决定下一步干什么。代码决定,是链;模型决定,是 Agent

而这个判断的价值不在分类学,在于它直接决定你的架构预算:直线流程你只需要为「每一步失败」做准备,Agent 你得为「每一步决策失误」做准备。后者贵得多,也只有在行动空间真的复杂时才值回票价。我的博客助手安分地做一条问答链,不是因为它做不了 Agent,是因为这个场景不需要。

Comments