一、什么是一个 Agent?RssHarness 凭什么算 Agent?

在深入探讨其架构之前,首先需要明确一个基本问题:RssHarness 为何可以被视为一个 Agent?

要回答这个问题,需要先确立一个可操作的 Agent 定义。业界对「AI Agent」的界定存在多种观点,但一个真正的 Agent 通常需要同时满足以下四个必要条件:

条件 含义 反例(不是 Agent)
感知(Perceive) 从外部环境获取结构化信息 只接收用户输入字符串,不做结构化解析
决策(Decide) 根据当前状态自主选择下一步动作 代码写死 if-else 分支,LLM 只负责填空
执行(Act) 通过工具对外部环境产生实际影响 只输出文本,不触发任何外部系统
观察 & 迭代(Observe & Loop) 根据执行结果调整策略,可能多轮循环 一次调用就返回结果,不管结果好坏

1.1 RssHarness 逐一验证

对照上述四条,RssHarness 的行为如下:

① 感知RouteCatalog 维护了一个从 RSSHub 同步的结构化路由索引(~80 个平台、2000+ 路由),readSummaries 返回每篇文章的 title、summary、score、url、publisher、publishTime。LLM 看到的不是原始网页 HTML,而是结构化后的信息资产。

② 决策 — 核心机制。RssHarness 的流程是不确定的——取决于 LLM 在每个节点的实时判断:

用户输入 → LLM 分析意图 → LLM 决定: 先 searchPlatforms("AI")
                         → LLM 看结果后决定: listRoutes("机器之心")
                         → LLM 看路由后决定: fetchRss(["/jiqizhixin/latest"])
                         → LLM 拿到数据后决定: readSummaries(...)
                         → LLM 聚合输出最终结论

全程没有一行代码规定「先做什么后做什么」。LLM 自主判断何时调用哪个 @Tool、传什么参数、结果不满意要不要换关键词重试。

③ 执行 — 4 个 @Tool 方法对应 4 种对外动作:搜索平台、列出路由、发起 HTTP 抓取、读取存储。LLM 的决策不是纸上谈兵——fetchRss 会真的发出 HTTP 请求,readSummaries 会真的从 EclipseStore 中读取持久化数据。

④ 观察 & 迭代 — [Spring AI 2.0 的 Tool Calling 循环 自动完成这一步]:LLM 输出 tool_call → 框架执行 → 结果注入上下文 → LLM 观察结果 → 决定下一步 → 重复直到输出最终回答。一次 chatClient.prompt().user(question).stream().content() 可能触发 5-10 次内部的「决策→执行→观察→再决策」循环。

一句话总结:RssHarness 被视作 Agent,并非因为其名称包含“Agent”一词,而是因为其控制流由 LLM 实时决策驱动,而非预先定义的固定流程。Spring AI 2.0 的 Tool Calling 为 LLM 提供了一组可以组合使用的原语,使模型能够自主编排检索策略,这体现了 Agent 的核心特征。


二、为什么 RSS 与 Agent 结合是实现可溯源搜索的有效方案?

2.1 可溯源危机:AI 搜索面临的关键挑战

2026 年,ChatGPT 周活用户突破 9 亿,Google AI Overviews 覆盖 16% 的搜索查询。但一个根本问题仍然存在:

LLM 生成的内容,如何验证其可靠性?

传统搜索引擎返回链接列表——用户可以自行判断来源可信度。而 AI 搜索直接给出「答案」,用户难以直接验证答案的来源和准确性。

根据 Princeton + Georgia Tech + Allen AI 在 2024 年联合发布的 GEO 研究论文 「GEO: Generative Engine Optimization」(发表于 KDD 2024),引用权威来源可使 AI 引用率提升 30-40%,加入统计数据再提升 30-40%,引入专家引语再提升 30-40%——三者叠加后 AI 引用率整体提升 41%。这表明内容的可溯源性不仅影响用户信任,也关系到 AI 系统是否将其作为引用来源。

2.2 现有方案的局限

方案 核心思路 主要局限
搜索引擎(Google/Bing) 倒排索引 + PageRank 返回链接列表,AI Overviews 同样不可溯源
向量 RAG(LangChain + Pinecone) 向量相似度检索 语义匹配 ≠ 事实准确;embedding 质量决定天花板
AI 搜索(Perplexity/Kimi/豆包) LLM + 网络爬虫 爬虫盲扫,时效性差,来源不可控
RssHarness RSSHub 结构化路由 + LLM Agent 编排 每个结果锚定可溯源 URL,Agent 自主决策检索路径

2.3 RSS 为什么被低估了?

RSS 有三个常被低估的特性:

  1. 结构化 —— 每篇内容天然带有 title、link、pubDate、publisher 元数据,无需爬虫解析
  2. 定点抓取 —— 不是你搜「AI」,而是你搜「机器之心 最新文章」
  3. 可溯源 —— 每个条目锚定一个 URL,不存在「AI 编了一个结论」的可能

RSSHub 将 RSS 的覆盖范围从原生支持 RSS 的网站扩展到更多网站——通过社区维护的众多路由规则,可以将许多网站内容转换为 RSS 格式。

RSSHub 的路由命名空间(platform/channel/keyword)构成了一个结构化的、可编程的、实时更新的信息索引,这种结构可能更适合 AI Agent 使用。

更关键的是:AI 现在可以直接生成 RSS 路由了

2025-2026 年,一个显著的变化正在发生:AI 可以自动为任意网站生成 RSS 路由了。这意味着 RSSHub 的覆盖范围从「社区手工维护的 2000+」变成了「AI 能理解的任意网页」:

工具 方式 亮点
OpenRSS Claude Code / Codex / Gemini CLI 等 AI Agent 驱动 将任意网站转为 RSS,支持登录页面、SPA 渲染
FeedHub 沙箱化 JS + 6 种 LLM(DeepSeek / 通义千问 / 豆包 / OpenAI / Gemini / Ollama) 安全运行自定义解析脚本,AI 内容分析 + 翻译
InsCode(快马) Kimi-K2 模型自动分析 HTML DOM 零代码,粘贴 URL → 自动识别字段 → 生成 RSSHub 规则
GitHub Copilot Agent + RSSHub Claude 3.7 Sonnet 自动编写 RSSHub 路由脚本 VS Code 内一键生成 lib/routes/<namespace>/<route>.ts

这显著改变了工作流程。以前「这个网站没有 RSS 路由」是一个阻塞问题;现在你只需要把 URL 丢给 AI,它就能自动分析网页 DOM、提取结构化字段、生成可用的 RSS 路由——耗时从手工的数小时缩短至数分钟,且无需编写代码即可完成。

三、四个 @Tool 与一个 Agent

3.1 RssHarness 的 4 个工具

RssHarness 暴露给 LLM 的工具只有 4 个:

# @Tool 方法 作用 LLM 什么时候调用
1 searchPlatforms(keyword) 在 ~80 个平台中按关键词搜索 分析用户意图后,需要定位相关平台
2 listRoutes(platform) 列出某平台的可用 RSS 路由 选定平台后,需要知道有哪些具体频道
3 fetchRss(routes) 对指定路由发起实时 RSS 抓取 确定路由后,发起真正的数据获取
4 readSummaries(routes) 读取已存储的 AI 摘要 抓取完成后,获取文章内容用于最终回答

这四个工具通过 Spring AI 2.0 的 @Tool 注解注册到 ChatClient:

@Configuration
public class AiConfig {
    @Bean
    @Primary
    public ChatClient chatClient(ChatModel chatModel, RssTools rssTools, ChatMemory chatMemory) {
        return ChatClient.builder(chatModel)
                .defaultTools(rssTools)          // ← 4 个 @Tool 注入 LLM
                .defaultAdvisors(
                    MessageChatMemoryAdvisor.builder(chatMemory).build(),  // 多轮对话记忆
                    new SimpleLoggerAdvisor())
                .defaultSystem("""
                    You are an RSS aggregation engine. Your output is always 
                    based on actual data retrieved, never on speculation.
                    Every step must adhere to structured route definitions; 
                    fuzzy searches or guessing routes are prohibited.
                    """)
                .build();
    }
}

Spring AI 2.0 的 Tool Calling 循环自动处理 LLM 与工具之间的交互:LLM 输出 tool_call → Spring AI 执行 → 结果注入上下文 → LLM 决定下一步 → 重复直到输出最终回答。整个过程开发者只需声明工具,框架负责编排。

3.2 为什么是「一次 ChatClient 调用」?

这是 RssHarness 的一个核心设计决策。在一些实现中,会将「选平台 → 选路由 → 抓取」拆分为三次独立的 LLM 调用,并由代码显式管理每一层的输入输出。

RssHarness 的做法相反——一次 chatClient.prompt().user(question).stream().content(),剩下的全部交给 Tool Calling 循环:

// ConversationService.java — 只有一次 chatClient 调用
public List<FetchResponse> searchStreaming(String sessionId, String question, 
                                            SearchCallback cb) {
    chatClient.prompt()
            .user(question)
            .stream()
            .content()
            .doOnNext(cb::onResponseToken)    // 打字机流式输出
            .blockLast();
    return rssTools.getLastResults();
}

这样设计的原因在于: 多层调用会将中间结果限制在每一层的局部上下文中,使得 LLM 在下一次调用时无法看到上一次的完整推理链。采用单次调用配合 Tool Calling 循环,可以让 LLM 在整个过程中维持一致的决策上下文:例如,当 searchPlatforms("AI") 返回空结果时,LLM 可以自行尝试更换关键词;如果 fetchRss 在某个路由上失败,LLM 可以评估是跳过该路由还是寻找替代方案。

四、架构解析:三个域的协作

RssHarness 采用三域架构,遵循 DDD(领域驱动设计)的边界划分:

CLI (CliRunner)                     ← 交互式 REPL,/sync /routes /new
  │
AI Domain (ai/)                     ← Agent 核心:LLM 决策 + Tool Calling
  ├─ ConversationService            ← 唯一一次 ChatClient 调用
  │    ├─ RssTools                  ← 4 个 @Tool,LLM 可调用的工具
  │    ├─ RouteCatalog              ← 内存路由索引,本地 JSON 持久化
  │    └─ RouteSyncTask             ← DOM+XPath 从 RSSHub 同步路由
  │
RSS Domain (rss/)                   ← 执行层:异步管道
  ├─ RssController                  ← 内部 Bean 入口
  ├─ RouteFetchService              ← async allOf 扇出编排
  │    ├─ ArticlesFetchService      ← @Async + tryMarkRefresh 原子 CAS
  │    ├─ RssFetcher                ← 多实例容错 + 中文 URL 编码
  │    │    └─ RssInstanceManager   ← 滑动窗口健康评分
  │    ├─ AiSummaryService          ← 每篇文章 LLM 摘要(@Lazy 解环依赖)
  │    └─ SummaryStorageService     ← 适配层 → 存储域
  │
Storage Domain (storage/)           ← DDD 持久化
  ├─ DataRoot                       ← EclipseStore 聚合根
  ├─ DataViewFactory                ← fromRoute() 工厂
  └─ SummaryView                    ← CQS 读写视图

4.1 AI 域:Agent 的「大脑」

AI 域的核心是使 LLM 具备在 RSSHub 路由体系中导航的能力。RouteCatalog 是一个内存路由索引,通过解析 RSSHub 的 /rsshub/routes/zh 端点构建,持久化到 data/routes.json

设计决策:为什么用 DOM+XPath 而不是 JSON API? RSSHub 的 RSS 输出中,每个 <item><guid> 就是路由路径本身。DOM 解析绕过 Rome 库的 GUID 处理污染,直接提取原始路径。这体现了在框架功能与实际需求之间的权衡:Rome 库的 GUID 规范化处理适用于 RSS 阅读器,但对于路由解析则可能引入不必要的干扰。

多轮对话由 Spring AI 的 MessageChatMemoryAdvisor 自动管理,开发者不需要手动维护会话历史。

4.2 RSS 域:支持多实例容错的异步管道

滑动窗口健康评分

多个 RSSHub 实例的负载均衡不宜采用简单的轮询方式——故障实例在每一轮都可能被选中,导致不必要的 HTTP 超时等待。

设计决策:维护一个 Deque<Boolean>(最近 10 次请求的成功/失败),按成功率排序。成功率高的实例会被优先尝试,而故障实例则会自动移至队列尾部。

// RssInstanceManager 的核心逻辑
// Deque<Boolean> — 最近 10 次,越新的在越前面
// 排序:成功率高的实例优先
// 失败 → 自动切换到下一个实例
tryMarkRefresh 原子 CAS

@Async 并发环境下,多个线程可能同时尝试刷新同一个路由,产生 TOCTOU(Time-of-check to Time-of-use)竞态。

设计决策:用 ConcurrentHashMap.compute() 将「检查是否已在刷新 + 标记为刷新中」合并为单个原子操作,消除竞态窗口。

boolean alreadyRefreshing = refreshMarks.compute(route, (k, v) -> {
    if (v != null && v) return true;  // 已在刷新中,跳过
    return true;                       // 标记为刷新中
});
降级保护 & @Lazy 解环

AI 摘要调用 DeepSeek Chat API 失败时,自动回退到占位摘要(保留 title + URL + publishTime)——核心数据永不丢失

AiSummaryService → ChatClient → RssTools → RssController → RouteFetchService → AiSummaryService 形成循环依赖。Spring 的 @Lazy 注解以最小侵入打破这个环。

4.3 存储域:EclipseStore 零配置持久化

没有 MySQL,没有 Redis,没有 ORM 配置。EclipseStore 将 Java 对象图直接序列化到磁盘:

@Storage
public class DataRoot {
    private Map<String, List<Summary>> routeSummariesListPair;
    private List<String> routePlatforms;
    private long lastRouteSync;
}

对于「单机部署、按路由分区存储」的场景,EclipseStore 比关系型数据库简洁得多——对象图即数据库,重启即恢复。

五、技术栈一览

层级 技术 版本 选型理由
运行时 Java 21 Virtual Threads + Pattern Matching
框架 Spring Boot 4.1.0 最新稳定版,Spring AI 2.0 原生集成
AI 编排 Spring AI 2.0.0 原生 Tool Calling,无需手动封装 Function Calling
模型 DeepSeek Chat - 中文理解强,成本约为 GPT-4 的 1/20
RSS 解析 Rome 2.1.0 业界标准 RSS/Atom 解析库
HTTP 客户端 Apache HttpClient 5.6.1 HTTP/2 支持,连接池管理
持久化 EclipseStore 4.1.0 零配置嵌入式对象图存储
JSON Jackson 2.22.0 Spring 默认
容器化 Docker + docker-compose - 一键部署含 RSSHub
测试 JUnit 5 + Mockito + AssertJ - 53 测试,0 失败

六、快速开始

Docker 部署

# 全栈部署:RssHarness + RSSHub
export DEEPSEEK_API_KEY=sk-your-key
docker-compose up -d

# 或直接拉取预构建镜像
docker pull makeiny/rss-harness:latest
docker run -e DEEPSEEK_API_KEY=sk-your-key makeiny/rss-harness:latest

本地运行

git clone https://github.com/Nexknit/rssgse.git
cd rssharness
export DEEPSEEK_API_KEY=sk-your-key
./mvnw package -DskipTests
java -jar target/rssharness-0.0.1-SNAPSHOT.jar

CLI 交互实录

下面是一次真实的交互过程——用户问了一个模糊的问题,Agent 自主完成全链路编排:

RssHarness> 最近AI领域有什么新进展?

  ⚙ searchPlatforms → "AI" → 5 platforms matched
  ⚙ listRoutes → "机器之心" (8 routes)
  ⚙ listRoutes → "量子位" (6 routes)
  ⚙ listRoutes → "36氪" (12 routes)
  ⚙ fetchRss → ["/jiqizhixin/latest", "/wukong/AI", "/36kr/latest"]
    ✓ /jiqizhixin/latest · SUCCESS · 20 articles · 1.2s
    ✓ /wukong/AI · SUCCESS · 15 articles · 0.9s
    ✓ /36kr/latest · SUCCESS · 18 articles · 1.5s
  3/3 routes fetched · 3 success

  ⚙ readSummaries → 53 article summaries loaded

[核心结论]
过去一周 AI 领域有三个值得关注的方向:(1) 多模态模型军备竞赛加剧,
(2) AI Agent 从概念走向生产部署,(3) 开源模型在中文场景首次逼近 GPT-4 水平。

[支撑信息]
1. GPT-5 多模态能力全面开放,支持实时视频理解 — /jiqizhixin/latest
2. Spring AI 2.0 GA 发布,企业级 Agent 框架成熟 — /36kr/latest  
3. DeepSeek-V3 在 C-Eval 上追平 GPT-4 — /wukong/AI

RssHarness> /new    ← 开始新会话
RssHarness> /exit

Agent 依次完成了:分析意图 → 搜索平台 → 选择路由 → 并发抓取 → 读取摘要 → 聚合输出,整个过程无需用户干预。

其他命令:

RssHarness> /sync              ← 从 RSSHub 同步最新路由表
RssHarness> /routes            ← 查看所有平台 (~80个)
RssHarness> /routes github     ← 查看 GitHub 的路由
RssHarness> /new               ← 开始新会话
RssHarness> /help

八、写在最后

RssHarness 的目标是:

让 AI 搜索的每一个结论,都能追溯到一个人可以验证的原始来源。

这看似一个基本要求,但当前多数 AI 搜索产品在可溯源性方面仍有不足。RSS 的复兴(感谢 RSSHub 社区)与 AI 自动生成路由技术的发展,提供了一个机会:尝试以结构化的、开放的路由生态,替代传统倒排索引的封闭性,使 AI Agent 能在更明确的范围内进行决策。

项目已在 GitHub — Nexknit/rssgse 开源。

路线图中包括 Web UI 等特性的实现计划。若对「RSS + Agent + 可溯源搜索」这一方向感兴趣,欢迎参与讨论或贡献。


本文由 RssHarness 项目作者撰写。项目基于 Spring Boot 4.1 + Spring AI 2.0 + DeepSeek Chat 构建

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐