<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>使用 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><item><title>在 OpenAI Agent SDK 中使用自定义的 AI Agent</title><link>https://lvv.me/posts/2026/02/04_custom_endpoint_openai_agent/</link><pubDate>Wed, 04 Feb 2026 11:32:26 +0800</pubDate><guid>https://lvv.me/posts/2026/02/04_custom_endpoint_openai_agent/</guid><description>&lt;p>OpenAI 的 SDK 可以自定义 &lt;code>base_url&lt;/code>，&lt;code>api_key&lt;/code> 和 &lt;code>model&lt;/code>，这样就可以使用第三方平台提供的大模型能力了，比如我使用的是字节火山引擎的 Kimi 模型，把下面 python 代码中的 OpenRouterConfig 配置换成你自己的信息就可以。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">asyncio&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">openai&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AsyncOpenAI&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">openai&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">OpenAIError&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">agents&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Agent&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">Runner&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">OpenAIChatCompletionsModel&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">set_tracing_disabled&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Disable tracing since we&amp;#39;re using Azure OpenAI&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">set_tracing_disabled&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">disabled&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">OpenRouterConfig&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">def&lt;/span> &lt;span class="fm">__init__&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">model&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;kimi-k2-250905&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">key&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;0058B9EE-D0C7-43C4-B214-1DF127FCB0C0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">endpoint&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://openrouter.me/ark/api/v1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">OpenRouterConfig&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">async&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Create the Async Azure OpenAI client&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">client&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AsyncOpenAI&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">api_key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">base_url&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">endpoint&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Configure the agent with Azure OpenAI&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">agent&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Agent&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Assistant&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="n">instructions&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;You are a helpful assistant&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="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">OpenAIChatCompletionsModel&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">openai_client&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">client&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>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">Runner&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">agent&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Who are you? &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="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">final_output&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">except&lt;/span> &lt;span class="n">OpenAIError&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;OpenAI API Error: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&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="k">except&lt;/span> &lt;span class="ne">Exception&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;An unexpected error occurred: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&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="n">asyncio&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">main&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="参考信息">参考信息&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://lvv.me/posts/2025/09/13_reverse_proxy/"target="_blank" rel="noopener noreferrer">https://lvv.me/posts/2025/09/13_reverse_proxy/&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://community.openai.com/t/agents-sdk-with-azure-hosted-models/1157781"target="_blank" rel="noopener noreferrer">https://community.openai.com/t/agents-sdk-with-azure-hosted-models/1157781&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>使用命令把 ipcc 文件安装到 iOS 上</title><link>https://lvv.me/posts/2025/10/28_install_ipcc_to_ios/</link><pubDate>Tue, 28 Oct 2025 06:56:33 +0800</pubDate><guid>https://lvv.me/posts/2025/10/28_install_ipcc_to_ios/</guid><description>&lt;p>首先需要安装第三方工具 &lt;code>ideviceinstaller&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 ideviceinstaller
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在 Finder 中先找到手机的 &lt;code>UDID&lt;/code>，我这里的值是 &lt;code>00008123-0004399E3CE0C01E&lt;/code>，然后执行下面的命令把 ipcc 文件安装到手机中：&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">$ ideviceinstaller -u 00008123-0004399E3CE0C01E -i ~/IPCC/ChinaTelecom_USIM_cn.ipcc
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>也可以在终端中使用 &lt;code>for&lt;/code> 批量更新 IPCC：&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="k">for&lt;/span> ipcc in &lt;span class="k">$(&lt;/span>ls *.ipcc&lt;span class="k">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ideviceinstaller -u 00008123-0004399E3CE0C01E install ./&lt;span class="nv">$ipcc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">done&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>在 iOS 上增加自己 App 的内存使用上限</title><link>https://lvv.me/posts/2025/10/19_increased_memory_limit_on_ios/</link><pubDate>Sun, 19 Oct 2025 16:30:57 +0800</pubDate><guid>https://lvv.me/posts/2025/10/19_increased_memory_limit_on_ios/</guid><description>&lt;p>不管 iPhone 的内存有多大，单个 App 能够使用的内存上限总是 3GB，如果超过这个上限就会被系统杀掉。&lt;/p>
&lt;p>如果 App 确实在某些情况下需要使用大量内存，那么可以在项目的 &lt;code>entitlements&lt;/code> 里面添加 &lt;code>increased-memory-limit&lt;/code> 来告诉 iOS 系统自己在某些情况下会需要使用更多的内存。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-xml" data-lang="xml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;key&amp;gt;&lt;/span>com.apple.developer.kernel.increased-memory-limit&lt;span class="nt">&amp;lt;/key&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;true/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Tips：iOS 系统为了当前运行的 App 能够有充足的内存，会杀掉其他 App 来释放内存。&lt;/p>
&lt;h1 id="参考资料">参考资料&lt;/h1>
&lt;p>&lt;a href="https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.kernel.increased-memory-limit"target="_blank" rel="noopener noreferrer">https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.kernel.increased-memory-limit&lt;/a>&lt;/p></description></item></channel></rss>