<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Unbound on 小众开发者</title><link>https://lvv.me/tags/unbound/</link><description>Recent content in Unbound on 小众开发者</description><generator>Hugo -- gohugo.io</generator><language>zh</language><copyright>&amp;copy;2021 lvvme.</copyright><lastBuildDate>Fri, 22 May 2026 06:21:38 +0800</lastBuildDate><atom:link href="https://lvv.me/tags/unbound/index.xml" rel="self" type="application/rss+xml"/><item><title>在 macOS 上跨平台编译 Swift 项目</title><link>https://lvv.me/posts/2026/07/09_swift_cross_build_on_macos/</link><pubDate>Thu, 09 Jul 2026 11:33:36 +0800</pubDate><guid>https://lvv.me/posts/2026/07/09_swift_cross_build_on_macos/</guid><description>&lt;p>在 macOS 上编译能在 Linux 上运行的 Swift 项目。&lt;/p>
&lt;h2 id="安装-swiftly">安装 Swiftly&lt;/h2>
&lt;p>下载 swiftly 安装包 &lt;a href="https://download.swift.org/swiftly/darwin/swiftly.pkg"target="_blank" rel="noopener noreferrer">swiftly&lt;/a>&lt;/p>
&lt;p>然后解压 pkg 安装包，只需要其中的 &lt;code>swiftly&lt;/code> 主程序复制到 &lt;code>/opt/local/bin&lt;/code>：&lt;/p>
&lt;pre tabindex="0">&lt;code>$ pkgutil --expand-full swiftly.pkg swiftly
$ sudo mv swiftly/swiftly-1.1.3.pkg/Payload/bin/swiftly /opt/local/bin
&lt;/code>&lt;/pre>&lt;h2 id="下载安装-swift-工具链">下载安装 Swift 工具链&lt;/h2>
&lt;p>需要使用 &lt;code>swiftly&lt;/code> 来安装 &lt;a href="https://www.swift.org"target="_blank" rel="noopener noreferrer">swift.org&lt;/a> 官方上的工具链，不能直接使用 Xcode 里自带的 swift 工具链。&lt;/p>
&lt;pre tabindex="0">&lt;code>$ swiftly init
&lt;/code>&lt;/pre>&lt;p>然后使用 &lt;code>swiftly&lt;/code> 自带的脚本配置环境变量，运行后只对当前终端窗口有效。&lt;/p>
&lt;pre tabindex="0">&lt;code>$ . ~/.swiftly/env.sh
&lt;/code>&lt;/pre>&lt;h2 id="安装-swift-sdk-for-linux">安装 Swift SDK for Linux&lt;/h2>
&lt;pre tabindex="0">&lt;code>$ swift sdk install https://download.swift.org/swift-6.3.3-release/static-sdk/swift-6.3.3-RELEASE/swift-6.3.3-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz --checksum 87c3eaf908e67c0e13a84367119e12273cec1d2cd3d81f7d74bb36722d6b607b
&lt;/code>&lt;/pre>&lt;p>安装完后查看一下结果：&lt;/p>
&lt;pre tabindex="0">&lt;code>$ swift sdk list
swift-6.3.3-RELEASE_static-linux-0.1.0
&lt;/code>&lt;/pre>&lt;h2 id="跨平台编译-linux-下的程序">跨平台编译 Linux 下的程序&lt;/h2>
&lt;pre tabindex="0">&lt;code>$ swift build --swift-sdk x86_64-swift-linux-musl -c release
Building for production...
/Users/v/Documents/NIOForwarder/Sources/NIOForwarder/EntryPoint.swift:4:8: error: no such module &amp;#39;Darwin&amp;#39;
2 | import Logging
3 | import NIOPosix
4 | import Darwin
| `- error: no such module &amp;#39;Darwin&amp;#39;
5 |
6 | @main
&lt;/code>&lt;/pre>&lt;p>报错了，是因为 Linux SDK 中没有 Darwin 模块，需要调整项目中的源码，把 &lt;code>import Darwin&lt;/code> 替换为：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-swift" data-lang="swift">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#if&lt;/span> &lt;span class="cp">os&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="cp">macOS&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="cp">os&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="cp">iOS&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">import&lt;/span> &lt;span class="nc">Darwin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#elseif&lt;/span> &lt;span class="cp">canImport&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="cp">Glibc&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">import&lt;/span> &lt;span class="nc">Glibc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#elseif&lt;/span> &lt;span class="cp">canImport&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="cp">Musl&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">import&lt;/span> &lt;span class="nc">Musl&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#elseif&lt;/span> &lt;span class="cp">os&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="cp">Windows&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">import&lt;/span> &lt;span class="nc">ucrt&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#else&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">#&lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Unknown platform&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#endif&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>再重新编译一次就没问题了：&lt;/p>
&lt;pre tabindex="0">&lt;code>$ swift build --swift-sdk x86_64-swift-linux-musl -c release
&lt;/code>&lt;/pre>&lt;p>查看一下编译好的程序文件信息：&lt;/p>
&lt;pre tabindex="0">&lt;code>$ file .build/release/NIOForwarder
.build/release/NIOForwarder: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=ef530910056993e46fa58dedc3bdab06db7f9683, with debug_info, not stripped
&lt;/code>&lt;/pre>&lt;p>现在已经是 Linux 下的文件格式了。&lt;/p>
&lt;h2 id="参考">参考&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://www.swift.org/documentation/articles/static-linux-getting-started.html"target="_blank" rel="noopener noreferrer">https://www.swift.org/documentation/articles/static-linux-getting-started.html&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>简洁现代的 Nginx TLS 配置</title><link>https://lvv.me/posts/2026/06/23_modern_nginx_tls_config/</link><pubDate>Tue, 23 Jun 2026 15:04:06 +0800</pubDate><guid>https://lvv.me/posts/2026/06/23_modern_nginx_tls_config/</guid><description>&lt;p>配置效果：&lt;/p>
&lt;ol>
&lt;li>仅支持 &lt;code>TLSv1.2&lt;/code>， &lt;code>TLSv1.3&lt;/code>&lt;/li>
&lt;li>仅保留高效安全的加密套件&lt;/li>
&lt;li>按照加密效率从高到低排序&lt;/li>
&lt;/ol>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Protocol support&lt;/th>
&lt;th>Cipher suites&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>TLS 1.3 only&lt;/td>
&lt;td>&lt;code>TLS_AES_128_GCM_SHA256&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>TLS_AES_256_GCM_SHA384&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>TLS_CHACHA20_POLY1305_SHA256&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>TLS 1.2 only&lt;/td>
&lt;td>&lt;code>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Nginx 配置文件：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ssl_protocols TLSv1.2 TLSv1.3&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ssl_prefer_server_ciphers on&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ssl_ecdh_curve X25519:secp256r1:secp384r1&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># TLS 1.3 套件（顺序按效率：AES-128 &amp;gt; AES-256 &amp;gt; ChaCha20）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># TLS 1.2 套件（效率从高到低）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>在 macOS 上通过命令安装 Rosetta 2</title><link>https://lvv.me/posts/2026/06/04_install_rosetta_on_macos/</link><pubDate>Thu, 04 Jun 2026 17:16:29 +0800</pubDate><guid>https://lvv.me/posts/2026/06/04_install_rosetta_on_macos/</guid><description>&lt;p>在命令行直接安装，跳过同意用户协议提示：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ softwareupdate --install-rosetta --agree-to-license
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>使用 Unbound 作为局域网 DNS 代理服务器</title><link>https://lvv.me/posts/2026/05/22_dns_ttl_and_unbound/</link><pubDate>Fri, 22 May 2026 06:21:38 +0800</pubDate><guid>https://lvv.me/posts/2026/05/22_dns_ttl_and_unbound/</guid><description>&lt;p>配置目标：客户端发起 DNS 查询时，避免 Unbound 服务器频繁向上游服务器发起查询请求，直接把缓存结果返回给客户端。&lt;/p>
&lt;p>因为大部分服务的 DNS 记录是基本不变的，默认情况下 DNS 的存活时间是 300 秒，超过了这个时间就会重新发起 DNS 解析查询，这样显然浪费了网络资源。&lt;/p>
&lt;pre tabindex="0">&lt;code>server:
prefetch: yes
cache-min-ttl: 300
serve-expired: yes
serve-expired-reply-ttl: 300
serve-expired-ttl: 86400
serve-expired-ttl-reset: yes
&lt;/code>&lt;/pre>&lt;h2 id="参考资料">参考资料&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html"target="_blank" rel="noopener noreferrer">https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://developers.cloudflare.com/dns/manage-dns-records/reference/ttl/"target="_blank" rel="noopener noreferrer">https://developers.cloudflare.com/dns/manage-dns-records/reference/ttl/&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://datatracker.ietf.org/doc/html/rfc8767"target="_blank" rel="noopener noreferrer">https://datatracker.ietf.org/doc/html/rfc8767&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>在 Debian 上完全卸载 exim4</title><link>https://lvv.me/posts/2026/05/19_uninstall_exim4_on_debian/</link><pubDate>Tue, 19 May 2026 13:46:12 +0800</pubDate><guid>https://lvv.me/posts/2026/05/19_uninstall_exim4_on_debian/</guid><description>&lt;p>&lt;code>exim4&lt;/code> 是邮件服务，如果不需要收发邮件可以把这个组件卸载了：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo apt remove exim4-base
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ sudo apt autoremove
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>在 Debian 上使用 ss 命令查看端口情况</title><link>https://lvv.me/posts/2026/05/19_ss_on_debian/</link><pubDate>Tue, 19 May 2026 13:38:49 +0800</pubDate><guid>https://lvv.me/posts/2026/05/19_ss_on_debian/</guid><description>&lt;p>以前查看端口开放情况使用的命令是 &lt;code>netstat&lt;/code>，现在有了新的替代命令 &lt;code>ss&lt;/code>，速度更快：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo ss -tulnp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>参数解释：&lt;/p>
&lt;ul>
&lt;li>&lt;code>-t&lt;/code>：显示TCP端口&lt;/li>
&lt;li>&lt;code>-u&lt;/code>：显示UDP端口&lt;/li>
&lt;li>&lt;code>-l&lt;/code>：仅显示处于监听状态的端口&lt;/li>
&lt;li>&lt;code>-n&lt;/code>：以数字形式显现地址和端口&lt;/li>
&lt;li>&lt;code>-p&lt;/code>：显示进程和用户信息&lt;/li>
&lt;/ul></description></item><item><title>开启 ECN</title><link>https://lvv.me/posts/2026/05/19_enable_ecn/</link><pubDate>Tue, 19 May 2026 09:57:57 +0800</pubDate><guid>https://lvv.me/posts/2026/05/19_enable_ecn/</guid><description>&lt;p>在 ECN 生效的网络中，拥塞控制可以在不真正丢弃数据包的情况下进行，减少了因丢包导致的 TCP 窗口剧烈波动，有利于维持更高的链路利用率和更平滑的传输性能。&lt;/p>
&lt;p>ECN 有 3 个选项，分别是关闭、双向开启、仅入站开启，默认情况下是仅入站开启，也就是 &lt;code>2&lt;/code>，出于性能最优考虑建议把所有服务器都配置为 &lt;code>1&lt;/code>，这样整条服务器链路都能享受 ECN 的好处。&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Value&lt;/th>
&lt;th>Details&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>0&lt;/td>
&lt;td>Disable ECN.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>1&lt;/td>
&lt;td>Allow incoming connections to request ECN. Outgoing connections will request ECN.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2 (default)&lt;/td>
&lt;td>Allow incoming connections to request ECN. Outgoing connections will not request ECN.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="debian">Debian&lt;/h2>
&lt;p>编辑 &lt;code>/etc/sysctl.conf&lt;/code>：&lt;/p>
&lt;pre tabindex="0">&lt;code>net.ipv4.tcp_ecn = 1
&lt;/code>&lt;/pre>&lt;h2 id="freebsd">FreeBSD&lt;/h2>
&lt;p>编辑 &lt;code>/etc/sysctl.conf&lt;/code>：&lt;/p>
&lt;pre tabindex="0">&lt;code>net.inet.tcp.ecn.enable = 1
&lt;/code>&lt;/pre>&lt;h2 id="参考资料">参考资料&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://oneuptime.com/blog/post/2026-03-20-configure-tcp-ecn-linux/view"target="_blank" rel="noopener noreferrer">https://oneuptime.com/blog/post/2026-03-20-configure-tcp-ecn-linux/view&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://wiki.freebsd.org/TransportProtocols/tcp_rfc_notes"target="_blank" rel="noopener noreferrer">https://wiki.freebsd.org/TransportProtocols/tcp_rfc_notes&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>ClaudeCode 接入字节火山的 Doubao-Seed-2.0-Code</title><link>https://lvv.me/posts/2026/03/18_claude_code_with_ark_coding_plan/</link><pubDate>Wed, 18 Mar 2026 11:17:52 +0800</pubDate><guid>https://lvv.me/posts/2026/03/18_claude_code_with_ark_coding_plan/</guid><description>&lt;p>操作系统： macOS ，包管理器：Macports&lt;/p>
&lt;p>安装 Claude Agent：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo port install claude
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Claude 连接官方的订阅服务，也可以通过环境变量来指定指定自己的 Agent 服务，创建一个配置文件 &lt;code>~/.claude/settings.json&lt;/code>：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;env&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ANTHROPIC_BASE_URL&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://api.openrouter.me/ark/coding&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ANTHROPIC_AUTH_TOKEN&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;f0ad683e-56f4-46a3-9f54-8218b89d1234&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ANTHROPIC_MODEL&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;doubao-seed-2.0-code&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在命令行启动 &lt;code>claude&lt;/code> 命令的时候，就不会再提示去连接 Calude 的订阅了。&lt;/p>
&lt;h2 id="其他问题">其他问题&lt;/h2>
&lt;p>因为 Claude Agent 使用 brew 来安装工具，然而我使用的是 Macports ，这就需要提前安装好需要的命令行工具。&lt;/p>
&lt;p>比如要生成 Xcode 项目，就需要自己手动先安装好 &lt;a href="https://github.com/yonaskolb/XcodeGen"target="_blank" rel="noopener noreferrer">XcodeGen&lt;/a>&lt;/p>
&lt;h2 id="一些小技巧">一些小技巧&lt;/h2>
&lt;p>如果是作为 Demo 演示核心功能，效果比较好的方式是让 Claude 使用 SwiftUI 生成界面。&lt;/p></description></item><item><title>编译 Telegram iOS 源码 （2026年最新指南）</title><link>https://lvv.me/posts/2026/03/03_build_telegram_ios/</link><pubDate>Tue, 03 Mar 2026 11:08:26 +0800</pubDate><guid>https://lvv.me/posts/2026/03/03_build_telegram_ios/</guid><description>&lt;h2 id="准备编译环境">准备编译环境&lt;/h2>
&lt;p>以下是我的开发环境：&lt;/p>
&lt;ul>
&lt;li>操作系统：macOS 26.3&lt;/li>
&lt;li>开发工具：Xcode 26.3&lt;/li>
&lt;li>包管理器：macports&lt;/li>
&lt;/ul>
&lt;h2 id="安装依赖">安装依赖&lt;/h2>
&lt;ol>
&lt;li>
&lt;p>安装 &lt;code>rsync&lt;/code>，然后在 &lt;code>PATH&lt;/code> 环境中覆盖系统自带的路径，不然编译的时候会提示莫名其妙的权限问题。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo port install rsync
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这里比较坑的一点是 bazel 的规则里写了固定的 &lt;code>PATH=&amp;quot;/opt/homebrew/bin:/usr/local/bin:$PATH&amp;quot;&lt;/code>：&lt;/p>
&lt;p>&lt;img loading="lazy" src="01.png"
alt=""/>&lt;/p>
&lt;p>因为我的 macports 安装在 &lt;code>/opt/local&lt;/code> 下面，bazel 这个糟糕的 workground 会导致我的 macports 的 &lt;code>PATH&lt;/code> 环境变量被覆盖，需要做一个符号链接修正这个问题：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo ln -s /opt/local /opt/homebrew
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>安装 &lt;code>opensdk&lt;/code>，因为 bazel 默认依赖它。&lt;/p>
&lt;p>我安装的是微软预编译的版本：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo port install openjdk25-microsoft
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ &lt;span class="nb">export&lt;/span> &lt;span class="nv">JAVA_HOME&lt;/span>&lt;span class="o">=&lt;/span>/Library/Java/JavaVirtualMachines/jdk-25-microsoft.jdk/Contents/Home
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;h2 id="修改-telegram-编译配置">修改 Telegram 编译配置&lt;/h2>
&lt;p>首先把 Telegram iOS 的源码 clone 回来：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git clone --recursive -j8 https://github.com/TelegramMessenger/Telegram-iOS.git
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>编辑源码根目录下的 &lt;code>versions.json&lt;/code> ，把 bazel 的版本号调整到最新的版本，其他可以不管：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;app&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;12.5&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;xcode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;26.2&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bazel&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;8.6.0:948a7186641f601c83344b63b88bc6943025585f2bb7f407e19cface5fe4aa3b&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;macos&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;26&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>再调整编译配置文件 &lt;code>build-system/template_minimal_development_configuration.json&lt;/code>：&lt;/p>
&lt;p>其中的 &lt;code>bundle_id&lt;/code> 和 &lt;code>team_id&lt;/code> 字段根据你的实际情况进行调整，如果没有开发者账号只能在模拟器上运行，功能上没有区别。&lt;/p>
&lt;p>&lt;code>api_id&lt;/code> 和 &lt;code>api_hash&lt;/code> 字段的值我是从 &lt;code>build-system/appstore-configuration.json&lt;/code> 复制过来的。&lt;/p>
&lt;p>其他字段不需要调整，保持默认就行。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bundle_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;me.lvv.Telegram&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;api_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;8&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;api_hash&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;7245de8e747a0d6fbe11f7cc14fcc0bb&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;team_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;J29VN6AP39&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;app_center_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;is_internal_build&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;is_appstore_build&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;false&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;appstore_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;app_specific_url_scheme&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;tg&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;premium_iap_product_id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enable_siri&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;enable_icloud&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">false&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>现在可以生成 Xcode 项目文件了：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ python3 build-system/Make/Make.py &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --overrideXcodeVersion &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --cacheDir&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/telegram-bazel-cache&amp;#34;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> generateProject &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --configurationPath&lt;span class="o">=&lt;/span>build-system/template_minimal_development_configuration.json &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --xcodeManagedCodesigning --disableProvisioningProfiles
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这里需要注意，脚本会先干掉所有正在运行的 Xcode ，如果你有正在打开的 Xcode 项目，需要先保存号项目以避免内容丢失。&lt;/p>
&lt;p>脚本运行结束后会自动打开 Telegram 的 Xcode 项目，而且第一次打开需要等待比较久的预编译过程，预编译结束后不出意外的话就可以在模拟器/真机上启动调试了。&lt;/p></description></item><item><title>OpenClaw 最小化配置和使用自定义模型</title><link>https://lvv.me/posts/2026/02/27_openclaw_minimal_configuration/</link><pubDate>Fri, 27 Feb 2026 15:15:20 +0800</pubDate><guid>https://lvv.me/posts/2026/02/27_openclaw_minimal_configuration/</guid><description>&lt;blockquote>
&lt;p>本文的配置环境是 macOS，已经预装好了 NodeJS 环境&lt;/p>
&lt;/blockquote>
&lt;p>安装 &lt;a href="https://openclaw.ai/"target="_blank" rel="noopener noreferrer">OpenClaw&lt;/a> 很简单，首先本机需要有 &lt;code>npm&lt;/code> 环境，然后一行命令就可以安装 OpenClaw ：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo npm install -g openclaw
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>OpenClaw 默认读取的配置文件路径是 &lt;code>~/.openclaw/openclaw.json&lt;/code>，以下就是能让 OpenClaw 使用起来的最小配置：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;models&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;providers&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;aliyun&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;baseUrl&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;https://dashscope.aliyuncs.com/compatible-mode/v1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;apiKey&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;sk-a0fcd3e999b64ae5b10bd00727a7fca5&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;api&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;openai-completions&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;models&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;kimi-k2.5&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Kimi K2.5&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;reasoning&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;input&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;cost&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;input&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;output&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;cacheRead&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;cacheWrite&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;contextWindow&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">256000&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;maxTokens&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">8192&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;agents&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;defaults&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;model&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;primary&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;aliyun/kimi-k2.5&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;workspace&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;/tmp/.openclaw/workspace&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;heartbeat&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nt">&amp;#34;every&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0m&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;gateway&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;port&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">18789&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;mode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;local&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bind&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;loopback&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;auth&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;mode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;token&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;token&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;7f65a503bf530797074b8cd1e5084475aafde5da13c61d0c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;session&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;dmScope&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;per-channel-peer&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>以上配置中，禁用 &lt;code>heartbeat&lt;/code> 可以有效减少 token 的消耗。&lt;/p>
&lt;p>接下来还需再安装 OpenClaw 的 Gateway 服务：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ sudo openclaw gateway install --force
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Tips: LaunchAgents 是 macOS 的设置里面 “登录项与扩展” - “App 后台活动” 所显示的项目
OpenClaw Gateway 就是一个后台服务&lt;/p>
&lt;/blockquote>
&lt;p>如果你和我一样，没有使用 Homebrew 作为 macOS 的包管理，还需要手动调整配置文件 &lt;code>~/Library/LaunchAgents/ai.openclaw.gateway.plist&lt;/code> 中的 &lt;code>PATH&lt;/code> 路径。&lt;/p>
&lt;p>然后重启一下 OpenClaw Gateway 服务：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ launchctl unload ~/Library/LaunchAgents/ai.openclaw.gateway.plist
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ launchctl load -w ~/Library/LaunchAgents/ai.openclaw.gateway.plist
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>OpenClaw Gateway 的控制命令：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">openclaw gateway start &lt;span class="c1"># 启动服务&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openclaw gateway stop &lt;span class="c1"># 停止服务&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openclaw gateway restart &lt;span class="c1"># 重启服务&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openclaw gateway install &lt;span class="c1"># 安装服务（仅需要执行一次）&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在浏览器打开 &lt;code>http://127.0.0.1:18789/#token=7f65a503bf530797074b8cd1e5084475aafde5da13c61d0c&lt;/code> 就可以和 OpenClaw 对话了：&lt;/p>
&lt;p>&lt;img loading="lazy" src="01.jpeg"
alt=""/>&lt;/p>
&lt;h2 id="其他问题">其他问题&lt;/h2>
&lt;p>如果你更新 OpenClaw 到了 3.2 版本，发现无法调用 Tools，要在配置里显式的指定 Tools 的权限：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;tools&amp;#34;&lt;/span>&lt;span class="err">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;profile&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;full&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sessions&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;visibility&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;all&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="npm-权限问题">NPM 权限问题&lt;/h2>
&lt;p>如果你希望把 &lt;code>npm -g&lt;/code> 的全局包安装到 &lt;code>$HOME/&lt;/code> 目录下，参考这篇文章进行配置：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ mkdir ~/.npm-global
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ npm config &lt;span class="nb">set&lt;/span> prefix &lt;span class="s1">&amp;#39;~/.npm-global&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ &lt;span class="nb">export&lt;/span> &lt;span class="nv">PATH&lt;/span>&lt;span class="o">=&lt;/span>~/.npm-global/bin:&lt;span class="nv">$PATH&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;a href="https://npm.github.io/installation-setup-docs/installing/a-note-on-permissions.html"target="_blank" rel="noopener noreferrer">https://npm.github.io/installation-setup-docs/installing/a-note-on-permissions.html&lt;/a>&lt;/p></description></item></channel></rss>