免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

Agent-Reach 技术解析

Agent-Reach 技术解析 1. 引言让本地 AI Agent「上网」这件事通常绕不开昂贵的商业 APIOpenAI 的网页浏览要按 token 计费SerpAPI、Bright Data 这类聚合搜索服务按月订阅各家社媒的官方 API 又一堆申请门槛和配额限制。对于想在本地跑通「Agent 自主调研」的开发者来说现实往往是——还没开始调研预算先被吃掉了。Agent-Reach给出了另一条思路不依赖任何付费 API直接用 CLI 封装各平台的公开网页抓取与搜索能力再把它们统一成一个 Agent 可调用的只读互联网接口。项目在 GitHub 上快速涨到了 1057 星说明这个「免费读互联网」的痛点切得很准。本文从技术实现角度拆解它的架构与代码帮读者理解「如何把各异构平台统一成 MCP 工具」。2. 项目定位与核心思路Agent-Reach 要解决的核心问题是Agent 需要一个稳定、统一、零 API 成本的方式来读取公开互联网内容。传统方案的问题官方 API 费用高、申请繁琐X推特基础 API 每月 100 美元起Reddit 有严格速率限制YouTube Data API 每天配额有限。商业搜索聚合服务又贵又不透明按请求计费长 Agent 任务很容易跑出一笔大账单。各站抓取规则不统一开发者得为每个平台单独写爬虫处理各自的 HTML 结构、反爬策略、分页逻辑。Agent-Reach 的应对策略是三点CLI-first 封装把每个平台的抓取/搜索封装成独立 CLI 命令Agent 通过子进程调用天然与语言模型解耦。只读接口只做「读取 搜索」不写、不互动绕开登录态、CSRF、反自动化等复杂问题。统一输出格式各平台返回结构化的 Markdown/JSONAgent 无需关心底层 HTML。这个设计让 Agent 的每一环都变得可控、可调试、可替换也方便贡献者逐平台接入。3. 整体架构Agent-Reach 的架构可以分层来看本地 Agent / LLM统一工具注册器CLI 路由器Twitter 模块Reddit 模块YouTube 模块Bilibili 模块小红书模块只读抓取 / 搜索结构化结果 Markdown/JSON关键设计决策Agent 侧通过 MCPModel Context Protocol或简单的函数调用把「搜索某平台」「读取某帖子」「搜索全网」暴露为工具。CLI 层每个平台是一个agent-reach platform action形式的命令支持直接在人终端里调试也方便 Agent 通过子进程调用。适配层各平台实现各自的解析器输出统一 schema。这种「CLI 作为通用接口」的设计让 Agent-Reach 可以被任意 Agent 框架LangChain、AutoGPT、自研 agent 等复用——只要 Agent 能执行 shell 命令或调用 HTTP 接口。4. CLI 统一接口设计4.1 命令格式Agent-Reach 的命令设计遵循一个统一的动词规范agent-reachplatformaction[options]例如# 搜索 X推特上关于某个话题的推文agent-reach twitter search--queryAI agent# 读取一条 Reddit 帖子的正文与评论agent-reach redditread--urlhttps://www.reddit.com/r/LocalLLaMA/comments/...# 搜索 YouTube 视频agent-reach youtube search--querylocal LLM# 搜索 B 站视频agent-reach bilibili search--keyword大模型# 搜索小红书笔记agent-reach rednote search--keywordAI 工具4.2 统一 Schema无论底层是哪个平台返回给 Agent 的数据都尽量对齐同一种结构核心字段包括字段含义示例platform来源平台twitter/reddit/youtubetype内容类型post/video/notetitle标题或正文摘要Local agents without API keysurl原始链接https://x.com/...author作者someuserpublished_at发布时间2026-08-18T10:00:00Zcontent正文内容Markdown 文本stats互动数据{likes: 120, comments: 34}Agent 拿到这份结构化数据后不再需要理解 HTML可以直接做总结、对比、引用。这是「只读接口」能高效工作的基础。5. 平台适配层实现Agent-Reach 的核心工作在于各平台适配层。每个平台有不同的抓取策略下面是各平台的技术要点。5.1 X推特公开网页 搜索端点X 官方 API 贵得离谱Agent-Reach 走的是公开网页路线使用 X 的guest token 搜索 APIapi.twitter.com/graphql端点无需用户登录。通过httpx发送请求解析 GraphQL 返回的 JSON。处理分页游标支持翻页获取多条推文。关键代码示意importhttpxclassTwitterClient:BASEhttps://api.twitter.com/graphqldef__init__(self)-None:self.clienthttpx.Client(headers{user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64),x-guest-token:self._fetch_guest_token(),})def_fetch_guest_token(self)-str:respself.client.get(https://api.twitter.com/1.1/guest/activate.json)returnresp.json()[guest_token]defsearch(self,query:str,count:int20):respself.client.get(f{self.BASE}/SearchTimeline,params{variables:{rawQuery:%s,count:%d}%(query,count),features:{responsive_web_graphql_timeline_navigation_enabled:false},},)timelineresp.json()[data][search_by_raw_query][search_timeline][timeline]returnself._parse_timeline(timeline)核心要点guest token 是免登录获取的临时令牌配合正确的 headers 就能走官方未公开的 JSON 接口省去了解析 HTML 的麻烦。5.2 RedditJSON API 的优雅之处Reddit 是所有平台里最「开发者友好」的任何 URL 后加.json就能拿到结构化数据无需任何 API key受速率限制。classRedditClient:defread(self,url:str):# Reddit 公开约定URL 后加 .json 即可拿数据resphttpx.get(url.rstrip(/).json,headers{user-agent:agent-reach/0.1},)dataresp.json()postdata[0][data][children][0][data]commentsdata[1][data][children]return{title:post[title],author:post[author],content:post.get(selftext,),score:post.get(score,0),comments:self._flatten_comments(comments),}这里用到的是 Reddit 官方隐式支持的 JSON 输出不需要第三方库稳定性和兼容性都很好。5.3 YouTube搜索与字幕抓取YouTube 官方 Data API 有配额限制Agent-Reach 采用两层策略视频搜索解析 YouTube 搜索结果页的初始数据ytInitialData提取视频列表。字幕/简介读取通过 open transcript 之类的公开字幕端点或解析视频页的 caption tracks。importreimportjsonclassYouTubeClient:defsearch(self,query:str):htmlhttpx.get(https://www.youtube.com/results,params{search_query:query},).text# ytInitialData 以 JSON 形式内嵌在页面中matchre.search(rvar ytInitialData (\{.*?\});/script,html)datajson.loads(match.group(1))returnself._extract_videos(data)这种「解析内嵌初始数据」的思路在很多站点都通用页面 JS 渲染所需的数据往往以var xxx {...}的形式直接写在 HTML 里比解析 DOM 更稳定。5.4 B 站 / 小红书更复杂的反爬场景B 站和小红书的反爬更严格Agent-Reach 采取的思路是B 站使用公开搜索 APIapi.bilibili.com/x/web-interface/search带cookie匿名可获取和wbi签名。B 站的 wbi 签名算法是公开逆向出来的只需对参数做一次基于mixinKey的加密即可。小红书解析笔记页面的window.__INITIAL_STATE__数据同时处理其风控校验实际项目中会优先使用用户 cookie 或共享的匿名 session 来保证稳定性。核心经验是当公开 API 可用时优先用 APIAPI 拿不到时退回到解析页面内嵌数据。这条退化策略让各平台接入都保持相对简单。6. Agent 集成以 MCP 为例Agent-Reach 最吸引人的地方是「能直接塞给 Agent 用」。下面演示如何把它接成 MCP server供 Claude Desktop、Cline 等客户端调用。6.1 暴露为工具# agent_reach_mcp.pyfrommcp.server.fastmcpimportFastMCP mcpFastMCP(agent-reach)mcp.tool()deftwitter_search(query:str,count:int10)-str:在 X推特上搜索指定话题的推文。fromagent_reach.clients.twitterimportTwitterClientreturnTwitterClient().search(query,count)mcp.tool()defreddit_read(url:str)-str:读取一条 Reddit 帖子的正文与热门评论。fromagent_reach.clients.redditimportRedditClientreturnRedditClient().read(url)mcp.tool()defbilibili_search(keyword:str,limit:int10)-str:在 B 站搜索相关视频。fromagent_reach.clients.bilibiliimportBilibiliClientreturnBilibiliClient().search(keyword,limit)if__name____main__:mcp.run()6.2 在 Agent 客户端中配置{mcpServers:{agent-reach:{command:python,args:[agent_reach_mcp.py]}}}配置完成后Agent 就会看到twitter_search、reddit_read等工具。当用户问「调研一下小红书上关于 AI 工具的热门笔记」Agent 会自动调用对应工具得到的结构化结果直接进入上下文。7. 代码结构总览项目的代码组织大致如下agent-reach/ ├── agent_reach/ │ ├── __init__.py │ ├── cli.py # CLI 入口与路由器 │ ├── schema.py # 统一数据 schema │ ├── models/ │ │ ├── base.py # 各平台 client 基类 │ │ ├── twitter.py │ │ ├── reddit.py │ │ ├── youtube.py │ │ ├── bilibili.py │ │ └── rednote.py │ ├── parsers/ │ │ ├── yt_initial_data.py # YouTube 页面数据解析 │ │ ├── bili_wbi.py # B 站 wbi 签名 │ │ └── xhs_initial.py # 小红书页面数据解析 │ └── outputs/ │ ├── markdown.py # Markdown 格式化输出 │ └── json_output.py # JSON 输出 ├── tests/ ├── examples/ │ └── mcp_server.py └── README.md这种「client parser output」的三层拆分让每个平台的接入都遵循同一模板贡献新平台时只需要实现search和read两个动作再写对应的 parser 即可。8. 局限与建议适用场景Agent 做公开信息调研、舆情监控、竞品分析等只读任务。个人开发者、本地 Agent 玩家想零成本跑通「Agent 互联网」链路。需要跨多平台聚合搜索结果的场景。需要注意的边界合规风险公开网页抓取要遵守各平台的服务条款控制请求频率避免批量高频抓取。稳定性页面结构、接口签名可能随时变化这类项目需要持续维护。数据新鲜度guest token 等匿名访问拿到的数据可能有延迟。性能与边界条件在实际跑 Agent 长任务时除了「能不能抓到」更重要的是「能不能稳定地抓到」。本节给出各平台在只读匿名场景下的一套保守可靠参数建议。推荐速率限制匿名抓取并不等于可以无限制请求。各平台的公开端点通常都有隐式风控阈值建议把请求间隔控制在比阈值更保守的范围平台匿名场景下的保守建议说明X推特搜索类 1 次 / 5–10 秒guest token 容易被高频搜索触发风控Reddit1 次 / 6 秒约 10 次/分钟.json端点未认证时速率较严YouTube搜索类 1 次 / 3–5 秒解析ytInitialData依赖页面返回过频易触发验证B 站搜索类 1 次 / 2–5 秒wbi 签名接口相对稳定但仍需限速小红书1 次 / 10–30 秒风控最严建议配合登录 cookie 或共享 session多平台聚合任务尤其要设置全局并发限制例如整个 Agent 进程同时发出的请求不超过 24 个避免短时间对同一站点形成脉冲流量。超时设置建议为每次请求同时设置连接超时与读取超时并给整条管线设置总超时连接超时5–10 秒读取超时15–30 秒单平台单次任务总超时30–60 秒之所以把读取超时放宽是因为某些页面内嵌数据较大、网络抖动较常见但 Agent 任务不能无限等待所以还要在 CLI 层再包一层总超时。importhttpx DEFAULT_TIMEOUThttpx.Timeout(connect10.0,read20.0,write10.0,pool10.0,)clienthttpx.Client(timeoutDEFAULT_TIMEOUT)错误重试策略重试只应该用来应对「临时性失败」而不是掩盖参数错误。建议遵循以下原则可重试错误429 Too Many Requests、5xx、网络超时、连接重置。不重试错误400、401、403、404等明确的客户端错误避免空耗配额。指数退避 随机抖动第n次重试等待min(cap, base * 2^(n-1))加随机抖动降低多请求同时重试造成的脉冲。上限控制每平台最多重试 3 次超过后向上抛结构化错误而不是无限循环。importrandomimporttimefromtypingimportCallabledefwith_retry(fn:Callable[[],object],max_retries:int3,base_delay:float2.0,cap:float30.0,)-object:forattemptinrange(max_retries1):try:returnfn()exceptExceptionasexc:ifattemptmax_retries:raisedelaymin(cap,base_delay*(2**attempt))jitterrandom.uniform(0,delay*0.2)time.sleep(delayjitter)反爬临时失败的处理平台反爬通常不是「直接封号」而是先返回临时失败信号。可以把处理拆成四步识别信号出现验证码页、空结果、429、403、结构异常解析不到目标字段时先判定为「疑似风控」。刷新匿名凭证X 的 guest token、B 站的匿名 cookie 等都有有效期失败后优先尝试重新获取并重试一次。退避降级同一平台连续失败时切换到更保守的路径——公开 API 不可用就回退到页面内嵌数据解析仍然失败则中断当前平台不让整个 Agent 任务卡死。带上下文失败退出最终失败时返回结构化错误包含平台、HTTP 状态、失败原因与建议等待时间让 Agent 决定是稍后重试还是换数据源。classTemporaryBlockError(Exception):平台疑似临时风控建议退避后重试。def__init__(self,platform:str,wait_seconds:int,detail:str):self.platformplatform self.wait_secondswait_seconds self.detaildetailsuper().__init__(f[{platform}] blocked, wait{wait_seconds}s:{detail})这样Agent 侧就能把「临时失败」当作一种可感知、可决策的状态而不是一串看不懂的爬虫异常。9. 总结Agent-Reach 的价值不在于「爬虫技术本身有多高深」而在于它做了一个非常实用的抽象把各个平台五花八门的抓取方式统一收敛成 Agent 能直接调用的只读工具。这让本地 Agent 的「免费上网」从各种 hack 拼凑变成了一套清晰的工程方案。从技术角度看它示范了三件事CLI 作为通用接口任何 Agent 框架都能接入。公开 JSON 端点 页面内嵌数据解析这条退化策略可以在无 API key 的前提下稳定获取结构化数据。统一 schema让 Agent 的上下文处理变得干净高效。
返回列表