侧边栏壁纸
博主头像
慧行说博主等级

保持理智,相信未来

  • 累计撰写 112 篇文章
  • 累计创建 139 个标签
  • 累计收到 388 条评论

目 录CONTENT

文章目录

PT Agent:一个能交给 AI Agent 使用的 PT Free 刷流工具

慧行说
2026-07-30 / 0 评论 / 0 点赞 / 4 阅读 / 3,915 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2026-07-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

PT Agent:一个能交给 AI Agent 使用的 PT Free 刷流工具

pt-agent-ai-agent-freeleech-banner

项目地址:https://github.com/daniellauyu/pt-agent

起因:一个大包差点让我把号玩废

前段时间在论坛求了一个馒头💊,进了馒头之后猛刷了两天,做种做到 1T 左右,感觉一切都很顺。

然后出事了。

有一个 Free 的大包,我下到一半,Free 到期了。qB 那边毫无察觉,继续吭哧吭哧地下。等我反应过来的时候,分享率已经从好好的掉到了 0.7

当时是真慌。刚求到邀请,我要是这么把号玩废了,实在说不过去。

冷静下来之后我想明白一件事:问题不在于我下得多快,而在于我根本不知道 Free 什么时候到期。

qB 里那个任务,看上去和别的任务没有任何区别。名字、大小、进度、速度,全都正常。唯独没有一个字告诉我:这个东西再过两小时就要开始计费了。

找现成工具:能用,但不解决我的问题

问了几个论坛,得到的答案基本一致:用 vertex,或者 ptool。

两个我都装了、部署了。说实话,配置是真的麻烦。规则、筛选器、站点适配、各种参数,我研究了半天没研究明白,最后是丢给 AI 让它帮我配完的。

配完之后各下了一些,感觉还是不太行。倒不是说工具不好,而是我最在意的那件事它们没解决

免费到期之后,我从 qB 里还是看不出来。

我要的其实很简单——我不需要一个能配置一百种规则的引擎,我需要一个新手保护装置:帮我挑一挑值得下的,然后在 Free 快到期的时候,把下不完的那些自动清理掉,别让我再被爆一次分享率。

既然没有,那就自己写一个。

核心思想

整个工具的逻辑可以用一段话讲完:

定时(或随机间隔)通过馒头的 API Token 拉取种子列表 → 只筛出 Free 的 → 用一个简单的算法算出「推荐」 → 推送到 qB → Free 到期前,把还没下完的自动删掉。

推荐的判断标准也很朴素:

  • Free 剩余时间足够长(默认至少 12 小时)
  • 下载人数 > 做种人数(说明有需求,上传才有得跑)

就这两条撑起了主干。剩下的都是围绕「别把号玩废」加的保险。

两个版本

我做了两个版本,功能定位不同,但决策逻辑是同一份代码

Chrome 插件版:自己手动刷

装在浏览器里。点一下扫一次,把当前所有 Free 资源按推荐 / 风险 / 拒绝分好,每行显示评分、体积、做种比、Free 剩余和绝对截止时间。看中哪个点哪个,或者「一键下载推荐」。

适合刚开始用的时候——你可以先看看它的判断标准合不合你的胃口,再决定要不要放手让它自己跑。

image-20260730114825630

终端守护进程版:无人值守

跑在 NAS 或者常开的小主机上,不需要浏览器。按随机间隔(默认 40–90 分钟)自动扫描、自动推送、自动清理。

为什么是随机而不是固定周期?两个原因:固定周期在站点侧是很明显的机器人特征;另外随机化也能错开抢种的高峰。两个值填成一样就退化成固定周期。

自带一个和插件同款视觉的 WebUI,默认只绑 127.0.0.1:7788

image-20260730114844586

原本还打算做个 Docker 版本,后来想了想——其实 Dockerfiledocker-compose.yml 直接写进去就完事了,没必要单独算一个版本。群晖上直接 docker compose up -d 就能跑。

关键设计:把 Free 截止时间写进标签

这是整个项目的地基,也是我觉得最值的一个设计。

问题的根源是下载器不知道 Free 什么时候结束——这个信息只存在于站点那边。所以入队的时候,我给每个任务打两个标签:

ptagent
ptagent-free-end=2026-07-30T18:00:00+08:00
  • 第一个标记「这是本工具加的」
  • 第二个是 Free 截止时间,保留时区的 ISO 8601

有了这个,后面的一切就都成立了:

  1. qB 里能直接看见。任务列表里那个原本什么都不说的任务,现在明明白白写着什么时候到期。
  2. 保护检查有了依据。守护进程每分钟回读一次这些标签,在到期前 10 分钟(可配)把还没下完的任务连文件一起删掉。
  3. 不误伤。没有 ptagent 标签的任务一律不碰——那是你自己加的,跟我无关。

顺带做了个「回填」功能:你在装这个工具之前手动加的那些馒头任务,可以按名称和字节体积精确匹配回查一遍,把截止标签补上。补上之后它们也受保护了。

删文件这件事,边界写死在代码里

一个会自动删文件的工具,最重要的不是它删得多准,而是它绝对不会删什么。这几条我是写死在代码里、并且有测试守着的:

  • 只删带 ptagent 标签的任务 —— 你自己加的、别的工具加的,一概不碰
  • 已完成的任务不删 —— 都下完了当然要留着做种,Free 过期也不影响
  • 打了 pt_agent_keep / pt_agent_nodel 的不删 —— 你说留就留
  • 关掉自动删除时只告警不动手 —— 默认行为可以改

所有删除动作都进审计日志。哪天你发现文件少了,ptagent audit 一查就知道是什么时候、因为什么被删的。

两道关,而不是一道

发种子到下载器之前要过两关,这个分法是踩过坑之后才改的。

第一关,决策引擎(扫描时逐个判定):不是明确 Free 的拒绝、已到期的拒绝、HR 的拒绝、0 做种的判风险、下载人数不高于做种人数的不进推荐。通过的按 2xFree、Free 时长、做种供给、供需比、体积算分,满分 100。

只有 1–2 个做种但下载需求极高的稀缺资源还有个额外的机会模型:Free 至少 6 小时、下载人数至少 20、下载/做种比至少 10、算下来所需均速不超过 512 KiB/s 的,允许推荐。能不能下完由「所需均速」判断,比拍一个固定的 GB 上限准得多。

第二关,本地安全准入(点下载的那一瞬间):评分够不够、体积超没超、Free 还剩多久、分享率达不达标。

为什么要分成两步?因为并发数、分享率这类条件是会变的,扫描那一刻的结论到点下载的时候可能已经不成立了,只能在入队瞬间重新判断。

有一条我特意改过:并发数只提示不拦截。一开始我让它超过上限就拦下,后来发现这是错的——下载器自己有队列,超出的任务会排队,不会丢。拦下来反而让人以为发送失败了。

踩过的坑

vibecoding 的过程不是一路顺风。有几个坑我觉得挺有代表性,说说。

1. 外网访问 qB 一直 403

在家用内网地址好好的,出门用公网地址就全是 403。查了半天是 qB 的 CSRF 保护:它会校验请求的 Origin / Referer。浏览器插件发出去的请求带的是插件自己的 origin,qB 认为这是跨站攻击。

解决办法是用 declarativeNetRequest 在发出前把这两个头去掉。但这里有个陷阱我第一版就掉进去了:如果用常驻规则,规则是按目标 URL 匹配的,那么任何网页对你 qB 发的请求都会被剥掉 Origin——等于把 qB 的 CSRF 保护全局关掉了。后来参考 PT-depiler 的做法改成了会话级规则 + 每次请求前装、请求后卸 + excludedTabIds 排除掉除自己以外的所有标签页。

2. 我自己把自己的 IP 封了

有一天突然连不上 qB,提示「身份认证失败次数过多,您的 IP 地址已被封禁」。查下来是我自己写的:代码里有 8 处无条件 login(),后台守护又每分钟跑一次,密码只要有一次不对,就是一场登录风暴。

改成了:平时不登录,只有真的因为没有会话被拒(403)时才登录一次并重试一次;识别到封禁消息就绝不再试——因为继续撞只会把封禁窗口无限续期,永远等不到自动恢复。

3. 明明添加成功了,却报失败

这个坑连着踩了四次,最后发现是同一个根因:把对方的正常响应当成失败

  • createCategory 在分类已存在时返回 409 Conflict → 我当成错误,直接中断了整次入队,种子根本没提交
  • torrents/add 在种子已存在时也返回 409 → 我报「添加失败」,但其实 qB 里明明有
  • 登录响应体被反向代理改写成空 → 我要求严格等于 "Ok.",于是成功的登录被判成失败

修完之后总结了三条原则,后面一直照着办:

以状态码为准;只在对方明确说失败时才判失败;幂等操作的冲突即成功。

4. 报错内容全是 [object Object]

排查上面那些问题的时候,我截了一堆图发给 AI,结果 Chrome 的错误页面上全是 [object Object]——因为 console.error("xxx", data) 的第二个参数在那个页面上不会被展开。

真正的教训不是这个 bug 本身,而是我意识到排查花的时间大部分耗在「看不到真相」上。后来专门做了一轮改造:所有报错统一进日志、未捕获异常和 Promise 拒绝也抓、Service Worker 休眠时日志有兜底、错误详情直接内联进消息字符串。之后再遇到问题,排查速度完全不是一个量级。

配合 AI Agent 用

守护进程的每条命令都支持 --json,日志和审计是 JSONL(一行一条 JSON),可以逐行解析。

我自己是搭配 hermes 用的:在 hermes 里起一个 watchDog,配置一下就能做进程监控。挂了自动拉起,出错了推给我。

image-20260730115003575

另外一个我觉得挺实用的点:如果嫌配置麻烦,可以直接把整个项目丢给 AI agent,让它帮你配。

我在仓库里专门写了一份 AGENTS.md,告诉 agent 该看哪些接口、日志怎么聚合(同一轮扫描的所有日志共享一个 operationId,按它聚合就能还原完整因果链)、哪些操作是安全的(--dry-run 保证零副作用)、哪些需要先问过用户(--force 会跳过安全准入)。

配置流程大概就是:ptagent doctor 体检 → 哪项红了改哪项 → ptagent scan --dry-run 空跑一轮看看它会挑什么 → 满意了再 ptagent start。这套流程 agent 自己就能跑完。

一点技术上的选择

决策逻辑只有一份。 两个版本的评分、决策、准入、Free 保护、qB 客户端是同一套代码——插件是源头,守护进程带一份逐字节副本。副本用 sha256 记在 MANIFEST.json 里,有测试确认两边一致。

这么做是因为:有两份副本,最大的风险不是它们不同步,而是不同步了却没人发现。插件那边改了评分权重,终端版还按老规则跑,你根本看不出来。

内外网自动切换。 Chrome 扩展拿不到 WiFi SSID,所以我没去判断「现在连的是哪个网」,而是直接探测「哪台下载器现在连得上」。配置里下载器的顺序就是探测优先级,内网地址放前面——在家秒通,出门超时后自动落到公网那条。效果等价,还不依赖任何系统权限。

终端版有个天然优势。 馒头的下载地址会 302 跳到 CDN,浏览器里要靠 host 权限才能跨域取回种子字节,取不到就只能退化成让 qB 自己去抓(成功率低,而且失败常常是静默的)。Node 里没有同源策略,种子文件永远能拿到字节再上传。

测试。 插件 177 个,守护进程 100 个。核心链路是用一个同时扮演馒头和 qBittorrent 的假网络跑完整流程的,不是只测单个函数——因为真正出问题的从来不是单个函数,而是它们串起来的边界:会话过期、409 冲突、种子字节取不到时的降级。

现状与限制

老实说清楚:

  • 站点只支持馒头(API 模式)。站点适配层是按多站点设计的,接新站点补一个适配器就行,但我暂时没有别的站可测。
  • 下载器只支持 qBittorrent。Transmission / Deluge 的适配层位置留好了,implemented 打开就能接。

最后

写这个东西的初衷特别朴素:我不想再被一个 Free 大包干到 0.7 一次。

如果你也是刚拿到药的新人,也在为「Free 到期了我怎么知道」发愁,也许它对你有点用。

项目地址:https://github.com/daniellauyu/pt-agent

MIT,随便用。有问题提 issue。


免责:自动化下载是否符合站点规则请自行确认。这个工具不绕过任何站点限制,只是把你本来就会手动做的判断和操作自动化。用它导致的账号问题由使用者自负。

    1. qrcode alipay
    2. qrcode weixin
博主关闭了所有页面的评论