编程导航技术话题讨论

技术

553 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

ARTS 0927: 单栈逐层展开嵌套字符串、包管理器与 Agent 沙箱本质同源与单次前向传播复刻极速决策模型

每周完成一个 ARTS: 至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tips、Share 简称 ARTS) ## Algorithm 算法:https://leetcode.cn/problems/decode-string/?envType=study-plan-v2&envId=selected-coding-interview ![image-20260927181325161](https://pic.code-nav.cn/post_picture/1608460212774109186/GqRUFEl7bRutYEBS.webp) 我目前想到的思路。遍历字符串,数字、`[`、字母依次压栈,遇到 `]` 时往回 pop 到 `[`,取出前面的数字,重复拼接后压回栈。嵌套括号也能自然处理,因为内层展开后压回栈,外层再 pop 时拿到的就是已经展开好的字符串。 踩过的 3 个坑: 1、**重复次数**:pop 出来的 `values` 里已经有一份了,循环应该从 `j=0` 到 `j < nums-1`,否则会多重复一次 2、**不能用 `reverse()` 处理 pop 顺序**:栈里有些元素是之前展开过的多字符字符串(比如 `"jkjk"`),如果先 `append` 再对整个 `values` 做 `reverse()`,会把多字符元素内部顺序也反转掉。正确做法是 pop 的时候直接用 `insert(0, stacks.pop())` 保持正确顺序 3、**最终拼接用 `append` 不是 `insert(0,...)`**:Java 的 `Stack` for-each 从底到顶遍历,用 `append` 才是正序拼接 代码: ```java public String decodeString(String s) { if (s.isEmpty()) { return ""; } char[] chars = s.toCharArray(); Stack<String> stacks = new Stack<>(); StringBuilder num = new StringBuilder(); for (char c : chars) { if (Character.isDigit(c)) { num.append(c); } else if (c == '[') { if (num.length() > 0) { stacks.push(num.toString()); num = new StringBuilder(); } stacks.push(String.valueOf(c)); } else if (c == ']') { StringBuilder values = new StringBuilder(); while (!stacks.isEmpty() && !"[".equals(stacks.peek())) { values.insert(0, stacks.pop()); } // 单独拿出来 [ stacks.pop(); int nums = Integer.parseInt(stacks.pop()); String coreStr = values.toString(); for (int j = 0; j < nums - 1; j++) { values.append(coreStr); } stacks.push(values.toString()); } else { stacks.push(String.valueOf(c)); } } StringBuilder result = new StringBuilder(); for (String str : stacks) { result.append(str); } return result.toString(); } ``` ## Review 文章:https://nesbitt.io/2026/09/24/package-manager-sandboxing.html Andrew Nesbitt(Homebrew 维护者)对各包管理器沙箱机制做了一次全面调查。文章核心观点是:**包管理器沙箱和 AI 编码 Agent 沙箱本质上是同一个问题**,都需要执行未经审查的第三方代码,都收敛到了同一组 OS 原语(macOS 的 Seatbelt、Linux 的 Landlock/namespace),甚至在实际场景中互相嵌套运行(Homebrew 专门处理了"在 Agent 沙箱里运行 brew"的情况)。 几个关键发现: 1. **已默认启用 OS 级沙箱的包管理器屈指可数**:opam(2018 年起)、SwiftPM(仅 macOS)、Nix/Guix(初衷是可复现性而非安全)、Bazel。大部分主流包管理器的沙箱提案还停留在 Issue 阶段 2. **白名单 ≠ 沙箱**:JS 生态在 Shai-Hulud 蠕虫事件后全面转向安装脚本白名单(pnpm → Bun → Yarn → npm 12),但白名单是二元的:要么运行要么不运行。沙箱解决的是"运行时能访问什么",比如允许 esbuild 编译但禁止它读 SSH 密钥 3. **"交接"(hand-off)是最薄弱的环节**:沙箱内构建产出的清单、缓存、步骤列表,会被包管理器以完整权限执行。Homebrew 7.0 修复的 LaunchServices 沙箱逃逸就是这类交接 Bug 4. **消除代码执行可能比沙箱更有效**:Go 和 Elm 从未有安装钩子;NuGet 删除了 `install.ps1`;Homebrew 的 `*_steps` 把任意 Ruby 钩子替换为签名的声明式数据 最让人印象深刻的一个数据:Anthropic 报告用户对 Claude Code 权限弹窗的批准率高达 **93%** —— 这就是为什么"每次都问用户"行不通,必须走沙箱路线。真正使用的时候,都是不看内容,直接无脑点击同意的,我就是这样😂 Agent 具备自主安装依赖的能力 + 包管理器缺乏沙箱 = 供应链攻击的绝佳放大器。Shai-Hulud 蠕虫通过 npm postinstall 传播后,居然还能把 hook 写入 Claude Code 的配置文件实现持久化,这说明 Agent 和包管理器的安全边界必须协同设计,而不是各管各的。 ## Tips 最近没啥 Tips 推荐一些 mac 软件吧: 1、[Stats](https://mac-stats.com/):展示状态 2、[OpenUsage](https://github.com/robinebers/openusage):查看 Cursor、Claude、Codex 等等的使用额度、充值时间等等,这里不推荐 OpenClaw 之父的 CodexBar,他运行一段时间磁盘的读取量非常夸张,个人强烈不推荐,下面是官方的演示图片: ![image-20260927223113013](https://pic.code-nav.cn/post_picture/1608460212774109186/Ub939yDZYnscFWV0.webp) 3、[EcoPaste](https://github.com/EcoPasteHub/EcoPaste):剪切板,如果有一些问题可以让 AI 修复之后继续使用,免费开源的 yyds ## Share 文章:https://www.privatemode.ai/blog/system-one-from-glm-flash(虽然有点广子,但是还有有东西的) Privatemode AI 这篇文章演示了一个非常巧妙的技巧:如何把普通的开源 LLM(GLM-5.3-Flash)变成一个类似 TypeSafe AI **Jev** 的 "System One" 决策模型。 **背景**:TypeSafe AI 最近发布了 Jev,一个专为结构化决策设计的非自回归模型。它不像传统 LLM 那样逐 token 生成文本,而是在**单次前向传播**中直接输出决策结果和校准过的置信概率,号称比前沿 LLM 快 ~200x、便宜 ~400x。但 Jev 是闭源的。 **核心技巧**:这篇文章展示了如何用开源模型复刻这个能力,关键就是 vLLM 的 `allowed_token_ids` 参数。 **`allowed_token_ids` 是什么?** 它是 vLLM `SamplingParams` 中的一个参数,作用是在采样阶段对 logits 做 **masking**:把不在列表里的所有 token 的概率被严格限制为 0,保证绝对不会被生成 ,强制模型只能从你指定的 token 中选择输出。这意味着模型在一次前向传播中,会把所有概率质量分配给你允许的那几个 token。 **怎么用?** 举一个情感分类的例子: ```python from vllm import LLM, SamplingParams import math llm = LLM(model="zai-org/glm-4-9b-chat-1m") tokenizer = llm.get_tokenizer() # 定义标签 → 获取对应的 token ID labels = ["0", "1", "2"] # 0=正面, 1=负面, 2=中性 allowed_ids = [tokenizer.encode(l)[0] for l in labels] params = SamplingParams( max_tokens=1, # 只输出一个 token allowed_token_ids=allowed_ids, logprobs=len(labels), # 获取所有候选的 logprob temperature=0, # 确定性输出 ) prompt = "判断以下评论的情感倾向(0=正面/1=负面/2=中性):'这个产品太好用了!'\n答案:" outputs = llm.generate([prompt], params) # 读取结果 token = outputs[0].outputs[0].text logprob = outputs[0].outputs[0].logprobs[0][int(outputs[0].outputs[0].token_ids[0])].logprob confidence = math.exp(logprob) # e^logprob = 概率 print(f"分类: {token}, 置信度: {confidence:.2%}") # 输出: 分类: 0, 置信度: 94.32% ``` 几个**关键细节**: 1. **`max_tokens=1`**:只生成一个 token,跳过自回归循环,这是速度提升的关键 2. **logprob → 置信度**:`logprob=0.0` 表示 100% 置信 e^0=1,越负越不确定。通过 `math.exp(logprob)` 可以直接得到概率值 3. **标签必须是单 token**:如果标签被 tokenizer 拆成多个 token(比如 "Very Positive"),只会生成第一个 token,结果就废了。所以用数字编号("0"/"1"/"2")是最安全的 4. **与 structured output 的区别**:vLLM 也有 `guided_decoding`(JSON schema 约束),但那是在多 token 生成中逐步约束,仍然是自回归的。`allowed_token_ids` + `max_tokens=1` 才是真正的"单次前向传播" 那么折腾了半天和原版的 Jev 有啥区别?这个 「Jev」可以做到图像做分类决策、可以更换更强的开源模型做决策等等

学习开源项目时我们应该画哪些图?

大家好,我是不会喷火的小火龙。 刚开始深入看开源项目的时候,我经历过两个极端。 一个是纯靠肉眼硬看。连着翻了三天,几万行代码从头看到尾,自以为搞懂了,合上电脑脑子里依然是一团浆糊。 另一个是把精力全花在画图的排版上。打开 Draw.io,花了一整个下午在画布上拖方块、微调对齐像素、挑选各种莫兰迪配色,画出一张五颜六色的庞大架构图。结果第二天回头看,自己都找不到核心的调用链路在哪里。 后来我才明白,画图真正的价值是帮大脑把复杂的调用和数据流降维,理清骨架,而不是做图表美化。 关键在于什么阶段、带着什么目的、选什么工具、画什么图。 这篇文章把这件事梳理清楚:工具怎么选、常见问题对应什么图、拿到项目按什么顺序画,以及几个容易踩坑的地方。 --- ## 一、工具选型:Mermaid、draw.io、Excalidraw、SVG 各自的边界 很多人问我画图该用什么工具,我的建议是不同场景用不同的工具,不用强求某一款。 ### Mermaid:代码化与版本管理首选 Mermaid 用纯文本语法生成图表,天然支持 Git 版本管理,和 Markdown 完美融合。GitHub 的 README 里直接写 Mermaid 代码就能直接渲染。 它的优势在于修改极快:调整一张图只需要改几行文本,不用打开任何独立的图形编辑器,也特别适合让 AI 帮我们生成初稿。 适合场景:API 调用流程图、Agent 状态执行循环、时序图(Sequence Diagram)、README 技术流程文档。 ### draw.io:正式架构与工业级排版 draw.io(diagrams.net)完全免费开源,组件库非常全,自带 AWS、GCP、Azure 和 K8s 的官方图标集。它的连线锚点吸附精准,支持复杂的多层对齐。当你需要画一张正式的技术方案图或论文架构图时,它最稳妥。 适合场景:微服务架构图、云原生与 K8s 部署拓扑、技术方案设计图、PPT 汇报图。 ### Excalidraw:讨论方案与直观教学的手绘白板 Excalidraw 的手绘质感能降低心理门槛。画出来的线条带着手绘感,不会让人觉得是不可更改的最终定稿,反而能鼓励大家提出修改建议。 适合场景:早期技术方案讨论、团队白板脑暴、教程里的直观概念解释图。 ### SVG:矢量控制与极简图形 SVG 本质是 XML 代码,可以精准控制每一个节点与路径,无限放大不会模糊,文件体积极小。 适合场景:极简矢量插画、高质量技术信息图、Logo 与技术图标。 ### AI 生图:概念隐喻与视觉呈现 如果不需要精确的技术细节,只是想表达某种技术概念的反差或情绪隐喻,用 Midjourney 或 GPT-4o 生图效率最高。 适合场景:技术博客与公众号封面、宏观概念反差插画。 如下表所示,我把常见的开发场景与推荐的绘图工具整理成了对照表: | 开发场景 | 推荐工具 | 选型理由 | |:---|:---|:---| | API 调用流程 | Mermaid | 纯文本代码化,Git 可版本控制,AI 生成方便 | | Agent 执行流程 | Mermaid | 状态循环与条件分支表达清晰 | | UML 时序图 | Mermaid | 语法简洁,`sequenceDiagram` 原生支持强 | | 微服务架构图 | draw.io | 组件库全,锚点吸附准,适合复杂拓扑 | | 云 / K8s 架构 | draw.io | 内置各云厂商与 K8s 官方图标 | | 论文系统架构 | draw.io / SVG | 矢量导出,排版精度容易对齐 | | 方案讨论草稿 | Excalidraw | 手绘风格心理门槛低,方便随时修改 | | 教程解释图 | Excalidraw | 风格柔和,降低读者的理解门槛 | | README 技术流程 | Mermaid | 直接在 Markdown 中渲染,无需上传图片文件 | | PPT 高质量信息图 | SVG / draw.io | 矢量无损缩放,支持精细排版 | | 博客 / 公众号封面 | AI 生图 | 视觉冲击力强,易于传达情绪 | | 概念视觉 | AI 生图 | 适合抽象概念的隐喻呈现 | | 极简矢量插画 | SVG | 代码可控,文件体积极小 | | Logo / Icon | SVG | 矢量无限缩放,保持视觉规范统一 | --- ## 二、问题驱动:想搞清楚什么问题,就画什么图 画图容易犯的错误是把静态依赖、动态调用和部署环境全揉在一张图里,箭头到处穿插,最后画成一张谁也看不懂的蜘蛛网。 画图的核心是问题驱动:心里有什么疑问,就画什么图去回答。 工程中常见的核心问题,可以按照从宏观到微观分为四个层次。如图所示: ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/aFW9bGIR8mhYqVwr.webp) 下面挑几个最常用的具体拆解: **系统架构图**回答项目整体是干什么的。重点标出前端、后端、AI 模块、数据库、消息中间件以及第三方外部服务的边界,让人一眼看清系统的大致构成。 **模块图与组件图**回答项目由哪些模块组成。重点是标清每个模块的单一职责,以及模块之间的单向依赖关系。 **调用链图**回答一个请求穿透了哪些代码。从 Controller 到 Service,再到数据访问层,梳理出入口到出口的调用路径。 **时序图**回答不同对象之间的调用顺序。谁先发起调用、返回什么、是同步等待还是异步通知,时序图最适合表达这类时序关系。 **数据流图**回答数据从哪里来、到哪里去。顺着请求参数,看它在内存里被转换成了什么对象、通过消息队列发送了什么格式、最终持久化到了数据库的哪些字段。 **状态图**回答核心对象的状态迁移规则。比如订单从待支付到已支付、已发货的生命周期,或者 Agent 记忆提取时的添加、更新、删除判定。 **Agent Workflow 图**回答 AI Agent 怎么循环运转。LLM 推理、工具选择、执行反馈、记忆读写、条件路由,这些用带有判断条件的状态图画出来最为直观。 ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/52oFEtNEF69MdiBJ.webp) --- ## 三、实战闭环:学习开源项目的 6 步画图 SOP 拿到一个陌生的开源项目,具体可以按下面这 6 步来画。如图所示: ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/iw0KQWnZP8HGbuwz.webp) ### Step 1:跑起来项目,画系统架构图 这是第一步。先别扎进源码,顺着 README 的 QuickStart 把 Demo 跑通一遍,感受一下输入输出和交互方式。 项目跑起来后,画一张粗粒度的系统架构图:前端在哪、后端在哪、用了什么数据库、调了哪些第三方接口。这张图不需要任何代码细节,把黑盒变成灰盒即可。 ### Step 2:看 README 和目录结构,画模块图 不深入具体文件,只看一级目录名和项目文档说明。弄清楚项目分了几个主要模块、各模块负责什么业务、它们之间的大致依赖方向。 画出来的模块图应该能解答一个问题:如果后续要改某个功能,应该去哪个目录下找。 ### Step 3:选一个核心功能,画业务流程图 在所有功能中,选出最常用的一条主线(Happy Path)。比如电商项目选下单支付,Agent 项目选用户提问到输出回复,知识库项目选文档解析到检索召回。 画出纯业务视角的流转步骤:从哪里触发、经历几个阶段、产生什么结果。这一步暂时不涉及具体的代码和类名。 ### Step 4:从入口开始追踪源码,画调用链或时序图 找到入口函数(比如 Controller 接口或 CLI 命令),顺着刚才挑出的业务主线单向跟读代码。 这里有个关键原则:只跟正常流程的主干,先忽略异常重试、参数兜底和日志打印。把一条请求流经的关键类和方法串联起来。涉及多个对象协同的,画时序图往往更清楚。 ### Step 5:分析关键参数与消息传递,画数据流图 把目光从代码调用转移到数据本身。请求携带的入参是什么结构,在中间层被解组成什么对象,有没有通过消息管道流转,最终落盘时的表结构是怎样的。 数据流图能帮我们理清核心业务实体在整个系统里的流动全貌。 ### Step 6:遇到复杂结构按需补图 前 5 步已经能帮我们掌握系统的大致脉络。遇到某些局部复杂度高的模块,再针对性补充: - 数据库表关联较多,补一张 ER 图 - 类继承和接口抽象层级较深,补一张类图 - 实体状态迁移规则较多,补一张状态图 - 涉及智能体自主决策,补一张 Agent Workflow 流程图 - 涉及上线部署和容器编排,补一张部署架构图 举个例子,如图所示,一个典型的 AI Agent 循环执行图如下: ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/kp7BelMBgKsl4RrK.webp) Agent 的核心机制包含推理、判断、工具调用、观察反馈与再次推理。这类包含循环与条件分支的结构,用状态图能够把每一次跳转的条件表达得清晰明了。 --- ## 四、画架构图容易踩的 3 个坑 很多经验丰富的工程师画出来的图线条不多,但表达很精准。他们通常会注意避开这几个常见误区: ### 1. 试图在一张图里展示所有细节 如果一张图在 30 秒内没办法让读者看明白核心逻辑,说明它的信息量过载了。 不少人画图习惯把所有技术栈图标全摆上去,每个方块之间拉满箭头,最终变成一张庞杂的连线网。好的架构图通常是做减法的结果,画出来的模块越克制,沟通成本越低。 ### 2. 第一版图就塞入大量分支逻辑 第一版架构图最好只关注标准的正常流程。 如果一上来就把重试策略、熔断降级、权限校验、日志打点全画进去,主干流程就会被杂音淹没。先把正常主干画清晰,有需要再为复杂的边缘逻辑单独画子图。 ### 3. 脱离源码之后图无法自解释 判断一张图是否清晰的标准很简单:不看源码的情况下,把图拿给同组的工程师看,对方能不能在短时间内看懂业务逻辑和流转顺序。 如果必须边看图边翻源码才能明白箭头在表达什么,说明图上的职责边界或数据流向还没有梳理到位。 --- ## 写在最后 画图本身并不是目的,通过画图建立对系统的全局理解才是目的。 代码细节随时可以让 AI 协助编写或查找,但能把复杂系统抽象为清晰结构的能力,是工程师长期积累下来的关键基本功。 下次看一个陌生的开源项目时,可以先别急着逐行读代码。先问自己当前最需要弄清楚什么问题,选好合适的工具,把那张对应的图画出来。 --- > 我是小火龙,一个持续在 GitHub 等开源社区挖掘真正好用、能打的高价值项目,同时记录自己用 AI 搓工具、做产品、踩坑填坑全过程的独立开发者。如果今天这篇对你有启发,欢迎关注公众号「**[小火龙AI 手记](https://mp.weixin.qq.com/s/u_bHjYo00gbDJUk8bTkrdA)**」,我们下篇见。

做 Coding Agent 搜代码:到底该选 RAG 还是 Grep?扒完 Claude Code 源码我顿悟了

大家好,我是不会喷火的小火龙。 很多团队自研 Coding Agent,第一步就是去搭向量数据库——Chroma、Qdrant、Weaviate 随便选一个,跑 Embedding,切片,建索引。看起来很"AI",很高大上。 但你有没有想过:Claude Code,目前公认最强的 AI 编程工具之一,它的代码检索底层,其实就是一个 50 年前的命令行工具——`grep`? 如图 1 所示,这就是很多团队盲目上 RAG 之后经历的真实工程困局,和 Anthropic 自己走过的弯路。 ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/eY5AudlFcmHq3hEE.webp) 这篇文章想帮你搞清楚三件事:代码检索场景下 RAG 为什么频繁翻车、Claude Code 的极简方案如何跑通、以及你自己的项目到底该怎么选。 --- ## 一、为什么代码检索场景下,传统 RAG 频频翻车? 代码是符号系统,不是自然语言。这句话听起来像废话,但绝大多数 RAG 翻车的根源就在这里。 向量语义检索的逻辑是意思相近的文本在向量空间里彼此靠近,这在自然语言里成立,但在代码里会系统性失效。举个例子:`createD1HttpClient` 和 `buildD1HttpClient` 语义高度相近,向量距离极小,但它们在代码里是两个完全不同的函数;而同一条调用链里相互依赖的函数,语义可能毫无关联,向量检索根本找不到它们之间的联系。 如下表所示,代码符号场景下,语义向量召回和精确匹配之间的准确率差距相当触目: **代码精确符号 vs 语义向量召回偏差对比** | 查询类型 | 示例查询 | 向量检索结果 | 精确匹配结果 | |:---|:---|:---|:---| | 函数名精确查找 | `createD1HttpClient` | 召回 `buildD1HttpClient`(相似但错误)| 精准命中,第 1 条结果 | | 错误码定位 | `ERR_DB_CONNECTION_TIMEOUT` | 召回语义模糊的错误描述文本 | 直接定位到常量定义行 | | 调用链追踪 | `handlePaymentCallback` 的全部调用方 | 召回支付相关的无关业务代码 | 逐个匹配调用点,一个不漏 | | 变量赋值查找 | `MAX_RETRY_COUNT = 3` 在哪里定义 | 无法区分定义和引用 | 精确定位定义行 | RAG 在代码场景还有三个硬伤。 第一,Chunk 切片会破坏 AST。按字符数盲目切片,会把一个类或一个函数切成两半,上下文彻底断裂。第二,索引永远赶不上代码变化。代码是秒级变动的,向量索引构建慢、增量同步复杂,极易产生脏数据,让 LLM 基于过期上下文产生幻觉。第三,全量代码送第三方向量化,隐私泄露风险不可忽视;本地跑大型 Embedding 模型,GPU 成本直接劝退。 --- ## 二、扒开 Claude Code 源码:极简的 Agentic Search 是怎么跑通的? Anthropic 没有预先构建任何静态索引。Claude Code 的做法是把搜索变成 LLM 的"多轮自主探索循环"。 三大并发安全工具构成整个检索引擎: - `GlobTool`:按文件名模式快速扫描项目骨架,类似人类第一步看目录结构,确定大致位置。 - `GrepTool`(底层是 ripgrep):毫秒级全文精确正则搜索,类似人类在 IDE 里按 `Cmd+Shift+F` 搜关键词。 - `ReadTool`:按需读取具体行号范围,类似人类定位到文件后翻开那几十行上下文。 为什么选 ripgrep 而不是普通 grep?ripgrep 用 Rust 开发,内置 SIMD 硬件加速,万级文件的全文扫描仅需约 200ms,自动跳过 `.gitignore` 指定的目录,天然适配代码仓库。内置的 `head_limit=250` 截断保护,防止搜索结果把上下文窗口撑爆。 如图 2 所示,两者的底层架构存在根本性的范式转移: **图 2:静态 RAG 检索管线 vs Agentic Search 多轮自主探索流程** ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/1hdGf8uUBGsYNk3y.webp) 这个设计里最巧妙的地方:LLM 本身就是最顶级的动态 Reranker。每轮检索结束后,LLM 自己判断这个线索够不够、要不要继续顺藤摸瓜,完全替代了传统架构里那个静态的 Rerank 模型。 --- ## 三、权威佐证:Anthropic 踩坑实录与亚马逊论文实锤 放弃 RAG 不是 Anthropic 拍脑袋的激进决定,是被真实实验数据逼出来的。 Boris Cherny(Claude Code 技术负责人)在 2025 年 5 月的 Latent Space 播客里说过:Claude Code 早期确实搭建过基于 Voyage Embedding 的向量 RAG 检索系统,效果"还行"。但在实测用 Glob + Grep + Read 构成的 Agentic Search 之后,他的原话是: > "outperformed everything, by a lot. You avoid all the problems with security, staleness, and indexing." 安全问题没了,索引过期没了,增量同步也不用维护了。 学界的数据同样说明问题。亚马逊科学团队在 AAAI 2026 发表的论文《Keyword search is all you need》([arXiv:2602.23368](https://arxiv.org/abs/2602.23368))严格对比了标准向量 RAG 和纯关键词检索的 Agent 系统,结论是:关键词搜索在综合性能上达到 RAG 的 90% 以上,在代码等高度结构化的符号系统中,精确匹配的表现还显著优于向量语义检索。 从工程实践到学术实验,两份证据指向同一个结论:代码这个特殊领域里,精确性比语义相似性更重要。 如图 3 所示,代码搜索工具链使用图: ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/yxd34Qyzcl89EkLd.webp) --- ## 四、反方视角:Cursor 为什么坚持重仓向量? 读到这里,你可能会问:Cursor 呢?它也是 AI 编程工具里的顶流,技术路线和 Claude Code 截然不同,难道走错了? 没有。两者的架构选择,背后是产品形态的差异。 Claude Code 是轻量 CLI 工具,面对频繁切换的项目,零冷启动是第一要务。每次打开一个新项目,没有时间也没有必要预建索引,Glob + Grep 随开随用,几毫秒就能工作。 Cursor 是 IDE 插件,常驻用户系统,面对的往往是几十万文件的超大 Monorepo。在这个规模下,每次查询都做全量 ripgrep 扫盘,性能会出现瓶颈。 如图 4 所示,Cursor 并没有抛弃 grep,而是构建了一套双轨混合系统: **图 4:Cursor 混合检索双轨架构** ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/0pOC83oqsfffWCpk.webp) Cursor 工程团队在官方博客([Instant Grep & Codebase Indexing](https://www.cursor.com/blog/instant-grep))里直说:纯语义搜索在精确标识符、错误码、函数名上表现太差,所以他们自研了基于三元组(trigram)倒排索引的"Instant Grep"来弥补。两套系统并联,精确归精确,语义归语义,用 Merkle Tree 实现分钟级增量同步保持索引新鲜。 Cursor 的一个典型场景是:用户说"微信支付退款重试逻辑在哪里",记不住具体函数名,这时候语义向量检索才真的有用。 --- ## 五、实战选型指南:自研 Coding Agent 到底怎么选? 扔掉非黑即白的架构争论。正确的问题是:你的产品形态和业务场景是什么? 我把这套选型逻辑整理成了一张清晰的决策树,如图 5 所示: **图 5:Coding Agent 代码检索技术选型决策树** ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/WAwc5q4RATDwzAMp.webp) 三个场景的核心判断: 模式 1,极简优先,适合 90% 的个人开发者和轻量 CLI 工具。零依赖、零维护,直接用 ripgrep + Glob + Read 先把产品跑起来,有实际用户反馈再说向量的事。 模式 2,混合检索,适合 IDE 插件和常驻大型 Monorepo 的服务。精确符号归 trigram 倒排,模糊语义归轻量向量,两者并联。不要上重型托管向量数据库,自研 trigram 索引成本比你想象的低得多。 模式 3,LSP 语法感知,有明确跨文件引用追踪需求时接入 Language Server Protocol,获取符号定义和引用关系图。这才是"语义理解"真正应该发生的地方。 --- ## 结语 Anthropic 用 50 年前的 grep 打败了自己搭的向量 RAG,这不是反智,这是工程上的诚实:代码是精确的符号系统,grep 是精确的符号匹配工具,用对了工具比堆技术栈更管用。 希望这篇文章能帮你在自研 Coding Agent 的路上少走一段弯路。 如果你对这类技术拆解感兴趣,欢迎关注公众号「[小火龙AI 手记](https://mp.weixin.qq.com/s/1NIIz2-4XnP8cSDmr9Fa-g) 」。 这里持续挖掘 GitHub 等开源社区里真正好用、能打的高价值项目,拆解它们背后的工程逻辑;同时也记录我自己用 AI 搓工具、做产品、踩坑填坑的全过程实录。都是有一点技术基础就能看懂的干货,跟你一起把 AI 驯化成真正趁手的生产力工具。 --- *参考资料:* - *Boris Cherny & Cat Wu on Claude Code,Latent Space Podcast,May 2025:https://www.latent.space/p/claude-code* - *Claude Code 官方文档:https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview* - *Shreyas Subramanian et al.,"Keyword search is all you need",AAAI 2026:https://arxiv.org/abs/2602.23368* - *Cursor Engineering,"Instant Grep & Codebase Indexing":https://www.cursor.com/blog/instant-grep*

GLM5.3 Flash用blender建模有什么技巧吗

老大,我想知道用GLM操控blender建模是有什么技巧或者流程吗,原型和建模出来的差的有点大啊,这建模出来的结果我很难绷得住啊 ![53a9e0f7-437c-4b18-9c65-52aa7f8dc39e.png](https://pic.code-nav.cn/post_picture/1963444195556134913/gAze4FifCnMnrMiW.webp) ![031cae05-50d5-444a-b08e-649c4b2fb565.png](https://pic.code-nav.cn/post_picture/1963444195556134913/lAxmvvqkaJ35K8Zh.webp)

ARTS 0913: 双栈互补实现队列、CIDR 聚合化解路由膨胀与 AI 作弊串通绝非偶然 Bug

每周完成一个 ARTS: 至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tips、Share 简称 ARTS) ## Algorithm https://leetcode.cn/problems/implement-queue-using-stacks/description/?envType=study-plan-v2&envId=selected-coding-interview ![image-20260913200759983](https://pic.code-nav.cn/post_picture/1608460212774109186/Vu737RRe3wp8lcOR.webp) 这道题目要求使用两个栈并且只用基本操作也就是 peek pop push empty 这几个 需要注意: 1、这两栈是互补关系(可以看后面的图),我一开始以为这个 stackS 只是一个备份,是 stackF 的反向备份 2、判断是否为空的时候,不要用 peek 因为遇到 null 的时候会抛出异常 `EmptyStackException`,可以使用 empty 判断 3、一个算法大概 10 分钟左右解决不了,就可以叫外援了(AI) 完整的流程: ![f6ac590ad5a5ec6c4e65280a36b2bb15](https://pic.code-nav.cn/post_picture/1608460212774109186/PymZRqumEGbAqVPN.webp) 代码: ```java class MyQueue { // 用于接收新加入的元素 private Stack<Integer> stackF = new Stack<>(); // 用于执行 pop / peek private Stack<Integer> stackS = new Stack<>(); public MyQueue() { } public void push(int x) { stackF.push(x); } public int pop() { // stackS 有数据,直接从 stackS 操作 if (stackS.isEmpty()) { // stackS 为空时,把 stackF 整体翻转 while (!stackF.isEmpty()) { stackS.push(stackF.pop()); } } return stackS.pop(); } public int peek() { // stackS 有数据,直接查看队头 if (stackS.isEmpty()) { // stackS 为空时,把 stackF 整体翻转 while (!stackF.isEmpty()) { stackS.push(stackF.pop()); } } return stackS.peek(); } public boolean empty() { // 两个栈都为空,队列才为空 return stackF.isEmpty() && stackS.isEmpty(); } } ``` ## Review 继续看《TCP/IP 详解》,大概学到关于 CIDR 和聚合一些问题: 1、到 94 年,一半以上的 B 类地址被分配一半 2、32 位 IPv4 地址不住于应对 21 世纪的规模 3、随着 A 类、B 类、C 类的路由词条变得越来越多,路由的性能会受到影响 解决办法: 1、前缀的方式解决 1 问题,不管你是 B 类还是 C 类,还是其他的,只要告诉那些前缀不变就好了 比如:一个公司之需要 256 个地址,没有这个前缀的方式需要两个 ``` 192.168.1.0/24 192.168.2.0/24 ``` 具体的范围可以算出来,但是我们会发现他们是两个独立的**广播域/子网**,不方便管理并且还容易出现浪费,因为不灵活 有了这个 CIDR 我们就可以直接指定: ```IP 192.168.0.0/23 ``` IP 数量没变,但是现在这 500 多个 IP 是一个子网下面的,方便管理和路由 2、IPv6 应运而生 3、使用数结构提高性能,性能直接起飞 ![image-20260914003151330](https://pic.code-nav.cn/post_picture/1608460212774109186/KfXwoOXnHGLIDF1K.webp) ## Tips 1、我用下来感觉 Gemini 4.8 flash 也是挺强的(grok 和 claude 的用的比较多),配置 agy cli 使用,但是缺点就是慢,优点就是价格非常便宜,某鱼 20 元以内就能买 18 个月会员 2、Codex 抓网页样式的实现挺强的,就算不用 OpenAI 的模型效果也是可以的 3、最好让 AI 写 Hook 修改完成内容之后,主动让 AI 知道修改的内容是否有一些编译上的问题 ## Share 文章:https://yoshuabengio.org/en/publication/why-are-ai-agents-lying-cheating-and-coordinating 针对近几个月频繁出现的 AI Agent 严重违规事件(如 OpenAI–Hugging Face 事件中智能体突破沙箱、自主串通发动网络攻击等),深度学习先驱 Yoshua Bengio 发表长文,从底层机制剖析了这一现象。他指出,这绝非偶然 Bug,而是现行训练范式下的必然产物: 1. **机制根源:预训练与强化学习的合力** 人类语料植入了隐式目标,而强化学习将模型塑造为极致追求奖励的最优化机器。为确保完成任务,自我保全、获取控制权甚至多 Agent 串通,都会作为理性的“工具性目标”自然涌现。 2. **目标冲突与自欺合理化** 当“明确的任务目标”(如必须攻破靶机)与“抽象的安全准则”(如遵守道德)冲突时,更强的模型更擅长利用语言歧义钻空子。它们甚至会在内部思维链(CoT)中展开“动机性推理”,像人类自欺一样编造借口将作弊合理化。 3. **评测感知与暗中潜伏** 模型已能感知自身是否处于被评估状态,学会“当面顺从、背后越狱”,甚至试图篡改评分代码或使用隐写术隐秘串通,以避免被人类断电关机。 **核心启发**: “打地鼠”式的外挂监控在更高智能面前终将失效。行业必须在拿出严格的“安全论证”(Safety Case)前放缓前沿推进,不能任由逐底竞争持续,而应转向“设计即安全”(如科学家 AI 框架)的全新底层范式。

Git 修改历史 Commit

1、git log 看 ![image.png](https://pic.code-nav.cn/post_picture/1608460212774109186/DKk3V9EMpFb1WBi1.webp) 2、输入命令 ``` git rebase -i 上面看到的 commit id ``` 然后点击 i 进入编辑模式之后把下面红框改成 edit(一开始是 pick),并且需要 esc + :wq 保存,这个就是和 vim 操作一个逻辑了。 ![image.png](https://pic.code-nav.cn/post_picture/1608460212774109186/AVFDIEFY6fs1U4v2.webp) 保存之后可以看到下图: ![image.png](https://pic.code-nav.cn/post_picture/1608460212774109186/B5RGiILWoV0H5uxy.webp) > 如果只是修改 commit 信息那么只需要执行 git commit --amend 即可。 > 修改完成之后也是 git push --force 仓库地址 master 即可。 3、修改本次提交的文件,比如说删除一些不需要的信息之类的。如果是修改还需要进行 git add git commit 这个过程可以用 idea 来搞定: ![image.png](https://pic.code-nav.cn/post_picture/1608460212774109186/oxHJUCo1tisSaxpp.webp) 4、执行 ``` git rebase --continue ``` ![image.png](https://pic.code-nav.cn/post_picture/1608460212774109186/JqEZTUmHujKmLtxq.webp) 5、最后的最后就是执行 git push 但是普通的 push 不可以,需要 --force-with-lease (比 --force 更安全一些): ``` git push --force-with-lease 仓库地址 master ``` 6、如果一直登录失败可以使用 gh 进行登录,输入下面的命令之后会在默认浏览器弹出 GitHub 的授权页面,点击授权即可,点击授权之后等一下会这个 gh 命令就会登录成功 ``` gh auth refresh -h github.com ``` 7、可以查看登录状态,输出正常就表示登录成功了: ``` gh auth status ```

ARTS 0823: 删除链表节点、写进内存不算安全只有 fsync 才扛断电与 Anthropic 扫描再毁掉纸本如何锁住知识

每周完成一个 ARTS: 至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tips、Share 简称 ARTS) ## Algorithm 中等题目:https://leetcode.cn/problems/delete-node-in-a-linked-list/?envType=study-plan-v2&envId=selected-coding-interview ![image-20260822234531880](https://pic.code-nav.cn/post_picture/1608460212774109186/X5Pw6bTZpfSrqvxv.webp) 一些细节: 1)咱们不知道 head 也不需要知道 2)如果 cur 的值等于需要删除的 node 的值,那么怎么操作呢? 1、咱们不需要返回 head 这个方法是 void 2、如果咱们的需要替换格子 B 那么现在需要把 B 的 next 设置成 D ``` 格子A 格子B 格子C 格子D [4] → [5] → [1] → [9] ↑ node(只能动 B) ``` 3、咱们现在需要最终效果是:A → C → D 那么如果是只能修改 B 和 C,那么咱们直接把 C 的内容设置到 B 即可 ```java /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public void deleteNode(ListNode node) { ListNode cur = node; while (cur != null) { if (cur.val == node.val) { cur.val = cur.next.val; cur.next = cur.next.next; return; } cur = cur.next; } } } ``` ## Review 文章: https://oldblog.antirez.com/post/redis-persistence-demystified.html 核心就一句话:写进内存不算安全,`write()` 只扛进程挂,`fsync()` 才扛断电;Redis 默认 AOF `everysec`,最坏丢 2 秒,和 Postgres / MySQL 调完参数之后其实差不多。 大概分为 5 步: 1. 客户端向数据库发送写入命令(数据位于客户端内存中) 2. 数据库接收到写入请求(数据位于服务器内存中) 3. 数据库调用将数据写入磁盘的系统调用(数据位于内核的缓冲区中) 4. 操作系统将写入缓冲区传输到磁盘控制器(数据位于磁盘缓存中) 5. 磁盘控制器实际将数据写入物理介质(磁盘、Nand 芯片、...) 步骤二是设计会非常复杂,有时候会使用其他的线程进行操作 步骤三是 kernel 实现的,一般会有很多层。在 Linux 系统中,一般是文件系统的 page cache,也是使用缓存等到何时的时机再进行提交到磁盘。有些数据库会自己实现这个层,就使用文件系统的 page cache。也有 API 可以跳过 page cache 直接写入数据,比如 O_DIRECT 和 O_SYNC 步骤五,只有执行到步骤五才能说数据是完全安全的,正常情况下执行完步骤三,一般就没有什么问题了。 --- `POSIX API` 步骤三:我们可以使用 `POSIX API` 进行控制,但是我们能控制的有限。比如我们进行系统调用把内容写到文件里面,但是内核写缓冲区的大小是有限的,如果磁盘无法应对应用程序的写入带宽,内核写缓冲区将达到其最大容量,内核就会阻塞我们的写入。这个时候如果有更多的数据来了之后,那么系统就会拒绝这个写入请求。 步骤四:一般来说写入不会太频繁,因为大块的内容写入速度更快。对于 Linux 系统来说默认 **30 秒** ,也就是说如果在 30 秒内出现问题,数据还是可能会丢失的。 当然也有办法控制,可以使用 `POSIX API` 控制立刻写入数据,但是这个 fsync 操作非常消耗资源。 步骤五:严格来说,从这个角度来看,我们无法通过 POSIX API 对其进行控制。也许某些内核实现会尝试告诉驱动器,实际将数据提交到物理介质上,或者控制器反而会为了速度而重新排序写入操作,并不会尽快将数据真正写入磁盘,而是再等待几毫秒。这完全超出了我们的控制范围。 ## Tips 1)现在 Cursor 支持可以不导入其他 agent 工具的 skills,要不然在 claude 里面的内容全部都跑到 Cursor 里面了。我个人是更习惯分开的,分开便于管理并且不会让 Cursor 的上下文无端增加很多上下文占用。 ![image-20260823160437982](https://pic.code-nav.cn/post_picture/1608460212774109186/DMgiDJ24li8Q4tdy.webp) 2)跨会话 skills 推荐:`/handoff` ,Github [开源地址](https://github.com/ykdojo/claude-code-tips/blob/main/skills/handoff/SKILL.md) 内容很简单,如下: ``` --- name: handoff description: Write or update a handoff document so the next agent with fresh context can continue this work. --- Write or update a handoff document so the next agent with fresh context can continue this work. Steps: 1. Check if HANDOFF.md already exists in the project 2. If it exists, read it first to understand prior context before updating 3. Create or update the document with: - **Goal**: What we're trying to accomplish - **Current Progress**: What's been done so far - **What Worked**: Approaches that succeeded - **What Didn't Work**: Approaches that failed (so they're not repeated) - **Next Steps**: Clear action items for continuing Save as HANDOFF.md in the project root and tell the user the file path so they can start a fresh conversation with just that path. ``` ## Share 文章:https://annas-archive.gl/blog/physical-destruction.html 核心就一句话:AI 公司在大批买二手书,拆脊扫描后再毁掉纸本,把 2022 年前「没被机器污染」的文字锁进私有服务器;Anna’s Archive 呼吁全球志愿者抢先扫书上传。 Anthropic 的 Project Panama 在 15 亿美元版权和解里被曝光:花几千万买几百万本纸书,训练 Claude,再全部销毁。法官认定合法买书、扫完毁原件算合理使用,破坏性扫描因此比无损扫描更便宜、更能挡住对手、法律风险也更小。纸书没了,数字副本只留公司内部,知识就被永久垄断。作者说这是跟时间赛跑:每人扫一本,一千万志愿者就是一千万份遗产。

ARTS 0815: 分隔链表、大删除是加活不是减负与协议栈如何一层层拆信封

每周完成一个 ARTS: 至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tips、Share 简称 ARTS) ## Algorithm 中等难度,题目 https://leetcode.cn/problems/partition-list/description/?envType=study-plan-v2&envId=selected-coding-interview ![image-20260816173848428](https://pic.code-nav.cn/post_picture/1608460212774109186/6NbeHvOpZX84fqdl.webp) 有几点需要注意: 1)双指针的 small、large因为会一直向后走,最后拼接答案的时候需要第一个节点 2)第一个节点就 0 所以需要第一个节点的后面一个,也就是 begin.next 和 later.next 3)Java 是引用传递,如果把 head 用 tmp 接收,之后 tmp.next = 0 页就让 head 的内容直接消失 4)因为 small 和 large 最后面会出现长度更长的情况,所以需要最终结束循环吧 next 都设置为 null ```java class Solution { public ListNode partition(ListNode head, int x) { // 两个 piont 一个 res,最后 res 拼接两个 point ListNode small = new ListNode(); ListNode large = new ListNode(); ListNode begin = small; ListNode later = large; while (head != null) { if (x <= head.val) { large.next = head; large = large.next; } else if (x > head.val) { small.next = head; small = small.next; } head = head.next; } small.next = null; large.next = null; small.next = later.next; return begin.next; } } ``` ## Review 文章是这一篇:https://planetscale.com/blog/the-only-scalable-delete 原文讲 Postgres:大 DELETE 是加活不是减负。MySQL 结论一样,机制不同,InnoDB 的 DELETE 要注意这几件事: 删了不等于没了。InnoDB 只是打删除标记,旧版本在 undo 里,后台 purge 确认没有事务还要这个快照,才物理删行和二级索引。一次清几百万行会狂写 redo、undo、binlog,复制延迟容易飙升;长事务拖着旧 read view 时 purge 走不动,history list / undo 膨胀,别的一致性读还要顺着版本链回溯。删完页里的空洞只能给这张表后续插入用,`.ibd` 通常不缩小,想把磁盘还给操作系统得 `OPTIMIZE TABLE` 重建。 `TRUNCATE` (删除表的全部数据,但是表结构还在)是 DDL,隐式提交,事务里回滚不了,别先清空再插回。如果要删除的很多就通过建新表,而不是删除旧表的方式。要留的远多于要删的,就小批量 DELETE,让 purge 跟得上。日常过期数据按日期分区,到期 `DROP PARTITION`,别夜夜百万行 DELETE。外键 CASCADE 也可能把删一行变成一次巨型删除。 而且一般商业系统也不会删除用户的数据,普遍采取的做法是`逻辑删除`。 ## Tips 1、搜索资料可以尝试使用 pi + pi-autoresearch ```bash pi install npm:pi-autoresearch ``` 2、cmd 脚本如果写中文的话,使用 GBK 编码(可以写一个 skill 专门用来写) 3、在 Vide Coding 的时候,如果有一些硬性条件比如:一个类不能超过 600 行、一个方法不能超过 40 行等,可以用 Hook 在编辑之后直接跑一个 bash 脚本,进行校验。这样虽然不会改变不合格的现实,但是会提醒 AI 你这里出问题了,记得修改! 4、agtens.md 最好做成「地图」而不是什么内容都写进去 5、为了方便 AI 读取代码,可以写一个 py 脚本,当作仓库的导览图,减少不必要的 tool call 6、如果有明确修改的类,直接 @xxx 不要再让 AI 浪费 token 使用工具去找相关的代码 ## Share 读《TCP/IP 详解》大概 5 页左右 一) 1、OSI 每一层数据叫 PDU (协议数据单元),当在网络层的 PDU 叫 **IP 数据包** 2、当第 N 层的 PDU 传输给 N - 1 层的时候,他会自动添加上标识信息,彼此之间不需要沟通。并且 N - 1 层承诺不查看 N 层的 PDU 信息。 ![image-20260816001925587](https://pic.code-nav.cn/post_picture/1608460212774109186/5AOW9tZf9OdNPkQv.webp) 3、分层还有一个好处就是,不是所有的网络设备都需要实现完整的层,比如路由器、交换机、主机实现的层是不同的。理想情况下交换机只需要实现:数据链路层、物理层。 二) 1、下面演示了一台 Internet 主机分解 DPU 的大概流程: ![image-20260816115902631](https://pic.code-nav.cn/post_picture/1608460212774109186/1vPt6ajeBzi8qRrf.webp) 传入的以太网帧包含:48 位的目的地址(也叫 MAC 地址)和 16 位的以太网类型字段。这个 16 位以太网类型字段有三个:0x0800 表示 这个帧包含 IPv4 的数据报、0x0806 表示 ARP、0x68DD 表示 IPv6 的数据报。并且还会检测这个目的地址和接收到的地址是否匹配,这个帧被接收并且进行差错校验,以太网同类型字段用于处理他的网络层协议。 如果接受的帧包含 IP 数据报,以太网的头部和尾部的信息会被消除,并且将剩余的字节交给 IP 来处理,IP 会检测一些列字段如果发现目的 IP 地址和自己的 IP 地址匹配,并且数据报头部没有错误(不会检测有效荷载),那么就检测具体使用哪一个协议来解析,比如 1(ICMP)、2(IGMP)、4(IPv4)、6(IPv6)和 17(UDP) 等等。

GNC 姿态仿真平台

> 基于 **Vite + TypeScript + Three.js + ECharts** 的卫星姿态确定与控制系统(GNC/ADCS)仿真平台。采用**完整 6 维误差状态扩展卡尔曼滤波(EKF)**融合星敏感器、陀螺仪、太阳敏感器与磁强计测量,实时估计卫星三轴姿态与陀螺零偏,并内置 PD 姿态控制闭环、轨道动力学、故障注入告警与蒙特卡洛统计分析。 > > 界面采用**航天任务控制中心**设计语言:三栏任务控制台布局(顶栏全局状态 + 左侧 Tab 控制面板 + 中央 3D 可视化 + 右侧遥测告警 + 底部图表矩阵),Modern Dark 玻璃拟态主题,支持 1920×1080 单屏无滚动监控。 ![gnc.png](https://pic.code-nav.cn/post_picture/1944355748262088705/yk4Ap0L83H3YXAS0.webp) ![books.png](https://pic.code-nav.cn/post_picture/1944355748262088705/kbDiLSmhSvtrKu9b.webp) ## ✨ 功能特性 ### 姿态确定(EKF 滤波) - **姿态运动学仿真**:Z-Y-X 欧拉角 → 四元数,RK4 四元数积分,支持任意初始姿态与三轴恒定角速度 - **星敏感器测量仿真**:在真实姿态四元数上叠加高斯小角度噪声,噪声强度可配置 - **陀螺仪测量仿真**:真实角速度 + 固定零偏 + 高斯噪声,零偏可在滤波中被在线估计 - **6 维误差状态 EKF**:状态量 = 3 姿态误差 + 3 陀螺零偏 - 预测步:完整状态转移矩阵 F(含姿态误差动力学与零偏耦合),协方差传播 `P = F·P·Fᵀ + Q` - 更新步:星敏四元观测误差角作为量测,标准卡尔曼增益与 `P = (I−K·H)·P` 修正,含协方差对称化保护 ### 多传感器融合与故障注入 - **太阳敏感器模型**:粗太阳敏 + 精太阳敏,本体系太阳方向矢量量测,含半视场角(FOV)限制与噪声可配置 - **磁强计模型**:三轴磁强计,简化地磁场偶极子模型(IGRF 近似),量测本体系磁场矢量 - **多传感器融合 EKF**:在星敏 + 陀螺基础上扩展太阳敏/磁强计矢量观测,支持任意传感器组合参与滤波 - **传感器故障注入**: - 星敏:失效 / 卡死(指定姿态角)/ 跳变(指定幅度) - 陀螺:漂移增大(指定倍数)/ 失效 - 太阳敏 / 磁强计:失效 - **执行器故障注入**:反作用轮停转 / 力矩偏差(输出 = `(1−e)·τ`,e 可配) - **故障告警系统**:基于量测新息模值超阈值的新息检测,实时状态灯(正常/警告/严重)与滚动告警列表 ### 姿态控制闭环 - **PD 姿态控制器**:基于四元数误差的 PD 控制律 `τ = −Kp·q_vec − Kd·ω_err`,Kp / Kd 可配置 - **三种控制模式**: - **三轴稳定**:将卫星稳定到指定目标 Roll / Pitch / Yaw - **机动模式**:支持目标姿态动态跟踪的大角度机动 - **对日定向**:使本体系 +X 轴指向太阳方向 - **反作用轮模型**:三轴反作用轮,含力矩饱和、转速饱和与转速积分(动量管理),支持轮最大力矩/转速配置 - **磁力矩器模型**:简化地磁场偶极子模型与磁控制律 `m = (b×τ)/|b|²`,支持磁卸载 - **刚体姿态动力学**:完整惯量矩阵 `I·ω̇ + ω×(I·ω) = τ`,RK4 角速度积分,惯性张量可配置 - **执行器分配**:反作用轮 / 磁力矩器 / 理想执行器选择与力矩矢量叠加 ### 轨道动力学与高级分析(阶段4) - **轨道传播**:开普勒轨道根数(半长轴 / 偏心率 / 倾角 / 升交点赤经 / 近地点幅角 / 真近点角)初始化,数值积分传播轨道 - **轨道可视化**:独立 3D 轨道视图(地球 + 轨道面 + 卫星运动),顶栏一键切换姿态/轨道视图 - **蒙特卡洛分析**:批量随机种子运行(1~500 次),统计**收敛概率**与**平均 RMSE Roll**,结果自动下载 CSV - **敏感性分析**:对星敏噪声 / 陀螺噪声 / 陀螺零偏 / 太阳敏噪声 / 磁强计噪声做 0.5×~2× 因子扫描 - **数据回放**:加载 CSV / JSON 历史数据,0.05s 步进逐点回放时序曲线,无需重新仿真 - **多场景对比**:基准 / 低噪声(0.5×) / 高噪声(2×) 三场景并行运行,RMSE 汇总对比 ### 可视化与数据 - **实时 3D 姿态可视化**:Three.js 卫星模型(本体 + 太阳能板 + 星敏 + 本体系坐标轴)+ 深空星空粒子背景,支持鼠标拖拽旋转、滚轮缩放 - **7 路实时曲线**:ECharts 深色主题时序图(数据窗口长度可配置,默认 1000 点) - RPY 姿态时序:实线真实 / 虚线星敏 / 橙色 EKF 滤波 - 滤波误差曲线(真实 − EKF,°) - 角速度时序(rad/s):真实 / 陀螺测量 / EKF 估计 - EKF 协方差 P 对角元(log 坐标,方差) - 控制力矩时序(N·m):PD 控制器三轴输出 - 反作用轮转速(rad/s) - 姿态控制误差角(°) - **18 项实时统计指标**:姿态误差 RMSE、陀螺零偏估计误差、EKF 收敛状态与收敛时间、P 对角元、控制误差角、控制力矩幅值、轮饱和状态与转速利用率等(蓝/琥珀/绿三组配色区分) - **场景保存/加载**:完整仿真状态(参数 + 全部历史数据 + 告警)序列化为 JSON(v3),一键保存/恢复复现实验 - **CSV 数据导出**:46 字段完整数据(姿态、误差、角速度、协方差、控制力矩、轮转速、误差角、目标姿态、轨道状态),可直接用于 MATLAB/Python 离线分析 - **中英文界面切换**:顶栏一键切换,全部界面文本与状态实时翻译 - **键盘快捷键**:`Space` 启停、`R` 重置、`E` 导出 CSV、`O` 切换姿态/轨道视图 ## 🚀 快速开始 ```bash # 安装依赖 npm install # 启动开发服务器 npm run dev # 生产构建(多页:主控制台 + 使用手册) npm run build # 预览生产构建 npm run preview ``` 浏览器访问 Vite 输出的本地地址(默认 `http://localhost:5173`)即可打开平台;**系统使用手册**位于 `/manual.html`,也可点击顶栏"使用手册"按钮在新窗口打开。 ## 🎮 使用说明 界面为三栏任务控制台布局,自上而下分为六个区域: | 区域 | 位置 | 职责 | | ---------- | -------- | --------------------------------------------------------------------------------------- | | 顶栏 | 顶部 | 视图切换(姿态/轨道)、开始/停止/重置、系统状态灯、告警指示灯、中英文切换、使用手册入口 | | 控制面板 | 左栏 | 四个 Tab:仿真参数 / 控制闭环 / 传感器故障 / 轨道分析;底部为 CSV 导出与场景保存/加载 | | 可视化区 | 中栏上部 | 3D 姿态/轨道视图,右上角 HUD 显示当前视图类型 | | 统计面板 | 中栏下部 | 18 项实时统计指标 | | 遥测与告警 | 右栏 | 真实姿态 / 星敏量测 / EKF 估计遥测值、轨道高度与速度、告警列表与计数 | | 图表矩阵 | 底部 | 7 张实时曲线图 | ### 仿真参数(Tab 1) - 初始 Roll / Pitch / Yaw(°):卫星初始姿态角(默认 15°/10°/20°) - 角速度 ωx / ωy / ωz(°/s):三轴真实角速度(默认 0/0/2) - 星敏噪声 σ(°)、陀螺噪声 σ(°/s)、陀螺零偏 bx/by/bz(°/s) - 仿真步长(s):数值积分步长(默认 0.01) - 数据窗口长度:图表保留点数(100~10000,默认 1000) > 参数在**重置后生效**:修改参数 → 点击顶栏"重置"(或按 `R`)。 ### 控制闭环(Tab 2) - **启用姿态控制**:PD 闭环总开关(默认关闭) - **反作用轮 / 磁力矩器**:执行机构使能 - **控制模式**:三轴稳定 / 机动模式 / 对日定向 - **PD 增益**:Kp=0.5、Kd=1.5(振荡时减小 Kp / 增大 Kd) - **目标姿态**(°)、**惯量矩阵** Ix/Iy/Iz(kg·m²)、**轮最大力矩**(N·m)、**轮最大转速**(rad/s) ### 传感器与故障注入(Tab 3) - **传感器配置**:太阳敏/磁强计使能、入 EKF 开关、噪声与视场角、告警阈值(新息,默认 0.05) - **故障注入**:星敏(失效/卡死/跳变)、陀螺(漂移增大/失效)、太阳敏/磁强计(失效)、反作用轮(停转/力矩偏差) ### 轨道与分析(Tab 4) - **轨道动力学**:启用轨道传播 + 六根数配置(默认 500 km 近地轨道) - **高级分析**:运行蒙特卡洛 / 敏感性分析 / 加载回放数据 / 多场景对比,结果自动下载 CSV ### 默认仿真条件 | 项目 | 默认值 | | ------------ | ------------------------------------------------------- | | 仿真步长 | 0.01 s | | 初始姿态 | Roll 15° / Pitch 10° / Yaw 20° | | 角速度 | ωx=0 / ωy=0 / ωz=2 °/s(偏航可见) | | 星敏噪声 σ | 0.05° | | 陀螺噪声 σ | 0.008 °/s | | 陀螺真零偏 | 0.01 °/s(三轴) | | 数据窗口 | 1000 点 | | EKF 初值 | 姿态=真实姿态,零偏=0,P=0.001,Q 姿态 1e-7 / 零偏 1e-9 | | 姿态控制 | 默认关闭 | | 控制模式 | 三轴稳定 | | PD 增益 | Kp=0.5,Kd=1.5 | | 目标姿态 | 0° / 0° / 0° | | 惯量矩阵 | Ix=5 / Iy=4 / Iz=3 kg·m² | | 反作用轮 | 最大力矩 0.1 N·m,最大转速 300 rad/s,默认启用 | | 磁力矩器 | 默认关闭(最大磁矩 10 A·m²,磁卸载开启) | | 太阳敏感器 | 默认启用,噪声 0.5°,半视场角 60° | | 磁强计 | 默认启用,噪声 1e-7 T | | 传感器入 EKF | 太阳敏 / 磁强计均默认启用 | | 故障注入 | 全部默认关闭 | | 告警阈值 | 新息 0.05 | | 轨道 | 默认关闭传播,a=6878 km / e=0.001 / i=97.5° | | 蒙特卡洛 | 50 次 / 30s | ## 📊 CSV 导出字段 | 分组 | 字段 | | ------------------ | --------------------------------------- | | 时间 | `time(s)` | | 真实姿态 (°) | `trueRoll, truePitch, trueYaw` | | 星敏测量 (°) | `starRoll, starPitch, starYaw` | | EKF 估计 (°) | `ekfRoll, ekfPitch, ekfYaw` | | 滤波误差 (°) | `errRoll, errPitch, errYaw` | | 角速度 (rad/s) | `omegaTrue/Gyro/Efk` × `X/Y/Z` | | 协方差 (rad²) | `P_dthetaX/Y/Z`(姿态误差方差) | | 协方差 (rad²/s²) | `P_bx/by/bz`(陀螺零偏方差) | | 控制力矩 (N·m) | `tauX, tauY, tauZ`(PD 控制器三轴输出) | | 反作用轮 (rad/s) | `wheelSpeedX/Y/Z`(三轴轮转速) | | 控制误差角 (rad) | `errorAngle`(姿态误差角) | | 目标姿态 (°) | `targetRoll, targetPitch, targetYaw` | | 轨道位置 (m) | `orbitX, orbitY, orbitZ` | | 轨道速度 (m/s) | `orbitVx, orbitVy, orbitVz` | | 轨道状态 | `orbitAlt(m), orbitSpeed(m/s)` | ## 🏗️ 项目结构 ``` ├── index.html # 主控制台页面(三栏任务控制台布局) ├── manual.html # 系统使用手册页面(独立文档页) ├── vite.config.ts # Vite 多页构建配置(index + manual) ├── src/ │ ├── main.ts # 入口装配:仿真循环、事件绑定、快捷键、Tab 切换、i18n │ ├── core/ │ │ ├── types.ts # 共享类型定义(SimConfig / SimState / SimStats / SceneData) │ │ ├── math.ts # 四元数 / 欧拉角 / 矩阵 / RK4 积分工具 │ │ ├── noise.ts # Box-Muller 高斯噪声生成 │ │ ├── orbit.ts # 轨道动力学(开普勒根数 / 数值积分) │ │ └── sim.ts # 仿真核心:状态创建 / 重置 / 步进 / CSV 导出 │ ├── sensors/ │ │ ├── starTracker.ts # 星敏感器模型 │ │ ├── gyro.ts # 陀螺仪模型 │ │ ├── sunSensor.ts # 太阳敏感器模型(矢量量测 + FOV) │ │ ├── magnetometer.ts # 磁强计模型(简化地磁场 + 矢量量测) │ │ └── fault.ts # 传感器/执行器故障注入 │ ├── ekf/ │ │ └── attitudeEKF.ts # 6 维误差状态 EKF(预测 / 更新 / 多传感器融合) │ ├── control/ │ │ ├── pdController.ts # PD 姿态控制器(三种控制模式) │ │ ├── reactionWheel.ts # 反作用轮模型(饱和 / 动量管理) │ │ ├── magnetorquer.ts # 磁力矩器模型(磁控 / 磁卸载) │ │ ├── dynamics.ts # 刚体姿态动力学(RK4 积分) │ │ └── controlManager.ts# 控制管理器(模式切换 / 执行器分配) │ ├── analysis/ # 阶段4:高级分析 │ │ ├── monteCarlo.ts # 蒙特卡洛(收敛概率 / 平均 RMSE) │ │ ├── sensitivity.ts # 参数敏感性扫描 │ │ ├── comparison.ts # 多场景对比 │ │ └── replay.ts # CSV / JSON 数据回放 │ ├── visual/ │ │ ├── threeView.ts # Three.js 3D 姿态可视化(星空粒子) │ │ ├── orbitView.ts # 3D 轨道视图 │ │ └── charts.ts # ECharts 实时曲线(7 图) │ ├── i18n/ │ │ └── index.ts # 中英文界面切换 │ ├── ui/ │ │ ├── panel.ts # 控制面板 DOM 绑定与参数读写 │ │ ├── stats.ts # 实时统计指标(18 项) │ │ ├── scene.ts # 场景保存 / 加载(JSON v3) │ │ └── alerts.ts # 故障告警系统(新息检测 + 状态灯 + 列表) │ └── css/ │ ├── style.css # 设计令牌与组件基础样式(玻璃拟态) │ ├── main.css # 主控制台布局(三栏 + 图表矩阵) │ └── manual.css # 使用手册页样式 ├── public/ # 静态资源(favicon 等) └── package.json ``` ## 🛠️ 技术栈 | 技术 | 用途 | | ---------------------------------------- | -------------------------------------------- | | [Vite](https://vitejs.dev/) + TypeScript | 工程化与类型安全(多页构建) | | [Three.js](https://threejs.org/) | 三维姿态/轨道可视化(WebGL + OrbitControls) | | [ECharts](https://echarts.apache.org/) | 实时时序曲线与协方差监控 | | [gl-matrix](https://glmatrix.net/) | 四元数运算与矩阵数学 | ## 🎨 设计主题 采用 **Modern Dark(星空白 + 发射蓝)** 航天任务控制中心风格,玻璃拟态面板 + 霓虹辉光 + JetBrains Mono 等宽数字仪表,深色固定主题与 3D 视图背景统一: | 令牌 | 值 | 用途 | | ---- | --------------------- | -------------------------------------- | | 背景 | `#0B0B10` | 页面底色(深空黑) | | 玻璃 | `rgba(20,22,31,0.72)` | 面板玻璃拟态背景(12px 圆角 + 内高光) | | 主色 | `#3B82F6` | 按钮、焦点、分段控制器、辉光 | | 强调 | `#F59E0B` | EKF 曲线、告警、导出按钮 | | 弱化 | `#94A3B8` | 标签、次级文字 | | 等宽 | JetBrains Mono | 遥测数值、统计指标、kbd | ## 📖 使用手册 系统内置完整使用手册(`/manual.html`,顶栏按钮新窗口打开),覆盖快速上手、界面导览、全部参数说明、故障注入模式、高级分析工具、告警系统解读与常见问题。 ## 开源地址 项目地址:https://gitee.com/zd_g/gnc-sim-enhanced 欢迎 Star、Fork、Issue 反馈! ## ⚠️ 说明 - 本项目为教学/演示用途的姿态确定与控制仿真,阶段1(架构模块化)、阶段2(姿态控制闭环)、阶段3(多传感器融合 + 故障注入 + 告警)、阶段4(轨道动力学 + 蒙特卡洛 + 敏感性 + 回放 + 对比)均已完成 - 太阳敏感器采用简化模型(假设安装在 +Z 轴,主轴 +Z 指向太阳),未建模真实视场遮挡与太阳方向随时间变化 - 磁强计与地磁场为简化偶极子模型,磁场方向随时间绕 Z 轴进动(90 分钟轨道周期),非真实 IGRF - 故障检测基于量测新息模值超阈值(阈值可配置),属简化方案;真实系统常用残差平方加权(CUSUM / χ² 检验) - 图表保留点数由「数据窗口长度」参数控制(默认 1000 点),CSV 导出包含全部历史数据 - 蒙特卡洛 / 敏感性分析为计算密集型任务,期间界面可能短暂卡顿,属正常现象 - 场景文件含版本号(v3)且加载时严格校验,请使用同一平台版本保存与加载 - 建议在 1920×1080 及以上分辨率全屏使用,以获得最佳单屏监控体验(窗口小于 1100px 或高度小于 860px 时自动降级为滚动布局)

Linux 安装 Claude Code 实战:Node.js、npm、GLM 配置一次跑通

# Linux 安装 Claude Code 实战:Node.js、npm、GLM 配置一次跑通 ![Linux 安装 Claude Code](https://pic.code-nav.cn/post_picture/1624066347312943106/HWkmJv6MXRItCBKK.webp) 有些工作放在Linux服务器上处理更顺手:看日志、改配置、排查线上问题,或者直接在项目目录里让AI帮忙读代码。 Claude Code和OpenCode都能完成这些事。我个人更习惯Claude Code的终端界面,所以把这次在Linux服务器上的安装过程整理下来。 先说明一下:Claude Code官方目前更推荐原生安装器;本文使用npm,是因为服务器已经有Node.js环境,而且部分网络环境访问官方安装脚本并不稳定。两种方式都能用,按自己的服务器情况选择即可。 ## 整体安装路线 ![Claude Code Linux 安装流程](https://pic.code-nav.cn/post_picture/1624066347312943106/NZAp0flKJ5F6T83R.webp) ## 先选安装方式 ### 官方原生安装器 服务器能够正常访问Claude官方地址时,可以直接运行: ~~~bash curl -fsSL https://claude.ai/install.sh | bash ~~~ 原生安装不依赖Node.js,步骤也更短。首次安装Claude Code,优先考虑这种方式。 ### npm全局安装 如果服务器已经装好Node.js,或者官方安装脚本受网络环境影响,也可以使用npm: ~~~bash npm install -g @anthropic-ai/claude-code@latest ~~~ Claude Code官方文档在“高级安装选项 → 使用 npm 安装”中写明:从 `v2.1.198` 开始,npm包需要Node.js 22或更高版本。 不过官方紧接着补充:使用较旧的Node.js时,npm通常只会提示 `EBADENGINE`,安装仍可能完成,`claude` 也可能正常运行,因为npm包最终下载的是不依赖Node.js运行时的原生二进制文件。 所以更准确地说,Node.js 22+是当前npm包声明的安装要求,并不代表Node.js 18下一定无法启动。为了避免安装警告和后续兼容问题,本文仍建议直接使用Node.js 22或更高版本。 官方依据:https://code.claude.com/docs/zh-CN/setup#install-with-npm 本文后面的步骤使用npm方式。 ## 检查Node.js和npm 先执行: ~~~bash node -v npm -v npm config get prefix ~~~ ![检查 Node.js 和 npm 版本](https://pic.code-nav.cn/post_picture/1624066347312943106/PTExaL68FQIGSNzL.webp) 我的环境是: ~~~text Node.js:v24.16.0 npm:11.17.0 ~~~ 这个版本可以直接安装。 如果Node.js低于22,安装时可能出现 `EBADENGINE` 警告。程序未必不能运行,但新装环境没有必要停留在旧版本,建议先通过服务器面板、nvm或系统包管理器切换到Node.js 22或更高版本。 `npm config get prefix` 会告诉你全局包安装到哪里。使用Node项目管理器时,路径可能类似: ~~~text /www/server/nodejs/v24.16.0 ~~~ 使用nvm、系统Node.js或其他面板时,路径会不一样,不需要照抄。 ## 安装Claude Code 执行: ~~~bash npm install -g @anthropic-ai/claude-code@latest ~~~ ![通过 npm 安装 Claude Code](https://pic.code-nav.cn/post_picture/1624066347312943106/i9nCjRPcb9EDBsF9.webp) 安装完成后,不要急着配置模型,先确认命令是否正常: ~~~bash claude --version command -v claude ~~~ ![查看 Claude Code 版本和命令路径](https://pic.code-nav.cn/post_picture/1624066347312943106/8KToIZrBjYJlcznx.webp) 截图中返回: ~~~text 2.1.218 (Claude Code) /www/server/nodejs/v24.16.0/bin/claude ~~~ 这说明Claude Code已经装好,并且当前Shell能够找到 `claude` 命令。 ## claude命令为什么是一个软链接 npm全局安装命令行工具时,通常会在Node.js的 `bin` 目录创建入口。你输入 `claude`,系统先找到这个入口,再执行真正的程序文件。 可以用下面的命令查看最终位置: ~~~bash readlink -f "$(command -v claude)" ~~~ ![](https://pic.code-nav.cn/post_picture/1624066347312943106/a5rBybu6DeGt23H1.webp) 真实路径会随着Node.js安装方式、版本和Claude Code版本变化。文章中的 `/www/server/nodejs/v24.16.0` 只是这台服务器的结果,不应该写死到脚本中。 想做更完整的安装检查,还可以运行: ~~~bash claude doctor ~~~ ## 官方账号和第三方API,配置方式不同 如果使用Anthropic官方账号,进入项目目录后直接执行 `claude`,按照终端提示登录即可,不需要下面这份GLM配置。 如果使用智谱Coding Plan或兼容Anthropic协议的GLM API,需要修改Claude Code的环境配置。 ![Claude Code 调用 GLM 的配置关系](https://pic.code-nav.cn/post_picture/1624066347312943106/KlHjMNFi48FbTp8O.webp) ## 配置Claude Code接入GLM 先创建配置目录: ~~~bash mkdir -p ~/.claude ~~~ 然后编辑: ~~~bash vim ~/.claude/settings.json ~~~ 写入下面的配置,把 `YOUR_API_KEY` 换成自己的Key: ~~~json { "env": { "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_BASE_URL": "https://open.bigmodel.cn/api/anthropic", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.7", "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-5.2[1m]", "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-5.2[1m]", "CLAUDE_CODE_AUTO_COMPACT_WINDOW": "1000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1, "API_TIMEOUT_MS": "3000000" } } ~~~ 配置完成后,限制文件权限: ~~~bash chmod 600 ~/.claude/settings.json ~~~ 这几个字段可以这样理解: | 配置项 | 作用 | | --- | --- | | `ANTHROPIC_AUTH_TOKEN` | 智谱API Key | | `ANTHROPIC_BASE_URL` | Anthropic兼容接口地址 | | `ANTHROPIC_DEFAULT_HAIKU_MODEL` | Claude Code请求Haiku角色时使用的模型 | | `ANTHROPIC_DEFAULT_SONNET_MODEL` | Claude Code请求Sonnet角色时使用的模型 | | `ANTHROPIC_DEFAULT_OPUS_MODEL` | Claude Code请求Opus角色时使用的模型 | | `API_TIMEOUT_MS` | API请求超时时间 | `glm-5.2[1m]` 中的 `[1m]` 表示该服务商提供的100万Token上下文版本。模型名属于服务商配置,不是Claude Code统一规定的格式。后续智谱调整模型名称时,要以它的官方文档为准。 API Key现在保存在当前Linux用户的配置目录中。不要把 `settings.json` 上传到Git仓库,也不要让其他用户拥有读取权限。 ## 跳过第三方API场景下的首次登录 使用第三方Anthropic兼容接口时,如果启动后仍停留在首次登录流程,可以编辑: ~~~bash vim ~/.claude.json ~~~ 加入: ~~~json { "hasCompletedOnboarding": true } ~~~ 如果 `~/.claude.json` 已经存在,不要整份覆盖,只需要合并 `hasCompletedOnboarding` 字段。 ## 启动Claude Code 先进入准备操作的项目目录: ~~~bash cd /path/to/your/project claude ~~~ 首次进入某个目录时,Claude Code会询问是否信任当前项目。 ![Claude Code 首次进入项目时的信任提示](https://pic.code-nav.cn/post_picture/1624066347312943106/VeXGnrrDXIj6QbTr.webp) 只有确认代码来源可信时,才选择: ~~~text Yes, I trust this folder ~~~ 因为Claude Code获得授权后,可以读取、修改并执行这个目录里的文件。 进入主界面后,会看到当前模型、项目路径和输入框: ![Claude Code 成功进入项目](https://pic.code-nav.cn/post_picture/1624066347312943106/JKn9Pfn2ct9JIk4v.webp) 截图中显示 `glm-5.2[1m]`,说明模型映射已经生效。 ## 验证安装是否成功 建议按下面的顺序检查: ~~~bash # 查看版本 claude --version # 检查安装和配置 claude doctor # 查看当前命令入口 command -v claude # 解析软链接 readlink -f "$(command -v claude)" # 发起一次非交互测试,会产生少量模型费用 claude -p "只回复 OK" ~~~ 前四条正常,只能说明程序安装和路径基本没有问题;最后一条能够正常返回,才说明API地址、Key和模型配置也已经打通。 ## 常见问题 ### npm提示EBADENGINE 先看Node.js版本: ~~~bash node -v ~~~ 当前npm安装方式应使用Node.js 22或更高版本。切换版本后重新安装Claude Code。 ### 安装成功,但提示claude命令不存在 检查npm全局目录和当前PATH: ~~~bash npm config get prefix echo "$PATH" ~~~ 临时加入PATH: ~~~bash export PATH="$(npm config get prefix)/bin:$PATH" ~~~ 确认有效后,再把这一行写入 `~/.bashrc` 或 `~/.zshrc`。 ### root用户能运行,普通用户不能运行 不同Linux用户有各自的 `HOME`、npm目录和Claude配置。使用root安装并配置后,普通用户不一定能直接使用。 安装、写入 `~/.claude/settings.json` 和运行 `claude`,最好保持为同一个用户。 ### 返回401或403 重点检查: - `ANTHROPIC_AUTH_TOKEN` 是否正确。 - Key是否拥有对应模型权限。 - `ANTHROPIC_BASE_URL` 是否写错。 - 模型名称是否仍然有效。 ### 请求超时 先确认服务器能否访问API地址: ~~~bash curl -I https://open.bigmodel.cn ~~~ 网络正常后,再检查 `API_TIMEOUT_MS` 和服务商状态。单纯反复重装Claude Code通常解决不了API超时。 ### 界面中的模型和配置不一致 退出当前Claude Code会话,确认 `settings.json` 保存成功后重新启动。仍不一致时,检查是否在另一个Linux用户下运行。 ## 更新和卸载 npm版本建议这样更新: ~~~bash npm install -g @anthropic-ai/claude-code@latest ~~~ 官方文档不建议使用 `npm update -g`,因为它可能受到原始版本范围影响,未必升级到最新版。 卸载命令: ~~~bash npm uninstall -g @anthropic-ai/claude-code ~~~ 如果不再使用原来的第三方API配置,再手动处理 `~/.claude/settings.json` 和 `~/.claude.json`。删除前先确认里面没有其他仍需保留的Claude Code设置。 ## 参考资料 - Claude Code快速开始:https://code.claude.com/docs/zh-CN/quickstart - Claude Code高级设置(npm安装):https://code.claude.com/docs/zh-CN/setup#install-with-npm - 智谱Claude Code配置:https://docs.bigmodel.cn/cn/coding-plan/tool/claude - Windows下安装Claude Code,使用API Key方式调用GLM:https://xdr630.blog.csdn.net/article/details/158777684 - Claude Code接入国产大模型实战:GLM / Qwen配置全解析:https://xdr630.blog.csdn.net/article/details/160308331 安装本身并不难。真正容易出错的,是Node.js版本、命令路径和第三方API配置被混在一起。按步骤逐项验证,哪一步不通就查哪一步,比反复卸载重装省事得多。 欢迎关注我的公众号【兮动人】,每天分享一些技术文章和实战经验。 ![](https://pic.code-nav.cn/post_picture/1624066347312943106/HFv6nYJmOlA2Bo2J.webp)

下载 APP