<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Telegram on 小众开发者</title><link>https://lvv.me/tags/telegram/</link><description>Recent content in Telegram on 小众开发者</description><generator>Hugo -- gohugo.io</generator><language>zh</language><copyright>&amp;copy;2021 lvvme.</copyright><lastBuildDate>Tue, 03 Mar 2026 11:08:26 +0800</lastBuildDate><atom:link href="https://lvv.me/tags/telegram/index.xml" rel="self" type="application/rss+xml"/><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><item><title>APFS 开启透明压缩</title><link>https://lvv.me/posts/2025/10/16_apfs_compress/</link><pubDate>Thu, 16 Oct 2025 21:21:55 +0800</pubDate><guid>https://lvv.me/posts/2025/10/16_apfs_compress/</guid><description>&lt;p>Apple 系统的文件格式 HFS+ 和 APFS 都支持透明压缩，需要使用第三方开源工具开启这个特性：&lt;/p>
&lt;p>如果你使用的包管理工具是 MacPorts，安装命令是：&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 afscompress
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>如果你使用的包管理工具是 HomeBrew，安装命令是：&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">$ brew install afsctool
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>使用方法很简单，以下命令中的 &lt;code>afscompress&lt;/code> 是使用 MacPorts 安装的，如果是 HomeBrew 安装的则要改成 &lt;code>afsctool&lt;/code>：&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">$ afscompress -c ~/Documents
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&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">$ afscompress -v ~/Documents
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Total number of files: &lt;span class="m">15215&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Total number of folders: &lt;span class="m">1550&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Total number of items &lt;span class="o">(&lt;/span>number of files + number of folders&lt;span class="o">)&lt;/span>: &lt;span class="m">16765&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Folder size &lt;span class="o">(&lt;/span>uncompressed&lt;span class="p">;&lt;/span> reported size by Mac OS 10.6+ Finder&lt;span class="o">)&lt;/span>: &lt;span class="m">1830398656&lt;/span> bytes / 1.87 GB &lt;span class="o">(&lt;/span>gigabytes, base-10&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Folder size &lt;span class="o">(&lt;/span>compressed&lt;span class="o">)&lt;/span>: &lt;span class="m">1327370600&lt;/span> bytes / 1.24 GiB
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Compression savings: 27.5% over &lt;span class="m">14997&lt;/span> of &lt;span class="m">15215&lt;/span> files
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Approximate total folder size &lt;span class="o">(&lt;/span>files + file overhead + folder overhead&lt;span class="o">)&lt;/span>: &lt;span class="m">1328291569&lt;/span> bytes / 1.24 GiB
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>值得注意的是，并不是所有类型的文件都会被压缩，比如视频文件是不支持压缩的。&lt;/p>
&lt;h1 id="参考">参考&lt;/h1>
&lt;p>&lt;a href="https://github.com/RJVB/afsctool/issues/3"target="_blank" rel="noopener noreferrer">https://github.com/RJVB/afsctool/issues/3&lt;/a>&lt;/p></description></item><item><title>在 macOS 上创建虚拟内存盘（RamDisk）</title><link>https://lvv.me/posts/2025/09/25_ramdisk_on_macos/</link><pubDate>Thu, 25 Sep 2025 14:13:29 +0800</pubDate><guid>https://lvv.me/posts/2025/09/25_ramdisk_on_macos/</guid><description>&lt;p>使用命令行工具 &lt;code>hdid&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">$ hdid -nomount ram://16777216
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/disk6
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>16777216&lt;/code> 表示磁盘扇区数，每个扇区大小是 512 字节，总共就是 8GB 大小，所以计算磁盘大小的方式是&lt;strong>字节数&lt;/strong>除以 512。&lt;/p>
&lt;p>在 &lt;code>磁盘管理工具&lt;/code> 里可以看到刚才创建出来的虚拟磁盘，可以进行初始化和加载等操作，装载之后可以和普通磁盘一样使用。&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">$ diskutil apfs create /dev/disk6 ramdisk
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Started APFS operation on disk6
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Creating a new empty APFS Container
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Unmounting Volumes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Switching disk6 to APFS
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Creating APFS Container
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Created new APFS Container disk7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Disk from APFS operation: disk7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Finished APFS operation on disk6
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Started APFS operation on disk7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Preparing to add APFS Volume to APFS Container disk7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Creating APFS Volume
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Created new APFS Volume disk7s1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Mounting APFS Volume
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Setting volume permissions
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Disk from APFS operation: disk7s1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Finished APFS operation on disk7
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="设置开机自动创建虚拟磁盘">设置开机自动创建虚拟磁盘&lt;/h2>
&lt;ol>
&lt;li>写一个 Shell 脚本，自动执行创建虚拟磁盘、格式化为 APFS，然后创建 Xcode 的缓存目录
&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="cp">#!/usr/bin/env bash
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -e
&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="o">[&lt;/span> -d /Volumes/ramdisk &lt;span class="o">]&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">then&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s1">&amp;#39;found /Volumes/ramdisk.&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">exit&lt;/span> &lt;span class="m">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">fi&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="nv">ramdev&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="k">$(&lt;/span>hdid -nomount ram://16777216&lt;span class="k">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">diskutil apfs create &lt;span class="si">${&lt;/span>&lt;span class="nv">ramdev&lt;/span>&lt;span class="si">}&lt;/span> ramdisk
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">mkdir -p /Volumes/ramdisk/Xcode/DerivedData
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>把以上脚本内容保存到 &lt;code>/opt/local/share/libexec/mkramdisk.sh&lt;/code>&lt;/li>
&lt;li>再写一个 launchd plist 文件，作用是在系统启动的时候自动执行上面的脚本
&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="cp">&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&amp;lt;!DOCTYPE plist PUBLIC &amp;#34;-//Apple//DTD PLIST 1.0//EN&amp;#34; &amp;#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&amp;#34;&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;plist&lt;/span> &lt;span class="na">version=&lt;/span>&lt;span class="s">&amp;#34;1.0&amp;#34;&lt;/span>&lt;span class="nt">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;dict&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;key&amp;gt;&lt;/span>Label&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;string&amp;gt;&lt;/span>me.lvv.mkramdisk&lt;span class="nt">&amp;lt;/string&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;key&amp;gt;&lt;/span>EnvironmentVariables&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;dict&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;key&amp;gt;&lt;/span>PATH&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;string&amp;gt;&lt;/span>/sbin:/usr/sbin:/bin:/usr/bin&lt;span class="nt">&amp;lt;/string&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;/dict&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;key&amp;gt;&lt;/span>ProgramArguments&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;array&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;string&amp;gt;&lt;/span>/bin/bash&lt;span class="nt">&amp;lt;/string&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;string&amp;gt;&lt;/span>-i&lt;span class="nt">&amp;lt;/string&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;string&amp;gt;&lt;/span>/opt/local/share/libexec/mkramdisk.sh&lt;span class="nt">&amp;lt;/string&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;/array&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;lt;key&amp;gt;&lt;/span>RunAtLoad&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;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/dict&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;/plist&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>把以上内容保存到 &lt;code>/Library/LaunchDaemons/me.lvv.mkramdisk.plist&lt;/code>，然后加载这个服务：
&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 launchctl load -w /Library/LaunchDaemons/me.lvv.mkramdisk.plist
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>配置 Xcode 的 DerivedData 目录为虚拟磁盘：
&lt;img loading="lazy" src="01.png"
alt=""/>&lt;/li>
&lt;/ol>
&lt;p>Tips: 虚拟磁盘并不是一创建就把内存空间划走，而是等到真正写入了虚拟磁盘的时候，才会使用对应的内存空间，所以给虚拟磁盘分配大一点的空间是没有问题的。&lt;/p>
&lt;h2 id="参考资料">参考资料&lt;/h2>
&lt;p>&lt;a href="https://leopard-adc.pepas.com/documentation/Darwin/Reference/ManPages/man8/hdid.8.html"target="_blank" rel="noopener noreferrer">https://leopard-adc.pepas.com/documentation/Darwin/Reference/ManPages/man8/hdid.8.html&lt;/a>&lt;/p></description></item><item><title>设置 TCP Keepalive，适用于 Linux、FreeBSD 和 macOS</title><link>https://lvv.me/posts/2025/09/23_tcp_keepalive/</link><pubDate>Tue, 23 Sep 2025 21:07:53 +0800</pubDate><guid>https://lvv.me/posts/2025/09/23_tcp_keepalive/</guid><description>&lt;p>配置系统级别的 TCP Keepalive ：&lt;/p>
&lt;ul>
&lt;li>空闲 10 分钟开始检测&lt;/li>
&lt;li>每次检测间隔 30 秒&lt;/li>
&lt;li>检测 3 次都失败就断开连接&lt;/li>
&lt;/ul>
&lt;p>把以下配置参数写在 &lt;code>/etc/sysctl.conf&lt;/code> 里。&lt;/p>
&lt;h2 id="配置-linux-的-tcp-keepalive">配置 Linux 的 TCP Keepalive&lt;/h2>
&lt;pre tabindex="0">&lt;code>net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
&lt;/code>&lt;/pre>&lt;h2 id="配置-freebsd-和-macos-的-tcp-keepalive">配置 FreeBSD 和 macOS 的 TCP Keepalive&lt;/h2>
&lt;p>BSD 系列的配置都是通用的：&lt;/p>
&lt;pre tabindex="0">&lt;code>net.inet.tcp.keepidle = 600000
net.inet.tcp.keepintvl = 30000
net.inet.tcp.keepcnt = 3
&lt;/code>&lt;/pre></description></item><item><title>使用命令行精确调整 macOS 的音量大小</title><link>https://lvv.me/posts/2025/09/20_adjust_macos_volume_using_the_command_line/</link><pubDate>Sat, 20 Sep 2025 13:50:14 +0800</pubDate><guid>https://lvv.me/posts/2025/09/20_adjust_macos_volume_using_the_command_line/</guid><description>&lt;p>macOS 把 &lt;code>100%&lt;/code> 音量分成 16 格，使用快捷键每次增加或减少 1 格音量，每一格音量的百分比就是 &lt;code>6.25%&lt;/code>。&lt;/p>
&lt;p>使用命令行可以精确的控制音量大小，调整 6 格的音量就是把输出音量调整为 &lt;code>37.5%&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">$ osascript -e &lt;span class="s1">&amp;#39;set volume output volume 37.5&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>