跳到正文
Hacker News· enjoyyourlife·· 9 天前AI 评分62

llm-desktop-electron:用非 Anthropic 模型驱动 Claude 前端

Show HN: Run Claude Frontend with Non-Anthropic Models

AI 导读

GitHub 项目 llm-desktop-electron 发布,通过本地代理在 Anthropic Messages API 与 OpenAI API 之间转换,让 Claude Code 和 Claude Desktop 的智能体层改用 OpenAI、本地 GPU 模型或其他兼容服务。

正文 · AI 翻译

在 OpenAI、本地 GPU 模型或 Anthropic 上运行 Claude 的 agent 工具

Claude Code 和 Claude Desktop 是很好的 agent 运行框架。这个仓库让你用自选的后端来驱动它们的 agent 层——一个 OpenAI 密钥、一个运行在你自己 GPU 上的设备端模型,或原生的 Anthropic——方法是在本地于 Anthropic 和 OpenAI API 之间进行转换。聊天窗口始终是真正的 claude.ai Web 应用;只有 agent 子层(Claude Code)被重新指向。

Claude Desktop Code tab with the multi-provider model picker

桌面版的 Code 标签页。模型选择器列出了 Composite(跨提供商的回退链)以及每个已配置密钥的提供商的模型,如 provider:model——Gemini、Mistral、nvidia、ollama-cloud、llm7、freetoken、cloudflare——每一轮都通过代理路由到各自的上游;本地使用情况仪表盘汇总了 agent 活动。

这里有两件相互独立的东西,而你可能只想要第一件:

它是什么 你需要什么
1. 代理——openai-proxy/ 一个本地服务器,前端使用 Anthropic Messages API,后端调用 OpenAI(或任何兼容 OpenAI 的服务器)。把任何 Anthropic API 客户端指向它即可。 Node 22+(原生 fetch),以及一个 OpenAI 密钥或像 Ollama 这样的本地服务器
2. 桌面版构建 Anthropic 的 Claude Desktop 应用,解包后在原版 Electron 运行时下运行,并接入代理、提供商切换和设置 GUI Linux 或 macOS,外加你自己的一份 Claude Desktop 副本

代理是普遍有用的部分:它能在任何机器上配合普通的 claude CLI 使用,且不需要本仓库 app/ 目录中的任何内容。桌面版构建标题以下的所有内容都专门针对运行 Anthropic 的 Electron 应用。

许可,请先读这里。app/ 是 Anthropic 解包后的专有捆绑包(约 40 MB 的 JavaScript、原生二进制文件和资源)。它不可再分发,这就是本仓库为私有的原因。对于第 2 部分,你必须从你自己获得许可的 Claude Desktop 安装中提供该目录——参见 提供捆绑包。第 1 部分完全不涉及它。


1. 代理——在 OpenAI(或本地模型)上运行 Claude Code

快速开始

export OPENAI_API_KEY=sk-...              # or point at a local server; see below
cd openai-proxy && node supervise.mjs     # listens on 127.0.0.1:8123, restarts on crash

node proxy.mjs 仍然有效,适合一次性使用。对于任何你打算长期运行的东西,请优先使用 supervisor:代理曾在上游 socket 断开时自行关闭,而数小时内无人察觉——应用、启动器和每个 agent 都继续对着一个已关闭的端口运行。supervisor 会重启它、记录原因,并在无法启动时大声放弃而不是循环重试。

把原版 Claude Code CLI 指向它:

ANTHROPIC_BASE_URL=http://127.0.0.1:8123 ANTHROPIC_API_KEY=unused claude -p "hello"

ANTHROPIC_API_KEY 必须被设置为某个值,因为 CLI 坚持要求如此,但代理会忽略它,并使用 OPENAI_API_KEY 向 OpenAI 进行身份验证。

已用未修改的 CLI 完成端到端验证:一次完整的 agent 回合、221 个工具、工具调用被执行并反馈结果,代理日志显示 model=claude-opus-4-8->gpt-5.6-sol。CLI 仍然声称是“Opus”,因为它在自己的提示中硬编码了这一点;代理日志和进程环境中的 ANTHROPIC_BASE_URL 才是事实依据。

把它指向本地设备端模型

将 OPENAI_BASE_URL 设置为任何兼容 OpenAI 的服务器(Ollama、llama.cpp、LM Studio、vLLM),代理就会像对 OpenAI 一样精确地转换到它。回环基础 URL 被视为无需密钥——不需要 OPENAI_API_KEY(会发送一个占位 bearer,本地服务器会忽略它):

OPENAI_BASE_URL=http://127.0.0.1:11434/v1 OPENAI_MODEL=qwen2.5:7b-instruct OPENAI_API=chat \
  node openai-proxy/proxy.mjs

桌面版将其配置为 local 提供程序,它还会为你启动并调优 Ollama。

配置

一切都有默认值;只设置你想更改的内容。

变量 默认值 作用
OPENAI_API_KEY — 远程端点必需;回环端点可选。也会从 .openai-key 读取(见下文)。
OPENAI_MODEL gpt-5.6-sol 任意模型 id。名称中包含 codex 的会自动路由到 Responses;其他任何内容都会落到 Chat Completions,除非设置了 OPENAI_API=responses。
OPENAI_BASE_URL https://api.openai.com/v1 任何兼容 OpenAI 的端点,包括本地端点。
PORT 8123
OPENAI_API responses responses 或 chat,覆盖名称启发式规则。非 codex 远程模型必需:此应用会发送 200 多个工具,而 Chat Completions 上限为 128。
OPENAI_REASONING_EFFORT max 代理会降级到你的模型可接受的最高值。
OPENAI_CLASSIFIER_SAFETY_MODEL gpt-5.4-2026-03-05 用于 Claude Code 自动模式安全裁决的模型。它有 60 秒的截止时间,超时后会拒绝该操作,因此这里需要一个快速模型——测量数据见 openai-proxy/README.md。

完整列表——约三十个可调项,每个都附有促成它的 bug 说明——位于 openai-proxy/README.md。

不用环境变量,而是在仓库根目录的 .openai-model 中放置 KEY=VALUE 行 (已检入,用于非机密项)。机密 API 密钥 放在其自己的、被 git 忽略的文件中, .openai-key(apiKey=…;复制 .openai-key.example 即可开始)。优先级为 环境变量 → .openai-model → .openai-key → 默认值。

该优先级只存在于一个地方,openai-proxy/config.mjs, 它还会生成下面的配置哈希。要查看一次启动实际会使用什么:

node openai-proxy/config.mjs            # the effective config, with the source of each value

--hash 只打印配置哈希;--validate 会检查它并在出错时以非零状态退出。密钥 从不会出现在其中任何一个里——只有它的 sha256: 指纹。

了解哪个代理正在运行

/health 报告的是身份,而不仅仅是存活状态:

{ "ok": true, "instance": "8f3c…", "pid": 82110, "configHash": "38d9c8b2…",
  "codeVersion": "a8e08f01…", "inflight": 0, "model": "gpt-5.6-sol", "…": "…" }
  • instance 是启动时生成的 nonce,也会写入 proxy-runtime.json。只有 生成它的进程才能提供它,因此两者匹配即可证明所有权——这正是 启动器能够重启它自己的代理并拒绝触碰其他任何东西的原因。
  • configHash 涵盖所有影响行为的设置,外加密钥的指纹。 启动器会比较它,并重启正在提供过时设置的代理,而不是旧行为 ——旧行为中,/health 上的任何应答都算作健康,而更改的模型会静默地不生效。
  • codeVersion 是代理源代码的哈希,用于捕获正在以当前设置运行旧翻译 逻辑的进程。
  • inflight 是当前正在应答的轮次数,因此重启可以说明它会中断什么。

监督程序的行为由环境变量调优;默认值意味着无需改动。 PROXY_MAX_FAST_FAILURES(8)限制立即重启尝试次数,PROXY_RESTART_BASE_MS(500) 和 PROXY_RESTART_MAX_MS(30000)设置退避,而 PROXY_HEALTH_EVERY_MS(15000)/ PROXY_HEALTH_TIMEOUT_MS(5000)/ PROXY_HEALTH_MISSES(3)控制看门狗,用于替换 占用端口却不响应的代理。被外部杀死的代理总是会重启,且从不 计入放弃上限。

使用哪个 API 表面,以及为何重要

Chat Completions Responses
工具限制 128(129 → HTTP 400) 未观察到——探测到 512
推理控制 无 reasoning.effort、推理摘要
本地服务器支持 通用 较新的 Ollama;并非所有本地服务器

Claude Code 提供 27 个工具;Claude Desktop 提供 200 多个。在聊天界面上,128 个工具的上限是真实存在的,因此代理会保留核心工具(读取/写入/编辑/运行/搜索/规划/网络,外加渲染器),并按代理自身的顺序填充其余部分,同时记录被丢弃的内容——一个被静默截断的工具列表与一个只是拒绝使用工具的模型无法区分。

翻译涵盖的内容

双向的文本和工具调用,流式与非流式,外加针对两个模型家族之间行为差异的修复:

  • 渲染 —— GPT 模型会为数学公式输出 \(…\) / \[…\],而 Claude 的渲染器会将其原样显示。已重写为 $…$ / $$…$$,并感知代码围栏,使代码示例保持原样。
  • 持续性 —— GPT 模型经常在回合结束时停下来确认(“如果你愿意,我现在就运行”),这在代理循环中会被视为停滞。通过显式的持续性指令,以及当某个回合宣布了动作却未调用任何工具时自动继续,来解决这一问题。
  • 上下文溢出 —— Claude Code 会根据它以为自己在与之对话的模型来设定自身的自动压缩规模,因此它永远不会触发。代理会进行压缩并重试,包括当溢出以流中事件而非 HTTP 400 的形式出现时。
  • 空回合与截断回合 —— 重试或恢复,而不是作为空白回复呈现出来。
  • 不支持的参数 —— CLI 会发送 stop_sequences,而某些模型会拒绝它。代理会丢弃 API 指名的那个参数并重试,因此下一个不支持的旋钮也会自我修复。
  • 思考 —— OpenAI 的推理摘要被映射为 Anthropic 的思考块。原始思维链在任何设置下都无法从 API 获取。

图像可用。 Anthropic 的 {type:"image", source:{…}} 块——base64 或 url——在 Chat Completions 上变为 image_url,在 Responses 上变为 input_image。如果模型没有视觉能力,则丢弃图片并保留问题,在其位置附上诚实的说明,而不是让该回合失败。

已知缺口:/v1/messages/count_tokens 是估算值,CLI 打印的成本数字是根据 Anthropic 的价格表计算得出的,在代理场景下没有意义。

评估基线

npm run eval           # run the corpus, diff against the frozen baseline
npm run eval:freeze    # overwrite the baseline with what the code does NOW

eval/ 包含一个合成的、无网络的语料库。每个用例都通过真实代理针对一个假上游运行,记录的是代理决定发送的载荷:解析后的模型、工具数量、迟到的工具是否幸存、tool_choice、提示注入、推理、详细程度、输出上限、缓存键、定价层级。所有这些决策都在生成任何 token 之前就已确定,这正是它成为基线而非样本的原因。npm test 在每次运行时检查冻结的基线,因此行为变化无法在无关提交中悄无声息地出现。与之并列的是基线不允许编码消除的不变量——分类器永远不会被赋予工具,安全裁决永远不会解析到主模型,仅仅引用分类器契约的代理回合会保留其完整目录。

测试

npm test        # the whole suite: proxy + settings + launcher scripts + eval baseline

大多数测试是针对特定的错误行为编写的;注释说明了是哪一个。


2. 桌面构建

在标准 Electron 运行时下,从其解包后的 app.asar 运行 Anthropic 的 Claude Desktop(@ant/desktop v1.24012.9,一个 Electron Forge + Vite 构建),并将代理接入代理层、一个提供商切换开关,以及一个覆盖启动器配置的设置 GUI。可在 Linux 和 macOS 上运行。

提供捆绑包

app/ 已提交在此仓库中——Anthropic 的代码——这正是它 私有且不得发布的原因。node_modules/ 和 app/node_modules/ 未提交; 你从自己拥有许可的安装中填充它们。

要从你自己的安装重建 app/:

  1. Find app.asar in your Claude Desktop installation:
    • Linux:/usr/lib/claude-desktop/resources/
    • macOS:/Applications/Claude.app/Contents/Resources/
  2. npx @electron/asar extract app.asar app/
  3. 将同级的 app.asar.unpacked/node_modules/ 合并回 app/node_modules/ 之上—— 原生插件(@ant/claude-native、node-pty,在 macOS 上还有 @ant/claude-swift)以平台二进制形式存在于那里, 应用期望它们与各自的 JS 放在一起。在 Linux 上,@ant/claude-swift 按设计缺失并会安全失败。

此处的版本是 @ant/desktop v1.24012.9;不同版本不一定匹配 那些由环境变量门控的补丁,它们以该构建中的字符串为键。

设置

npm install        # stock Electron 42.9.2, once
./run.sh

Electron 42.9.2 被固定,以匹配从当前 Claude Desktop 安装中提取的原生模块。窗口会在 claude.ai 登录界面打开;照常登录。run.sh 会在每次启动时重新创建 resources/app.asar → app/ 符号链接并重新安装 disclaimer 辅助程序,因此 重新安装 node_modules 没有代价。

Linux 注意:npm install 从 GitHub 的发布 CDN 下载 Electron 二进制文件。如果该主机 在你的网络上被屏蔽,请使用镜像:

ELECTRON_MIRROR=https://registry.npmmirror.com/-/binary/electron/ \
  ELECTRON_CUSTOM_DIR="v{{ version }}" node node_modules/electron/install.js

run.sh 是跨平台的(uname -s):它解析 Electron 资源目录(Linux 上为 dist/resources, macOS 上为 Electron.app/Contents/Resources)、Claude Desktop 配置文件 (~/.config/Claude 与 ~/Library/Application Support/Claude),以及各平台的 disclaimer 辅助程序路径。 有关该移植的设计和折叠条件式的陷阱,请参见 LINUX.md。

在现代 Ubuntu(kernel.apparmor_restrict_unprivileged_userns=1)上,Electron 的命名空间沙箱被 阻止,因此它需要一个 setuid-root 的 chrome-sandbox——而下载的 Electron 并不是。run.sh 通过符号链接到 Claude Desktop .deb 已安装的 setuid-root chrome-sandbox(相同的 Electron 构建,字节完全一致) 来自我修复此问题,使渲染器沙箱保持开启且无需 sudo。如果 没有匹配的系统副本,它会打印一次性的 sudo chown root:root … && sudo chmod 4755 … 修复方法。

免责声明辅助程序

原版 Electron 没有 Claude Desktop 的 TCC 归属辅助程序的等价物,而应用会以 disclaimer <command> <args…> 的方式调用 它——这使其成为本仓库可以选择代理内部模型身份的唯一受支持边界。该辅助程序是仓库自有的源代码 (scripts/claude-code-disclaimer.sh),由 scripts/install-disclaimer.mjs 安装为 各平台 Helpers/ 路径下的绝对符号链接。在 OpenAI/本地模式下,它会把捆绑的 Claude Code 可执行文件重写为 配置的 [1m] 能力身份;在 Anthropic 模式下,它是精确的 argv 透传。它还会 导出 CLAUDE_CODE_SUBAGENT_MODEL,以便 Task/Explore/队友生成——它们在 会话进程内运行且没有可重写的 argv——获得正确的模型。没有任何东西会修补 Claude Code 二进制文件或应用包。

要求

Linux 或 macOS,以及 Node ≥ 22(Electron 42 为应用本身捆绑了自己的 Node)。应用 在低于 Electron 34 时拒绝启动。

设置 GUI

./settings.sh

每个参数都分组展示,并附上其背后的理由,以及实时状态和 Save & restart。状态行将 configured 与 active 区分开来:正在沿用先前设置的代理会被标记为 STALE — restart to apply;启动时的 OPENAI_MODEL=x ./run.sh 覆盖会显示为覆盖;而在 Anthropic 模式下,仅适用于 OpenAI 的设置会因未生效而变暗。Save & restart 会停止应用(它持有对会话存储的独占 LevelDB 锁),等待其退出,仅在能证明该代理属于我们时才停止代理,重新启动,并在报告成功之前确认新代理报告了预期的配置哈希。这是一个本地 127.0.0.1 页面,需要每次启动的令牌,因为该 API 会写入配置并可以重启应用。

选择提供商

两种模式:anthropic(Claude,直连)或 proxy(经由本地翻译代理)。在代理模式下,单个 DEFAULT_PROVIDER(位于 .provider 中)会选择为默认轮次、后台分类器和压缩提供支持的上游——即 openai、local(设备端 Ollama)、openrouter、cohere、gemini、mistral、groq、ollama(Ollama Cloud)之一——而任何单个轮次都可以通过从 Code 标签页的模型下拉菜单中选择一个 <provider>:<model> 来运行在不同的提供商上(代理会将该轮次路由到 .openai-key 中指定提供商的密钥)。

./run-proxy.sh        # via the local translation proxy — upstream = DEFAULT_PROVIDER in .provider
./run-anthropic.sh    # Claude, calling Anthropic directly (stock behaviour)
./run.sh              # whichever .provider says (default: proxy, upstream openai)

旧的 PROVIDER=openai|local|openrouter|cohere|gemini|mistral|groq|ollama(位于 .provider 中或命令行上)仍然有效——它会选择代理模式,并将该提供商作为默认上游。

anthropic proxy
代理的 ANTHROPIC_BASE_URL https://api.anthropic.com http://127.0.0.1:8123
翻译代理 未启动 已启动,已通过健康检查
代理所调用的后端 — DEFAULT_PROVIDER 上游(OpenAI / 设备端 Ollama / OpenRouter / Cohere / Gemini / Mistral / Groq / Ollama Cloud),以及任何按轮次选择的提供商
API 密钥 你的 Anthropic 登录 按上游而定——.openai-key(远程)或无(回环 Ollama)
模型 Claude,按出厂设置 上游的模型,或在下拉菜单中选择的 <provider>:<model>

切换无需取消补丁:对 bundle 的每次编辑都受环境变量控制(PROXY_ANTHROPIC_BASE_URL || <original host>),因此在该变量未设置时,应用会使用其自有的 Anthropic 主机。这仅影响 agent——聊天窗口是远程的 claude.ai Web 应用,在所有模式下都与 Anthropic 通信。

设备端模型(local)

DEFAULT_PROVIDER=local 会将代理指向本地兼容 OpenAI 的服务器,而不是 api.openai.com,因此代理运行在本机的 GPU 上,且无需 API 密钥。它使用 Ollama,在 .local-model 中配置。Code 标签页的下拉菜单还会将你已安装的 Ollama thinking 模型列为 local:<model>(在启动时发现),因此你可以在任何模式下于设备端运行单个轮次。

它会为你管理 Ollama。代理的提示词(系统 + 最多 128 个工具)很大,而系统 Ollama 通常被其服务单元固定为较小的上下文——这会静默截断该提示词,且在没有 root 权限的情况下无法重新绑定。因此 run.sh 会在侧端口(OLLAMA_MANAGED_PORT,默认 11435)启动它自己的 Ollama,具有大上下文,共享你已拉取的模型,并且不干扰系统 Ollama 为其其他客户端服务。它会在多次启动间复用该实例,仅在上下文变化时重启它。使大上下文能适配笔记本显卡的 GPU 调优会自动应用:q8_0 KV 缓存(约为 f16 显存的一半)、flash attention,以及 OLLAMA_NUM_PARALLEL=1,以便将完整上下文发送给单个代理请求,而不是分散到多个槽位。将 OLLAMA_AUTOSTART=0 设为自行管理服务器。

  • 上下文是按模型计算的。OLLAMA_CONTEXT_LENGTH 是默认值;CONTEXT_<model> 会按模型覆盖它(更大的原生窗口可以承载更多;大模型需要更少才能装进 VRAM)。压缩窗口会自动跟随——run.sh 将 CLAUDE_CODE_AUTO_COMPACT_WINDOW 推导为当前生效上下文的 3/4,因此切换模型时能保持一个合理的窗口(可按模型用 COMPACT_<model> 覆盖,或用显式的 CLAUDE_CODE_AUTO_COMPACT_WINDOW 全局覆盖)。
  • 需要支持工具调用的模型。该 agent 从头到尾都是工具调用,因此模型必须发出正确的 OpenAI tool_calls,而不是把它们当作文本倾倒出来。qwen2.5:7b-instruct(32K)、qwen3:8b(40K)和 granite4.1:8b(128K)可以;qwen2.5-coder:7b 不行。先拉取它(ollama pull <model>)。

local 默认使用 Chat Completions(在本地服务器上通用;其 128 个工具的上限也有助于小模型适配上下文)。笔记本 GPU 上的 7-8B 模型能力远不如托管模型——这是为了隐私/离线使用,而非追求最高质量。

启动器配置

仓库根目录下的点文件,全部由 run.sh(或代理)读取,每个都可通过同名环境变量覆盖。

文件 设置 默认值 作用
.provider PROVIDER openai openai = agent 通过代理访问 api.openai.com;local = 代理 → 设备端 GPU 模型;anthropic = agent 直接调用 Anthropic
.openai-model OPENAI_MODEL 及同类 gpt-5.6-sol 上表代理配置中的所有内容,用于 openai 模式
.local-model OPENAI_MODEL、上下文、Ollama 调优 Ollama qwen2.5:7b-instruct 用于 local 模式的本地服务器、模型、按模型上下文和 GPU 调优
.openai-key (已 gitignore) apiKey — 用于 openai 模式的 OpenAI 密钥。在 local/anthropic 中不读取。复制 .openai-key.example 即可开始
.privacy DISABLE_TELEMETRY 1 关闭第一方遥测和 Sentry,并将分析主机黑洞化
.sync SYNC_CLAUDE_SESSIONS、SYNC_CLAUDE_GROUPING 1 与此构建共享 Claude Desktop 的会话和侧边栏分组

user-data/ 是一个隔离的配置文件,但有一个刻意的例外:claude-code-sessions 是指向真实安装存储的符号链接,因此会话是真正共享的,并且双向写入(issue #3)。在任一应用中创建或重命名的会话会立即成为另一个应用的——删除一个会为两者都删除。user-data/ 中的其他所有内容(cookies、缓存、Local Storage)都保持对此构建私有。Local Storage 刻意不共享:LevelDB 一次只允许一个进程,因此共享目录会阻止第二个应用打开自己的 UI 状态。

应用以未打包方式运行(app.isPackaged === false)。

哪些可用,哪些不可用

可用:在 Linux 和 macOS 上启动并保持运行,渲染真实的 Claude Web UI,原生插件加载,桌面↔Web IPC 桥在 claude.ai 源上有效,agent 通过代理在 OpenAI 或本地 GPU 模型上运行,遥测已关闭(isolated-segment 信标显示 ERR_BLOCKED_BY_CLIENT),并且会话与真实安装同步。

在签名包之外无法工作——自动更新、claude:// 深链接,以及任何依赖 macOS 权限(原版 Electron 二进制不具备)的功能(VM/“虚拟化”功能,应用会报告为不可用)。在 Linux 上,仅限 macOS 的部分(全局热键、来自 @ant/claude-swift 的内存压力遥测、计算机使用帧流)按设计缺失并安全失败;启动器为包在启动时无条件调用的少数仅限 macOS 的 Electron API 提供了 polyfill,以便干净启动。

不是问题的启动噪音

每次启动都会出现令人警觉的行,包括健康启动——启动竞态、@ant/claude-swift/office365 ERR_MODULE_NOT_FOUND(仅限 macOS 的模块,安全失败)、Wayland 绑定警告,以及 MISSING_TRANSLATION / “Cowork not supported” 通知。要判断启动是否真正成功,请 grep 这些:

grep -c "isLoggedOut: false" boot.log      # signed in
grep -c "loaded .* features" boot.log       # feature flags fetched

重置

删除 user-data/。


文档

文档 包含内容
openai-proxy/README.md 深入解析代理:每个可调参数、每处行为修复及其背后的 bug、分类器测量、压缩阶梯
SESSIONS.md 桌面构建与你真实的 Claude 安装有何关联:共享内存、会话同步,以及分组为何如此表现
ARCHITECTURE.md 桌面应用如何构建:哪些 UI 是本地、哪些是远程,远程页面使用的 IPC 桥接,哪些层可以修改
ANTHROPIC_ENDPOINTS.md 应用调用的每个 Anthropic 端点,包含载荷及各自用途
FINDINGS.md 包中的值得注意之处——权限模式、扩展注册表、配套硬件配对、自动批准的工具列表
LINUX.md Linux 移植:原生模块采集、折叠条件阻塞项,以及脱离 macOS 后哪些功能会降级
OPENROUTER.md OpenRouter 提供商:基于免费层密钥的目录分析、11 个模型的免费允许列表、质量/速度排序,以及允许列表如何控制选择器和网关发现

回馈贡献

该代理是自包含的(openai-proxy/,GUI 另需 settings/),且不包含任何 Anthropic 代码,因此可以独立于该包进行开发和分享。如果你要扩展它, 请添加一个以你修复的行为命名的测试——这是贯穿始终的惯例,也正是它 在修复本身中捕获了若干回归。

来源:Hacker News · github.com