<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>业余玩家</title><description>个人记录</description><link>https://jk.sb/</link><language>zh_CN</language><item><title>Fuwari 主题：添加文章置顶功能</title><link>https://jk.sb/posts/fuwari-pinned/</link><guid isPermaLink="true">https://jk.sb/posts/fuwari-pinned/</guid><description>本教程详细介绍如何为Fuwari博客主题添加文章置顶功能，包括修改排序逻辑、配置文件和显示标签的完整步骤。</description><pubDate>Wed, 08 Oct 2025 21:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;修改工具文件&lt;/h2&gt;
&lt;h3&gt;修改排序逻辑（一）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src/utils/content-utils.ts&lt;/code&gt;，首先修改 &lt;code&gt;getRawSortedPosts&lt;/code&gt; 函数。该函数被归档页面调用，同样需要加入置顶排序逻辑：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async function getRawSortedPosts() {
    const allBlogPosts = await getCollection(&quot;posts&quot;, ({ data }) =&amp;gt; {
        return import.meta.env.PROD ? data.draft !== true : true;
    });

    const sorted = allBlogPosts.sort((a, b) =&amp;gt; {
        // 如果一个是置顶一个不是置顶，置顶的排在前面
        if (a.data.pinned !== b.data.pinned) {
            return a.data.pinned ? -1 : 1;
        }
        // 都是置顶或都不是置顶，按发布日期时间排序（包含小时分钟秒）
        const dateA = new Date(a.data.published);
        const dateB = new Date(b.data.published);
        return dateA &amp;gt; dateB ? -1 : 1;
    });
    return sorted;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;修改排序逻辑（二）&lt;/h3&gt;
&lt;p&gt;接着修改 &lt;code&gt;getSortedPosts&lt;/code&gt; 函数，该函数被首页和 RSS 等页面调用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export async function getSortedPosts() {
	const allBlogPosts = await getCollection(&quot;posts&quot;, ({ data }) =&amp;gt; {
		return import.meta.env.PROD ? data.draft !== true : true;
	});
	const sorted = allBlogPosts.sort((a, b) =&amp;gt; {
		// 如果一个是置顶一个不是置顶，置顶的排在前面
		if (a.data.pinned !== b.data.pinned) {
			return a.data.pinned ? -1 : 1;
		}
		// 都是置顶或都不是置顶，按发布日期时间排序（包含小时分钟秒）
		const dateA = new Date(a.data.published);
		const dateB = new Date(b.data.published);
		return dateA &amp;gt; dateB ? -1 : 1;
	});

	for (let i = 1; i &amp;lt; sorted.length; i++) {
		sorted[i].data.nextSlug = sorted[i - 1].slug;
		sorted[i].data.nextTitle = sorted[i - 1].data.title;
	}
	for (let i = 0; i &amp;lt; sorted.length - 1; i++) {
		sorted[i].data.prevSlug = sorted[i + 1].slug;
		sorted[i].data.prevTitle = sorted[i + 1].data.title;
	}
	
	return sorted;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;修改文章配置文件&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src/content/config.ts&lt;/code&gt;，在 &lt;code&gt;lang&lt;/code&gt; 字段后增加 &lt;code&gt;pinned&lt;/code&gt; 字段&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pinned: z.boolean().optional().default(false),
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;修改置顶显示标签&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;src/components/PostCard.astro&lt;/code&gt;,此文件需要修改两处。&lt;/p&gt;
&lt;h4&gt;第一处：添加置顶标签判断&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;const isPinned = entry.data.pinned === true;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;第二处：添加置顶标签显示&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;{isPinned &amp;amp;&amp;amp; (
    &amp;lt;span class=&quot;inline-flex items-center mr-2 px-2 py-0.5 text-sm font-medium bg-[oklch(97%_0.1_var(--hue))] dark:bg-[oklch(30%_0.1_var(--hue))] text-[oklch(55%_0.1_var(--hue))] dark:text-[oklch(80%_0.1_var(--hue))] rounded&quot;&amp;gt;
        &amp;lt;Icon name=&quot;material-symbols:push-pin&quot; class=&quot;mr-1 text-base&quot; /&amp;gt; 置顶
    &amp;lt;/span&amp;gt;
)}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Linux 网络排查：TIME_WAIT、偶发丢包与 MTU 黑洞的内核调优实战</title><link>https://jk.sb/posts/network-troubleshooting/</link><guid isPermaLink="true">https://jk.sb/posts/network-troubleshooting/</guid><description>一次诡异的线上网络故障排查笔记。TIME_WAIT 堆积导致服务假死、偶发丢包定位思路、MTU 黑洞引发的&quot;半连通&quot;现象，以及对应的内核参数调优。</description><pubDate>Sun, 24 May 2026 14:31:19 GMT</pubDate><content:encoded>&lt;p&gt;线上网络故障最难受的不是宕机——宕机至少能快速定位。真正消耗时间的，是那些&quot;看上去都正常但就是不对劲&quot;的玄学问题：TCP 握手成功但传不动数据、curl 偶发卡 5s 然后突然返回、监控显示 0% 丢包但用户喊延迟飙升。这篇文章把我反复踩过的三类网络坑梳理一下，配上排查命令和内核参数调优。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;故事：从一个&quot;假死&quot;的服务说起&lt;/h2&gt;
&lt;p&gt;某天凌晨告警炸了：一个对外的 HTTP API 网关在持续 5xx，但进程没挂，CPU、内存、磁盘 IO 都健康，业务日志也没有报错堆栈。SSH 上去 &lt;code&gt;curl 127.0.0.1&lt;/code&gt; 是好的，从外网请求却几乎全部超时。&lt;/p&gt;
&lt;p&gt;第一反应是查连接数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ss -s
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Total: 142
TCP:   65823 (estab 312, closed 65498, orphaned 0, timewait 65497)

Transport Total     IP        IPv6
TCP       325       213       112
UDP       12        8         4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;timewait 65497&lt;/code&gt;——TIME_WAIT 已经把可用端口塞满了。这就是后面要讲的第一个坑。直观感受一下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; 本地端口范围   32768 ───────────────────────────── 60999
                ┌──────────────────────────────────────┐
 端口占用       │ ████████████████████████████████████ │  ← TIME_WAIT 把池子吃光
                └──────────────────────────────────────┘
                                  │
                                  ▼
                  新连接 connect() → EADDRNOTAVAIL
                  curl / 业务调用看到的就是&quot;超时 / 失败&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
排查网络问题之前，先做一件事：在脑子里把 OSI 七层从下到上过一遍，每一层问自己&quot;这里能挂吗&quot;。从物理层（网卡 / MTU）到传输层（TCP 状态、端口、conntrack）再到应用层（重试、超时），按层定位比拍脑袋猜要快得多。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;坑一：TIME_WAIT 堆积导致服务&quot;假死&quot;&lt;/h2&gt;
&lt;h3&gt;现象&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;服务进程活着、CPU 不高&lt;/li&gt;
&lt;li&gt;本地回环正常，外部请求大量超时或 &lt;code&gt;Connection reset&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ss -s&lt;/code&gt; 看到 TIME_WAIT 数万甚至几十万&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dmesg&lt;/code&gt; 里出现 &lt;code&gt;TCP: time wait bucket table overflow&lt;/code&gt; 或 &lt;code&gt;kernel: nf_conntrack: table full&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;原理速记&lt;/h3&gt;
&lt;p&gt;TCP 主动关闭方在四次挥手后会进入 &lt;strong&gt;TIME_WAIT&lt;/strong&gt; 状态，停留 &lt;code&gt;2 * MSL&lt;/code&gt;（Linux 内核里写死了 60 秒，对应 &lt;code&gt;TCP_TIMEWAIT_LEN&lt;/code&gt;）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   主动关闭方                          被动关闭方
   ──────────                          ──────────
  ESTABLISHED                         ESTABLISHED
       │                                   │
       │ ───────── FIN ──────────────▶     │
  FIN_WAIT_1                               │
       │ ◀───────── ACK ──────────────     │ CLOSE_WAIT
  FIN_WAIT_2                               │  (应用还没 close)
       │                                   │
       │ ◀───────── FIN ──────────────     │ LAST_ACK
       │ ───────── ACK ──────────────▶     │
   TIME_WAIT                            CLOSED
       │
       │   2 × MSL = 60s
       │   ↑ 等待两个 MSL，确保：
       │     ① 最后那个 ACK 真的送达
       │     ② 旧连接的迟到报文在网络中自然消亡
       ▼
    CLOSED
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个等待是必要的，目的是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;让网络中迟到的报文有机会被丢弃，避免污染下一个相同四元组的连接&lt;/li&gt;
&lt;li&gt;保证被动关闭方收得到最后一个 ACK&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;正常场景下 TIME_WAIT 完全无害。出问题的是这种模式：&lt;strong&gt;本机作为客户端短连接大量主动关闭&lt;/strong&gt;（典型场景：API 网关回源、PHP-FPM 调外部 HTTP 服务、爬虫）。&lt;/p&gt;
&lt;p&gt;每个 TIME_WAIT 占用一个四元组（&lt;code&gt;本地 IP + 本地端口 + 远端 IP + 远端端口&lt;/code&gt;）。如果回源目标固定，那相当于本地端口范围被吃光：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sysctl net.ipv4.ip_local_port_range
# net.ipv4.ip_local_port_range = 32768  60999
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;默认能用的端口只有约 28k 个，对一个高并发回源的网关来说撑不了多久。&lt;/p&gt;
&lt;h3&gt;排查命令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 查看各状态连接数
ss -ant | awk &apos;NR&amp;gt;1 {print $1}&apos; | sort | uniq -c | sort -rn

# 看 TIME_WAIT 都集中在哪个对端（确认是不是单点回源）
ss -ant state time-wait | awk &apos;{print $5}&apos; | cut -d: -f1 | sort | uniq -c | sort -rn | head

# 看本地端口耗尽情况
ss -s
cat /proc/net/sockstat
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sockets: used 65800
TCP: inuse 312 orphan 0 tw 65497 alloc 65812 mem 4123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tw&lt;/code&gt; 字段就是 TIME_WAIT 总数，&lt;code&gt;alloc&lt;/code&gt; 是已分配的 socket 数，逼近 &lt;code&gt;net.ipv4.tcp_max_tw_buckets&lt;/code&gt; 时就要警惕了。&lt;/p&gt;
&lt;h3&gt;调优&lt;/h3&gt;
&lt;p&gt;把以下参数加到 &lt;code&gt;/etc/sysctl.d/99-network.conf&lt;/code&gt;，&lt;code&gt;sysctl -p&lt;/code&gt; 生效：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 扩大本地端口范围
net.ipv4.ip_local_port_range = 1024 65535

# 允许重用 TIME_WAIT 状态的端口给新的出向连接（依赖时间戳）
net.ipv4.tcp_tw_reuse = 1

# TIME_WAIT 桶上限，超过即直接销毁，避免内核打日志
net.ipv4.tcp_max_tw_buckets = 262144

# 时间戳必须打开，tcp_tw_reuse 才有效
net.ipv4.tcp_timestamps = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning
不要再用 &lt;code&gt;net.ipv4.tcp_tw_recycle&lt;/code&gt;。这个参数从 Linux 4.12 起已经被&lt;strong&gt;完全移除&lt;/strong&gt;——它依赖时间戳做快速回收，在客户端经过 NAT 时会因时间戳乱序丢连接，是经典坑。能调的只有 &lt;code&gt;tcp_tw_reuse&lt;/code&gt;。
:::&lt;/p&gt;
&lt;p&gt;:::important
&lt;code&gt;tcp_tw_reuse&lt;/code&gt; 只对**主动发起连接（客户端方向）**有效。监听端口收到的入向 TIME_WAIT 它管不着。如果是服务端 TIME_WAIT 堆积，要解决的是&quot;为什么是服务端主动关闭&quot;——通常是长连接被错误地关掉，或者应用层 keep-alive 没启用。
:::&lt;/p&gt;
&lt;p&gt;应用层能做的事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开启 &lt;strong&gt;HTTP keep-alive&lt;/strong&gt;（连接复用），nginx 上游加 &lt;code&gt;keepalive 256;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用&lt;strong&gt;连接池&lt;/strong&gt;而不是每次新建（Go &lt;code&gt;http.Client&lt;/code&gt; 一定要全局复用，Python 用 &lt;code&gt;requests.Session&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;协议允许就走长连接（gRPC / WebSocket / 数据库连接池）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;坑二：偶发丢包——监控显示 0%，但用户在喊延迟&lt;/h2&gt;
&lt;p&gt;这是最折磨人的一类问题，因为它不是&quot;完全坏&quot;，是&quot;偶尔坏&quot;。&lt;/p&gt;
&lt;p&gt;排查之前先建立一张&quot;包从网线到应用&quot;的全景图，每一层都可能默默丢包，下面的 5 个步骤就是按这张图自底向上走的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ┌──────────────────────────────────────────────────────────────┐
 │  应用层                                                       │
 │     ┌──────────────┐                                         │
 │     │  accept() 队列│  ← 第 2 步：ListenOverflows / Backlog drop
 │     └──────┬───────┘                                         │
 ├────────────┼─────────────────────────────────────────────────┤
 │  传输层    │   TCP / UDP                                      │
 │     ┌──────▼───────┐    ┌──────────┐                         │
 │     │ recv buffer  │    │ SYN 队列  │  ← TcpExtListenDrops    │
 │     └──────────────┘    └──────────┘                         │
 ├──────────────────────────────────────────────────────────────┤
 │  网络层 / netfilter                                           │
 │     ┌────────────────────┐                                   │
 │     │ conntrack 表       │  ← 第 3 步：table full → 静默丢包   │
 │     └────────────────────┘                                   │
 │     ┌────────────────────┐                                   │
 │     │ iptables / nftables│  ← DROP / REJECT                  │
 │     └────────────────────┘                                   │
 ├──────────────────────────────────────────────────────────────┤
 │  软中断 (softirq / RPS)                                       │
 │     ┌────────────────────┐                                   │
 │     │ per-CPU backlog    │  ← netdev_max_backlog 满          │
 │     └────────────────────┘                                   │
 ├──────────────────────────────────────────────────────────────┤
 │  网卡驱动                                                     │
 │     ┌────────────────────┐                                   │
 │     │ RX ring buffer     │  ← 第 1 步：rx_dropped / fifo_err  │
 │     └────────────────────┘                                   │
 ├──────────────────────────────────────────────────────────────┤
 │  物理网卡 / 线缆                                              │
 │     ←───────────── 报文从这里进来 ─────────────               │
 └──────────────────────────────────────────────────────────────┘
                                          ↑
                                     抓不到包就上 tcpdump (第 4 步)
                                     还是定位不到就 dropwatch (第 5 步)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第 1 步：先看网卡层有没有丢&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 看接口统计：errors / dropped 是关键
ip -s link show eth0

# 网卡硬件层统计（更细，包含 rx_no_buffer 等）
ethtool -S eth0 | grep -Ei &apos;drop|err|miss|fifo&apos;

# 看 ring buffer 是否打满
ethtool -g eth0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果 &lt;code&gt;rx_dropped&lt;/code&gt;、&lt;code&gt;rx_fifo_errors&lt;/code&gt;、&lt;code&gt;rx_missed_errors&lt;/code&gt; 在涨，说明&lt;strong&gt;网卡 ring buffer 不够大&lt;/strong&gt;或者 &lt;strong&gt;softirq 处理不过来&lt;/strong&gt;。前者改 ring buffer：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 当前可能是 256/256，最大支持看 &quot;Pre-set maximums&quot;
ethtool -G eth0 rx 4096 tx 4096
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;后者是 CPU/中断的问题：单队列网卡所有中断打到一个 CPU，那个核飙到 100% si（软中断）就开始丢包。检查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 看 softirq 是否倾斜
mpstat -P ALL 1

# 看中断在哪个 CPU
cat /proc/interrupts | grep eth0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解决方案：开启 &lt;strong&gt;RPS（Receive Packet Steering）&lt;/strong&gt; 或 &lt;strong&gt;RSS（多队列）&lt;/strong&gt;，把软中断分散到多核：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 把 eth0 的 rx 队列 0 的软中断分散到 CPU 0-7
echo ff &amp;gt; /sys/class/net/eth0/queues/rx-0/rps_cpus
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第 2 步：协议栈是不是在丢&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# TCP/UDP/IP 层各种异常计数器（强烈推荐）
nstat -az | grep -Ei &apos;drop|retrans|listen|overflow|prune&apos;

# 老牌工具，等价信息
netstat -s | grep -Ei &apos;drop|retrans|listen|overflow|prune&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重点看几个字段：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;字段&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TcpExtListenOverflows&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accept 队列溢出，应用层 accept 不及时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TcpExtListenDrops&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SYN 队列或 accept 队列丢 SYN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TcpExtTCPBacklogDrop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;已建连但 socket 缓冲区满，包被丢&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TcpExtPruneCalled&lt;/code&gt; / &lt;code&gt;TCPRcvCollapsed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;接收缓冲区不够，触发回收，性能急剧下降&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TcpRetransSegs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;重传段，对照基线看是否飙升&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IpReasmFails&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IP 分片重组失败（提示 MTU 问题，见坑三）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;ListenOverflows&lt;/code&gt; 涨说明应用 accept 慢了，调大队列：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;应用层也要配套，nginx 的 &lt;code&gt;listen 80 backlog=65535;&lt;/code&gt;、Go &lt;code&gt;net.Listen&lt;/code&gt; 后的 &lt;code&gt;ListenConfig{KeepAlive}&lt;/code&gt;、Java Netty 的 &lt;code&gt;SO_BACKLOG&lt;/code&gt; 都要设。&lt;/p&gt;
&lt;h3&gt;第 3 步：conntrack 表满&lt;/h3&gt;
&lt;p&gt;这个特别隐蔽，&lt;strong&gt;会让数据包&quot;无声&quot;地被丢，应用层完全感知不到&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 当前 conntrack 数 / 上限
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max

# dmesg 里搜 &quot;table full&quot;
dmesg | grep -i conntrack
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;nf_conntrack: table full, dropping packet&lt;/code&gt; 出现就说明已经在丢。调大：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_buckets = 262144   # 通常设为 max 的 1/4
net.netfilter.nf_conntrack_tcp_timeout_established = 600
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::caution
如果机器只是单纯做转发或者根本不需要 NAT，可以直接 &lt;code&gt;modprobe -r nf_conntrack&lt;/code&gt; 或在 iptables 里给关键链加 &lt;code&gt;NOTRACK&lt;/code&gt;，比调大表更治本。但前提是你不用 docker / k8s 默认的 SNAT，否则关掉会炸网络。
:::&lt;/p&gt;
&lt;h3&gt;第 4 步：抓包确认&lt;/h3&gt;
&lt;p&gt;到这一步还没结论，就上 &lt;code&gt;tcpdump&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 抓特定对端的所有包，写到文件方便 Wireshark 分析
tcpdump -i eth0 -nn -s 0 -w /tmp/cap.pcap host 10.0.0.5 and port 443

# 只看 SYN 和 RST，定位握手问题
tcpdump -i eth0 -nn &apos;tcp[tcpflags] &amp;amp; (tcp-syn|tcp-rst) != 0&apos;

# 实时看重传（粗略）
tcpdump -i eth0 -nn -A &apos;tcp[13] &amp;amp; 0x04 != 0 or tcp[13] &amp;amp; 0x02 != 0&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wireshark 里看 &lt;code&gt;tcp.analysis.retransmission&lt;/code&gt;、&lt;code&gt;tcp.analysis.duplicate_ack&lt;/code&gt;、&lt;code&gt;tcp.analysis.zero_window&lt;/code&gt;，比命令行直观得多。&lt;/p&gt;
&lt;p&gt;:::tip
线上抓包加 &lt;code&gt;-s 0 -w&lt;/code&gt; 必加 &lt;code&gt;host&lt;/code&gt; / &lt;code&gt;port&lt;/code&gt; 过滤，否则 pcap 文件能在分钟内吃光磁盘。还有个更好的工具是 &lt;code&gt;tcpdump -i eth0 -nn ... | head -1000&lt;/code&gt;，限制行数防止刷屏。
:::&lt;/p&gt;
&lt;h3&gt;第 5 步：内核层面看丢包点&lt;/h3&gt;
&lt;p&gt;如果以上都没线索，用 &lt;code&gt;dropwatch&lt;/code&gt; 直接定位是内核哪一行代码丢的包：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dropwatch -l kas
&amp;gt; start
# ...几秒后
&amp;gt; stop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出会告诉你 &lt;code&gt;tcp_v4_rcv+0x1b3/0x500&lt;/code&gt; 之类的具体函数。对深度排查很有用，但门槛较高，作为最后手段。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;坑三：MTU 黑洞——能 ping 通但传文件卡死&lt;/h2&gt;
&lt;p&gt;这是最玄学的一个。现象典型组合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ping&lt;/code&gt; 对端正常，&lt;strong&gt;延迟也不高&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;curl&lt;/code&gt; 拉小页面 200 OK&lt;/li&gt;
&lt;li&gt;一旦响应体变大（比如 10KB+）就卡死、超时&lt;/li&gt;
&lt;li&gt;SSH 登录能连上，敲命令到一半再回车就没反应了&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;九成是 &lt;strong&gt;MTU 不匹配 + ICMP 被防火墙吞了&lt;/strong&gt;，也就是教科书上说的 &lt;strong&gt;Path MTU Discovery 黑洞&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                  ┌──── 中间链路 MTU = 1400 ────┐
   Client                                          Server
   MTU=1500  ──── 物理网卡 ────  ──── 物理网卡 ──── MTU=1500

   ① 小包 (1200B, DF=1)
      ────●─────────────────────────────●────▶   ✓ 顺利通过

   ② 大包 (1500B, DF=1)
      ────●─────────╳                   ●        ✗ 在中间链路被丢
                    │
                    │  路由器本应回送 ICMP Type 3 Code 4
                    ▼  &quot;Fragmentation Needed, MTU=1400&quot;
                    ╳  被防火墙整段 ban 掉 ICMP → 发送方完全不知情
                          │
                          ▼
                    持续按 1500 重传 → 应用层看到的现象就是
                    &quot;能 ping 通、能建连、一传大包就卡死&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;原理&lt;/h3&gt;
&lt;p&gt;TCP 协商时会基于本地 MTU 算 MSS（&lt;code&gt;MSS = MTU - 40&lt;/code&gt;），一张图看清各字段在以太帧里占的位置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ┌──── Ethernet 帧 (链路层) ─────────────────────────────────────┐
 │ DMAC 6│ SMAC 6│ Type 2│           Payload ≤ MTU (默认1500)    │
 └───────┴───────┴───────┴───────────────────────────────────────┘
                         │
                         ▼
                ┌──── IP 包  (MTU = 1500) ───────────────────────┐
                │ IP 头 20  │ TCP 头 20 │   TCP 数据 ≤ MSS = 1460 │
                └───────────┴───────────┴─────────────────────────┘
                                         ↑
                          MSS = MTU − IP头(20) − TCP头(20) = 1460
                          IPv6 / TCP 时间戳选项启用时再各扣几字节
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当数据包经过中间链路（VPN、隧道、运营商 PPPoE）时，链路 MTU 可能比两端都小。本来应该靠 ICMP &lt;code&gt;Fragmentation Needed (Type 3, Code 4)&lt;/code&gt; 通知发送方降低分片大小，但很多防火墙傻乎乎把所有 ICMP 全 ban 了，于是发送方既不知道要分片，又因为 IP 头有 DF 标记不能在中间分片——大包就这样被静默吞掉。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么小包没事&lt;/strong&gt;？因为小包没超过中间最小 MTU，根本走得过去。&lt;/p&gt;
&lt;h3&gt;排查&lt;/h3&gt;
&lt;p&gt;最简单的方法：手动试探 PMTU。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# -M do：禁止分片；-s 1472：1472 + 28(ICMP+IP) = 1500 字节
ping -M do -s 1472 target.example.com

# 如果上面失败，逐步减小，直到通过
ping -M do -s 1400 target.example.com
ping -M do -s 1300 target.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到能通过的最大 &lt;code&gt;-s&lt;/code&gt; 值，加 28 就是路径 MTU。&lt;/p&gt;
&lt;p&gt;或者用 &lt;code&gt;tracepath&lt;/code&gt;，自动探测：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tracepath target.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt; 1?: [LOCALHOST]                      pmtu 1500
 1:  10.0.0.1                                          0.523ms 
 1:  10.0.0.1                                          0.491ms 
 2:  ...                                               1.234ms pmtu 1400
 3:  target.example.com                                3.456ms reached
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;pmtu 1400&lt;/code&gt; 这一跳就是瓶颈。&lt;/p&gt;
&lt;p&gt;抓包视角看就更明显：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tcpdump -i eth0 -nn -vv &apos;icmp[icmptype] = 3&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看不到 ICMP Type 3 → 中间防火墙吞了 → PMTU 黑洞实锤。&lt;/p&gt;
&lt;h3&gt;修复&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;方案 A：调小本机 MTU&lt;/strong&gt;（兜底，但治标不治本）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip link set eth0 mtu 1400
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;方案 B：在路由表上钉死 MSS&lt;/strong&gt;（推荐，对特定目标生效）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 通过 iptables 在 SYN 上 clamp MSS
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
  -j TCPMSS --clamp-mss-to-pmtu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对 VPN/WireGuard/IPSec 场景几乎是必配。WireGuard 默认 MTU 1420，对端如果走再套一层 GRE 之类还得继续减。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方案 C：开启 TCP MTU Probing&lt;/strong&gt;，让内核自己探测：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_base_mss = 1024
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tcp_mtu_probing = 1&lt;/code&gt; 是&quot;只在检测到黑洞时启用&quot;，比较保守；&lt;code&gt;= 2&lt;/code&gt; 是&quot;始终启用&quot;。建议从 1 开始。&lt;/p&gt;
&lt;p&gt;:::important
做 Overlay 网络（Docker、k8s CNI、VXLAN、IPIP）时，永远要意识到内层 MTU 会比物理网卡小。VXLAN 头 50 字节，所以物理 MTU 1500 时内层应该是 1450。Flannel、Calico 默认会处理这件事，但自建隧道时常常忘掉。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;内核参数调优清单&lt;/h2&gt;
&lt;p&gt;把上面散落的参数汇总成一份可以直接抄的模板，放在 &lt;code&gt;/etc/sysctl.d/99-network.conf&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ===== 连接管理 =====
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_fin_timeout = 15

# ===== 队列与缓冲区 =====
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 32768
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1

# ===== 收发缓冲区（按需，大带宽延迟积场景才调） =====
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# ===== 拥塞控制 =====
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

# ===== conntrack（NAT / 转发场景）=====
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 600

# ===== MTU 探测 =====
net.ipv4.tcp_mtu_probing = 1

# ===== Keepalive（让僵尸连接更快被清理）=====
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;应用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sysctl -p /etc/sysctl.d/99-network.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning
&lt;strong&gt;不要照搬&lt;/strong&gt;。这份参数适合&quot;高并发、对外提供服务的 Linux 主机&quot;。如果你的机器是数据库、做 NAT 网关、还是单纯桌面，每一项都要按场景判断。比如把 &lt;code&gt;rmem_max&lt;/code&gt; 调到 16M 在低 BDP（带宽延迟积）链路上反而浪费内存。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;常用排查命令速查&lt;/h2&gt;
&lt;p&gt;按&quot;看哪一层&quot;组织，故障来时按顺序敲：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip -s link show eth0                   # 接口收发计数、错误统计
ethtool eth0                           # 协商速率、双工
ethtool -S eth0 | grep -i err          # 网卡硬件错误
ethtool -g eth0                        # ring buffer 大小
dmesg -T | tail -50                    # 网卡 reset / 链路抖动
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ip route                               # 路由表
ip neigh                               # ARP / NDP 邻居
ping -M do -s 1472 &amp;lt;host&amp;gt;              # PMTU 探测
mtr -rwn &amp;lt;host&amp;gt;                        # 持续 traceroute，看丢包点
tracepath &amp;lt;host&amp;gt;                       # 自动 PMTU 探测
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ss -ant                                # 所有 TCP，比 netstat 快得多
ss -anti                               # 加 -i 看每个连接的拥塞窗口、RTT
ss -ltnp                               # 监听端口 + 进程
ss -s                                  # 各状态汇总
nstat -az                              # 协议栈计数器（推荐）
netstat -s                             # 同上，老牌
cat /proc/net/sockstat                 # socket / TIME_WAIT 总览
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;iptables -L -vn --line-numbers
nft list ruleset
cat /proc/sys/net/netfilter/nf_conntrack_count
conntrack -L                           # 当前所有连接追踪记录
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;tcpdump -i eth0 -nn -s 0 -w cap.pcap host X
tshark -i eth0 -Y &apos;tcp.analysis.retransmission&apos;
dropwatch -l kas                       # 内核丢包点定位
bpftrace -e &apos;kprobe:tcp_drop { @[kstack] = count(); }&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;线上网络问题之所以&quot;玄学&quot;，是因为表象（应用层报错）和根因（内核状态、链路 MTU、conntrack 表）之间有好几层间接关系。一旦养成&quot;按层排查&quot;的肌肉记忆，绝大多数所谓诡异问题都会变成可复现、可解释的事故。&lt;/p&gt;
&lt;p&gt;收尾建议：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;基线监控比事中救火更重要&lt;/strong&gt;。把 &lt;code&gt;ss -s&lt;/code&gt;、&lt;code&gt;nstat&lt;/code&gt;、&lt;code&gt;conntrack_count&lt;/code&gt;、&lt;code&gt;net_dropped&lt;/code&gt; 拉到监控里，比出事后再去看真实数据有价值得多&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要迷信&quot;重启就好了&quot;&lt;/strong&gt;。能重启好的问题大多是参数 / 资源耗尽问题，下一次它一定会再来&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;改内核参数前先记下原值&lt;/strong&gt;。&lt;code&gt;sysctl net.ipv4.tcp_tw_reuse&lt;/code&gt; 看到旧值再改，回滚才有依据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应用层和内核层一起调&lt;/strong&gt;。&lt;code&gt;somaxconn = 65535&lt;/code&gt; 但 nginx &lt;code&gt;backlog&lt;/code&gt; 默认 511，等于白调&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最后一句话：&lt;strong&gt;&lt;code&gt;tcp_tw_recycle&lt;/code&gt; 永远不要碰，永远。&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>Claude Code 对接 DeepSeek V4 Pro：完整配置指南</title><link>https://jk.sb/posts/claude-code-deepseek-v4/</link><guid isPermaLink="true">https://jk.sb/posts/claude-code-deepseek-v4/</guid><description>Claude Code CLI 和 VSCode 插件对接 DeepSeek V4 Pro 的配置详解，包含环境变量、模型映射和常见问题。</description><pubDate>Sat, 23 May 2026 12:49:50 GMT</pubDate><content:encoded>&lt;p&gt;Claude Code 是 Anthropic 推出的命令行 AI 编程助手，深度集成在终端和 VSCode 中。虽然它默认使用 Anthropic 自家的 Claude 模型，但通过 DeepSeek 提供的 Anthropic 兼容 API，我们可以用 DeepSeek V4 Pro 来驱动 Claude Code，大幅降低成本（约 99%）。&lt;/p&gt;
&lt;h2&gt;1. Claude Code CLI 对接 DeepSeek V4 Pro&lt;/h2&gt;
&lt;h3&gt;1.1 安装 Claude Code&lt;/h3&gt;
&lt;p&gt;首先确保安装了 Node.js 18+，然后全局安装 Claude Code：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -g @anthropic-ai/claude-code
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;验证安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;claude --version
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.2 配置环境变量&lt;/h3&gt;
&lt;p&gt;DeepSeek 提供了一个兼容 Anthropic API 的端点 &lt;code&gt;https://api.deepseek.com/anthropic&lt;/code&gt;，只需设置几个环境变量即可让 Claude Code 指向 DeepSeek。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;~/.zshrc&lt;/code&gt;（或 &lt;code&gt;~/.bashrc&lt;/code&gt;）中添加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export ANTHROPIC_BASE_URL=&quot;https://api.deepseek.com/anthropic&quot;
export ANTHROPIC_AUTH_TOKEN=&quot;&amp;lt;你的 DeepSeek API Key&amp;gt;&quot;
export ANTHROPIC_MODEL=&quot;deepseek-v4-pro[1m]&quot;
export ANTHROPIC_DEFAULT_OPUS_MODEL=&quot;deepseek-v4-pro[1m]&quot;
export ANTHROPIC_DEFAULT_SONNET_MODEL=&quot;deepseek-v4-pro[1m]&quot;
export ANTHROPIC_DEFAULT_HAIKU_MODEL=&quot;deepseek-v4-flash&quot;
export CLAUDE_CODE_SUBAGENT_MODEL=&quot;deepseek-v4-flash&quot;
export CLAUDE_CODE_EFFORT_LEVEL=&quot;max&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使配置生效：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.3 环境变量说明&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_BASE_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://api.deepseek.com/anthropic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DeepSeek 的 Anthropic 兼容端点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;你的 API Key&lt;/td&gt;
&lt;td&gt;在 &lt;a href=&quot;https://platform.deepseek.com/api_keys&quot;&gt;DeepSeek Platform&lt;/a&gt; 获取&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_MODEL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deepseek-v4-pro[1m]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;主力模型，适合复杂代码分析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_DEFAULT_HAIKU_MODEL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deepseek-v4-flash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;轻量模型，适合简单任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE_CODE_SUBAGENT_MODEL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;deepseek-v4-flash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;子 Agent 使用 Flash 以节省成本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE_CODE_EFFORT_LEVEL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;max&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;最高努力级别&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;1.4 模型选择&lt;/h3&gt;
&lt;p&gt;DeepSeek V4 系列目前提供两个模型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;deepseek-v4-pro[1m]&lt;/code&gt;&lt;/strong&gt;：主力模型，1M 上下文窗口，适合复杂代码分析、大型项目重构、多文件编辑&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;deepseek-v4-flash&lt;/code&gt;&lt;/strong&gt;：快速轻量模型，适合日常问答、简单代码修改、子 Agent 任务&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.5 启动使用&lt;/h3&gt;
&lt;p&gt;配置完成后，在项目目录下直接运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /path/to/your-project
claude
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即可进入 Claude Code 交互界面，底层已经切换为 DeepSeek V4 Pro。&lt;/p&gt;
&lt;h2&gt;2. VSCode 插件对接 DeepSeek V4 Pro&lt;/h2&gt;
&lt;p&gt;在 VSCode 中使用 Claude Code 插件对接 DeepSeek，配置方式略有不同——需要通过 VSCode 的 &lt;code&gt;settings.json&lt;/code&gt; 来注入环境变量。&lt;/p&gt;
&lt;h3&gt;2.1 安装插件&lt;/h3&gt;
&lt;p&gt;在 VSCode 扩展市场搜索 &lt;strong&gt;Claude Code&lt;/strong&gt;（作者：Anthropic），点击安装。&lt;/p&gt;
&lt;h3&gt;2.2 配置 settings.json&lt;/h3&gt;
&lt;p&gt;打开 VSCode 设置（&lt;code&gt;Cmd+Shift+P&lt;/code&gt; → &lt;code&gt;Preferences: Open User Settings (JSON)&lt;/code&gt;），添加以下配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;claudeCode.environmentVariables&quot;: [
    {
      &quot;name&quot;: &quot;ANTHROPIC_BASE_URL&quot;,
      &quot;value&quot;: &quot;https://api.deepseek.com/anthropic&quot;
    },
    {
      &quot;name&quot;: &quot;ANTHROPIC_AUTH_TOKEN&quot;,
      &quot;value&quot;: &quot;&amp;lt;你的 DeepSeek API Key&amp;gt;&quot;
    },
    {
      &quot;name&quot;: &quot;ANTHROPIC_MODEL&quot;,
      &quot;value&quot;: &quot;deepseek-v4-pro[1m]&quot;
    },
    {
      &quot;name&quot;: &quot;ANTHROPIC_DEFAULT_OPUS_MODEL&quot;,
      &quot;value&quot;: &quot;deepseek-v4-pro[1m]&quot;
    },
    {
      &quot;name&quot;: &quot;ANTHROPIC_DEFAULT_SONNET_MODEL&quot;,
      &quot;value&quot;: &quot;deepseek-v4-pro[1m]&quot;
    },
    {
      &quot;name&quot;: &quot;ANTHROPIC_DEFAULT_HAIKU_MODEL&quot;,
      &quot;value&quot;: &quot;deepseek-v4-flash&quot;
    },
    {
      &quot;name&quot;: &quot;CLAUDE_CODE_SUBAGENT_MODEL&quot;,
      &quot;value&quot;: &quot;deepseek-v4-flash&quot;
    },
    {
      &quot;name&quot;: &quot;CLAUDE_CODE_EFFORT_LEVEL&quot;,
      &quot;value&quot;: &quot;max&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;code&gt;ANTHROPIC_AUTH_TOKEN&lt;/code&gt; 的值换成你自己的 DeepSeek API Key。API Key 可以在 &lt;a href=&quot;https://platform.deepseek.com/api_keys&quot;&gt;platform.deepseek.com/api_keys&lt;/a&gt; 创建。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2.3 切换模型&lt;/h3&gt;
&lt;p&gt;配置完成后重启 VSCode，打开 Claude Code 面板，可以通过以下方式切换模型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用快捷键打开命令面板，输入 &lt;code&gt;Claude Code: Switch Model&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;或在对话中输入 &lt;code&gt;/model&lt;/code&gt; 选择模型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;日常使用建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;复杂任务（代码分析、重构）→ &lt;code&gt;deepseek-v4-pro[1m]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;简单问答、小修改 → &lt;code&gt;deepseek-v4-flash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.4 验证配置&lt;/h3&gt;
&lt;p&gt;在 Claude Code 面板中输入「你当前使用的是哪个模型？」，如果返回 DeepSeek 相关信息，说明配置成功。&lt;/p&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;环境变量不要放在 &lt;code&gt;.env&lt;/code&gt; 文件中&lt;/strong&gt;。Claude Code 不读取项目 &lt;code&gt;.env&lt;/code&gt; 文件，必须通过 shell 配置文件（CLI 方式）或 VSCode 设置（插件方式）注入。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Key 安全&lt;/strong&gt;。不要将 API Key 硬编码在项目文件中，确保 &lt;code&gt;.zshrc&lt;/code&gt; 或 &lt;code&gt;settings.json&lt;/code&gt; 不会被提交到公开仓库。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具调用能力&lt;/strong&gt;。DeepSeek 在工具调用（tool calling）方面与原生 Claude 模型存在差距，部分复杂的多步骤操作可能需要更多调试。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型名称中的 &lt;code&gt;[1m]&lt;/code&gt;&lt;/strong&gt;。这是 DeepSeek 官方文档中 &lt;code&gt;deepseek-v4-pro&lt;/code&gt; 的完整名称后缀，如果接口报错可以尝试去掉该后缀。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>CPA Usage Keeper：CLIProxyAPI 用量追踪与可视化面板</title><link>https://jk.sb/posts/cpa-usage-keeper/</link><guid isPermaLink="true">https://jk.sb/posts/cpa-usage-keeper/</guid><description>详细介绍 CPA Usage Keeper 的安装部署、配置、Dashboard 功能、Nginx 反代等全流程，为 CLIProxyAPI 补充用量持久化与统计分析能力</description><pubDate>Sat, 23 May 2026 02:04:04 GMT</pubDate><content:encoded>&lt;p&gt;CPA Usage Keeper 是一个独立的 CPA（CLIProxyAPI）用量持久化与可视化服务。它在 CPA 之上补充了 SQLite 持久化存储与统计分析能力，提供内置 Web Dashboard 用于查看 usage、pricing、request health 以及 model/API 维度的统计信息。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Willxup/cpa-usage-keeper&quot;}&lt;/p&gt;
&lt;h2&gt;核心概念&lt;/h2&gt;
&lt;p&gt;CPA Usage Keeper 本质上是一个用量数据的中转 + 持久化 + 可视化层：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CLIProxyAPI (CPA)
    ↓  Redis usage 队列推送事件
CPA Usage Keeper
    ├── 消费队列 → 写入 SQLite
    ├── 定时拉取 CPA metadata
    ├── 暴露聚合 API
    └── 内置 Web Dashboard (8080 端口)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;它与 CPA 的关系：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;依赖 CPA&lt;/strong&gt;：Keeper 从 CPA 的 Redis usage 队列消费事件，通过 CPA 管理接口拉取 metadata&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;补充 CPA&lt;/strong&gt;：CPA 本身不做持久化存储，重启后用量数据丢失；Keeper 用 SQLite 持久保存，提供历史和趋势分析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;独立部署&lt;/strong&gt;：Keeper 是独立进程/容器，不修改 CPA 的任何配置或代码&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip[核心价值]
让 CPA 的用量数据&quot;落地&quot;——持久化存储、历史回溯、趋势分析、成本估算，一个面板全部搞定。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;功能特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;用量持久化&lt;/strong&gt;：从 CPA Redis usage 队列消费事件并写入 SQLite，重启不丢数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dashboard 总览&lt;/strong&gt;：请求量、Token、成本、缓存命中率、成功率和延迟一目了然&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多维度筛选&lt;/strong&gt;：按时间范围、模型、API Key 和来源筛选用量明细&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分析页面&lt;/strong&gt;：Token 趋势图、模型/API Key/AI Provider 构成、时段热力图&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Key 独立查询&lt;/strong&gt;：可按 CPA API Key 查看专属用量&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;凭证页面&lt;/strong&gt;：展示 Auth File 与 AI Provider 使用情况，支持凭证限额查询与刷新&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型价格管理&lt;/strong&gt;：可维护模型价格，用于成本估算和统计展示&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全保护&lt;/strong&gt;：可选密码登录保护、SQLite 备份、Docker/Docker Compose 和 systemd 部署&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;前置条件&lt;/h2&gt;
&lt;p&gt;使用 CPA Usage Keeper 之前，请确认 CPA 已开启 usage 统计：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# CPA 配置中必须启用
usage-statistics-enabled: true
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;安装部署&lt;/h2&gt;
&lt;h3&gt;方式一：Docker Compose（推荐）&lt;/h3&gt;
&lt;p&gt;同时部署 CPA 和 Keeper 的最佳选择。仓库提供了 &lt;code&gt;docker-compose.example.yml&lt;/code&gt; 作为模板：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  cli-proxy-api:
    image: eceasy/cli-proxy-api:latest
    container_name: cli-proxy-api
    restart: unless-stopped
    ports:
      - &quot;8317:8317&quot;
      - &quot;1455:1455&quot;
    volumes:
      - ./cpa/config.yaml:/CLIProxyAPI/config.yaml
      - ./cpa/auths:/root/.cli-proxy-api
      - ./cpa/logs:/CLIProxyAPI/logs
    networks:
      - cpa-network

  cpa-usage-keeper:
    image: ghcr.io/willxup/cpa-usage-keeper:latest
    container_name: cpa-usage-keeper
    restart: unless-stopped
    depends_on:
      - cli-proxy-api
    ports:
      - &quot;8080:8080&quot;
    environment:
      TZ: Asia/Shanghai
      CPA_BASE_URL: http://cli-proxy-api:8317
      CPA_MANAGEMENT_KEY: replace-with-your-management-key
      REDIS_QUEUE_ADDR: cli-proxy-api:8317
      AUTH_ENABLED: true
      LOGIN_PASSWORD: replace-with-your-login-password
    volumes:
      - ./keeper:/data
    networks:
      - cpa-network

networks:
  cpa-network:
    driver: bridge
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 启动
docker compose up -d

# 停止
docker compose down
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CPA 相关文件放在 &lt;code&gt;./cpa&lt;/code&gt; 目录，Keeper 数据（SQLite 数据库、日志、备份）放在 &lt;code&gt;./keeper&lt;/code&gt; 目录。&lt;/p&gt;
&lt;h3&gt;方式二：Docker（CPA 已在宿主机运行）&lt;/h3&gt;
&lt;p&gt;如果 CPA 已经在宿主机运行，只需单独部署 Keeper：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 复制配置模板
cp .env.example .env
vim .env
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;CPA_BASE_URL=http://host.docker.internal:8317
CPA_MANAGEMENT_KEY=replace-with-your-management-key
REDIS_QUEUE_ADDR=host.docker.internal:8317
AUTH_ENABLED=true
LOGIN_PASSWORD=replace-with-your-login-password
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;docker run -d \
  --name cpa-usage-keeper \
  --add-host=host.docker.internal:host-gateway \
  -p 8080:8080 \
  -v &quot;$(pwd)/keeper:/data&quot; \
  --env-file .env \
  ghcr.io/willxup/cpa-usage-keeper:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
&lt;code&gt;--add-host=host.docker.internal:host-gateway&lt;/code&gt; 让容器能通过 &lt;code&gt;host.docker.internal&lt;/code&gt; 访问宿主机上的 CPA 服务。
:::&lt;/p&gt;
&lt;h3&gt;方式三：Linux 二进制&lt;/h3&gt;
&lt;p&gt;前往 &lt;a href=&quot;https://github.com/Willxup/cpa-usage-keeper/releases/latest&quot;&gt;Releases 页面&lt;/a&gt; 下载对应架构的二进制包：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 下载（请替换为实际下载地址）
curl -L -o cpa-usage-keeper.tar.gz &quot;https://github.com/Willxup/cpa-usage-keeper/releases/latest/download/cpa-usage-keeper_linux_amd64.tar.gz&quot;
mkdir -p cpa-usage-keeper
tar -xzf cpa-usage-keeper.tar.gz -C cpa-usage-keeper --strip-components=1
cd cpa-usage-keeper

# 配置并启动
cp .env.example .env
vim .env
./cpa-usage-keeper
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;systemd 常驻运行&lt;/h4&gt;
&lt;p&gt;二进制包内置了 &lt;code&gt;cpa-usage-keeper.service&lt;/code&gt; 文件，可直接注册为 systemd 服务：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo cp cpa-usage-keeper.service /etc/systemd/system/cpa-usage-keeper.service
sudo sed -i &quot;s|__CPA_USAGE_KEEPER_DIR__|$(pwd)|g&quot; /etc/systemd/system/cpa-usage-keeper.service
sudo systemctl daemon-reload
sudo systemctl enable --now cpa-usage-keeper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;常用管理命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl status cpa-usage-keeper   # 查看服务状态
sudo journalctl -u cpa-usage-keeper -f   # 实时查看日志
sudo systemctl restart cpa-usage-keeper  # 重启服务
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;配置详解&lt;/h2&gt;
&lt;p&gt;所有配置通过环境变量（&lt;code&gt;.env&lt;/code&gt; 文件）管理。复制模板后按需修改：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;最小必填&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;必填&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPA_BASE_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Keeper 服务端访问 CPA 的地址。Docker Compose 内通常是 &lt;code&gt;http://cli-proxy-api:8317&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPA_MANAGEMENT_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;CPA management key（即 CPA &lt;code&gt;config.yaml&lt;/code&gt; 中的 &lt;code&gt;secret-key&lt;/code&gt;），用于读取 CPA 管理接口数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Web 访问与反代&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;必填&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;APP_PORT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;8080&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Keeper HTTP 监听端口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;APP_BASE_PATH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;根路径&lt;/td&gt;
&lt;td&gt;子路径部署前缀，例如 &lt;code&gt;/keeper&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPA_PUBLIC_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;浏览器同源根路径&lt;/td&gt;
&lt;td&gt;浏览器访问 CPA 的公开地址，用于&quot;返回 CPA&quot;跳转&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::tip[APP_BASE_PATH 说明]
&lt;code&gt;APP_BASE_PATH&lt;/code&gt; 必须为空或以 &lt;code&gt;/&lt;/code&gt; 开头。例如 &lt;code&gt;/cpa&lt;/code&gt; 是正确的，&lt;code&gt;/cpa/&lt;/code&gt; 会自动规范为 &lt;code&gt;/cpa&lt;/code&gt;。如果你通过 Nginx 的 &lt;code&gt;/keeper/&lt;/code&gt; 路径反代，需设置 &lt;code&gt;APP_BASE_PATH=/keeper&lt;/code&gt;。
:::&lt;/p&gt;
&lt;h3&gt;登录保护&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;必填&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AUTH_ENABLED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是否启用登录保护&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOGIN_PASSWORD&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;鉴权启用时必填&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;登录密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AUTH_SESSION_TTL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;168h&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;登录 session 有效时长&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::warning[安全提示]
公网部署务必设置 &lt;code&gt;AUTH_ENABLED=true&lt;/code&gt; 并配置强密码，防止用量数据被未授权访问。
:::&lt;/p&gt;
&lt;h3&gt;时区与请求&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;必填&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TZ&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Asia/Shanghai&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;统计和展示使用的时区&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;REQUEST_TIMEOUT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;30s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;请求 CPA HTTP 接口的超时时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TLS_SKIP_VERIFY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;跳过 CPA HTTPS 证书验证（仅自签名证书时启用）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Redis 队列高级配置&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;必填&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;REDIS_QUEUE_ADDR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;CPA 主机 + 8317&lt;/td&gt;
&lt;td&gt;CPA Redis/RESP TCP 地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;REDIS_QUEUE_TLS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是否使用 TLS 连接 Redis 队列&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;REDIS_QUEUE_BATCH_SIZE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;每次最多拉取的队列记录数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;REDIS_QUEUE_IDLE_INTERVAL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;队列为空时的检查间隔&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一般保持默认值即可，只有 CPA 的 Redis 端口不是默认 &lt;code&gt;8317&lt;/code&gt; 时才需要显式设置。&lt;/p&gt;
&lt;h3&gt;存储、日志与备份&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;必填&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WORK_DIR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./data&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;工作目录（数据库、日志、备份）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOG_LEVEL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;info&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;日志级别：&lt;code&gt;debug&lt;/code&gt; / &lt;code&gt;info&lt;/code&gt; / &lt;code&gt;warn&lt;/code&gt; / &lt;code&gt;error&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOG_FILE_ENABLED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是否写入持久化日志文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOG_RETENTION_DAYS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;日志保留天数，&lt;code&gt;0&lt;/code&gt; 不自动清理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BACKUP_ENABLED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是否启用 SQLite 数据库备份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BACKUP_INTERVAL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;24h&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;数据库备份间隔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BACKUP_RETENTION_DAYS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;备份保留天数&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;内置 HTTPS&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;变量&lt;/th&gt;
&lt;th&gt;必填&lt;/th&gt;
&lt;th&gt;默认值&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TLS_ENABLED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是否让 Keeper 自己启用 HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TLS_CERT_FILE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启用时必填&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;HTTPS 证书文件路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TLS_KEY_FILE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启用时必填&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;HTTPS 私钥文件路径&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;通常建议在 Nginx 或 Caddy 等反向代理层处理 HTTPS，而不是让 Keeper 自己处理。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Dashboard 功能导览&lt;/h2&gt;
&lt;p&gt;启动服务后，访问 &lt;code&gt;http://服务器IP:8080&lt;/code&gt; 进入 Dashboard。&lt;/p&gt;
&lt;h3&gt;总览页面&lt;/h3&gt;
&lt;p&gt;首页展示核心指标卡片：请求总量、Token 消耗、估算成本、缓存命中率、成功率、平均延迟。下方有请求趋势图和模型分布图，帮助你快速了解整体使用情况。&lt;/p&gt;
&lt;h3&gt;用量明细&lt;/h3&gt;
&lt;p&gt;支持按时间范围（Today / 7天 / 30天 / 自定义）、模型、API Key 和来源多维度筛选。每条记录包含请求时间、模型名称、Token 数、延迟、是否缓存命中、是否成功等字段。&lt;/p&gt;
&lt;h3&gt;分析页面&lt;/h3&gt;
&lt;p&gt;提供三个维度的深度分析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Token 趋势&lt;/strong&gt;：按天/按小时查看 Token 消耗变化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;构成分析&lt;/strong&gt;：模型占比、API Key 用量分布、AI Provider 占比&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;时段热力图&lt;/strong&gt;：一周内各时段的请求密度分布，直观发现使用高峰&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;API Key 独立查询&lt;/h3&gt;
&lt;p&gt;如果你在 CPA 中配置了多个 &lt;code&gt;api-keys&lt;/code&gt;（多用户场景），Keeper 支持按 Key 独立查询用量。每个 Key 对应一个专属页面，方便团队场景下的用量核算。&lt;/p&gt;
&lt;h3&gt;凭证页面&lt;/h3&gt;
&lt;p&gt;展示 CPA 中各 Auth File 的认证状态、对应的 AI Provider、剩余配额等信息。支持一键刷新凭证状态。&lt;/p&gt;
&lt;h3&gt;模型价格管理&lt;/h3&gt;
&lt;p&gt;Keeper 内置了主流模型的默认价格，但你可以在 Dashboard 中自定义价格，用于更准确的成本估算。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Nginx 反向代理&lt;/h2&gt;
&lt;p&gt;在生产环境中，建议通过 Nginx 反代访问 Keeper，统一处理 HTTPS 和路径：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate     /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # 如果部署在子路径 /keeper/
    location /keeper/ {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$host$request_uri;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;子路径部署时记得在 &lt;code&gt;.env&lt;/code&gt; 中设置 &lt;code&gt;APP_BASE_PATH=/keeper&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果 CPA 管理页和 Keeper 使用同一域名，&quot;返回 CPA&quot;按钮会自动跳转到同源 &lt;code&gt;/management.html&lt;/code&gt;，无需额外配置 &lt;code&gt;CPA_PUBLIC_URL&lt;/code&gt;。如果 CPA 在其他域名或端口，请设置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 示例：CPA 部署在独立域名
CPA_PUBLIC_URL=https://cpa.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;数据说明&lt;/h2&gt;
&lt;p&gt;了解数据流转有助于排查问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数据来源&lt;/strong&gt;：Keeper 从 CPA 的 Redis usage 队列消费每一条请求事件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储方式&lt;/strong&gt;：SQLite 数据库，文件位于 &lt;code&gt;WORK_DIR/app.db&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metadata 同步&lt;/strong&gt;：Keeper 定时从 CPA 管理接口拉取模型列表、Auth File 状态、配额信息等&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据清理&lt;/strong&gt;：Redis inbox 原始消息会自动清理——成功数据保留到当天结束后清理，失败数据保留 7 天&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;脱敏处理&lt;/strong&gt;：面向浏览器的 API 会对 key-like 的 source/lookup 字段做脱敏或稳定公开标识映射，但不会修改数据库原始值&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;常见问题&lt;/h2&gt;
&lt;h3&gt;启动后 Dashboard 没有数据？&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;确认 CPA 的 &lt;code&gt;config.yaml&lt;/code&gt; 中 &lt;code&gt;usage-statistics-enabled: true&lt;/code&gt; 已设置&lt;/li&gt;
&lt;li&gt;确认 &lt;code&gt;CPA_MANAGEMENT_KEY&lt;/code&gt; 的值与 CPA 的 &lt;code&gt;secret-key&lt;/code&gt; 一致&lt;/li&gt;
&lt;li&gt;确认 &lt;code&gt;REDIS_QUEUE_ADDR&lt;/code&gt; 能连通 CPA 的 8317 端口&lt;/li&gt;
&lt;li&gt;发起几个 API 请求后再查看，数据从 Redis 队列消费有一定延迟（默认空闲时 1s 检查一次）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;CPA 和 Keeper 的网络不通？&lt;/h3&gt;
&lt;p&gt;Docker Compose 部署时两者在同一 &lt;code&gt;cpa-network&lt;/code&gt; 下，服务名 &lt;code&gt;cli-proxy-api&lt;/code&gt; 即可互通。Docker 单独部署时使用 &lt;code&gt;host.docker.internal&lt;/code&gt; 访问宿主机。检查防火墙是否放行对应端口。&lt;/p&gt;
&lt;h3&gt;如何备份数据？&lt;/h3&gt;
&lt;p&gt;Keeper 内置自动备份功能（默认每 24 小时备份一次），备份文件在 &lt;code&gt;WORK_DIR/backups/&lt;/code&gt;。你也可以手动备份 &lt;code&gt;WORK_DIR/app.db&lt;/code&gt; 文件——SQLite 单文件数据库，直接复制即可。&lt;/p&gt;
&lt;h3&gt;数据库文件越来越大？&lt;/h3&gt;
&lt;p&gt;SQLite 数据库会随着用量数据积累而增长。目前 Keeper 暂不支持自动清理历史数据，如需清理可考虑定期重建。日志文件默认保留 7 天自动清理。&lt;/p&gt;
&lt;h3&gt;登录密码忘了？&lt;/h3&gt;
&lt;p&gt;登录 session 存在服务进程内存中，修改 &lt;code&gt;.env&lt;/code&gt; 中的 &lt;code&gt;LOGIN_PASSWORD&lt;/code&gt; 后重启服务即可用新密码登录（所有旧 session 会失效）。&lt;/p&gt;
&lt;h3&gt;子路径部署后页面白屏？&lt;/h3&gt;
&lt;p&gt;检查 &lt;code&gt;APP_BASE_PATH&lt;/code&gt; 是否正确设置，以及 Nginx 的 &lt;code&gt;proxy_pass&lt;/code&gt; 是否正确传递了路径前缀。确保静态资源的路径也正确映射。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;安全建议&lt;/h2&gt;
&lt;p&gt;:::warning[生产环境清单]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;AUTH_ENABLED=true&lt;/code&gt; 并设置强密码（16 位以上随机字符）&lt;/li&gt;
&lt;li&gt;[ ] 在反向代理层配置 HTTPS（Nginx / Caddy），不直接暴露 8080 端口&lt;/li&gt;
&lt;li&gt;[ ] 数据库备份文件不做加密，妥善保管 &lt;code&gt;WORK_DIR/backups/&lt;/code&gt; 目录&lt;/li&gt;
&lt;li&gt;[ ] 登录 session 存于内存，服务重启后失效——这是设计如此，不必疑惑&lt;/li&gt;
&lt;li&gt;[ ] 定期检查 &lt;code&gt;LOG_RETENTION_DAYS&lt;/code&gt; 和 &lt;code&gt;BACKUP_RETENTION_DAYS&lt;/code&gt;，避免磁盘占满
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;相关项目&lt;/h2&gt;
&lt;p&gt;::github{repo=&quot;router-for-me/CLIProxyAPI&quot;}&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;router-for-me/Cli-Proxy-API-Management-Center&quot;}&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;CPA Usage Keeper 让 CPA 的用量数据从&quot;用完即丢&quot;变成&quot;可追溯、可分析、可优化&quot;的资产。配合 Dashboard 的多维度分析能力，你可以清楚地了解各个模型的实际使用成本和效率，从而做出更合理的配额分配决策。&lt;/p&gt;
</content:encoded></item><item><title>DeepSeek-TUI：终端原生 AI 编程智能体</title><link>https://jk.sb/posts/deepseek-tui/</link><guid isPermaLink="true">https://jk.sb/posts/deepseek-tui/</guid><description>面向 DeepSeek V4 的终端原生编程智能体，支持 100 万 token 上下文、多种交互模式、子智能体并行、LSP 诊断等完整功能教程</description><pubDate>Fri, 15 May 2026 02:11:25 GMT</pubDate><content:encoded>&lt;p&gt;DeepSeek-TUI 是一款面向 DeepSeek V4 模型的终端原生编程智能体，完全在命令行中运行，提供文件操作、Shell 执行、Git 管理、网页浏览、子智能体协调等能力，通过键盘驱动的 TUI 界面交互。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Hmbown/DeepSeek-TUI&quot;}&lt;/p&gt;
&lt;h2&gt;核心特性&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;100 万 Token 上下文&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;完整窗口支持，带压缩追踪和前缀缓存遥测&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;流式推理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;实时观察模型思维链&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;自动模型选择&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;根据任务复杂度自动在 Flash 和 Pro 之间切换&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;三种交互模式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Plan（只读）/ Agent（审批）/ YOLO（自动批准）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;持久任务队列&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;任务在应用重启后仍可恢复&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;子智能体并行&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;最多 10 个（可配至 20 个）并发背景任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LSP 诊断集成&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;编辑后实时显示 rust-analyzer、pyright、gopls 等诊断信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP 服务器&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通过 Model Context Protocol 扩展工具能力&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;h3&gt;npm（推荐，无需 Node.js 运行时）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;npm install -g deepseek-tui
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Cargo（从 Rust 源码编译）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cargo install deepseek-tui-cli --locked
cargo install deepseek-tui --locked
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Homebrew（macOS）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;brew tap Hmbown/deepseek-tui
brew install deepseek-tui
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;直接下载二进制&lt;/h3&gt;
&lt;p&gt;前往 &lt;a href=&quot;https://github.com/Hmbown/DeepSeek-TUI/releases&quot;&gt;Releases 页面&lt;/a&gt; 下载对应平台的预编译二进制文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux x64 / ARM64&lt;/li&gt;
&lt;li&gt;macOS (Intel / Apple Silicon)&lt;/li&gt;
&lt;li&gt;Windows x64&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Docker&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 创建持久化数据卷
docker volume create deepseek-tui-home

# 启动容器（挂载当前目录为工作区）
docker run --rm -it \
  -e DEEPSEEK_API_KEY=&quot;$DEEPSEEK_API_KEY&quot; \
  -v deepseek-tui-home:/home/deepseek/.deepseek \
  -v &quot;$PWD:/workspace&quot; \
  -w /workspace \
  ghcr.io/hmbown/deepseek-tui:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
Docker 方式通过数据卷持久化配置和会话数据，容器删除后数据不丢失。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;配置 API&lt;/h2&gt;
&lt;h3&gt;DeepSeek 官方（推荐）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 设置提供商
deepseek auth set --provider deepseek

# 设置 API Key（从 platform.deepseek.com 获取）
export DEEPSEEK_API_KEY=&quot;your_api_key_here&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或写入 Shell 配置文件永久生效：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;export DEEPSEEK_API_KEY=&quot;your_api_key_here&quot;&apos; &amp;gt;&amp;gt; ~/.zshrc
source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;NVIDIA NIM&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;deepseek auth set --provider nvidia-nim --api-key &quot;YOUR_KEY&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;OpenRouter&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;deepseek auth set --provider openrouter --api-key &quot;YOUR_KEY&quot;

# 指定模型调用
deepseek --provider openrouter --model deepseek/deepseek-v4-pro
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自托管（Ollama / vLLM）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Ollama 本地部署
deepseek auth set --provider ollama --base-url &quot;http://localhost:11434&quot;

# vLLM
deepseek auth set --provider vllm --base-url &quot;http://localhost:8000&quot; --api-key &quot;YOUR_KEY&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;配置文件&lt;/h2&gt;
&lt;p&gt;用户级配置：&lt;code&gt;~/.deepseek/config.toml&lt;/code&gt;&lt;br /&gt;
工作区级配置：&lt;code&gt;.deepseek/config.toml&lt;/code&gt;（工作区配置优先级更高）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[tui]
locale = &quot;zh-Hans&quot;          # 界面语言：en / ja / zh-Hans / pt-BR，留空自动检测
theme = &quot;catppuccin&quot;        # 主题：catppuccin / tokyo-night / dracula / gruvbox / light / dark

[agent]
max_subagents = 10          # 最大并发子智能体数量（最高 20）
auto_mode = true            # 启用自动模型选择

[context]
user_memory = true          # 跨会话的用户记忆注入
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;可用主题：&lt;/strong&gt; &lt;code&gt;catppuccin&lt;/code&gt;、&lt;code&gt;tokyo-night&lt;/code&gt;、&lt;code&gt;dracula&lt;/code&gt;、&lt;code&gt;gruvbox&lt;/code&gt;，以及内置的 &lt;code&gt;light&lt;/code&gt; / &lt;code&gt;dark&lt;/code&gt;，运行时用 &lt;code&gt;/theme&lt;/code&gt; 命令切换。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;启动与使用模式&lt;/h2&gt;
&lt;h3&gt;基本启动&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 交互模式启动（默认 Agent 模式）
deepseek

# 一次性查询（非交互）
deepseek &quot;解释这个文件的作用&quot; @src/main.rs

# 指定工作目录
deepseek --dir /path/to/project
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;三种交互模式&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Plan 模式（只读探索）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deepseek --plan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;只读取文件和分析代码，不执行任何修改操作。适合先理解项目结构再决定行动。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agent 模式（默认）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deepseek
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;每次工具调用（文件写入、Shell 命令等）都需要用户审批确认，安全可控。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;YOLO 模式（自动批准）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deepseek --yolo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;自动批准所有工具调用，适合可信任的工作区或自动化脚本。&lt;/p&gt;
&lt;p&gt;:::caution[YOLO 模式注意事项]
YOLO 模式下 AI 会直接执行所有操作，建议仅在有版本控制的项目中使用，确保误操作可回滚。
:::&lt;/p&gt;
&lt;h3&gt;模型选择&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 自动选择（根据任务复杂度选 Flash 或 Pro）
deepseek --model auto

# 强制使用 Pro
deepseek --model deepseek-v4-pro

# 强制使用 Flash（速度快，成本低）
deepseek --model deepseek-v4-flash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Auto 模式&lt;/strong&gt;会在每轮对话前用 Flash 模型做预检，判断任务是否需要 Pro 的推理能力，从而在成本和质量间自动平衡。&lt;/p&gt;
&lt;h3&gt;Headless HTTP/SSE 模式&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 启动 HTTP API 服务（无界面）
deepseek serve --http --port 3000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;适合将 DeepSeek-TUI 作为后端服务集成到其他系统。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;内置工具&lt;/h2&gt;
&lt;p&gt;DeepSeek-TUI 内置以下工具，AI 可自主调用（Agent 模式下需用户审批）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;工具类别&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;文件操作&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;读写、创建、删除、重命名工作区文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Shell 执行&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;运行任意 Shell 命令，带当前目录验证和安全检查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Git 管理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;提交、分支、diff、stash 等版本控制操作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;网页浏览&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;搜索网页、抓取 URL 内容（含 SSRF 防护）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;补丁应用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通过 &lt;code&gt;apply-patch&lt;/code&gt; 应用代码修改&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;子智能体&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;生成具有独立上下文和工具注册表的并发后台任务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP 服务器&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;连接 Model Context Protocol 服务器扩展工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RLM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;持久 REPL 会话，用低成本 Flash 模型做批量分析&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;附加文件/目录上下文&lt;/h3&gt;
&lt;p&gt;在输入框中使用 &lt;code&gt;@&lt;/code&gt; 附加文件或目录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@src/main.rs 帮我重构这个函数
@./tests/ 分析测试覆盖率
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;子智能体系统&lt;/h2&gt;
&lt;p&gt;子智能体允许并发后台执行复杂任务：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;非阻塞启动：&lt;/strong&gt; &lt;code&gt;agent_open&lt;/code&gt; 立即返回，子智能体在后台独立运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;并行执行：&lt;/strong&gt; 默认最多 10 个子智能体并发（可配置至 20 个）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;完成通知：&lt;/strong&gt; 子智能体完成时发送结构化事件，包含摘要、证据列表和指标。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;按需读取结果：&lt;/strong&gt; 大型对话日志使用 &lt;code&gt;var_handle&lt;/code&gt; 引用，通过 &lt;code&gt;handle_read&lt;/code&gt; 配合切片、范围查询或 JSONPath 投影按需读取。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;典型用法示例：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在对话框中让 AI 并行分析多个模块
分析这个项目的所有模块，为每个模块启动一个子智能体并行工作，最后汇总报告
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;键盘快捷键&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;快捷键&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Tab&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自动补全 &lt;code&gt;/&lt;/code&gt; 或 &lt;code&gt;@&lt;/code&gt;；或队列草稿 / 切换模式（视上下文）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Shift+Tab&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;循环切换推理强度：关闭 → 高 → 最大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打开可搜索的帮助面板&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Esc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;返回 / 关闭对话框&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl+K&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;命令面板&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl+R&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;恢复历史会话&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Alt+R&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;搜索历史 / 恢复草稿&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl+S&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;暂存当前草稿&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;↑&lt;/code&gt;（输入框开头）&lt;/td&gt;
&lt;td&gt;移除上一行附件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::note
完整快捷键列表可在项目的 &lt;code&gt;docs/KEYBINDINGS.md&lt;/code&gt; 查看，或按 &lt;code&gt;F1&lt;/code&gt; 在应用内搜索。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;LSP 诊断集成&lt;/h2&gt;
&lt;p&gt;每次文件编辑后，DeepSeek-TUI 自动调用对应语言服务器提供内联错误/警告反馈：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;语言&lt;/th&gt;
&lt;th&gt;LSP 服务器&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rust-analyzer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pyright&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript / JavaScript&lt;/td&gt;
&lt;td&gt;&lt;code&gt;typescript-language-server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gopls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C / C++&lt;/td&gt;
&lt;td&gt;&lt;code&gt;clangd&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;AI 会读取诊断信息并自动修复，形成&quot;编辑 → 检查 → 修复&quot;的闭环。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;会话持久化与回滚&lt;/h2&gt;
&lt;p&gt;DeepSeek-TUI 通过旁路 Git 记录实现会话快照：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 恢复上次会话
deepseek   # 然后按 Ctrl+R 选择历史会话

# 查看会话历史
deepseek sessions list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;长时间任务中途断开后，重新启动并恢复会话，AI 会从中断点继续执行。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Skills 系统&lt;/h2&gt;
&lt;p&gt;Skills 是可组合的指令包，可从 GitHub 安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装内置 Skill
deepseek skills install &amp;lt;skill-name&amp;gt;

# 从 GitHub 安装
deepseek skills install github:username/repo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Skills 让你为特定项目或工作流定制 AI 行为，例如代码审查规范、提交信息格式等。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;价格参考&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模型&lt;/th&gt;
&lt;th&gt;上下文&lt;/th&gt;
&lt;th&gt;输入（缓存命中）&lt;/th&gt;
&lt;th&gt;输入（缓存未命中）&lt;/th&gt;
&lt;th&gt;输出&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;deepseek-v4-pro&lt;/td&gt;
&lt;td&gt;100 万 token&lt;/td&gt;
&lt;td&gt;$0.003625/1M*&lt;/td&gt;
&lt;td&gt;$0.435/1M*&lt;/td&gt;
&lt;td&gt;$0.87/1M*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;deepseek-v4-flash&lt;/td&gt;
&lt;td&gt;100 万 token&lt;/td&gt;
&lt;td&gt;$0.0028/1M&lt;/td&gt;
&lt;td&gt;$0.14/1M&lt;/td&gt;
&lt;td&gt;$0.28/1M&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;* Pro 价格为限时 75% 折扣，有效期至 2026 年 5 月 31 日。&lt;/p&gt;
&lt;p&gt;DeepSeek-TUI 实时显示每轮对话的 Token 消耗和费用，并统计缓存命中/未命中情况，帮助控制成本。&lt;/p&gt;
&lt;p&gt;:::tip[降低成本的技巧]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;--model auto&lt;/code&gt; 让简单任务自动切换到 Flash 模型&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;@&lt;/code&gt; 精确附加相关文件，避免传入不必要的上下文&lt;/li&gt;
&lt;li&gt;利用前缀缓存：相同前缀的对话可大幅降低输入 Token 费用
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;常用工作流示例&lt;/h2&gt;
&lt;h3&gt;理解新项目&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;deepseek --plan
&amp;gt; @./ 帮我分析这个项目的整体架构，生成一份架构文档
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;修复 Bug&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;deepseek
&amp;gt; 运行测试套件，找出失败的测试并修复对应的 Bug
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;代码重构&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;deepseek --yolo
&amp;gt; 将 src/ 目录下所有 JavaScript 文件迁移到 TypeScript，保持逻辑不变
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;并行分析&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;deepseek
&amp;gt; 为每个子目录启动一个子智能体，并行分析代码质量，最后汇总评分报告
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>CLIProxyAPI：将 AI CLI 工具统一转换为标准 API 服务</title><link>https://jk.sb/posts/cli-proxy-api/</link><guid isPermaLink="true">https://jk.sb/posts/cli-proxy-api/</guid><description>详细介绍 CLIProxyAPI 的安装、配置、多账号管理、API 调用、客户端接入等全流程，一个代理统一所有 AI 编程工具</description><pubDate>Wed, 22 Apr 2026 02:04:04 GMT</pubDate><content:encoded>&lt;p&gt;CLIProxyAPI 是一个将 Gemini CLI、Claude Code、ChatGPT Codex、Grok Build、Antigravity 等 AI CLI 工具包装成 OpenAI / Gemini / Claude / Codex 兼容 API 服务的代理层，让你通过统一的标准 API 接口免费调用这些模型。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;router-for-me/CLIProxyAPI&quot;}&lt;/p&gt;
&lt;h2&gt;核心概念&lt;/h2&gt;
&lt;p&gt;CLIProxyAPI 本质上是一个中间层代理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;你的客户端 (Cursor / NextChat / Python SDK / curl)
        ↓  标准 API 请求 (OpenAI / Claude / Gemini 格式)
   CLIProxyAPI  (8317 端口)
        ↓  调用本地/远程 CLI 工具
Gemini CLI / Claude Code / Codex / Grok Build
        ↓  OAuth 免费额度
     云端 AI 模型
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;支持的 CLI 后端：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CLI 工具&lt;/th&gt;
&lt;th&gt;对应模型&lt;/th&gt;
&lt;th&gt;免费额度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gemini CLI&lt;/td&gt;
&lt;td&gt;Gemini 2.5 Pro / Flash&lt;/td&gt;
&lt;td&gt;每日大量免费请求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Claude Sonnet / Opus&lt;/td&gt;
&lt;td&gt;按月计费账户&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ChatGPT Codex&lt;/td&gt;
&lt;td&gt;GPT-4o / o3&lt;/td&gt;
&lt;td&gt;Plus 会员额度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grok Build&lt;/td&gt;
&lt;td&gt;Grok 3 / 4&lt;/td&gt;
&lt;td&gt;xAI 免费额度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Antigravity&lt;/td&gt;
&lt;td&gt;多模型&lt;/td&gt;
&lt;td&gt;自定义&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;支持的 API 协议：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI Chat Completions (&lt;code&gt;/v1/chat/completions&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;OpenAI Responses API (&lt;code&gt;/v1/responses&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Anthropic Messages (&lt;code&gt;/v1/messages&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Google Gemini (&lt;code&gt;/v1beta/models/:model/generateContent&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip[核心价值]
通过一个本地/服务器服务，用标准 API 接口调用多个免费 AI 额度，Cursor、NextChat、OpenClaw 等工具无缝接入。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;h3&gt;方式一：二进制文件（推荐新手）&lt;/h3&gt;
&lt;p&gt;前往 &lt;a href=&quot;https://github.com/router-for-me/CLIProxyAPI/releases&quot;&gt;Releases 页面&lt;/a&gt; 下载对应系统的压缩包，解压后直接运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linux / macOS：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 下载（以 Linux amd64 为例，请替换为最新版本号）
wget https://github.com/router-for-me/CLIProxyAPI/releases/latest/download/CLIProxyAPI-linux-amd64.tar.gz
tar -xzf CLIProxyAPI-linux-amd64.tar.gz
chmod +x cliproxyapi

# 初始化默认配置
./cliproxyapi init

# 启动服务
./cliproxyapi start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;macOS（Homebrew）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;brew tap router-for-me/tap
brew install cliproxyapi
cliproxyapi init &amp;amp;&amp;amp; cliproxyapi start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Windows（PowerShell）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 下载 windows-amd64.zip 后解压，在目录内执行
.\cliproxyapi.exe init
.\cliproxyapi.exe start
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方式二：Docker（推荐服务器部署）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 创建工作目录
mkdir -p ~/cliproxyapi/{auths,logs}
cd ~/cliproxyapi

# 下载示例配置
curl -O https://raw.githubusercontent.com/router-for-me/CLIProxyAPI/main/config.example.yaml
cp config.example.yaml config.yaml

# 拉取并启动
docker run -d \
  --name cliproxyapi \
  --restart unless-stopped \
  -p 8317:8317 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -v $(pwd)/auths:/app/auths \
  -v $(pwd)/logs:/app/logs \
  ghcr.io/router-for-me/cliproxyapi:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方式三：Docker Compose（推荐生产环境）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;services:
  cliproxyapi:
    image: ghcr.io/router-for-me/cliproxyapi:latest
    container_name: cliproxyapi
    restart: unless-stopped
    ports:
      - &quot;8317:8317&quot;
    volumes:
      - ./config.yaml:/app/config.yaml
      - ./auths:/app/auths
      - ./logs:/app/logs
    environment:
      - TZ=Asia/Shanghai
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;配置文件详解&lt;/h2&gt;
&lt;p&gt;CLIProxyAPI 通过 &lt;code&gt;config.yaml&lt;/code&gt; 管理所有配置，&lt;strong&gt;支持热重载&lt;/strong&gt;，修改后即时生效无需重启。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ── 服务器基础配置 ──────────────────────────────
server:
  host: &quot;&quot;          # 留空表示监听所有网卡（0.0.0.0）
  port: 8317        # 服务端口，默认 8317
  # tls:            # 可选：开启 HTTPS
  #   cert: /path/to/cert.pem
  #   key: /path/to/key.pem

# ── 远程管理 / WebUI ──────────────────────────────
remote-management:
  allow-remote: true      # 是否允许远程访问管理接口
  secret-key: &quot;your-strong-password&quot;  # WebUI 登录密码，务必修改！

# ── 认证文件目录 ──────────────────────────────────
auth-dir: &quot;./auths&quot;       # 存放 OAuth 认证文件的目录

# ── 各 CLI 后端配置 ───────────────────────────────
providers:

  # Gemini CLI
  gemini:
    enabled: true
    api-keys:             # 客户端调用时使用的 API Key（自定义，随意填写）
      - &quot;sk-gemini-your-key-1&quot;
      - &quot;sk-gemini-your-key-2&quot;
    load-balance: round-robin   # round-robin | fill-first

  # Claude Code
  claude:
    enabled: true
    api-keys:
      - &quot;sk-claude-your-key-1&quot;
    load-balance: round-robin

  # ChatGPT Codex
  codex:
    enabled: false
    api-keys:
      - &quot;sk-codex-your-key-1&quot;

  # Grok Build
  grok:
    enabled: false
    api-keys:
      - &quot;sk-grok-your-key-1&quot;

# ── 全局 API Key（可同时访问所有后端）────────────
global-api-keys:
  - &quot;sk-global-master-key&quot;

# ── 日志配置 ──────────────────────────────────────
log:
  level: info             # debug | info | warn | error
  dir: &quot;./logs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning[安全提示]
&lt;code&gt;secret-key&lt;/code&gt; 是 WebUI 的登录密码，生产环境务必设置强密码。&lt;code&gt;api-keys&lt;/code&gt; 是自定义的认证凭据，客户端连接时填写这里配置的值。
:::&lt;/p&gt;
&lt;h3&gt;负载均衡策略&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;策略&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;round-robin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;轮询均匀分配到所有账号&lt;/td&gt;
&lt;td&gt;多号薅配额，最大化吞吐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fill-first&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;优先压满第一个账号，满了才切换&lt;/td&gt;
&lt;td&gt;主力号 + 备用号组合&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;CLI 认证授权&lt;/h2&gt;
&lt;h3&gt;Gemini CLI 授权&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 本地安装 Gemini CLI（需要 Node.js 18+）
npm install -g @google/gemini-cli

# 触发 OAuth 授权（会打开浏览器）
gemini auth login

# 授权成功后，将认证文件复制到 auths 目录
# CLIProxyAPI 会自动读取该目录下的认证信息
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::note
Gemini 个人 Google 账号每天有大量免费请求额度（Gemini 2.5 Pro 约 1000 次/天），特别适合轻量使用场景。
:::&lt;/p&gt;
&lt;h3&gt;Claude Code 授权&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装 Claude Code（需要 Node.js 18+）
npm install -g @anthropic-ai/claude-code

# 触发 OAuth 授权
claude auth login

# 会在浏览器中完成 Anthropic 账号授权
# 授权后认证文件默认在 ~/.claude/ 目录
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
Claude Code 使用 Claude Max 订阅的额度，适合需要更高质量代码生成的场景。
:::&lt;/p&gt;
&lt;h3&gt;ChatGPT Codex 授权&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装 Codex CLI
npm install -g @openai/codex

# 登录 OpenAI 账号
codex auth login
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Grok Build 授权&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装 Grok Build
npm install -g @xai/grok-build

# 使用 xAI 账号授权
grok auth login
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;多账号管理&lt;/h3&gt;
&lt;p&gt;CLIProxyAPI 支持同一个后端绑定多个账号（认证文件），实现轮询负载均衡：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;auths/
├── gemini-account1.json
├── gemini-account2.json
├── gemini-account3.json
├── claude-account1.json
└── codex-account1.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;每个认证文件对应一个账号，CLIProxyAPI 按配置的策略自动分配请求。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;WebUI 管理界面&lt;/h2&gt;
&lt;p&gt;启动服务后，访问 &lt;code&gt;http://服务器IP:8317/management.html&lt;/code&gt; 进入后台管理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;账号状态&lt;/strong&gt;：实时查看各 CLI 账号的认证状态和剩余配额&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置管理&lt;/strong&gt;：在线修改 &lt;code&gt;config.yaml&lt;/code&gt;，热重载即时生效&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志查看&lt;/strong&gt;：实时查看请求日志和错误信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上传认证&lt;/strong&gt;：直接上传 OAuth 认证文件，无需手动拷贝&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;管理页面地址: http://YOUR_SERVER:8317/management.html
密码: config.yaml 中的 secret-key
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;API 调用示例&lt;/h2&gt;
&lt;p&gt;CLIProxyAPI 服务默认在 &lt;code&gt;http://localhost:8317&lt;/code&gt; 监听。&lt;/p&gt;
&lt;h3&gt;cURL 调用&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;OpenAI 格式（Chat Completions）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl http://localhost:8317/v1/chat/completions \
  -H &quot;Content-Type: application/json&quot; \
  -H &quot;Authorization: Bearer sk-gemini-your-key-1&quot; \
  -d &apos;{
    &quot;model&quot;: &quot;gemini-2.5-pro&quot;,
    &quot;messages&quot;: [
      {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;你好，介绍一下你自己&quot;}
    ]
  }&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Anthropic 格式（Messages）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl http://localhost:8317/v1/messages \
  -H &quot;Content-Type: application/json&quot; \
  -H &quot;x-api-key: sk-claude-your-key-1&quot; \
  -H &quot;anthropic-version: 2023-06-01&quot; \
  -d &apos;{
    &quot;model&quot;: &quot;claude-sonnet-4-5&quot;,
    &quot;max_tokens&quot;: 1024,
    &quot;messages&quot;: [
      {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;写一个快速排序算法&quot;}
    ]
  }&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;流式输出（Streaming）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl http://localhost:8317/v1/chat/completions \
  -H &quot;Content-Type: application/json&quot; \
  -H &quot;Authorization: Bearer sk-gemini-your-key-1&quot; \
  -d &apos;{
    &quot;model&quot;: &quot;gemini-2.5-pro&quot;,
    &quot;stream&quot;: true,
    &quot;messages&quot;: [
      {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;写一篇关于量子计算的科普文章&quot;}
    ]
  }&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Python SDK 调用&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;from openai import OpenAI

# 指向本地 CLIProxyAPI 服务
client = OpenAI(
    base_url=&quot;http://localhost:8317/v1&quot;,
    api_key=&quot;sk-gemini-your-key-1&quot;
)

# 普通调用
response = client.chat.completions.create(
    model=&quot;gemini-2.5-pro&quot;,
    messages=[
        {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;解释一下什么是 RAG 技术&quot;}
    ]
)
print(response.choices[0].message.content)

# 流式调用
stream = client.chat.completions.create(
    model=&quot;gemini-2.5-pro&quot;,
    messages=[{&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;写一个 Python 爬虫示例&quot;}],
    stream=True
)
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end=&quot;&quot;, flush=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;import anthropic

# 使用 Anthropic SDK 调用 Claude 后端
client = anthropic.Anthropic(
    base_url=&quot;http://localhost:8317&quot;,
    api_key=&quot;sk-claude-your-key-1&quot;
)

message = client.messages.create(
    model=&quot;claude-sonnet-4-5&quot;,
    max_tokens=1024,
    messages=[
        {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;用 Go 语言实现一个并发安全的缓存&quot;}
    ]
)
print(message.content[0].text)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;查询可用模型&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 列出所有可用模型
curl http://localhost:8317/v1/models \
  -H &quot;Authorization: Bearer sk-gemini-your-key-1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;接入主流客户端&lt;/h2&gt;
&lt;h3&gt;Cursor&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;打开 Cursor → Settings → Models&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base URL&lt;/strong&gt;: &lt;code&gt;http://localhost:8317/v1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Key&lt;/strong&gt;: 填入 &lt;code&gt;config.yaml&lt;/code&gt; 中配置的任意 &lt;code&gt;api-keys&lt;/code&gt; 值&lt;/li&gt;
&lt;li&gt;选择模型（如 &lt;code&gt;gemini-2.5-pro&lt;/code&gt;）后保存&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;:::tip
如果 Cursor 和 CLIProxyAPI 在同一台机器，使用 &lt;code&gt;http://localhost:8317/v1&lt;/code&gt;；如果是远程服务器，替换为服务器 IP。
:::&lt;/p&gt;
&lt;h3&gt;NextChat / ChatGPT-Next-Web&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;打开 NextChat 设置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自定义接口&lt;/strong&gt;: 勾选&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接口地址&lt;/strong&gt;: &lt;code&gt;http://localhost:8317&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Key&lt;/strong&gt;: 填入对应的 &lt;code&gt;api-keys&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自定义模型名称&lt;/strong&gt;: &lt;code&gt;gemini-2.5-pro,claude-sonnet-4-5&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;OpenClaw&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;设置 → Provider → 自定义
Base URL: http://localhost:8317
API Type: openai-compatible
API Key: sk-global-master-key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::caution[注意路径]
OpenClaw 接入时 Base URL &lt;strong&gt;不要带&lt;/strong&gt; &lt;code&gt;/v1&lt;/code&gt; 后缀，因为 OpenClaw 会自动追加路径，否则会出现 &lt;code&gt;/v1/v1/messages&lt;/code&gt; 404 错误。
:::&lt;/p&gt;
&lt;h3&gt;Open WebUI&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 在 Open WebUI 的环境变量中设置
OPENAI_API_BASE_URL=http://localhost:8317/v1
OPENAI_API_KEY=sk-gemini-your-key-1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Continue（VSCode 插件）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;models&quot;: [
    {
      &quot;title&quot;: &quot;Gemini 2.5 Pro (Free)&quot;,
      &quot;provider&quot;: &quot;openai&quot;,
      &quot;model&quot;: &quot;gemini-2.5-pro&quot;,
      &quot;apiBase&quot;: &quot;http://localhost:8317/v1&quot;,
      &quot;apiKey&quot;: &quot;sk-gemini-your-key-1&quot;
    },
    {
      &quot;title&quot;: &quot;Claude Sonnet&quot;,
      &quot;provider&quot;: &quot;anthropic&quot;,
      &quot;model&quot;: &quot;claude-sonnet-4-5&quot;,
      &quot;apiBase&quot;: &quot;http://localhost:8317&quot;,
      &quot;apiKey&quot;: &quot;sk-claude-your-key-1&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;Nginx 反向代理（生产环境）&lt;/h2&gt;
&lt;p&gt;在服务器部署时，建议套一层 Nginx + HTTPS：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate     /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    location / {
        proxy_pass         http://127.0.0.1:8317;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection &quot;upgrade&quot;;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_read_timeout 300s;   # 流式响应需要较长超时
        proxy_buffering    off;    # 关闭缓冲，确保流式传输即时转发
    }
}

server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$host$request_uri;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 申请证书（Certbot）
certbot --nginx -d your-domain.com

# 重载 Nginx
nginx -s reload
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;常见问题&lt;/h2&gt;
&lt;h3&gt;认证失效怎么办？&lt;/h3&gt;
&lt;p&gt;CLI 工具的 OAuth Token 有有效期，过期后需要重新授权：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 重新授权 Gemini
gemini auth login

# 重新授权 Claude Code  
claude auth login

# 将新生成的认证文件复制到 auths 目录
# CLIProxyAPI 会热重载自动识别
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;如何查看请求日志？&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Docker 部署查看日志
docker logs -f cliproxyapi

# 或访问 WebUI 管理页面的日志面板
http://YOUR_SERVER:8317/management.html
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;模型名称不对？&lt;/h3&gt;
&lt;p&gt;CLIProxyAPI 支持模型名称映射，可以在 &lt;code&gt;config.yaml&lt;/code&gt; 中自定义：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;model-mapping:
  &quot;gpt-4o&quot;: &quot;gemini-2.5-pro&quot;       # 把 gpt-4o 请求转发到 Gemini
  &quot;claude-3-5-sonnet&quot;: &quot;claude-sonnet-4-5&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;端口被占用？&lt;/h3&gt;
&lt;p&gt;修改 &lt;code&gt;config.yaml&lt;/code&gt; 中的 &lt;code&gt;port&lt;/code&gt; 字段，或 Docker 部署时修改端口映射：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -p 9000:8317 ...  # 映射到宿主机 9000 端口
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;流式响应中断？&lt;/h3&gt;
&lt;p&gt;检查 Nginx 配置中是否设置了 &lt;code&gt;proxy_buffering off&lt;/code&gt; 和足够长的 &lt;code&gt;proxy_read_timeout&lt;/code&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;安全建议&lt;/h2&gt;
&lt;p&gt;:::warning[生产环境清单]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;secret-key&lt;/code&gt; 设置为强密码（16 位以上随机字符）&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;api-keys&lt;/code&gt; 不要使用简单字符串&lt;/li&gt;
&lt;li&gt;[ ] 服务器防火墙只开放必要端口（建议套 Nginx + HTTPS，不直接暴露 8317）&lt;/li&gt;
&lt;li&gt;[ ] 定期轮换 &lt;code&gt;api-keys&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;allow-remote: false&lt;/code&gt; 如果不需要远程访问管理接口
:::&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;相关项目&lt;/h2&gt;
&lt;p&gt;::github{repo=&quot;router-for-me/Cli-Proxy-API-Management-Center&quot;}&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;router-for-me/EasyCLI&quot;}&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;justlovemaki/AIClient2API&quot;}&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;CLIProxyAPI 的&lt;a href=&quot;https://help.router-for.me/cn/&quot;&gt;官方文档&lt;/a&gt;有更多高级配置细节，包括配额限制、安全策略、Webhook 等企业级功能。&lt;/p&gt;
</content:encoded></item><item><title>Telegram 双向机器人：验证码版部署</title><link>https://jk.sb/posts/banad-tgbot/</link><guid isPermaLink="true">https://jk.sb/posts/banad-tgbot/</guid><description>通过验证码屏蔽垃圾广告的双向私信机器人！</description><pubDate>Fri, 14 Nov 2025 23:40:01 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;本周双向私信机器人被轰炸，我一天收到了上千条垃圾广告。故拿AI搓了一个&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Ham0mer/TGbot&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Telegram 消息转发机器人&lt;/h1&gt;
&lt;p&gt;具有图片验证码和用户管理功能的 Telegram 消息转发机器人。&lt;/p&gt;
&lt;h2&gt;✨ 特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;🔐 图片验证码防垃圾消息&lt;/li&gt;
&lt;li&gt;💬 主人回复功能（直接回复转发消息）&lt;/li&gt;
&lt;li&gt;🚫 用户拉黑/解除拉黑（&lt;code&gt;/block&lt;/code&gt; 和 &lt;code&gt;/unblock&lt;/code&gt; 命令）&lt;/li&gt;
&lt;li&gt;☁️ Supabase 云数据库（数据永不丢失）&lt;/li&gt;
&lt;li&gt;🐳 Docker 支持&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;🚀 快速开始&lt;/h1&gt;
&lt;p&gt;先配置数据库&lt;/p&gt;
&lt;h2&gt;配置 Supabase 数据库&lt;/h2&gt;
&lt;p&gt;在 &lt;a href=&quot;https://supabase.com&quot;&gt;Supabase&lt;/a&gt; 创建项目，然后在 SQL Editor 中执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 消息映射表
CREATE TABLE message_mappings (
  id BIGSERIAL PRIMARY KEY,
  forwarded_message_id BIGINT UNIQUE NOT NULL,
  user_id BIGINT NOT NULL,
  username TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 已验证用户表
CREATE TABLE verified_users (
  id BIGSERIAL PRIMARY KEY,
  user_id BIGINT UNIQUE NOT NULL,
  username TEXT,
  verified_at TIMESTAMPTZ DEFAULT NOW()
);

-- 待验证用户表
CREATE TABLE pending_verifications (
  id BIGSERIAL PRIMARY KEY,
  user_id BIGINT UNIQUE NOT NULL,
  code TEXT NOT NULL,
  attempts INTEGER DEFAULT 0,
  expires_at TIMESTAMPTZ NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 拉黑用户表
CREATE TABLE blocked_users (
  id BIGSERIAL PRIMARY KEY,
  user_id BIGINT UNIQUE NOT NULL,
  blocked_at TIMESTAMPTZ DEFAULT NOW()
);

-- 创建索引
CREATE INDEX idx_message_mappings_forwarded_id ON message_mappings(forwarded_message_id);
CREATE INDEX idx_verified_users_user_id ON verified_users(user_id);
CREATE INDEX idx_pending_verifications_user_id ON pending_verifications(user_id);
CREATE INDEX idx_blocked_users_user_id ON blocked_users(user_id);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🐳 Docker 部署&lt;/h2&gt;
&lt;h3&gt;方法一：直接运行&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;docker run -d \
  --name telegram-bot \
  --restart unless-stopped \
  -e BOT_TOKEN=&quot;你的Bot_Token&quot; \
  -e OWNER_ID=&quot;你的用户ID&quot; \
  -e SUPABASE_URL=&quot;你的Supabase_URL&quot; \
  -e SUPABASE_KEY=&quot;你的Supabase_Key&quot; \
  -v $(pwd)/logs:/app/logs \
  ghcr.io/ham0mer/tgbot:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方法二：使用 docker-compose&lt;/h3&gt;
&lt;p&gt;修改 &lt;code&gt;docker-compose.yml&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  telegram-bot:
    image: ghcr.io/ham0mer/tgbot:latest
    container_name: telegram-bot
    restart: unless-stopped
    environment:
      - BOT_TOKEN=${BOT_TOKEN}
      - OWNER_ID=${OWNER_ID}
      - SUPABASE_URL=${SUPABASE_URL}
      - SUPABASE_KEY=${SUPABASE_KEY}
      - LOG_LEVEL=info
    volumes:
      - ./logs:/app/logs
    logging:
      driver: &quot;json-file&quot;
      options:
        max-size: &quot;10m&quot;
        max-file: &quot;3&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后启动：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;启动并查看日志&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d &amp;amp;&amp;amp; docker compose logs -f
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;🔄 更新镜像&lt;/h2&gt;
&lt;h3&gt;更新到最新版本&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;docker compose pull &amp;amp;&amp;amp; docker compose down &amp;amp;&amp;amp; docker compose up -d &amp;amp;&amp;amp; docker compose logs -f
docker image prune
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;使用说明&lt;/h1&gt;
&lt;h2&gt;用户使用&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;发送 &lt;code&gt;/start&lt;/code&gt; 获取验证码&lt;/li&gt;
&lt;li&gt;回复验证码完成验证&lt;/li&gt;
&lt;li&gt;验证后可正常发送消息&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;主人功能&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;回复用户&lt;/strong&gt;：直接回复转发的消息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拉黑用户&lt;/strong&gt;：回复用户消息并发送 &lt;code&gt;/block&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解除拉黑&lt;/strong&gt;：回复用户消息并发送 &lt;code&gt;/unblock&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>generate_204：网络连通性检测服务汇总</title><link>https://jk.sb/posts/generate-204/</link><guid isPermaLink="true">https://jk.sb/posts/generate-204/</guid><description>什么是 generate_204？原理是什么？国内外主流 generate_204 服务地址汇总，含国内厂商（小米、华为、Vivo）及 Google、Apple、Cloudflare 等。</description><pubDate>Mon, 27 Oct 2025 13:19:07 GMT</pubDate><content:encoded>&lt;h2&gt;什么是 generate_204&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;generate_204&lt;/code&gt; 是一种用于检测网络联通性的轻量 HTTP 接口。设备连接到 Wi-Fi 后，操作系统会自动向预设 URL 发送 HTTP 请求，根据返回的状态码判断当前网络状态：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;返回 &lt;strong&gt;204 No Content&lt;/strong&gt; 或 &lt;strong&gt;200 OK&lt;/strong&gt; → 网络畅通，可正常上网&lt;/li&gt;
&lt;li&gt;返回 &lt;strong&gt;302 重定向&lt;/strong&gt; → 可能处于需要认证的 Captive Portal（如酒店/机场 Wi-Fi 登录页）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求超时 / 无响应&lt;/strong&gt; → 网络不通或被封锁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::note
&quot;204&quot; 的含义是 HTTP 状态码 No Content（无内容），服务器返回空响应体，流量消耗极少，非常适合作为周期性心跳检测。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;工作原理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;设备连接 Wi-Fi
    ↓
发送 HTTP GET → http://www.gstatic.com/generate_204
    ↓
┌───────────────────────────────────────┐
│  返回 204   →  网络正常，无感知通过   │
│  返回 302   →  弹出 Portal 登录界面   │
│  超时/其他  →  显示&quot;无互联网访问&quot;     │
└───────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;各主流操作系统使用不同的检测地址：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;系统 / 浏览器&lt;/th&gt;
&lt;th&gt;使用的检测 URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Android (AOSP)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connectivitycheck.gstatic.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chrome / ChromeOS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.gstatic.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft Edge&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://edge-http.microsoft.com/captiveportal/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows (NCSI)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.msftconnecttest.com/connecttest.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;macOS / iOS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://captive.apple.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firefox&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://detectportal.firefox.com/canonical.html&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIUI (小米)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connect.rom.miui.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HarmonyOS (华为)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connectivitycheck.platform.hicloud.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;服务地址汇总&lt;/h2&gt;
&lt;p&gt;:::tip
下表中的&quot;体验评分&quot;为粗略延迟测试（满分 10 分），实际结果因地区和时段而异，仅供参考。
:::&lt;/p&gt;
&lt;h3&gt;国际服务&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;服务提供者&lt;/th&gt;
&lt;th&gt;链接&lt;/th&gt;
&lt;th&gt;大陆体验&lt;/th&gt;
&lt;th&gt;境外体验&lt;/th&gt;
&lt;th&gt;HTTP / HTTPS 响应码&lt;/th&gt;
&lt;th&gt;IP 版本&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.gstatic.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.google.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connectivitycheck.gstatic.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connectivitycheck.android.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://clients3.google.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://play.googleapis.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.google-analytics.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apple&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://captive.apple.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;200 / 200&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apple 🔥&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.apple.com/library/test/success.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;200 / 200&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.msftconnecttest.com/connecttest.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;200 / error&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://edge-http.microsoft.com/captiveportal/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.msftncsi.com/ncsi.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;200 / 200&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare 🔥&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://cp.cloudflare.com/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firefox&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://detectportal.firefox.com/success.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;200 / 200&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firefox&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://detectportal.firefox.com/canonical.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;200 / 200&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GNOME&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://nmcheck.gnome.org/check_network_status.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;200 / 200&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;V2EX&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.v2ex.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;204 / 301&lt;/td&gt;
&lt;td&gt;4+6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;国内服务&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;服务提供者&lt;/th&gt;
&lt;th&gt;链接&lt;/th&gt;
&lt;th&gt;大陆体验&lt;/th&gt;
&lt;th&gt;境外体验&lt;/th&gt;
&lt;th&gt;HTTP / HTTPS 响应码&lt;/th&gt;
&lt;th&gt;IP 版本&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;小米 / MIUI 🔥&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connect.rom.miui.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;华为 / HiCloud&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connectivitycheck.platform.hicloud.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vivo&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://wifi.vivo.com.cn/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;204 / 204&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::warning
国内服务（小米、华为、Vivo）在境外网络环境下延迟较高甚至不可达，不建议在海外服务器上使用。反之，Google 系地址在大陆网络中通常被封锁，大陆用户推荐使用 Apple、Cloudflare 或国内厂商地址。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;常见使用场景&lt;/h2&gt;
&lt;h3&gt;1. 代理软件联通性测试&lt;/h3&gt;
&lt;p&gt;主流代理工具（如 Clash、sing-box）的延迟测试（URL Test）默认使用 &lt;code&gt;http://www.gstatic.com/generate_204&lt;/code&gt;，可根据需要替换为延迟更低的地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Clash / Mihomo 示例
url-test:
  url: &quot;http://cp.cloudflare.com/&quot;   # 或使用 apple.com/library/test/success.html
  interval: 300
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 替换 Android 默认检测地址（去除感叹号）&lt;/h3&gt;
&lt;p&gt;在 Android 设备（需 Root 或 ADB）中修改检测地址，可将 Google 服务替换为国内可访问的地址，解决 Wi-Fi 图标感叹号问题：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 通过 ADB 修改（Android 7+）
adb shell settings put global captive_portal_http_url &quot;http://connect.rom.miui.com/generate_204&quot;
adb shell settings put global captive_portal_https_url &quot;https://connect.rom.miui.com/generate_204&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::caution
修改系统检测地址可能影响 Captive Portal 的自动弹出功能（如机场/酒店 Wi-Fi 登录页），请根据实际需求谨慎操作。
:::&lt;/p&gt;
&lt;h3&gt;3. 自建检测服务&lt;/h3&gt;
&lt;p&gt;可以用 Nginx 快速搭建私有 generate_204 端点，适合企业内网或私有部署场景：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;location /generate_204 {
    return 204;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;选择建议&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;使用环境&lt;/th&gt;
&lt;th&gt;推荐地址&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;大陆用户，追求速度&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.apple.com/library/test/success.html&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;大陆用户，Android 原生&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://connect.rom.miui.com/generate_204&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;境外服务器 / 代理测速&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://cp.cloudflare.com/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;需要严格 204 状态码&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://www.gstatic.com/generate_204&lt;/code&gt;（境外）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全球通用，兼容性佳&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://cp.cloudflare.com/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;体验评分仅为粗略延迟测试，大概率与实际不符，仅作参考。&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>Remnawave 节点管理面板：落地篇</title><link>https://jk.sb/posts/remna-install-3/</link><guid isPermaLink="true">https://jk.sb/posts/remna-install-3/</guid><description>落地篇是指在Remnawave节点管理面板中配置落地节点，用于转发流量。</description><pubDate>Thu, 23 Oct 2025 18:57:09 GMT</pubDate><content:encoded>&lt;p&gt;:::info
落地篇是指在Remna节点管理面板中配置落地节点，用于转发流量。
:::&lt;/p&gt;
&lt;h2&gt;搭建落地节点&lt;/h2&gt;
&lt;p&gt;本人习惯使用&lt;a href=&quot;https://github.com/MHSanaei/3x-ui/blob/main/README.zh_CN.md&quot;&gt;3xui&lt;/a&gt;搭建落地节点&lt;/p&gt;
&lt;h3&gt;新建socks5入站&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;入站协议：socks&lt;/li&gt;
&lt;li&gt;监听端口：9999  &lt;em&gt;&lt;strong&gt;#随机即可&lt;/strong&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;密码：开启&lt;/li&gt;
&lt;li&gt;用户名：testuser&lt;/li&gt;
&lt;li&gt;密码：testpwd&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./images/1.png&quot; alt=&quot;新建socks5入站&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;快捷获取出站配置&lt;/h3&gt;
&lt;p&gt;左侧导航栏 &lt;code&gt;Xray设置&lt;/code&gt;-&amp;gt;&lt;code&gt;出站规则&lt;/code&gt;-&amp;gt;&lt;code&gt;添加出站&lt;/code&gt; ，这里就有老铁问了，我落地鸡添加什么出站？
其实是利用3xui的工具来获取配置参数，不用快捷工具徒手搓这简直唐的没边了！
&lt;img src=&quot;./images/2.png&quot; alt=&quot;快捷获取出站配置&quot; /&gt;
填入刚刚新建的socks5入站配置参数
&lt;img src=&quot;./images/3.png&quot; alt=&quot;填入刚刚新建的socks5入站配置参数&quot; /&gt;
点击 &lt;code&gt;JSON&lt;/code&gt;选项卡，复制出配置参数
&lt;img src=&quot;./images/4.png&quot; alt=&quot;复制出配置参数&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;tag&quot;: &quot;落地鸡&quot;,
  &quot;protocol&quot;: &quot;socks&quot;,
  &quot;settings&quot;: {
    &quot;servers&quot;: [
      {
        &quot;address&quot;: &quot;落地鸡IP&quot;,
        &quot;port&quot;: 9999,
        &quot;users&quot;: [
          {
            &quot;user&quot;: &quot;testuser&quot;,
            &quot;pass&quot;: &quot;testpwd&quot;
          }
        ]
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里算是完成落地鸡的配置，后面就可以在Remna节点管理面板中配置中转节点了。&lt;/p&gt;
&lt;h2&gt;修改Remna节点配置&lt;/h2&gt;
&lt;p&gt;先进入Xray设置
&lt;img src=&quot;./images/5.png&quot; alt=&quot;Xray设置&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;log&quot;: {
    &quot;loglevel&quot;: &quot;info&quot;
  },
  &quot;inbounds&quot;: [
    {
      &quot;tag&quot;: &quot;test1&quot;,
      &quot;port&quot;: 30004,
      &quot;protocol&quot;: &quot;vless&quot;,
      &quot;settings&quot;: {
        &quot;clients&quot;: [],
        &quot;decryption&quot;: &quot;none&quot;
      },
      &quot;sniffing&quot;: {
        &quot;enabled&quot;: true,
        &quot;destOverride&quot;: [
          &quot;http&quot;,
          &quot;tls&quot;,
          &quot;quic&quot;
        ]
      },
      &quot;streamSettings&quot;: {
        &quot;network&quot;: &quot;tcp&quot;,
        &quot;security&quot;: &quot;reality&quot;,
        &quot;realitySettings&quot;: {
          &quot;dest&quot;: &quot;www.amd.com:443&quot;,
          &quot;show&quot;: false,
          &quot;xver&quot;: 0,
          &quot;spiderX&quot;: &quot;&quot;,
          &quot;shortIds&quot;: [
            &quot;42aeec&quot;,
            &quot;66c8bd6b1002427d&quot;,
            &quot;5a1f&quot;,
            &quot;6c&quot;,
            &quot;adfb6126&quot;,
            &quot;ce557a621e&quot;,
            &quot;5fc062b8b4c2b9&quot;,
            &quot;e4cfaf01e274&quot;
          ],
          &quot;publicKey&quot;: &quot;3FB5YuwJgxCbQurerSwjhXDIHAB_SRdyecd5XLhtwE0&quot;,
          &quot;privateKey&quot;: &quot;m5mIb4EXjqkcfDDHRW_pU7Vz-hehwNgR5Hi2HFCO4S0&quot;,
          &quot;serverNames&quot;: [
            &quot;www.amd.com&quot;
          ]
        }
      }
    }
  ],
  &quot;outbounds&quot;: [
    {
      &quot;tag&quot;: &quot;落地鸡&quot;,
      &quot;protocol&quot;: &quot;socks&quot;,
      &quot;settings&quot;: {
        &quot;servers&quot;: [
          {
            &quot;address&quot;: &quot;落地鸡IP&quot;,
            &quot;port&quot;: 9999,
            &quot;users&quot;: [
              {
                &quot;user&quot;: &quot;testuser&quot;,
                &quot;pass&quot;: &quot;testpwd&quot;
              }
            ]
          }
        ]
      }
    },
    {
      &quot;tag&quot;: &quot;DIRECT&quot;,
      &quot;protocol&quot;: &quot;freedom&quot;
    },
    {
      &quot;tag&quot;: &quot;BLOCK&quot;,
      &quot;protocol&quot;: &quot;blackhole&quot;
    }
  ],
  &quot;routing&quot;: {
    &quot;rules&quot;: [
      {
        &quot;type&quot;: &quot;field&quot;,
        &quot;inboundTag&quot;: [
          &quot;test1&quot;,
        ],
        &quot;outboundTag&quot;: &quot;落地鸡&quot;
      },
      {
        &quot;ip&quot;: [
          &quot;geoip:private&quot;
        ],
        &quot;type&quot;: &quot;field&quot;,
        &quot;outboundTag&quot;: &quot;BLOCK&quot;
      },
      {
        &quot;type&quot;: &quot;field&quot;,
        &quot;domain&quot;: [
          &quot;geosite:private&quot;
        ],
        &quot;outboundTag&quot;: &quot;BLOCK&quot;
      },
      {
        &quot;type&quot;: &quot;field&quot;,
        &quot;protocol&quot;: [
          &quot;bittorrent&quot;
        ],
        &quot;outboundTag&quot;: &quot;BLOCK&quot;
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;点击下方&lt;code&gt;保存&lt;/code&gt;，开始奔放吧！&lt;/p&gt;
</content:encoded></item><item><title>Remnawave 节点管理面板：面板篇</title><link>https://jk.sb/posts/remna-install-1/</link><guid isPermaLink="true">https://jk.sb/posts/remna-install-1/</guid><description>Remnawave节点管理面板Docker部署安装教程</description><pubDate>Sat, 18 Oct 2025 21:37:53 GMT</pubDate><content:encoded>&lt;p&gt;:::tip
Remnawave 是一款功能强大的节点管理面板，可以帮助你管理节点状态、配置、订阅和用户等。
:::&lt;/p&gt;
&lt;p&gt;面板官网：&lt;a href=&quot;https://remna.st/&quot;&gt;https://remna.st/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;安装 Docker&lt;/h2&gt;
&lt;p&gt;如果尚未安装 Docker，使用官方脚本一键安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo curl -fsSL https://get.docker.com | sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第一步 - 下载所需文件&lt;/h2&gt;
&lt;p&gt;创建项目目录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir /opt/remnawave &amp;amp;&amp;amp; cd /opt/remnawave
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下载 &lt;code&gt;docker-compose.yml&lt;/code&gt; 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -o docker-compose.yml https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/docker-compose-prod.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下载 &lt;code&gt;.env&lt;/code&gt; 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -o .env https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/.env.sample
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第二步 - 配置 .env 文件&lt;/h2&gt;
&lt;h3&gt;生成安全密钥&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;JWT_AUTH_SECRET&lt;/code&gt; 和 &lt;code&gt;JWT_API_TOKENS_SECRET&lt;/code&gt; 用于身份验证和相关安全功能，运行以下命令自动生成：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sed -i &quot;s/^JWT_AUTH_SECRET=.*/JWT_AUTH_SECRET=$(openssl rand -hex 64)/&quot; .env &amp;amp;&amp;amp; sed -i &quot;s/^JWT_API_TOKENS_SECRET=.*/JWT_API_TOKENS_SECRET=$(openssl rand -hex 64)/&quot; .env
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;生成随机密码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;sed -i &quot;s/^METRICS_PASS=.*/METRICS_PASS=$(openssl rand -hex 64)/&quot; .env &amp;amp;&amp;amp; sed -i &quot;s/^WEBHOOK_SECRET_HEADER=.*/WEBHOOK_SECRET_HEADER=$(openssl rand -hex 64)/&quot; .env
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;更改 Postgres 密码&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;强烈建议&lt;/strong&gt;修改默认的 Postgres 密码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pw=$(openssl rand -hex 24) &amp;amp;&amp;amp; sed -i &quot;s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$pw/&quot; .env &amp;amp;&amp;amp; sed -i &quot;s|^\(DATABASE_URL=\&quot;postgresql://postgres:\)[^\@]*\(@.*\)|\1$pw\2|&quot; .env
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置域名&lt;/h3&gt;
&lt;p&gt;打开 &lt;code&gt;.env&lt;/code&gt; 文件，更新以下两个变量：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FRONT_END_DOMAIN&lt;/code&gt;：面板的访问域名。例：&lt;code&gt;panel.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SUB_PUBLIC_DOMAIN&lt;/code&gt;：订阅地址，在面板域名后加上 &lt;code&gt;/api/sub&lt;/code&gt;。例：&lt;code&gt;panel.yourdomain.com/api/sub&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip
更多环境变量的说明，请参考&lt;a href=&quot;https://remna.st/docs/install/environment-variables&quot;&gt;官方文档 - Environment Variables&lt;/a&gt;。
:::&lt;/p&gt;
&lt;h2&gt;第三步 - 启动容器&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d &amp;amp;&amp;amp; docker compose logs -f -t
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动后稍等片刻，日志输出正常即表示面板已成功运行。&lt;/p&gt;
&lt;h2&gt;下一步 - 配置反向代理&lt;/h2&gt;
&lt;p&gt;:::danger
&lt;strong&gt;必须配置反向代理才能正常使用 Remnawave 面板。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;请勿将服务直接暴露到公网，Remnawave 各服务应仅绑定到 &lt;code&gt;127.0.0.1&lt;/code&gt;。
:::&lt;/p&gt;
&lt;p&gt;建议使用 1Panel 或 Nginx Proxy Manager 管理反向代理，将 &lt;code&gt;panel.yourdomain.com&lt;/code&gt; 反向代理到本机 &lt;code&gt;3000&lt;/code&gt; 端口。&lt;/p&gt;
</content:encoded></item><item><title>Remnawave 节点管理面板：节点篇</title><link>https://jk.sb/posts/remna-install-2/</link><guid isPermaLink="true">https://jk.sb/posts/remna-install-2/</guid><description>Remnawave节点管理面板Docker部署及节点配置教程</description><pubDate>Sat, 18 Oct 2025 17:16:41 GMT</pubDate><content:encoded>&lt;p&gt;:::note
Remnawave Panel 不包含 Xray-core，因此需要在单独的服务器上安装 Remnawave Node 才能使用完整功能。节点端同样需要先安装 Docker。
:::&lt;/p&gt;
&lt;h2&gt;第一步 - 创建项目目录&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mkdir /opt/remnanode &amp;amp;&amp;amp; cd /opt/remnanode
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第二步 - 在面板添加节点&lt;/h2&gt;
&lt;p&gt;进入面板的 &lt;code&gt;节点&lt;/code&gt; → &lt;code&gt;管理&lt;/code&gt;，点击 &lt;code&gt;+&lt;/code&gt; 按钮添加新节点。&lt;/p&gt;
&lt;p&gt;填写表单时注意 &lt;strong&gt;Node Port&lt;/strong&gt; 字段，这是节点监听面板内部 API 请求的端口，不用于其他用途。&lt;/p&gt;
&lt;p&gt;填好后点击 &lt;strong&gt;&lt;code&gt;复制 docker-compose.yml&lt;/code&gt;&lt;/strong&gt; 按钮，将配置复制到剪贴板。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./images/02.png&quot; alt=&quot;rem-02.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;第三步 - 创建 docker-compose.yml 文件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;nano /opt/remnanode/docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将从面板复制的内容粘贴进去，生成的文件格式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
    remnanode:
        container_name: remnanode
        hostname: remnanode
        image: remnawave/node:latest
        restart: always
        network_mode: host
        environment:
          - NODE_PORT=2222
          - SECRET_KEY=&quot;supersecretkey&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存文件后启动容器：&lt;/p&gt;
&lt;h2&gt;第四步 - 启动节点容器&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d &amp;amp;&amp;amp; docker compose logs -f -t
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第五步 - 完成节点关联&lt;/h2&gt;
&lt;p&gt;回到面板的节点创建卡片，点击 &lt;strong&gt;&lt;code&gt;下一步&lt;/code&gt;&lt;/strong&gt;，选择所需的&lt;strong&gt;配置文件（Config Profile）&lt;/strong&gt;，然后点击 &lt;strong&gt;&lt;code&gt;创建&lt;/code&gt;&lt;/strong&gt; 按钮完成关联。&lt;/p&gt;
&lt;p&gt;:::danger 防火墙安全提示
&lt;strong&gt;请务必在节点防火墙中将 &lt;code&gt;NODE_PORT&lt;/code&gt; 仅对面板服务器的 IP 开放&lt;/strong&gt;，不要对公网开放此端口。
:::&lt;/p&gt;
&lt;h2&gt;编辑 Xray 配置文件&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./images/03.png&quot; alt=&quot;rem-03.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;vless+tcp+reality配置&lt;/h3&gt;
&lt;p&gt;想图方便可以直接复制粘贴进配置文件，入站标签是唯一的可以自定义&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;log&quot;: {
    &quot;loglevel&quot;: &quot;info&quot;
  },
  &quot;inbounds&quot;: [
    {
      &quot;tag&quot;: &quot;test1&quot;,
      &quot;port&quot;: 30004,
      &quot;protocol&quot;: &quot;vless&quot;,
      &quot;settings&quot;: {
        &quot;clients&quot;: [],
        &quot;decryption&quot;: &quot;none&quot;
      },
      &quot;sniffing&quot;: {
        &quot;enabled&quot;: true,
        &quot;destOverride&quot;: [
          &quot;http&quot;,
          &quot;tls&quot;,
          &quot;quic&quot;
        ]
      },
      &quot;streamSettings&quot;: {
        &quot;network&quot;: &quot;tcp&quot;,
        &quot;security&quot;: &quot;reality&quot;,
        &quot;realitySettings&quot;: {
          &quot;dest&quot;: &quot;www.amd.com:443&quot;,
          &quot;show&quot;: false,
          &quot;xver&quot;: 0,
          &quot;spiderX&quot;: &quot;&quot;,
          &quot;shortIds&quot;: [
            &quot;42aeec&quot;,
            &quot;66c8bd6b1002427d&quot;,
            &quot;5a1f&quot;,
            &quot;6c&quot;,
            &quot;adfb6126&quot;,
            &quot;ce557a621e&quot;,
            &quot;5fc062b8b4c2b9&quot;,
            &quot;e4cfaf01e274&quot;
          ],
          &quot;publicKey&quot;: &quot;3FB5YuwJgxCbQurerSwjhXDIHAB_SRdyecd5XLhtwE0&quot;,
          &quot;privateKey&quot;: &quot;m5mIb4EXjqkcfDDHRW_pU7Vz-hehwNgR5Hi2HFCO4S0&quot;,
          &quot;serverNames&quot;: [
            &quot;www.amd.com&quot;
          ]
        }
      }
    }
  ],
  &quot;outbounds&quot;: [
    {
      &quot;tag&quot;: &quot;DIRECT&quot;,
      &quot;protocol&quot;: &quot;freedom&quot;
    },
    {
      &quot;tag&quot;: &quot;BLOCK&quot;,
      &quot;protocol&quot;: &quot;blackhole&quot;
    }
  ],
  &quot;routing&quot;: {
    &quot;rules&quot;: [
      {
        &quot;ip&quot;: [
          &quot;geoip:private&quot;
        ],
        &quot;type&quot;: &quot;field&quot;,
        &quot;outboundTag&quot;: &quot;BLOCK&quot;
      },
      {
        &quot;type&quot;: &quot;field&quot;,
        &quot;domain&quot;: [
          &quot;geosite:private&quot;
        ],
        &quot;outboundTag&quot;: &quot;BLOCK&quot;
      },
      {
        &quot;type&quot;: &quot;field&quot;,
        &quot;protocol&quot;: [
          &quot;bittorrent&quot;
        ],
        &quot;outboundTag&quot;: &quot;BLOCK&quot;
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;publicKey&lt;/code&gt;和&lt;code&gt;privateKey&lt;/code&gt;,可以在下方工具栏生成&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./images/04.png&quot; alt=&quot;rem-04.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;将配置文件与节点关联&lt;/h2&gt;
&lt;p&gt;如果需要更换已关联的配置文件，可在 &lt;code&gt;节点&lt;/code&gt; → &lt;code&gt;管理&lt;/code&gt; 中选中对应节点，点击&lt;code&gt;更改配置文件&lt;/code&gt;，重新选择 Xray 配置文件和入站标签，点击应用更改后保存。&lt;/p&gt;
&lt;p&gt;完成配置文件关联后，节点仍无法直接使用，还需要继续创建主机。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./images/05.png&quot; alt=&quot;rem-05.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;创建主机&lt;/h2&gt;
&lt;p&gt;在这就是将入站真正的开启并监听端口
选择主机 → 创建主机
备注自定义，选择入站配置文件为刚刚创建的&lt;code&gt;test1&lt;/code&gt;，点击应用更改
&lt;img src=&quot;./images/06.png&quot; alt=&quot;rem-06.png&quot; /&gt;
可以看到端口自动填入了&lt;code&gt;30004&lt;/code&gt;，地址要填绑定了节点的IP的域名，将右上角按钮到开启状态，
&lt;img src=&quot;./images/07.png&quot; alt=&quot;rem-07.png&quot; /&gt;
至此可以看到入站为如下状态
&lt;img src=&quot;./images/08.png&quot; alt=&quot;rem-08.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;最后一步&lt;/h2&gt;
&lt;p&gt;完成以上的步骤是99%，剩下1%是将配置文件赋予给用户。
进入内部分组，编辑默认分组文件，将配置文件赋予给分组，点击应用更改，再点击保存。
&lt;img src=&quot;./images/10.png&quot; alt=&quot;rem-10.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;现在可以再用户列表选中用户，看到订阅链接。
&lt;img src=&quot;./images/09.png&quot; alt=&quot;rem-09.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;此面板玩法极其丰富，适合几个人合租使用。&lt;/p&gt;
</content:encoded></item><item><title>Fuwari 主题：集成 Giscus 评论区</title><link>https://jk.sb/posts/giscus/</link><guid isPermaLink="true">https://jk.sb/posts/giscus/</guid><description>本教程详细介绍如何为Fuwari博客主题集成giscus评论系统，包括GitHub仓库配置、giscus设置、创建评论组件以及在文章页面中引入评论区的完整步骤。</description><pubDate>Wed, 08 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;giscus简介&lt;/h2&gt;
&lt;p&gt;giscus 加载时，会使用 GitHub Discussions 搜索 API 根据选定的映射方式（如 &lt;code&gt;URL&lt;/code&gt;、&lt;code&gt;pathname&lt;/code&gt;、&lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; 等）来查找与当前页面关联的 discussion。如果找不到匹配的 discussion，giscus bot 就会在第一次有人留下评论或回应时自动创建一个 discussion。&lt;/p&gt;
&lt;h2&gt;配置Github&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;该仓库是&lt;a href=&quot;https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/setting-repository-visibility#making-a-repository-public&quot;&gt;公开&lt;/a&gt;的，否则访客将无法查看 discussion。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/apps/giscus&quot;&gt;giscus app&lt;/a&gt; 已安装，否则访客将无法评论和回应。&lt;/li&gt;
&lt;li&gt;Discussions 功能已在你的&lt;a href=&quot;https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/enabling-or-disabling-github-discussions-for-a-repository&quot;&gt;仓库中启用&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;配置giscus&lt;/h2&gt;
&lt;p&gt;打开&lt;a href=&quot;https://giscus.app/&quot;&gt;giscus官网&lt;/a&gt;，填入仓库地址，选择 Discussion 分类和映射方式后，页面会自动生成配置脚本。其中 &lt;code&gt;data-repo-id&lt;/code&gt; 和 &lt;code&gt;data-category-id&lt;/code&gt; 是 giscus 根据你填写的仓库和分类自动生成的唯一标识，直接复制即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;https://giscus.app/client.js&quot;
        data-repo=&quot;Ham0mer/giscus-fuwari&quot;
        data-repo-id=&quot;R_kgDOP-iBJw&quot;
        data-category=&quot;Announcements&quot;
        data-category-id=&quot;DIC_kwDOP-iBJ84CwZLW&quot;
        data-mapping=&quot;pathname&quot;
        data-strict=&quot;0&quot;
        data-reactions-enabled=&quot;1&quot;
        data-emit-metadata=&quot;0&quot;
        data-input-position=&quot;bottom&quot;
        data-theme=&quot;preferred_color_scheme&quot;
        data-lang=&quot;zh-CN&quot;
        crossorigin=&quot;anonymous&quot;
        async&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;创建/修改fuwari文件&lt;/h2&gt;
&lt;h3&gt;创建GiscusComment&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;src/components/misc/&lt;/code&gt; 目录下创建 &lt;code&gt;GiscusComment.astro&lt;/code&gt;。该组件接收 &lt;code&gt;repo&lt;/code&gt;、&lt;code&gt;repoId&lt;/code&gt;、&lt;code&gt;category&lt;/code&gt;、&lt;code&gt;categoryId&lt;/code&gt; 等参数，动态加载 giscus 脚本，并监听主题变化自动切换 giscus 的亮/暗主题。&lt;/p&gt;
&lt;p&gt;组件代码可参考项目仓库中的 &lt;a href=&quot;https://github.com/Ham0mer/jk-fuwari/blob/master/src/components/misc/GiscusComment.astro&quot;&gt;GiscusComment.astro&lt;/a&gt;，核心逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;根据页面 &lt;code&gt;dark&lt;/code&gt; class 判断当前主题色，传给 giscus&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;MutationObserver&lt;/code&gt; 监听主题切换，用 &lt;code&gt;postMessage&lt;/code&gt; 通知 giscus iframe 更新主题&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;引入到文章页面&lt;/h3&gt;
&lt;p&gt;编辑 &lt;code&gt;src/pages/posts/[...slug].astro&lt;/code&gt;，在文件头部引入组件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import GiscusComment from &quot;../../components/misc/GiscusComment.astro&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在文章内容下方（License 之后、上一篇/下一篇导航之前）放入评论区：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;GiscusComment
    repo=&quot;Ham0mer/giscus-fuwari&quot;
    repoId=&quot;R_kgDOP-iBJw&quot;
    category=&quot;Announcements&quot;
    categoryId=&quot;DIC_kwDOP-iBJ84CwZLW&quot;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;repoId&lt;/code&gt; 和 &lt;code&gt;categoryId&lt;/code&gt; 即上一步 giscus 官网生成的对应值，替换为你自己的即可。&lt;/p&gt;
</content:encoded></item><item><title>Steam Web API：简易使用介绍</title><link>https://jk.sb/posts/steam-api/</link><guid isPermaLink="true">https://jk.sb/posts/steam-api/</guid><description>Steam Web API使用方法详解，包含接口格式、参数说明及常用功能示例</description><pubDate>Tue, 07 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近想更新关于页面的 Steam 展示组件，记录一下 Steam Web API 的使用方法。官方文档地址：&lt;a href=&quot;https://steamcommunity.com/dev&quot;&gt;steamcommunity.com/dev&lt;/a&gt;，第三方可视化文档：&lt;a href=&quot;https://steamapi.xpaw.me/&quot;&gt;steamapi.xpaw.me&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;准备工作&lt;/h2&gt;
&lt;h3&gt;1. 申请 API Key&lt;/h3&gt;
&lt;p&gt;打开 &lt;a href=&quot;https://steamcommunity.com/dev/apikey&quot;&gt;Steam API Key 申请页面&lt;/a&gt;，登录后填写域名（随意填写，如 &lt;code&gt;localhost&lt;/code&gt;），即可获得密钥。下文用 &lt;code&gt;XXXXXX&lt;/code&gt; 代替。&lt;/p&gt;
&lt;p&gt;:::warning
API Key 是私密凭证，请勿公开或提交到代码仓库。
:::&lt;/p&gt;
&lt;h3&gt;2. 查询 SteamID64&lt;/h3&gt;
&lt;p&gt;Steam 使用 64 位 ID 唯一标识用户，有以下几种方式查询：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://steamdb.info/calculator/&quot;&gt;SteamDB 计算器&lt;/a&gt;：用 Steam 账号登录或输入社区昵称查询&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://steamid.io/&quot;&gt;steamid.io&lt;/a&gt;：输入任意格式 Steam ID 互转&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ResolveVanityURL&lt;/code&gt; 接口：通过自定义 URL 解析（见下文）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下文用 &lt;code&gt;123456&lt;/code&gt; 代替 SteamID64，用 &lt;code&gt;000000&lt;/code&gt; 代替游戏 AppID。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;接口格式&lt;/h2&gt;
&lt;p&gt;Steam Web API 的统一请求格式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/{interface}/{method}/v{version}/?key=XXXXXX&amp;amp;{params}
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;interface&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;API 分类，如 &lt;code&gt;ISteamUser&lt;/code&gt;、&lt;code&gt;IPlayerService&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;method&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;具体功能，如 &lt;code&gt;GetPlayerSummaries&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;version&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;版本号，通常为 &lt;code&gt;v1&lt;/code&gt; 或 &lt;code&gt;v2&lt;/code&gt;，写 &lt;code&gt;v1&lt;/code&gt; 与 &lt;code&gt;v0001&lt;/code&gt; 均可&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;key&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;您的 API Key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;format&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;可选，返回格式：&lt;code&gt;json&lt;/code&gt;（默认）、&lt;code&gt;xml&lt;/code&gt;、&lt;code&gt;vdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::tip
http 和 https 均可使用。&lt;code&gt;key&lt;/code&gt; 参数必须传递，否则大多数接口会返回错误。
:::&lt;/p&gt;
&lt;p&gt;查询当前 Key 可用的所有 API：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamWebAPIUtil/GetSupportedAPIList/v1/?key=XXXXXX
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;用户相关 API&lt;/h2&gt;
&lt;h3&gt;用户基本信息&lt;/h3&gt;
&lt;p&gt;获取昵称、头像、在线状态、国家、创建时间等。&lt;code&gt;steamids&lt;/code&gt; 支持逗号分隔传入多个 ID。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=XXXXXX&amp;amp;steamids=123456
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自定义 URL 解析 SteamID&lt;/h3&gt;
&lt;p&gt;通过用户设置的自定义社区 URL 解析出 SteamID64：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUser/ResolveVanityURL/v1/?key=XXXXXX&amp;amp;vanityurl=gaben
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;好友列表&lt;/h3&gt;
&lt;p&gt;获取好友列表及成为好友的时间（UNIX 时间戳）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUser/GetFriendList/v1/?key=XXXXXX&amp;amp;steamid=123456
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;组列表&lt;/h3&gt;
&lt;p&gt;获取用户加入的 Steam 组：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUser/GetUserGroupList/v1/?key=XXXXXX&amp;amp;steamid=123456
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;封禁记录&lt;/h3&gt;
&lt;p&gt;查询 VAC 封禁、游戏封禁信息，&lt;code&gt;steamids&lt;/code&gt; 支持多个 ID：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUser/GetPlayerBans/v1/?key=XXXXXX&amp;amp;steamids=123456
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;游戏库与游玩相关 API&lt;/h2&gt;
&lt;h3&gt;游戏库存&lt;/h3&gt;
&lt;p&gt;获取用户拥有的所有游戏及游玩时间。添加 &lt;code&gt;include_appinfo=1&lt;/code&gt; 可在响应中包含游戏名称和图标：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?key=XXXXXX&amp;amp;steamid=123456&amp;amp;include_appinfo=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
Steam 曾清理过部分低质量游戏，这些游戏不计入用户主页的游戏总数，但此接口仍会列出。
:::&lt;/p&gt;
&lt;h3&gt;最近游玩&lt;/h3&gt;
&lt;p&gt;获取两周内游玩过的游戏，包含游戏名、AppID、图标和游玩时间。可选参数 &lt;code&gt;count&lt;/code&gt; 限制返回数量：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/IPlayerService/GetRecentlyPlayedGames/v1/?key=XXXXXX&amp;amp;steamid=123456&amp;amp;count=5
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;所有游戏使用时长&lt;/h3&gt;
&lt;p&gt;获取所有产品的总游玩时间，以及在 Windows/Linux/Mac 各平台的分别时长：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/IPlayerService/ClientGetLastPlayedTimes/v1/?key=XXXXXX
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;等级与徽章 API&lt;/h2&gt;
&lt;h3&gt;社区等级&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/IPlayerService/GetSteamLevel/v1/?key=XXXXXX&amp;amp;steamid=123456
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;徽章列表&lt;/h3&gt;
&lt;p&gt;获取所有已获得徽章的详情，包括徽章 ID、等级、经验值、解锁时间等：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/IPlayerService/GetBadges/v1/?key=XXXXXX&amp;amp;steamid=123456
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;成就相关 API&lt;/h2&gt;
&lt;h3&gt;玩家成就&lt;/h3&gt;
&lt;p&gt;获取指定游戏中玩家的成就完成情况（必须指定 AppID）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v1/?key=XXXXXX&amp;amp;steamid=123456&amp;amp;appid=000000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;全球成就完成率&lt;/h3&gt;
&lt;p&gt;无需 Key，获取某款游戏所有成就在全球玩家中的完成百分比：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/?gameid=000000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;游戏统计数据定义&lt;/h3&gt;
&lt;p&gt;获取游戏开发者定义的成就和统计数据结构：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamUserStats/GetSchemaForGame/v2/?key=XXXXXX&amp;amp;appid=000000
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;游戏信息 API&lt;/h2&gt;
&lt;h3&gt;游戏新闻&lt;/h3&gt;
&lt;p&gt;获取指定游戏的最新公告，可控制数量和内容长度：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamNews/GetNewsForApp/v2/?appid=000000&amp;amp;count=5&amp;amp;maxlength=500
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;商店详情（非官方 Store API）&lt;/h3&gt;
&lt;p&gt;获取游戏详细信息，包括简介、价格、类型、标签、系统需求、截图等（中文内容加 &lt;code&gt;l=schinese&lt;/code&gt;）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://store.steampowered.com/api/appdetails?appids=000000&amp;amp;l=schinese
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;所有游戏列表&lt;/h3&gt;
&lt;p&gt;获取 Steam 商店上的所有游戏列表（AppID + 名称），数据量较大：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://api.steampowered.com/ISteamApps/GetAppList/v2/
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;游戏资源&lt;/h2&gt;
&lt;h3&gt;游戏头图&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://cdn.cloudflare.steamstatic.com/steam/apps/{appid}/header.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;游戏胶囊图（纵向）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;https://cdn.cloudflare.steamstatic.com/steam/apps/{appid}/library_600x900.jpg
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;游戏截图&lt;/h3&gt;
&lt;p&gt;游戏截图 URL 可从 &lt;code&gt;appdetails&lt;/code&gt; 接口的 &lt;code&gt;screenshots&lt;/code&gt; 字段中获取。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;便捷代理接口&lt;/h2&gt;
&lt;p&gt;如果不想自己管理 API Key，可使用封装好的代理接口（以下为示例站点，数据仅供参考）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;接口示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;个人信息&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://o.jk.sb/steam/profile/76561198887857717&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;游戏库存&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://o.jk.sb/steam/games/76561198887857717&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最近游玩&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://o.jk.sb/steam/recentlyplayed/76561198887857717&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最近游玩（指定数量）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://o.jk.sb/steam/recentlyplayed/76561198887857717/3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;游戏成就&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://o.jk.sb/steam/achievements/76561198887857717/275850&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;游戏封面（Base64）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://o.jk.sb/steam/imageurl2base64/275850&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;注意事项&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;大部分用户相关接口需要&lt;strong&gt;账号社区信息设为公开&lt;/strong&gt;，否则返回数据异常或为空&lt;/li&gt;
&lt;li&gt;不同类型的 Key（开发者 / 普通玩家）可访问的接口范围不同&lt;/li&gt;
&lt;li&gt;API 存在速率限制，请勿频繁大量请求，否则 IP 可能被临时封禁&lt;/li&gt;
&lt;li&gt;Steam 周年庆游玩回顾（Replay）页面：&lt;code&gt;https://store.steampowered.com/replay/{steamid}/{year}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>ASF + TGbot：Docker 部署指南</title><link>https://jk.sb/posts/asf-install/</link><guid isPermaLink="true">https://jk.sb/posts/asf-install/</guid><description>ASF 是一个帮助您轻松获得 Steam 卡牌掉落的程序，支持多账号和 Web UI 管理</description><pubDate>Sun, 05 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ArchiSteamFarm（ASF）是一个开源的 Steam 挂卡程序，支持多账号管理、Web UI 以及 Telegram Bot 控制。本文介绍如何用 Docker 快速部署 ASF 及其 Telegram 控制 Bot。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;JustArchiNET/ArchiSteamFarm&quot;}&lt;/p&gt;
&lt;h2&gt;安装 ASF&lt;/h2&gt;
&lt;h3&gt;1. 启动容器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;docker run -d \
  -p 127.0.0.1:1242:1242 \
  -v /opt/ASF/config:/app/config \
  -v /opt/ASF/plugins:/app/plugins \
  --name asf \
  --restart unless-stopped \
  --pull always \
  justarchi/archisteamfarm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
端口绑定到 &lt;code&gt;127.0.0.1&lt;/code&gt; 而非 &lt;code&gt;0.0.0.0&lt;/code&gt;，可防止 IPC 接口暴露到公网。
:::&lt;/p&gt;
&lt;h3&gt;2. 配置 ASF.json&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;/opt/ASF/config/&lt;/code&gt; 下创建全局配置文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;IPCPassword&quot;: &quot;yourpassword&quot;,
  &quot;SteamOwnerID&quot;: 76561198000000000
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IPCPassword&lt;/code&gt;：访问 Web UI 所需的密码，建议设置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SteamOwnerID&lt;/code&gt;：您的 Steam 64位 ID，可在 &lt;a href=&quot;https://steamid.io/&quot;&gt;steamid.io&lt;/a&gt; 查询&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 配置 IPC.config&lt;/h3&gt;
&lt;p&gt;此文件让 ASF Web UI 可以在容器外访问：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;Kestrel&quot;: {
    &quot;Endpoints&quot;: {
      &quot;HTTP&quot;: {
        &quot;Url&quot;: &quot;http://*:1242&quot;
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 添加 Steam 账号&lt;/h3&gt;
&lt;p&gt;为每个 Steam 账号在 &lt;code&gt;/opt/ASF/config/&lt;/code&gt; 下创建一个以账号命名的 JSON 文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;SteamLogin&quot;: &quot;你的Steam用户名&quot;,
  &quot;SteamPassword&quot;: &quot;你的Steam密码&quot;,
  &quot;Enabled&quot;: true
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning
Bot 配置文件名（如 &lt;code&gt;MyBot.json&lt;/code&gt;）即为机器人名称，请避免使用特殊字符或空格。
:::&lt;/p&gt;
&lt;h3&gt;5. 重启并访问 Web UI&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;docker restart asf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;浏览器打开 &lt;code&gt;http://localhost:1242&lt;/code&gt;，使用 &lt;code&gt;IPCPassword&lt;/code&gt; 登录即可管理所有账号。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;配置 2FA（可选但推荐）&lt;/h2&gt;
&lt;p&gt;若您的 Steam 账号已开启手机令牌，ASF 支持托管 2FA，登录后无需手动输入验证码，并可自动确认交易。&lt;/p&gt;
&lt;p&gt;在 ASF Web UI 的 &lt;strong&gt;2FA 管理&lt;/strong&gt; 页面，按提示导入手机令牌的 &lt;code&gt;shared_secret&lt;/code&gt; 完成绑定。&lt;/p&gt;
&lt;p&gt;:::caution
导入 2FA 后，请妥善保存原始密钥备份。ASF 2FA 与手机令牌并行存在，两者均可生成有效验证码。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;安装 TGbot&lt;/h2&gt;
&lt;p&gt;ASFBot 让您可以通过 Telegram 远程控制 ASF。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;dmcallejo/ASFBot&quot;}&lt;/p&gt;
&lt;h3&gt;1. 创建 Telegram Bot&lt;/h3&gt;
&lt;p&gt;前往 &lt;a href=&quot;https://t.me/BotFather&quot;&gt;@BotFather&lt;/a&gt;，发送 &lt;code&gt;/newbot&lt;/code&gt; 创建一个 Bot，保存返回的 &lt;strong&gt;Token&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;2. 使用 docker-compose（推荐）&lt;/h3&gt;
&lt;p&gt;使用 docker-compose 同时管理 ASF 和 ASFBot，两个服务通过内部网络通信，无需将 IPC 端口暴露给外部：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  asf:
    image: justarchi/archisteamfarm
    container_name: asf
    restart: unless-stopped
    ports:
      - &quot;127.0.0.1:1242:1242&quot;
    volumes:
      - ./config:/app/config
      - ./plugins:/app/plugins

  asfbot:
    image: ghcr.io/dmcallejo/asfbot
    container_name: asfbot
    restart: unless-stopped
    depends_on:
      - asf
    environment:
      - ASF_IPC_HOST=asf
      - ASF_IPC_PORT=1242
      - ASF_IPC_PASSWORD=yourpassword
      - TELEGRAM_BOT_TOKEN=你的Bot_Token
      - TELEGRAM_USER_ALIAS=@你的Telegram用户名
      # 国内服务器可取消注释以下代理配置
      # - TELEGRAM_PROXY=http://代理IP:代理端口
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
使用 docker-compose 时，&lt;code&gt;ASF_IPC_HOST&lt;/code&gt; 填写 &lt;code&gt;asf&lt;/code&gt;（服务名），两个容器在同一网络内直接通信，无需 &lt;code&gt;--network host&lt;/code&gt;。
:::&lt;/p&gt;
&lt;h3&gt;3. 单独运行 ASFBot&lt;/h3&gt;
&lt;p&gt;如果 ASF 已单独运行，可用以下命令单独启动 ASFBot：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -d \
  --name asfbot \
  --restart unless-stopped \
  --network host \
  -e ASF_IPC_HOST=127.0.0.1 \
  -e ASF_IPC_PORT=1242 \
  -e ASF_IPC_PASSWORD=yourpassword \
  -e TELEGRAM_BOT_TOKEN=你的Bot_Token \
  -e TELEGRAM_USER_ALIAS=@你的Telegram用户名 \
  ghcr.io/dmcallejo/asfbot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;国内服务器可添加 &lt;code&gt;-e TELEGRAM_PROXY=http://代理IP:代理端口&lt;/code&gt; 通过代理连接 Telegram。&lt;/p&gt;
&lt;h3&gt;4. 常用 Bot 命令&lt;/h3&gt;
&lt;p&gt;向您的 Bot 发送以下命令来控制 ASF：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看所有 Bot 运行状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/start BotName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动指定 Bot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/stop BotName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;停止指定 Bot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/pause BotName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;暂停挂卡&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/resume BotName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;恢复挂卡&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/farm BotName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;手动触发挂卡&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/2fa BotName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;获取当前 2FA 令牌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查看全部可用命令&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>Maddy：自建邮件服务器指南</title><link>https://jk.sb/posts/maddy-mail/</link><guid isPermaLink="true">https://jk.sb/posts/maddy-mail/</guid><description>从零开始用 Docker 搭建 maddy 自建邮件服务器，包含 DNS、DKIM、SPF、DMARC 配置及账户管理。</description><pubDate>Sat, 06 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;maddy 是一个开箱即用的一体化邮件服务器，集 MTA、IMAP、DKIM、SPF、DMARC 于一身，配置比传统 Postfix + Dovecot 方案简单很多。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;foxcpp/maddy&quot;}&lt;/p&gt;
&lt;h2&gt;前置条件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;一台有&lt;strong&gt;独立公网 IP&lt;/strong&gt; 的 VPS（需要开放 25、587、993、143 端口，部分云厂商默认封禁 25 端口，需提工单申请）&lt;/li&gt;
&lt;li&gt;一个已解析的&lt;strong&gt;域名&lt;/strong&gt;（例如 &lt;code&gt;example.com&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;一个指向服务器 IP 的&lt;strong&gt;子域名&lt;/strong&gt;作为邮件主机名（例如 &lt;code&gt;mx.example.com&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;SSL/TLS 证书（推荐 Let&apos;s Encrypt，可用 acme.sh 或 Certbot 申请）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::warning
请先确认您的 VPS 已开放 TCP 25 端口，否则无法收发外部邮件。阿里云、腾讯云等默认封禁，需单独申请。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;安装 maddy&lt;/h2&gt;
&lt;h3&gt;使用 docker-compose（推荐）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;services:
  maddy:
    image: foxcpp/maddy:latest
    container_name: maddy
    restart: unless-stopped
    ports:
      - &quot;25:25&quot;       # SMTP (接收外部邮件)
      - &quot;587:587&quot;     # SMTP Submission (客户端发信)
      - &quot;143:143&quot;     # IMAP
      - &quot;993:993&quot;     # IMAPS (TLS)
    environment:
      - MADDY_HOSTNAME=mx.example.com   # 邮件服务器主机名
      - MADDY_DOMAIN=example.com        # 处理的邮件域名
    volumes:
      - ./maddy-data:/data
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::tip
&lt;code&gt;/data&lt;/code&gt; 目录会自动生成默认配置文件 &lt;code&gt;maddy.conf&lt;/code&gt;，以及 DKIM 私钥等数据。需要自定义配置时，直接编辑 &lt;code&gt;./maddy-data/maddy.conf&lt;/code&gt; 后重启容器。
:::&lt;/p&gt;
&lt;h3&gt;配置 TLS 证书&lt;/h3&gt;
&lt;p&gt;maddy 首次启动会因找不到证书而失败。将证书文件复制到数据目录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cp /path/to/fullchain.pem ./maddy-data/tls/fullchain.pem
cp /path/to/privkey.pem   ./maddy-data/tls/privkey.pem
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重启容器：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose restart maddy
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;DNS 配置&lt;/h2&gt;
&lt;p&gt;以下记录均以 &lt;code&gt;example.com&lt;/code&gt; 为例，请替换为您的实际域名。&lt;/p&gt;
&lt;h3&gt;基础记录&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;主机记录&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;服务器公网 IP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mx.example.com&lt;/code&gt;（优先级 10）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PTR&lt;/td&gt;
&lt;td&gt;服务器 IP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mx.example.com&lt;/code&gt;（在 VPS 管理面板设置反向解析）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::important
PTR 反向解析（rDNS）是许多邮件服务器判断是否接收邮件的重要依据，务必配置，否则发出的邮件极易进垃圾箱。
:::&lt;/p&gt;
&lt;h3&gt;SPF 记录&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;v=spf1 mx ~all
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;主机记录&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v=spf1 mx ~all&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;DKIM 记录&lt;/h3&gt;
&lt;p&gt;maddy 在首次启动后会自动生成 DKIM 密钥，查看公钥内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat ./maddy-data/dkim_keys/example.com_default.dns
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出示例（格式为 DNS TXT 记录值）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将该内容添加到 DNS：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;主机记录&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;default._domainkey&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;上方输出的完整内容&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;DMARC 记录&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;v=DMARC1; p=quarantine; rua=mailto:postmaster@example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;主机记录&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_dmarc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v=DMARC1; p=quarantine; rua=mailto:postmaster@example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::tip
DNS 记录生效通常需要几分钟到数小时，配置完成后可使用 &lt;a href=&quot;https://www.mail-tester.com&quot;&gt;mail-tester.com&lt;/a&gt; 检测评分，7 分以上为合格。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;账户管理&lt;/h2&gt;
&lt;p&gt;以下命令均在容器内执行，先进入容器终端：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker exec -it maddy sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;创建邮箱账户&lt;/h3&gt;
&lt;p&gt;创建登录凭证（执行后会提示设置密码）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;maddy creds create admin@example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建 IMAP 存储账户：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;maddy imap-acct create admin@example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::important
两步都要执行：&lt;code&gt;creds create&lt;/code&gt; 负责认证登录，&lt;code&gt;imap-acct create&lt;/code&gt; 负责创建邮件存储。缺少任意一步，账户都无法正常使用。
:::&lt;/p&gt;
&lt;h3&gt;修改密码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;maddy creds password admin@example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;查看账户列表&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;maddy creds list
maddy imap-acct list
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;管理邮箱文件夹&lt;/h3&gt;
&lt;p&gt;查看账户下的邮箱分类：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;maddy imap-mboxes list admin@example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;测试收发邮件&lt;/h2&gt;
&lt;h3&gt;测试收信&lt;/h3&gt;
&lt;p&gt;使用 QQ 邮箱、Gmail 等向 &lt;code&gt;admin@example.com&lt;/code&gt; 发送一封测试邮件，然后在容器内查看收件箱：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;maddy imap-msgs list admin@example.com INBOX
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;测试发信评分&lt;/h3&gt;
&lt;p&gt;使用邮件客户端（Thunderbird、Apple Mail 等）通过以下参数连接后发送测试邮件到 &lt;a href=&quot;https://www.mail-tester.com&quot;&gt;mail-tester.com&lt;/a&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IMAP 服务器&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mx.example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IMAP 端口&lt;/td&gt;
&lt;td&gt;&lt;code&gt;993&lt;/code&gt;（SSL/TLS）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP 服务器&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mx.example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP 端口&lt;/td&gt;
&lt;td&gt;&lt;code&gt;587&lt;/code&gt;（STARTTLS）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;用户名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;admin@example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;常见问题&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;邮件进了垃圾箱？&lt;/strong&gt;
检查 PTR 反向解析是否配置、DKIM/SPF/DMARC 是否全部生效，可在 &lt;a href=&quot;https://mxtoolbox.com&quot;&gt;MXToolbox&lt;/a&gt; 逐项验证。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;25 端口被封？&lt;/strong&gt;
联系 VPS 服务商提工单解封，或换用不封 25 端口的服务商（如 Vultr、Hetzner）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;日志查看：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker logs -f maddy
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Seedbox：一键安装与 PT 刷流指南</title><link>https://jk.sb/posts/play-pt/</link><guid isPermaLink="true">https://jk.sb/posts/play-pt/</guid><description>使用 jerry048 一键脚本搭建 qBittorrent Seedbox，含 autobrr、Vertex 刷流工具配置与网络优化说明</description><pubDate>Sat, 06 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Seedbox 是专用于 PT（私有 Tracker）下载和做种的服务器环境。本文介绍如何使用 jerry048 的一键脚本快速搭建，并说明各组件的用途与进阶优化方法。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;jerry048/Dedicated-Seedbox&quot;}&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;一键安装&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;bash &amp;lt;(wget -qO- https://raw.githubusercontent.com/jerry048/Dedicated-Seedbox/main/Install.sh) \
  -u &amp;lt;用户名&amp;gt; \
  -p &amp;lt;密码&amp;gt; \
  -c &amp;lt;缓存大小(MiB)&amp;gt; \
  -q &amp;lt;qBittorrent 版本&amp;gt; \
  -l &amp;lt;libtorrent 版本&amp;gt; \
  [选项...]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;参数说明&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;系统用户名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用户密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;qBittorrent 缓存大小（单位 MiB，建议为内存的 1/4）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-q&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;qBittorrent 版本号，如 &lt;code&gt;4.3.9&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;libtorrent 版本号，如 &lt;code&gt;v1.2.19&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安装 autobrr（国际 PT 自动抢种）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安装 Vertex（综合刷流管理工具）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安装 autoremove-torrents（自动删种）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启用 BBR V3 网络加速&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启用 BBRx 网络加速&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-o&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自定义端口&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;安装示例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;bash &amp;lt;(wget -qO- https://raw.githubusercontent.com/jerry048/Dedicated-Seedbox/main/Install.sh) \
  -u jerry048 \
  -p 1LDw39VOgors \
  -c 3072 \
  -q 4.3.9 \
  -l v1.2.19 \
  -v -x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此命令安装 qBittorrent 4.3.9（libtorrent v1.2.19），缓存 3 GB，安装 Vertex，启用 BBRx 加速。&lt;/p&gt;
&lt;h3&gt;支持的系统与架构&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类别&lt;/th&gt;
&lt;th&gt;支持范围&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;操作系统&lt;/td&gt;
&lt;td&gt;Debian 10+、Ubuntu 20.04+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU 架构&lt;/td&gt;
&lt;td&gt;x86_64、ARM64&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;工具介绍&lt;/h2&gt;
&lt;h3&gt;qBittorrent&lt;/h3&gt;
&lt;p&gt;主力下载/做种客户端，支持 Web UI 远程管理，是 PT 刷流的核心程序。&lt;/p&gt;
&lt;h3&gt;autobrr — 国际 PT 自动抢种&lt;/h3&gt;
&lt;p&gt;::github{repo=&quot;autobrr/autobrr&quot;}&lt;/p&gt;
&lt;p&gt;autobrr 通过监听 PT 站的 IRC &lt;code&gt;#announce&lt;/code&gt; 频道，在种子发布的第一时间自动推送到下载客户端，适合国际 PT 站（如 BTN、PTP、RED 等）的抢首发场景。&lt;/p&gt;
&lt;h3&gt;Vertex — 综合刷流管理工具&lt;/h3&gt;
&lt;p&gt;::github{repo=&quot;vertex-app/vertex&quot;}&lt;/p&gt;
&lt;p&gt;Vertex 是面向 PT 玩家的一体化管理工具，支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RSS 自动订阅与推送下载&lt;/li&gt;
&lt;li&gt;按规则自动删除低效种子&lt;/li&gt;
&lt;li&gt;多下载器负载均衡&lt;/li&gt;
&lt;li&gt;追剧与刷流一体化流程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:::tip
Vertex 官方文档：&lt;a href=&quot;https://wiki.vertex.icu/zh/home&quot;&gt;wiki.vertex.icu&lt;/a&gt;
:::&lt;/p&gt;
&lt;h3&gt;autoremove-torrents — 自动删种&lt;/h3&gt;
&lt;p&gt;::github{repo=&quot;jerrym19881225/autoremove-torrents&quot;}&lt;/p&gt;
&lt;p&gt;根据自定义规则（分享率、做种时间、种子大小等）自动清理低效种子，释放磁盘和带宽资源，支持 qBittorrent、Transmission、Deluge 等客户端。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;网络加速：BBR V3 与 BBRx&lt;/h2&gt;
&lt;p&gt;BBR（Bottleneck Bandwidth and Round-trip propagation time）是 Google 开发的 TCP 拥塞控制算法，相比传统 CUBIC 算法在高带宽、长延迟或轻微丢包网络环境下有明显优势。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;BBR V3（&lt;code&gt;-3&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;Google 官方最新版，已提交 Linux 内核主线，稳定性好&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BBRx（&lt;code&gt;-x&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;社区魔改版，激进调优，适合带宽充裕的 Seedbox 场景&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;:::tip
一般 Seedbox 推荐 BBRx；对稳定性有要求的生产环境选 BBR V3。两者互斥，只能选一个。
:::&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;进阶优化备注&lt;/h2&gt;
&lt;h3&gt;缓存大小&lt;/h3&gt;
&lt;p&gt;缓存建议设为机器内存的 &lt;strong&gt;1/4&lt;/strong&gt;。如使用 qBittorrent 4.3.x，受内存溢出问题影响，应保守设置在 &lt;strong&gt;1/8&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;异步 I/O 线程数&lt;/h3&gt;
&lt;p&gt;默认值为 4，对 HDD 友好。若使用 SSD 或 NVMe，可调整为 8～16：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;qBittorrent 4.3.x&lt;/strong&gt;：高级选项中直接修改&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;qBittorrent 4.1.x&lt;/strong&gt;：在 &lt;code&gt;/home/$username/.config/qBittorrent/qBittorrent.conf&lt;/code&gt; 的 &lt;code&gt;[BitTorrent]&lt;/code&gt; 段添加：&lt;pre&gt;&lt;code&gt;Session\AsyncIOThreadsCount=8
&lt;/code&gt;&lt;/pre&gt;
修改前请先关闭 qBittorrent。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deluge&lt;/strong&gt;：通过 &lt;a href=&quot;https://github.com/ratanakvlun/deluge-ltconfig/releases/tag/v0.3.1&quot;&gt;ltconfig 插件&lt;/a&gt; 设置 &lt;code&gt;aio_threads=8&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;发送缓冲区（I/O 较差的机器）&lt;/h3&gt;
&lt;p&gt;对于磁盘 I/O 较弱的机器，适当降低以下参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;qBittorrent 4.3.x&lt;/strong&gt;：高级选项中修改&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;qBittorrent 4.1.x&lt;/strong&gt;：在配置文件 &lt;code&gt;[BitTorrent]&lt;/code&gt; 段添加：&lt;pre&gt;&lt;code&gt;Session\SendBufferWatermark=5120
Session\SendBufferLowWatermark=1024
Session\SendBufferWatermarkFactor=150
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deluge（ltconfig）&lt;/strong&gt;：&lt;pre&gt;&lt;code&gt;send_buffer_low_watermark=1048576
send_buffer_watermark=5242880
send_buffer_watermark_factor=150
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;tick_interval（CPU 较差的机器）&lt;/h3&gt;
&lt;p&gt;调高 &lt;code&gt;tick_interval&lt;/code&gt; 可节省 CPU 资源（qBittorrent 暂不支持此项）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deluge（ltconfig）&lt;/strong&gt;：&lt;code&gt;tick_interval=250&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;TCP 缓存大小&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/sysctl.conf&lt;/code&gt; 中配置的 TCP 缓存对低端机器可能偏大，请根据实际情况酌情调低。&lt;/p&gt;
&lt;h3&gt;文件系统&lt;/h3&gt;
&lt;p&gt;强烈推荐使用 &lt;strong&gt;XFS&lt;/strong&gt; 文件系统，在多并发做种场景下 I/O 性能优于 ext4。&lt;/p&gt;
</content:encoded></item></channel></rss>