This commit is contained in:
Build Bot
2026-05-18 01:20:38 +08:00
parent d67630c144
commit f7310caea0
28 changed files with 3756 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
# Structured Output for Beginners (Part 3)
**URL:** https://pocketflow.substack.com/p/structured-output-for-beginners-3
**Source:** PocketFlow Substack newsletter
**Saved:** 2026-05-12
> ⚠️ 笔记无法直接抓取正文内容Substack 从当前环境不可访问)
## 关于该文章
这是 PocketFlow 的 "Structured Output for Beginners" 系列的第三部分。PocketFlow 是一个轻量级 AI 工作流框架,该系列文章主要讲解如何利用结构化输出(如 JSON Schema、Pydantic 模型等)来约束 LLM 输出格式,实现更可靠的 AI 应用。
请手动查看原文获取完整内容。

View File

@@ -0,0 +1,87 @@
# AI-First 产研团队的交付路径
**来源:** [微信公众号 - 昀启AI+](https://mp.weixin.qq.com/s/dNLJagjAoHtiUJj_bc8k0g)
**作者:** 昀启
**日期:** 2026年4月21日 09:47
**标签:** #AI-First #上下文工程 #Skill-as-Code #产研协作 #交付路径
---
## 核心框架
- **指标**AI 初稿准确率
- **底座**:上下文工程 (L0/L1/L2 三层收敛)
- **载体**Skill-as-Code — 把团队规范和工作方法硬编码为可版本管理的工程资产
---
## 初稿准确率是 AI 协作的前置变量
> 为什么同样使用模型,不同团队的产出质量会出现显著差异?
**差异的根源不在模型能力,而在于 AI 所获得的上下文质量。** 上下文充分且精准时第一版初稿往往已接近可交付标准上下文残缺或含混时AI 的产出更像基于有限信息的推测,返工成本随之上升。
**核心度量:** AI 生成的第一版初稿,有多大比例可以进入审查流程,或仅经少量调整后即可交付。
这个指标直接关联 AI 协作的真实 ROI
- 初稿准确率高 → 人的精力更多用在审查和决策上
- 初稿准确率低 → 人的精力持续消耗在返工和修补上
很多团队引入 AI 后体感"快了但不稳",本质上就是这个指标波动过大。
---
## 六段式交付闭环:上下文逐级收敛与同步更新
六个阶段的核心逻辑不是线性流程编排,而是**上下文逐级收敛、阶段持续校验、结果最终回写**。
| 阶段 | 人的职责 | AI 的职责 | 显性资产(给人的) | 隐性上下文(给下阶段 AI 的) |
|------|----------|-----------|-------------------|---------------------------|
| 业务需求 | 定义目标、边界、优先级 | 起草需求内容 | 需求文档 | 业务意图、边界约束 |
| PRD 设计write-prd Skill | 澄清歧义、确认范围 | 生成结构化 PRD | AI 可执行的 PRD | 功能目标、业务规则、验收标准 |
| 技术方案设计write-tech-design Skill | 评审架构可行性 | 产出方案初稿 | 技术方案 + API 契约 | 模块边界、接口约定、架构约束 |
| 任务拆解breakdown-tasks Skill | 确认优先级与依赖 | 拆解为可执行单元 | WBS 任务列表 | 单任务输入/输出/依赖/验收标准 |
| Daily Coding Agent编码/单测/CR Skill | 审核关键逻辑与架构边界 | 编码→单测→CR→修复循环 | 经验证后可交付的代码 | 代码变更记录、新增接口与规则 |
| 上下文更新update-context Skill | 审检沉淀结果 | 回写知识与上下文 | 更新后的知识资产 | 下一轮迭代的全量上下文基线 |
**关键洞察**:注意"隐性上下文"这一列——需求阶段提供业务意图PRD 阶段将意图转为结构化约束,技术方案阶段将约束收敛为技术决策,任务拆解阶段再将决策压缩为最小执行单元。到 Daily Coding Agent 阶段AI 拿到的已不是一个模糊需求,而是一份高度收敛的任务上下文。
最后一个阶段"上下文更新"负责闭合整个循环:代码变更后上下文同步刷新,确保下一轮迭代时 AI 的输入不会过时。
---
## 上下文工程:知识库与分层加载
### 系统知识库
| 业务视角 | 技术视角 |
|----------|----------|
| 功能清单、业务流程、领域知识、状态规则 | 架构文档、数据模型、API 契约、技术规范 |
两者之间通过**共享术语表**打通,确保 AI 在生成内容时,业务概念与技术实现使用同一套语义。
> 知识库的完整度,直接决定了 AI 理解业务的深度,也决定了首稿在业务逻辑层面的可用程度。
### 三层加载模型
- **L0项目级**:全局一致性
- **L1文件级**:局部适配
- **L2任务级**:单次任务准确率
核心原则:**只在需要的时候给需要的信息。**
### 上下文工程为什么应被视为组织级投入
1. 决定了 AI 投入能否产生实际回报
2. 是团队能力的沉淀载体(人员流动冲击减小)
3. 具备复利效应——正向循环 vs 负向衰减
---
## Skill 体系:上下文工程的可复用封装
Skill-as-Code把团队的工作方法与质量约束写成可版本管理的文本契约而不是散落在聊天窗口里的一次性指令。
文章中提到的 Skill 包括:
- `write-prd`:生成结构化 PRD
- `write-tech-design`:产出技术方案初稿
- `breakdown-tasks`:拆解为可执行单元
- `update-context`:回写知识与上下文

View File

@@ -0,0 +1,215 @@
# AutoHarness 深度解读
> 来源https://zhuanlan.zhihu.com/p/2016839356833341880
> 收藏时间2026-03-25
## 一句话总结
用小模型Gemini-2.5-Flash自动写一段"规则检查代码"包裹在 LLM 外面,让它不再犯"非法操作"的低级错误,结果小模型+代码 > 大模型裸跑。
---
## 这篇论文到底在解决什么问题?
### LLM 做 Agent 时的尴尬现实
你可能已经知道,现在很多人在用 LLM 做 agent——让模型去完成一些需要"行动"的任务,而不是简单地回答问题。比如让 LLM 下棋、玩游戏、操控机器人等。
**问题来了LLM 经常做出"非法操作"。**
论文举了一个非常生动的例子:在 Kaggle GameArena 的国际象棋比赛中Gemini-2.5-Flash 78% 的失败不是因为下棋策略差,而是因为走了不符合规则的棋。比如让马走直线、让兵倒着走之类的。
这就好比你请了一个非常聪明的人来帮你下棋,他对棋局分析得头头是道,但就是经常把棋子摆到不合法的位置上。
### 为什么会这样?
LLM 本质上是一个文本生成模型。它"知道"国际象棋的规则(因为训练数据里有大量棋谱),但它没有一个硬编码的规则引擎来确保输出的每一步都合法。它的"知道"是概率性的、模糊的,不是精确的。
### 现有解决方案及其问题
| 方案 | 怎么做 | 问题 |
|------|--------|------|
| Fine-tuning | 用大量合法游戏轨迹去微调模型 | 成本极高;可能降低模型在其他任务上的能力 |
| 手写 Harness | 人工为每个游戏写一个规则检查器 | 费时费力,每换一个游戏就要重写 |
**这篇论文的创新点是:让 LLM 自己写这个规则检查器。**
---
## 核心概念:什么是 "Harness"
### Harness 的直觉理解
"Harness" 这个词在英文里是"挽具/马具"的意思用来控制和约束马的行为方向。在这篇论文里Harness 就是包裹在 LLM 外面的一层"安全壳",确保 LLM 输出的动作是合法的。
用工程的话说,这就是一个 wrapper / middleware / interceptor
```
传统做法:
用户请求 → LLM → 输出动作(可能非法)→ 环境报错
加了 Harness 之后:
用户请求 → LLM → Harness检查 → 合法? → 执行
↓ 不合法
告诉LLM"这步不行" → LLM重新生成 → 再检查...
```
### 三种 Harness 变体
论文提出了三种不同"约束力度"的 harness
#### ① Harness-as-Action-Verifier动作验证器— 论文主要聚焦的方案
```python
while True:
action = LLM.generate(observation) # LLM 提出一个动作
if code_harness.is_legal_action(obs, action): # 代码检查是否合法
break # 合法就执行
else:
# 不合法,告诉 LLM 这步不行,让它重新想
observation += f"\n警告:{action} 是非法操作,请重新选择"
return action
```
类比:就像你写代码时 IDE 的实时语法检查——你写了不合法的代码,红线提示你改。
#### ② Harness-as-Action-Filter动作过滤器
```python
legal_actions = code_harness.propose_action(obs) # 代码先列出所有合法动作
best_action = LLM.rank(legal_actions) # LLM 从中选最好的
return best_action
```
类比:就像下拉菜单——用户只能从合法选项中选,不可能输入非法值。
#### ③ Harness-as-Policy代码即策略— 最激进的方案
```python
action = code_harness.propose_action(obs) # 完全由代码决定动作
return action # 根本不需要 LLM
```
类比:你直接写了一个规则引擎/算法来玩游戏LLM 只在"开发阶段"用来写这个算法。运行时零 LLM 调用,零成本。
---
## 核心方法:怎么让 LLM 自动写出 Harness
这是论文最核心的技术贡献。如果你熟悉 GRPO你可以把这个过程理解为用环境反馈来优化代码而不是优化模型权重。
### 整体流程
```
1. 初始化LLM 写一版 harness 代码propose_action + is_legal_action
2. 测试:用这个代码在游戏环境里跑 rollout
3. 评估:记录哪些动作被判为非法,收集错误信息
4. 反馈:把错误信息喂给 LLMCritic 模块整理错误)
5. 优化LLM 基于错误反馈生成改进版代码Refiner 模块)
6. 重复 2-5直到合法率达到 100% 或超时
```
### 和 GRPO 的对比
| 维度 | GRPO | AutoHarness |
|------|------|-------------|
| 优化的对象 | 模型权重 θ | 代码文本(程序) |
| 搜索空间 | 参数空间(连续) | 程序空间(离散) |
| 反馈信号 | reward标量 | 执行反馈(错误日志+reward |
| 优化方法 | 梯度下降 | LLM 当"突变算子"改代码 |
| 探索策略 | 采样多个 response 对比 | Thompson sampling 做 tree search |
| 类比 | 调参让模型更好 | 让 AI 写更好的代码 |
**关键区别**GRPO 改的是模型内部的权重AutoHarness 改的是模型外部的代码。一个改"大脑",一个改"工具"。
### Tree Search + Thompson Sampling
#### 为什么要用 Tree Search
简单的迭代优化(写代码 → 测试 → 改代码 → 测试…)有个问题:容易陷入局部最优。比如 LLM 沿着一个思路改了 5 版代码,发现这个方向走不通了,但已经回不去了。
Tree search 的思路是:同时维护多个版本的代码,像一棵树一样分叉发展。
```
初始代码 v0
/ \
v1a v1b ← 两个不同的改进方向
/ \ |
v2a v2b v2c ← 继续分叉
|
v3a ← 这个方向成功了合法率100%
```
#### Thompson Sampling 是什么?
你面对这棵树上的多个节点,每次迭代应该选哪个节点来继续优化?这就是经典的 exploration-exploitation探索-利用)问题:
- **利用Exploitation**:选当前表现最好的代码版本继续改进
- **探索Exploration**:试试那些还没被充分优化的代码版本,也许潜力更大
Thompson sampling 是一种概率性的选择策略:
```
对每个节点:
1. 根据它历史的"合法率"数据建一个概率分布Beta 分布)
2. 从这个分布中随机采样一个值
3. 选采样值最高的节点来优化
效果:表现好的节点被选中的概率更高(利用),
但表现差的节点也有机会被选中(探索)
```
工程类比:这和你做 A/B testing 时的 Multi-Armed Bandit 问题几乎一模一样。Thompson sampling 就是一种 bandit 算法。
### Critic 和 Refiner 的分工
**Critic批评者**
- 输入rollout 中失败的步骤(最多 5 个)
- 工作:整理和归纳各种错误类型
- 输出:结构化的错误摘要
- 类比Code Review 时给你提 bug 的同事
**Refiner优化者**
- 输入:当前代码 + Critic 的错误摘要
- 工作:基于反馈生成改进版代码
- 输出:新版本的 harness 代码
- 类比:你根据 code review 意见改代码
一个关键细节:如果 `is_legal_action()` 返回 True 但环境说动作非法(漏判),则两个函数都要改;如果 `is_legal_action()` 返回 False 且动作确实非法(检查器工作正常,只是 `propose_action` 提出了错误动作),则只改 `propose_action()`。这个区分很重要,避免了"改了不该改的代码"。
---
## 实验结果解读
### 训练效率:多快能学会?
- 平均 **14.5 次迭代**就能学会(即 LLM 改代码 14.5 次)
- **19/32 个游戏**不到 10 次就搞定了
- 最难学的游戏GermanWhist43次、Chess64次、Othello62次
直觉理解:简单游戏(如猜数字、骰子)规则简单,几次就能写对检查器;复杂游戏(如国际象棋)规则多样(王车易位、吃过路兵等),需要更多轮迭代。
最终结果:**全部 145 个游戏都达到了 100% 合法动作率。**
### 双人游戏:小模型+Harness vs 大模型
| 对阵 | 我们的方法胜率 | 对手胜率 |
|------|--------------|----------|
| Flash+Harness vs Gemini-2.5-Pro | **56.3%** | 38.2% |
| Flash+Harness vs Flash原始 | **64.8%** | — |
这意味着什么?**一个小模型Flash配上自动生成的规则检查代码可以打败一个大几倍的模型Pro。**
---
## 核心启示
1. **"代码即策略"可能是 LLM Agent 的终局形态** — 让 LLM 写代码,然后运行时零 LLM 调用
2. **小模型+好代码 > 大模型裸跑** — 这打破了"模型越大越好"的迷信
3. **Program Synthesis + RL 的结合** — 这可能是下一代 AI 系统的核心范式
---
## 标签
#论文解读 #AutoHarness #LLM #Agent #ProgramSynthesis #GRPO #强化学习

View File

@@ -0,0 +1,91 @@
# CLI-SwitchAgent 调用 Claude Code / Codex 的正确姿势
**来源:** [微信公众号 - WilleAi笔记](https://mp.weixin.qq.com/s/_lFBObJClMx74DuJVegAaw)
**作者:** 上心12138
**日期:** 2026年5月13日 02:05
**标签:** #cli-switch #ClaudeCode #Codex #Agent #AI #开发工具
---
## 从工具箱到手术刀
三个月前作者发过一篇文章介绍 cli-switch定位是"Agent 的 CLI 工具箱"——支持多个编码 Agent能调很多模型。跑了一段时间后发现做得太多反而没有一个做得够好。
Claude Code 和 Codex 在编码场景的领先优势越来越明显,其他工具逐渐边缘化。所以整个项目重构了。
**v1.0.0** 换成了 TypeScript / Node.jsnpm 安装,聚焦只做一件事:
> **让 Agent 正确调用 Claude Code 和 Codex并知道选对应的什么模型。**
### 重构带来的关键变化
- **更干净**:砍掉了不必要的 Agent 支持,专注 Claude Code + Codex
- **环境隔离**:每次调用起独立子进程,不碰全局配置
- **策略引擎**4 种执行策略——single单步、write_review写完审查、write_test_fix写完跑测试、不过就修、high_quality全程 premium 模型)
- **Skill 系统**:给 Agent 操作手册,自动识别 8 种能力(写代码、代码审查、重构、修 bug、分析、写测试、跑测试、解释代码
---
## 两个人的电脑(核心痛点)
Claude Code 只有一份全局配置。Agent 没法单独指定模型,只能用全局配的那个。就像两个人共用一台电脑,谁改了设置另一个都受影响。
Codex 也一样。每次调 Codex 要手动设 `OPENAI_API_KEY``OPENAI_BASE_URL`,用完还得改回来。
---
## 一行安装,一个 Key 搞定
```bash
npm install -g cli-switch
```
配一个环境变量:
```bash
export SWITCH_API_KEY=your-gateway-key
export SWITCH_BASE_URL=https://your-relay.example.com/v1
```
Agent 调 Claude Code 时自动注入为 `ANTHROPIC_API_KEY`,调 Codex 时注入为 `OPENAI_API_KEY`。**不碰全局配置**,通过子进程临时环境变量注入,用完即焚。
---
## 使用示例
**调 Claude Code**
```bash
cli-switch run "给 src/auth.ts 补单元测试" --agent claude-code
```
**调 Codex**
```bash
cli-switch run "重构 utils 模块" --agent codex
```
**写完自动跑测试,不过就修(最多循环 5 次):**
```bash
cli-switch run "实现登录功能" --strategy write_test_fix
```
**路由预览,不花 Token**
```bash
cli-switch run "重构 auth 模块" --dry-run
```
---
## 对比表
| | 之前 | 之后 |
|---|---|---|
| 调 Claude Code | 手动设环境变量,担心改全局配置 | 一条命令,自动注入 |
| 调 Codex | 又得手动设一套 OpenAI 的变量 | 同一条命令,换 `--agent codex` |
| Key 管理 | 中转站 Key 要手动塞给每个工具 | 配一次,两个工具都能用 |
| 模型切换 | 改全局配置,影响自己正在用的 | Agent 用自己的,互不影响 |
| 执行隔离 | 直接在项目里改,改坏了就麻烦 | worktree 或临时副本,随便折腾 |
---
## 与 Hermes Agent 的关联
这个工具直接解决了 Hermes Agent以及类似 AI Agent在调用 Claude Code / Codex 时的**环境变量冲突**和**配置隔离**问题。Hermes 的 `delegate_task` 工具配合 `acp_command` 参数可以调用 Claude Code 和 Codex而 cli-switch 进一步简化了 Key 注入和模型选择。

29
InBox/CLIProxyAPI.md Normal file
View File

@@ -0,0 +1,29 @@
# CLIProxyAPI
**GitHub**: https://github.com/router-for-me/CLIProxyAPI
**添加时间**: 2026-03-24
**提醒时间**: 2026-03-25 10:00
**标签**: #代理 #CLI #工具
---
## 项目简介
(待补充 - 明天落实时填写)
## 主要功能
(待补充)
## 安装使用
(待补充)
## 备注
- 用户要求:无风险的情况下落实
- 提醒已设置明天3月25日10:00
---
**原始链接**: https://github.com/router-for-me/CLIProxyAPI

View File

@@ -0,0 +1,53 @@
# Claude Code 2.1.141 重磅发布61项更新细节体验再次升级
> 来源:[微信公众平台](https://mp.weixin.qq.com/s/73PuGdfvSt7j2l-tTigd_g)
> 作者:晓明兄
> 日期2026年5月15日 08:04
## 本次更新三大亮点
### 1. Hook 通知能力大幅提升(最实用!)
- 新增 `terminalSequence` 字段到 Hook JSON 输出
- 即使没有控制终端non-TTYHook 也能直接发出:
- 桌面通知
- 窗口标题变更
- 终端铃声
- 长任务跑完、重要事件发生时Claude 终于能"主动叫你"
- 社区用户直呼这是 "sleeper hit"(潜伏杀手级改动),让 Agent 感觉更像真实同事
### 2. Rewind 菜单新增 "Summarize up to here"
- 长会话上下文爆炸时,不用手动重启丢失历史
- 选中位置后一键压缩早期上下文,保留最近对话
- 完美解决 token 限制痛点,同时不丢失"为什么之前方案失败"的重要信息
### 3. Agent View 与后台任务更稳定
- `claude agents --cwd <path>`:支持按目录过滤会话列表
- 后台 Agent 完成工作但仍有 shell 时,自动移到 Completed 状态
- 空闲后台会话 5 分钟后自动清理
- 权限模式、模型切换等并发问题得到大量修复
## 其他重要新增与改进
**新增功能:**
- `CLAUDE_CODE_PLUGIN_PREFER_HTTPS`:无 SSH Key 环境也能轻松安装 GitHub Plugin
- `ANTHROPIC_WORKSPACE_ID`:支持 Workload Identity Federation精确作用域
- `CLAUDE_CODE_VOICE_FORWARD_INTERIMS_TYPED` 等语音相关环境变量
**体验与修复亮点:**
- 长思考 Spinner 10 秒后变 amber 色,提醒你 Claude 还在努力
- 大量 Windows、插件、MCP、权限对话框、markdown 表格等修复
- Auto Mode 权限提示更清晰,说明是由哪个 rule 触发
- Prompt tokens 优化tools 占比从 43.5% 提升至 47.3%
## 开发者真实声音
- "一个小改动,却让长跑 Agent 真正能‘喊’人。"
- "Rewind 压缩功能直接解决上下文爆炸问题,不用再手动重启丢失历史。"
结合之前的 Agent View + /goalClaude Code 正在成为一套真正可管、可控、可长时间运行的 AI 工程体系。
## 写在最后
Claude Code 的迭代节奏越来越快。从 Agent View 的全局视野,到 /goal 的目标驱动,再到这次的 Hook 通知和上下文压缩,它正在一步步把"把任务扔给 AI"从理想变成稳定可靠的生产力工具。
---
#ClaudeCode #AI编程 #开发者工具 #AgenticAI

View File

@@ -0,0 +1,108 @@
# Cursor 开源团队工作流 Team-kit
> 来源:[微信公众平台](https://mp.weixin.qq.com/s/YT-yD6LcYJhUm5aTQtCsKQ)
> 作者VibeCoder · Vibe编码
> 时间2026年5月7日 07:56
---
Cursor 官方插件仓库发布了 `cursor-team-kit`v1.1.0),将 Cursor 团队内部的 CI、Code Review、PR、测试、验证、代码清理、周报等工作流打包成可直接安装的插件。
**安装:** `/add-plugin cursor-team-kit`
**内容构成:** 17 Skills + 1 Sub Agent + 2 Rules
特点:不依赖 Linear、Jira、Slack、Notion 等第三方服务,靠 Git、GitHub CLI、本地测试、浏览器自动化、终端 harness 等基础能力工作。
---
## 它是什么
manifest 里写得直白:*Internal workflows used by Cursor developers*。
官方强调:**plug and play without requiring third-party service integrations**。价值不是把 SaaS 接进 IDE而是把团队怎么收尾、验证、review 写成 agent 能读懂的操作手册。
---
## 技术原理
目录结构:
```
cursor-team-kit/
├── .cursor-plugin/plugin.json
├── agents/ci-watcher.md
├── rules/
│ ├── no-inline-imports.mdc
│ └── typescript-exhaustive-switch.mdc
└── skills/
├── loop-on-ci/
├── verify-this/
├── control-cli/
├── control-ui/
├── pr-review-canvas/
└── ...
```
设计哲学Skills 很多Sub Agent 很少。只有一个后台 agent `ci-watcher`(盯 PR checks。其他复杂动作都拆成独立 skill按需触发更像 checklist。
---
## verify-this最有价值的 skill
硬性要求:
1. 把用户 claim 改写为**可证伪命题**
2. 采集 baseline 和 treatment 两组 artifact
3. 相同命令、相同数据、相同环境比较
4. 只允许三种结论:**VERIFIED** | **NOT VERIFIED** | **INCONCLUSIVE**
直击 agent 写代码最大的毛病——太容易凭感觉宣布完成。这个 skill 可迁移到 Claude Code、Codex、OpenCode 等任何本地 coding agent。
---
## control-cli & control-ui执行层
- **control-cli**:给交互式 CLI/TUI 搭可重复 harness用 tmux、PTY、Expect、Node inspector 驱动输入、捕获屏幕、记录 transcript
- **control-ui**:面向 Web/IDE/Electron用 Playwright/CDP 连接真实页面,截图、读 accessibility tree、抓 console/network、做性能和内存分析
说明 Cursor 内部对 agent 的要求已不止读代码和写代码——代码写完后 agent 要真的去操作它。
---
## PR 被当成阅读体验来设计
PR 生命周期工具:
- `new-branch-and-pr`
- `review-and-ship`
- `make-pr-easy-to-review` — 整理 noisy history、改 PR 描述、补风险说明
- `get-pr-comments`
- `pr-review-canvas` — 将 diff 渲染为交互式 HTML 走读页面加伪代码、流程图、review checklist
AI 让代码产出速度变快后review 压力上升,审查代码也要做信息设计。
---
## 两条 Rules 暴露代码品味
只有两条 always-on rules
1. **typescript-exhaustive-switch** — TypeScript union/enum switch 做穷尽处理(`never` 兜底)
2. **no-inline-imports** — import 放文件顶部
共同指向:代码要容易被静态分析,也要容易被人扫读。
---
## workflow-from-chats元技能
从最近对话里提取团队偏好:触发条件、工作步骤、质量标准、停止条件、证据和置信度。判断该写成 skill、rule、workflow doc 还是不落地。
解决长期问题:人会不断纠正 agent 的行为习惯,但这些纠正如果不显式沉淀成 artifact就不会累积为能力。
---
## 总结
- **verify-this** 解决了 agent 自证的问题
- **control-cli/ui** 把 agent 从代码生成推进到操作验证
- **pr-review-canvas** 承认审查代码需要信息设计
- **两条 rules** 是品位种子
- **workflow-from-chats** 解决团队知识沉淀

View File

@@ -0,0 +1,72 @@
# Cursor: 持续改进我们的智能体框架 (Continually Improving Agent Harness)
> 原文: [cursor.com/cn/blog/continually-improving-agent-harness](https://cursor.com/cn/blog/continually-improving-agent-harness)
> 作者: Stefan Heule & Jediah Katz · 2026-04-30
## 核心思想
改进智能体框架 = 愿景驱动 → 提出假设 → 实验验证 → 定量/定性信号迭代。大多数改进不是跃迁式突破,而是执着地叠加一个个小优化。
---
## 1. 上下文窗口的演进
- **早期 (2024末):** 模型自行选择上下文能力弱 → 大量护栏lint/类型错误反馈、改写文件读取请求、限制单轮工具调用数量、预填大量静态上下文(文件夹布局、语义匹配代码片段、用户附件压缩版)
- **现在:** 上述做法大多淡出。保留少量实用静态上下文OS、git 状态、当前/最近查看文件)。转向**动态上下文**——模型在工作过程中按需拉取(过往对话、活跃终端会话、相关工具等)
## 2. 评估框架变更
| 方式 | 说明 |
|------|------|
| **离线评估** | 自有评估套件 + 公开基准 [CursorBench](https://cursorbench.com);快速、标准化、可跨时间对比 |
| **在线 A/B 测试** | 同时部署两个+框架变体,在生产环境真实用户中测试 |
**质量衡量指标:**
- **直接指标:** 延迟、token 效率、工具调用次数、缓存命中率
- **保持率 (Keep Rate):** 智能体生成的代码变更在固定时间后仍保留在代码库中的比例
- **语义满意度分析:** 用 LLM 读取用户对智能体输出的回应——用户进入下个功能=成功信号,用户粘贴堆栈追踪=失败信号
➤ 案例: 尝试用更贵模型做上下文摘要,改善微乎其微,不值得成本。
## 3. 跟踪并修复性能退化
**工具调用错误分类:**
- `InvalidArguments` / `UnexpectedEnvironment` — 模型出错、上下文矛盾
- `ProviderError` — 外部工具服务中断GenerateImage、WebSearch 等)
- `UserAborted` / `Timeout` — 用户中止或超时
**告警策略:**
- 未知错误=缺陷 → 超阈值即告警
- 预期错误 → 异常检测告警(每个工具×每个模型分别计算基线),显著偏离基线时触发
- 自动化工单: 每周运行一个特化智能体,搜索日志找出新增/激增问题,在 Linear 创建或更新工单
➤ 成果: 一次集中冲刺将意外工具调用错误降低一个数量级,所有工具可靠性达 99%+(很多 99.9%)。
## 4. 为不同模型定制框架
- 所有框架抽象不依赖具体模型,但可深度定制
- **工具格式差异:** OpenAI 训练使用 patch 格式编辑文件Anthropic 习惯字符串替换。用错格式会消耗更多 reasoning token 并产生错误
- **提示定制:** OpenAI 遵循指令更字面/精确Claude 更偏直觉,对不精确指令容忍度高
- **Early Access 调优:** 从最接近的现有框架入手 → 离线评估找出易错点 → 团队成员实际使用反馈 → 迭代直到可发布
- **"上下文焦虑"context anxiety:** 一个模型在上下文窗口渐满时拒绝执行任务,通过调整提示缓解
## 5. 支持聊天中途切换模型
- 切换时自动切换到对应模型的框架(不同提示、不同工具接口)
- 添加自定义指令告诉模型它是"中途接手"对话
- 缓存是 provider/model 特定的,切换导致缓存未命中 → 尝试用对话摘要缓解
- 替代方案: 使用**子智能体**(从全新上下文窗口开始),最近支持用户指定模型运行子智能体
## 6. 框架与软件开发的未来
- **多智能体模式**是方向: 一个负责规划、一个负责快速编辑、一个负责调试,各司其职
- **框架是关键:** 知道调度哪个智能体、如何描述任务、如何整合结果——这些编排能力体现在框架中,而非单个智能体身上
---
## 启发
> 与 Hermes Agent 的开发哲学高度一致——持续关注动态上下文、工具可靠性、评估方法论、以及为不同模型优化框架。
---
原文链接: [https://cursor.com/cn/blog/continually-improving-agent-harness](https://cursor.com/cn/blog/continually-improving-agent-harness)

View File

@@ -0,0 +1,41 @@
---
title: GPU的BVH以及排序相关实现心得史上最简洁GPU原理论述
source: 游戏开发技术教程 (微信公众号)
url: https://mp.weixin.qq.com/s/FJxTDw9KdVwZx0RfojdYCg
date: 2026-05-06
tags: [GPU, BVH, ComputeShader, 碰撞检测, GPU排序]
---
# GPU的BVH以及排序相关实现心得史上最简洁GPU原理论述
## 核心内容
作者在Unity中实现了GPU版本的BVHBounding Volume Tree碰撞检测以及双调排序和radix-sort两种GPU排序算法。
## GPU原理简述
- **GPU架构**grid → block → warp 三级结构
- **SIMT**单指令多线程一个warp默认32线程
- **分支发散divergence**同一个warp内的线程必须执行相同指令不同warp/block的线程可以独立执行不同逻辑分支
- **Bank Conflict**同一个warp的两个线程同时访问同一bank的不同地址时访问会被串行化
- **内存层次**全局内存RWStructuredBuffer和共享内存groupshared— 共享内存访问速度更快但只能在block内共享
## 关键见解
1. GPU完全可以做条件分支计算前提是同一warp内的线程走相同分支
2. Compute Shader本质上是低级的GPGPU编程语言能力远不止"shader"
3. BVH每一帧都重新构造以处理运动物体并防止树木退化
4. 双调排序实现简单几行shader代码就能搞定
5. Radix-sort效率更高包含sweep upreduce和sweep down前缀和两个过程
## 相关链接
- 知乎GPU BVH系列https://zhuanlan.zhihu.com/p/707169090
- 作者的知乎专栏游戏开发https://zhuanlan.zhihu.com/column/c_1861690729694359552
## 技术细节
- 实现的是2D版本BVH支持100万量级无明显卡顿
- 使用instancing drawing渲染大量quadUnity缺省渲染太卡
- 作者显卡有19个SM每个SM支持2048线程最高并行约4万线程
- 碰撞结果回传CPU方案异步+分发器模式

View File

@@ -0,0 +1,227 @@
---
source: 微信公众号
url: https://mp.weixin.qq.com/s/Rao9okjfY7gzsHldjRKdDw
title: Hermes Agent 架构分析
tags: [hermes-agent, architecture, AI-agent]
---
# Hermes Agent 架构分析
## 系统全景
Hermes Agent 是一个**多平台、可扩展的 AI Agent 框架**,核心组件包括:
- **核心 Agent 引擎** — AIAgent 类run_agent.py
- **工具系统与注册中心** — registry 架构
- **网关与多平台适配** — 20+ 平台适配器
- **配置与状态管理** — 双轨配置 + SQLite 会话存储
- **安全模型** — 多层审批 + 纵深防御
---
## 核心 Agent 引擎
### AIAgent 类设计
采用**大类单文件设计**run_agent.py所有核心逻辑汇聚于一个文件中。
**60+ 构造器参数**按语义分区:
- 模型配置
- 工具控制enabled/disabled_toolsets
- 行为控制quiet_mode, save_trajectories
- 上下文标识platform, session_id
- 回调注入clarify, approval, sudo, progress callbacks
这是一种**配置注入Configuration Injection**模式。
### 双接口设计
```python
def chat(self, message: str) -> str:
"""简单接口 — 返回最终响应字符串"""
def run_conversation(self, ...) -> dict:
"""完整接口 — 返回字典"""
```
Facade + Full API 双层设计。
### 核心循环
```
while api_call_count < max_iterations and budget.remaining > 0:
# 1. 预飞检查 — 上下文压缩
# 2. API 调用
# 3. 工具调用分支(支持并行执行)
# 4. 终止条件
```
**关键设计决策:**
| 权衡 | 选择 | 理由 |
|------|------|------|
| 同步 vs 异步 | 同步循环 | 可预测性、调试简单 |
| 迭代控制 | 双重限制 | 线程安全预算管理 |
| 上下文压缩 | 触发式 | 仅在 token 上限时启动 |
### IterationBudget — 线程安全预算管理
使用 threading.Lock 实现,解决子代理委派场景下的预算共享问题。
### 上下文压缩5 阶段管线)
1. **工具输出裁剪** — 截断超长返回值
2. **头部保护** — 锁定系统提示 + 前 N 轮
3. **Token 预算尾部定位** — 从尾部向前累积
4. **结构化摘要** — LLM 摘要被截断的中间部分
5. **工具对消毒** — 确保 tool_use/tool_result 成对出现
**防抖机制**:检测连续多次压缩则触发紧急降级。
### Prompt 缓存策略
Anthropic system_and_3 策略:系统提示 + 最后 3 条消息设置 cache_control 断点。
### 多 API 模式适配
支持 4 种 LLM API 协议OpenAI、Anthropic、Google、OpenRouter内部统一格式后在 API 调用前动态转换。
---
## 工具系统与注册中心
### Registry 架构tools/registry.py
```python
class ToolEntry:
__slots__ = ('name', 'toolset', 'schema', 'handler', 'check_fn',
'requires_env', 'platform_filter', 'is_mcp')
```
**设计亮点:**
- **AST 自动发现** — 扫描 tools/ 目录的 registry.register() 调用,无需手动维护导入列表
- **MCP 影子保护** — MCP 工具同名时优先内置版本
- **__slots__ 优化** — 减少内存开销
### 工具分层6 层)
从底层执行环境到顶层 Agent 循环,每一层单向依赖。
### 工具集定义
_HERMES_CORE_TOOLS 列表,用户通过 enabled/disabled_toolsets 精确控制。
### 工具调用生命周期8 步流程)
LLM → tool_calls → model_tools.handle_function_call() → registry.dispatch() → 审批检查 → handler → JSON result → tool_result message
---
## 网关与多平台适配
### Gateway 架构
异步事件循环20+ 平台适配器并发运行,统一路由到 AIAgent。
### 平台适配器模式Template Method + Strategy
```python
class BasePlatformAdapter(ABC):
# 4 个必须实现的抽象方法
async def send_text(self, chat_id, text): ...
async def send_typing(self, chat_id): ...
async def get_display_name(self, user_id): ...
async def start(self): ...
# 10+ 可选覆盖方法
```
支持 20+ 适配器Telegram、Discord、Slack、WhatsApp、QQ、Signal、HomeAssistant、WeChat元宝等。
### 会话管理
- 双写持久化SQLite+ JSONL向后兼容
- 重置策略idle空闲超时/ daily每日定时
### Agent 缓存LRU
最大 128 个 Agent 实例的资源感知缓存。
---
## 数据流转
### 主流程(键盘 → 屏幕)
CLI 入口 → Agent 循环 → LLM API → 工具执行 → 流式渲染 → 会话持久化
### 工具调用流细节
- **Agent 级拦截**todo_tool、memory_tool 直接处理不进 registry
- **审批流程**:环境豁免 → YOLO 模式 → LLM 智能评估 → 人工审批
---
## 配置与状态管理
### 双轨配置系统
```
~/.hermes/
├── config.yaml # 结构化配置 (YAML)
├── .env # 环境变量 (API keys)
├── skins/ # 自定义皮肤
├── skills/ # 已安装技能
└── sessions/ # 会话数据 (SQLite + FTS5)
```
### 三套配置加载器
- load_cli_config() — CLI 交互模式
- load_config() — 子命令
- 直接 YAML 加载 — Gateway
### SessionDB
SQLite + FTS5 全文搜索WAL 模式读写并发自动迁移Jitter 写重试。
---
## 安全模型
### 多层审批体系
1. 环境检测豁免 → 2. YOLO 模式 → 3. LLM 智能评估 → 4. 人工审批回调
### 危险模式检测30+ 模式)
```python
DANGEROUS_PATTERNS = [
r"rm\s+(-[rf]+\s+)?/", # 文件系统破坏
r"curl.*\|\s*(bash|sh)", # 网络风险
r"sudo\s+", # 权限提升
# ...
]
```
Unicode 规范化防绕过NFKC + 零宽字符移除)。
### 凭证保护
- 环境变量黑名单(工具执行时自动过滤)
- 敏感路径保护(~/.ssh/, ~/.gnupg/ 等)
### SSRF 防护
在平台适配器基类中验证 URL阻止内网/回环地址访问。
### 安全设计哲学
纵深防御Defense in Depth最小特权、分层检查、反绕过、环境隔离、凭证隔离。
---
## 可扩展性体系
### 工具扩展(最核心的扩展机制)
添加新工具仅需 2 个文件 + AST 自动发现。零配置。
### 技能系统Skills
纯文本能力增强(~/.hermes/skills/),通过自然语言描述注入系统提示。
### MCP 生态
Hermes 同时作为 MCP Server 和 MCP Client。
### 皮肤系统
纯数据扩展YAML运行时通过 /skin 命令即时切换。
---
## 设计哲学
### 核心原则
- **实用主义胜于教条主义** — 大文件不如过度拆分
- **回调注入实现界面无关** — 4 个入口共享同一个 AIAgent
- **分层而非分片** — 6 层清晰分层
- **安全作为一等公民** — 深度嵌入架构
- **约定优于配置** — 自动发现、自动加载、自动集成
### 主要权衡
| 权衡 | 选择 | 收益 |
|------|------|------|
| 大文件 vs 小模块 | 大文件 | 核心逻辑内聚 |
| 同步 vs 异步 | 同步 | 可预测性 |
| 单进程 vs 微服务 | 单进程 | 部署简单 |
| AST 发现 vs 显式注册 | 动态发现 | 零配置 |
### 一句话总结
> Hermes 是一个以实用主义为导向、以可扩展性为骨架、以安全性为底线的工业级 AI Agent 框架。

View File

@@ -0,0 +1,66 @@
---
title: Hermes 编排 Agent + Web 可观测性方案
date: 2026-04-29
tags: [Hermes, Agent编排, ttyd, tmux, 可观测性]
---
# Hermes 编排 Agent + Web 可观测性方案
## 背景
Hermes 作为母 Agent 编排不同的子 AgentCodex、Claude Code 等),但全部在后台运行,无法直观看到每个 Agent 的实时输出和进度。需要将后台 tmux session 暴露到 Web 前端观察。
## 方案ttyd + tmux
**ttyd**GitHub 31k+ stars可以把任意终端程序变成 Web 页面,通过 WebSocket 实时推流。
### 架构
```
Hermes (编排大脑)
├─ tmux session codex1 ─── ttyd :8080 ──► http://localhost:8080
├─ tmux session claude1 ─── ttyd :8081 ──► http://localhost:8081
└─ tmux session codex2 ─── ttyd :8082 ──► http://localhost:8082
```
### 使用方式
```bash
# 启动 Agent 的 tmux session
tmux new-session -d -s codex1 -x 140 -y 40
tmux new-session -d -s claude1 -x 140 -y 40
# ttyd 暴露每个 session 到 web
ttyd -p 8080 tmux attach -t codex1 &
ttyd -p 8081 tmux attach -t claude1 &
# 浏览器打开
open http://localhost:8080 # 看 Codex
open http://localhost:8081 # 看 Claude Code
```
### 类似方案
- **Wetty / Gotty** — 与 ttyd 类似
- **LangFuse / AgentOps** — 专业 Agent trace 平台,但偏事后日志分析,非实时终端画面
### 文件握手通信
Agent 之间通过文件交换上下文:
```
/tmp/handoff.json # Codex 输出 → Claude Code 读取
/tmp/instruction.md # Claude Code 重注入指令 → 拉起新 Codex
/tmp/next_prompt.txt # 下一步指令
```
## 关键结论
1. **不要** 让 Agent 之间直接互相调用(失控)
2. **要** 用 Hermes 作为中央编排大脑
3. **用文件作为 Agent 间通信协议**
4. **ttyd 解决实时观察问题**,浏览器多标签同时查看所有 Agent
---
*来源Hermes Agent 对话 (2026-04-29)*

View File

@@ -0,0 +1,84 @@
# OpenSpec + Superpowers workflow orchestratorOpenFlow连接需求与工程的工作流编排器
**来源:** [微信公众号 - 幽人](https://mp.weixin.qq.com/s/8PT7nlj-Jcu8Xa6lwyApYQ)
**作者:** 幽人
**日期:** 2026年5月15日 11:12
**标签:** #OpenFlow #OpenSpec #Superpowers #工作流编排 #AI编码
---
## 核心定位
> OpenSpec + Superpowers workflow orchestrator — bridging requirements specs and engineering execution, eliminating the format gap.
**OpenFlow 是连接需求规格与工程执行的工作流编排器**,消除两者之间的格式鸿沟。它是一个 npm 全局包(`@lininn/openflow`),纯粹作为一个独立的**编排层**,不嵌入 OpenSpec 或 Superpowers 的代码。
GitHub: [lininn/openflow](https://github.com/lininn/openflow)
### 解决的问题
- **需求模糊**:用户说"做一个贪吃蛇游戏"AI 需要自行猜测技术栈、复杂度、边界条件
- **规格缺失**:没有结构化的设计文档,代码写到一半发现需求变了
- **进度不明**:做到哪里了?哪些功能已完成?哪些待验证?
- **验收困难**:如何确认代码实现了设计?设计变更是否同步到代码?
---
## 核心架构
- **技术栈**TypeScript98.6%npm 全局包
- **核心依赖**OpenSpec结构化规格生成+ Superpowers实现规划与执行
- **目录结构**CLI 优先 + 模板驱动 + 平台兼容(.claude/ 技能 + .omc/ 会话存储)
### 双层依赖检测机制
**优雅降级策略** — 不强制依赖 OpenSpec 或 Superpowers
- Init 时检测:检测缺失 → 引导安装,但技能文件仍然生成
- 运行时检测Build 阶段发现缺失时自动降级为手动步骤执行
核心理念:**让工具先能用,再逐步完善。**
---
## 五阶段工作流
| 命令 | 阶段 | 描述 |
|------|------|------|
| `/openflow proposal` | proposal | 轻量需求捕获 — 3-5 个问题快速收敛需求 |
| `/openflow brainstorming` | brainstorming | 深度设计 — 多轮权衡探索 |
| `/openflow spec` | spec | 生成规格 + 自动翻译为 plan-ready.md |
| `/openflow build` | build | 执行实现(调用 Superpowers |
| `/openflow close` | close | 验证一致性 + 归档 |
### Proposal 阶段:需求的起点
用最少的提问3-5 个),把用户脑子里的需求变成可执行的变更描述:
1. **做什么** — 想实现什么功能/变更?
2. **为什么** — 解决什么问题?给谁用的?
3. **成功标准** — 怎样算做完了?验收条件?
4. **边界** — 什么不在范围内?
5. **现有约束** — 技术栈、兼容性、时间上的限制?
输出格式proposal.md
### Spec 阶段:从 proposal 到可执行规格
将 proposal 升级为完整的规格文档包含详细的功能描述、数据结构、API 设计、组件树等。最终产出包括:
- `design.md` — 完整设计文档
- `specs/` 目录 — 规格细节(包含详细的 spec 和 `plan-ready.md`
- `tasks.md` — 任务清单(含依赖关系和验收标准)
### Build 阶段:自动执行实现
关键概念是**任务沙箱**task sandbox
1. 每个 task 从 tasks.md 中被抽取到一个独立的 `.snapshot/` 沙箱
2. 沙箱内包含:任务描述、相关规格、类/方法骨架、依赖说明
3. 为每个 task 生成独立的 contextLLM 上下文隔离,避免信息过载)
### Close 阶段:验证与归档
- `verify` 子命令:对照 tasks.md 验证每个任务的实现状态和格式一致性
- `close` 归档:将 changes 目录中的内容归档到当前项目的 `changes/`
---
## 编排 vs 工具绑定
OpenFlow 与其他方案的区别:
- **不是**将 Cursor/Claude Code/Codex 等工具与工作流深度绑定
- **而是**在每个阶段生成描述性的 prompt 和产出,让各阶段的 AI Agent 可以看懂指令并产出对接产物
- 靠**文件格式**(统一的 markdown 规范)打通各阶段,而不是靠 API 集成

View File

@@ -0,0 +1,96 @@
# AI编程新范式规格驱动编程 OpenSpec 的落地实战
**来源:** [微信公众号 - AI软件产品经理](https://mp.weixin.qq.com/s/5CSEUj1R7q3KhaRBkJE-ZA)
**作者:** melong
**日期:** 2026年4月7日 07:00
**标签:** #OpenSpec #规格驱动编程 #AI编程 #Cursor #落地实战
---
## OpenSpec 简介
> OpenSpec 是一个命令行工具,帮助我们和 AI 助手之间建立规范驱动spec-driven的开发流程强调变更隔离、人类与 AI 的共识和审查闭环,本质上是在构建一种新的"人机协作语言"。
GitHub: [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec)
### 核心思想
将开发流程拆解为两个清晰的阶段:
1. **明确"要什么"** — 在 `openspec/specs/` 文件夹中定义当前系统的完整规范
2. **管理"怎么改"** — 在 `openspec/changes/` 文件夹中存放所有变更提案
从"边写边改"到"规范先行",非常适合 **1→n 的项目迭代**
### 亮点
- 变更从提案到落地、全流程规范、闭环管理,每一步可溯源、复查与协同
- 规范落地后,后续团队成员查阅 specs 文档即可快速了解业务历史和变更细节
---
## 初始化工作
### 1. 安装 OpenSpec
```bash
npm install -g @fission-ai/openspec@latest
# 需要 Node >= 20.19.0
```
### 2. 项目初始化
```bash
cd your_project
openspec init
```
选择使用的工具Cursor、Claude Code、Codex 等),会在项目根目录下生成对应的 skill 文件夹。
### 3. 填充项目上下文信息
在 Cursor 对话框中输入:
```
Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions
```
`project.md` 结构包括Purpose、Tech Stack、Project ConventionsCode Style / Architecture / Testing / Git Workflow、Domain Context、Important Constraints、External Dependencies。
### 4. 生成变更提案
在 Cursor 中使用 `/openspec-propose` 命令:
```
/openspec-propose 需求文档地址为https://mi.feishu.cn/wiki/xxx
```
每次提案生成一个 Change ID`changes/` 下创建目录,包含:
- **proposal.md** — 提案Why / What Changes / Impact
- **design.md** — 技术方案和架构决策
- **tasks.md** — 任务清单(多阶段 checkbox 任务)
- **specs/xxx/spec.md** — 可测试的需求规格
### 5. 审查与验证
- **重新提案**:不满意时可反复迭代,直到符合预期
- **反复迭代**:直接在 tasks.md 上修改,而不是新建提案
---
## 执行落地
### 拆分任务为可用交付walkthrough
- 将 tasks.md 的每个阶段按最细粒度拆分
- 让 AI 搞清楚当前阶段全部任务细节
- 确认前后端各自的任务边界
### 增量编码模式
- 每完成一个 phase`/review``/fix``/test`
- 用自然语言描述期望,比问"有没有bug"更有效
- tips频繁 `/clear` 清空上下文,避免 token 老化
---
## 常见报错与解决
| 报错 | 原因 | 解决 |
|------|------|------|
| `openspec: command not found` | Node 版本不够或全局安装路径问题 | 用 `npx @fission-ai/openspec` 替代,或升级 Node |
| 图片/head 标签被截断 | Cursor 的响应长度限制 | 分阶段执行,或要求 AI 仅输出关键修改部分 |
| 上下文过长导致幻觉 | 长时间未 `/clear` | 每个 phase 完成后 `/clear`,重新加载上下文 |
---
## 总结
> **OpenSpec 的核心价值不在于工具本身,而在于它强制执行的"先想清楚再动手"的工程纪律。** 在 AI 编码能力越来越强的今天,真正的瓶颈已经不是"写不出代码",而是"写不对代码"。OpenSpec 通过规范驱动的方式,把人的判断力放在设计阶段,把 AI 的执行力放在编码阶段,各取所长。

View File

@@ -0,0 +1,51 @@
---
title: TMP字体Atlas内存优化实战
source: https://mp.weixin.qq.com/s/iPSxQvg-riGh66efHlSyLA
author: 侑虎科技
date: 2026-05-06
tags: [Unity, TMP, 内存优化, Atlas, UWA]
---
# 【厚积薄发】从64MB降至5MBTMP字体Atlas内存优化实战
> 来源UWA公众号 - 第474篇UWA技术知识分享
## 实战案例一字体Atlas双实例冗余 + RW动态图集内存过高
**问题:** GOT Online报告显示项目游戏字体Atlas出现双实例冗余且开启RW动态图集内存占用过高。
**原因:**
- 字体Atlas实例数量为2通常是因为该字体既在初始包中的初始场景中被引用又在后续AssetBundle资源中重复引用
- RWRead/Write Enabled开启导致CPU和GPU各存一份内存翻倍
**解决方案:**
1. 将初始场景中使用的字符单独创建对应的小字体,避免初始场景中有大图集和大字体的引用
2. 预先收集游戏的大部分字符集将Atlas设置为**静态图集配置**可减少16MB占用
3. 不在静态图集中的字符通过TMP的**Fallback机制**设定一个小分辨率如512×512的动态Atlas进行字符补充
## 实战案例二TMPAsset内嵌Atlas纹理无法压缩
**问题:** TMPAsset内嵌Atlas纹理属于子资源无法单独进行纹理压缩参数配置。
**解决方案Editor脚本改造**
1. 通过Editor编辑器脚本对该纹理进行独立复制
2. 将TMPAsset材质球关联替换为复制后的新纹理
3. 移除原TMPAsset内的内嵌纹理
4. 剥离后的独立纹理可自由配置压缩格式ASTC6×6、ASTC8×8等进一步降低内存开销
5. 真机测试:压缩后文字美术表现无明显差异
## 优化前后对比
| 项目 | 内存 |
|------|------|
| 优化前 | **64MB** |
| 优化后合计 | **4.75MB** |
| 初始场景 512×512 静态图集 | 0.25MB |
| 4096×4096 静态图集ASTC8×8 | 4MB |
| Fallback兜底纹理 512×512Alpha8 | 0.5MB |
## 相关资源
- UWA社区community.uwa4d.com
- UWA官网www.uwa4d.com
- UWA学堂edu.uwa4d.com
- QQ群793972859

View File

@@ -0,0 +1,62 @@
# 97.9%采纳率胶水编程业务需求出码最佳实践【天猫AI Coding实践系列】
> 来源:[微信公众平台](https://mp.weixin.qq.com/s/G3aKbzdGUyD2h1aVjvbr2g)
> 作者:天猫品牌行业前端 / 大淘宝技术
> 日期2026年3月27日
## 摘要
本文分享了天猫团队在"胶水编程"场景下的最佳实践即利用AI高效连接现有业务模块以快速响应需求实现了高达97.9%的代码采纳率。文章指出,针对业务逻辑组装、接口对接及样板代码填充等"胶水"型任务通过构建精准的上下文提示策略和标准化的开发流程能极大发挥AI在理解业务意图和组合代码片段上的优势显著缩短从需求到上线的周期。
---
## 核心认知别让AI写代码让它抄代码
试点业务域半年前采纳率 50%——不是AI写不出代码而是写出来的代码不可控组件乱用、规范不守、已知的坑反复踩。
**核心认知:** 把团队已有的开发规范、代码模式、领域知识喂给 Agent让它组装而非创作——这套方法叫"**胶水编程**"。**SPEC 管意图,物料管执行**,两者叠加才是完整的可控编码。
## 核心理念AI不应该"写(SPEC)"代码,而应该"抄(GLUE)"代码
中后台业务绝大部分需求以 CRUD 为基础——列表页、表单页、详情页、导入导出场景高度相似。90%的代码本来就有现成的参照。
> **胶水编程不是在限制 AI而是在顺应它的能力结构——让AI做拟合的事。能抄不写能连不造能复用不原创。**
> Agent 的工作不是从零创作,而是从内部物料中组装出新的交付,只在业务差异点写最少量的"胶水代码"——**90%抄10%写**,胶水只在缝隙处。
## AI编码可控性的三个递进层次
1. **Vibe Coding** → 解决"能不能用AI写代码"。用自然语言描述需求AI直接生成代码。产出完全不可控不可能直接合入生产仓库。
2. **SPEC Coding** → 解决"AI写的代码对不对"。用结构化的技术方案约束AI行为。但管不到具体实现——Agent知道要写列一页但不知道团队列表页长什么样。
3. **Glue Coding** → 解决"AI写的代码像不像我们的"。在SPEC基础上给Agent三样东西**开发规范(规矩)、代码模式(骨架)、领域知识(经验)**。产出的代码风格统一、组件正确、CR一次通过。
> **Vibe让AI能写代码SPEC让AI写对代码Glue让AI写出"你的"代码。**
## 四层物料体系
Agent写代码时背后有四个彼此独立的决策每一层物料恰好堵一个漏洞
| 物料层 | 加载方式 | 技术机制 | 触发时机 |
|--------|----------|----------|----------|
| **开发规范** | 静态注入 | 云端配置→AGENTS.md→注入system prompt | 打开仓库时自动加载 |
| **代码模式** | 静态注入 | 样板间代码文件通过提示词引用注入Agent上下文 | 打开仓库时自动加载 |
| **领域知识** | 动态检索 | Agent通过MCP协议调用Knowledge Server按需检索 | 编码过程中按需触发 |
| **任务规格** | 动态生成 | 开发者选择SPEC模板→填写→生成spec.md作为初始上下文 | 每次需求启动时生成 |
**为什么开发规范必须静态加载?** 56%的场景中AI根本不会主动调用文档工具将同样内容直接写入AGENTS.md静态加载后通过率从53%提升到100%。**关键规则必须始终在场**不能依赖AI的主动调用。
**为什么不能全量塞进去?** Anthropic上下文工程博客"一个精准的300 token上下文往往胜过一个混杂的113,000 token上下文。" 上下文越长安全特性实现反而下降了47%。
## 这个转变意味着什么
- **投资方向变了**核心投资不再是prompt工程或等待更强的模型而是建设内部物料体系让单次交付可控和需求规格的持久化管理让长期迭代可控
- **质量标准变了**好的AI编码不是"生成了多少代码",而是"原创了多少代码"——在可标准化的部分,**原创越少,说明物料体系越完善**,产出越可控。
- **团队资产观变了**:已有项目代码是可复用的样板间资产,已完成的需求规格是后续需求的决策上下文——每一次交付都在积累物料和上下文,形成**复利效应**。
## 关键设计原则
- **开发规范**AGENTS.md仓库级别的编码约束是写代码的底线。定义不可逾越的约束而非可选的建议。
- **代码模式**样板间代码具体的、经过评审的已有实现文件作为Agent的"抄写范本"。
- **领域知识**Knowledge Server通过MCP协议提供的内部组件坑点、接口注意事项等长效知识点。
- **Task Spec**(任务规格):当前需求的完整上下文描述。
> 相关阅读《Spec Coding 不是银弹》内部文章——SPEC编码的三个结构性局限AI缺乏真正的理解能力、规范无法完整描述系统、规范比代码更难维护。

View File

@@ -0,0 +1,36 @@
# 大家有没有感觉最近大模型变笨了
**来源**: https://www.v2ex.com/t/1196441#reply25
**保存时间**: 2026-03-24
**标签**: #AI #大模型 #讨论
---
## 帖子摘要
楼主提问:大家有没有感觉最近大模型变笨了?
主要讨论点:
- 用户感觉 GPT-4、Claude 等大模型最近回复质量下降
- 有人认为是心理作用或期望值提高
- 也有人提到可能是模型更新导致的风格变化
- 讨论涉及多个主流大模型GPT-4、Claude、Gemini 等
---
## 关键回复观点
1. **心理作用论**: 用多了之后对模型能力边界更清楚,所以感觉"变笨"
2. **模型更新论**: OpenAI 等厂商确实会调整模型,可能影响某些任务的表现
3. **任务复杂度**: 随着使用深入,提出的问题更难,模型显得力不从心
4. **对比效应**: 新模型出来后,旧模型相对显得弱了
---
## 个人思考
(待补充)
---
**原始链接**: https://www.v2ex.com/t/1196441#reply25

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
---
title: 知乎文章 - 2028819446546932894
source: https://zhuanlan.zhihu.com/p/2028819446546932894
created: 2026-05-09 15:02
tags: [zhihu, article, saved]
---
# 知乎文章
**URL:** https://zhuanlan.zhihu.com/p/2028819446546932894
**说明:** 此 URL 由 Hermes 保存文章内容因知乎反爬虫机制zse_ck暂无法自动抓取。
> 请手动访问该链接查看完整文章内容,然后将正文粘贴到此处。
---

View File

@@ -0,0 +1,377 @@
---
title: Unity 热更新的隐形命门:一篇讲透"确定性构建管线" - 知乎
source: https://zhuanlan.zhihu.com/p/2028488903561163102
created: 2026-05-09 15:35
tags: [zhihu, article, unity, assetbundle, deterministic-build]
---
# Unity 热更新的隐形命门:一篇讲透"确定性构建管线" - 知乎
**来源:** [https://zhuanlan.zhihu.com/p/2028488903561163102](https://zhuanlan.zhihu.com/p/2028488903561163102)
---
写在前面
文章是由AI生成的最开始是为了当个人笔记让AI补全一下相关内容
核心观点是确定性构建管线这个在6000.x的官方文档里已经有明确说明
Deterministic builds
如发现错误,以官方文档为准
起因:看到 Unity Partner Engineer 发的一篇帖子 Understanding Old Dependency Reuse in Unity AssetBundles通篇在反复强调一个短语——deterministic pipeline。这个概念在中文社区里几乎没人讲透但它恰恰是 AssetBundle 热更新体系的根基。本文尝试把它讲清楚。
一、一个看似简单的问题,藏着一个深坑
先抛一个场景给你,你试着回答一下:
线上已经下发了 Bundle A 给玩家。现在你新打了一个 Bundle BB 依赖 A。你想让玩家继续用本地那个旧的 A不要重新下载可以吗
凭直觉回答多数人会说”当然可以A 没改嘛”。
但真相是:在”确定性构建管线”下可以,在”非确定性构建管线”下不行。
Unity 官方的说法原话是:
It might work, but do not rely on it. (可能能用,但别指望它。)
这个”能不能依赖”的分界线就是Deterministic Build Pipeline。
二、到底什么是”确定性构建”?
一句话定义:
给定完全相同的输入(资源 + 代码 + 配置 + 工具链 + 环境),无论构建多少次、在哪台机器、谁来构建,输出的二进制文件字节级完全一致。
写成公式:
same input + same pipeline = same output (byte-identical)
初学者常常会有这样一种错觉:
“我重新打了一次包,文件哈希没变,那我的管线肯定是确定性的。”
这个理解方向对,但不够精准。我们需要区分两个概念:
概念 性质 描述
“输出未变” 结果现象 两次构建 AB 的 MD5/SHA 相同
“确定性管线” 管线属性 只要输入不变,就必然输出不变的能力
换句话说——“输出未变”只是一次幸运的观测;“确定性”是一种架构保证。后者才是工程意义上的可依赖性。
三、为什么它是热更新的命门?
让我们把场景画出来:
上线日: Bundle A (已推送给 1000 万玩家)
次月更新: Bundle B (依赖 A),本次不想动 A
你希望玩家的流量账单是这样:
下载 B + 复用本地 A = 省下一整个 A 的流量
要做到这点你必须回答一个问题B 里记录的那个”指向 A 的引用”,今天还指得到吗?
这就要讲 AB 的内部机制了。
AB 是怎么记录跨包引用的
每个 AssetBundle 内部是一个 SerializedFile开头有一张 External References 表:
External References
path(1): "Library/unity default resources"
path(2): "Resources/unity_builtin_extra"
path(3): "archive:/CAB-35fce856128a6714740898681ea54bbe/CAB-35fce856128a6714740898681ea54bbe"
然后对象内部的引用长这样:
m_Material PPtr<Material>
m_FileID : 3 ← 指向上面 path(3)
m_PathID : 6 ← 目标文件里的第 6 号对象
所以 B 里的一个引用本质是一个二元组:
(file, object) = (CAB 路径, PathID)
关键点CAB 路径里那个 hash是由”构建出的 SerializedFile“决定的不是抽象的”Bundle A”。
现在你就能看懂这个”坑”了
如果管线是确定性的:
A 没改 → 重新打也一定得到字节完全一致的 A → CAB 路径不变 → PathID 不变
B 里的 (CAB-xxx, PathID=6) 仍然能 100% 命中旧 A
玩家本地的旧 A 可以安全复用,不用重新下载
如果管线是非确定性的:
A 没改,但重新打出来的 A 可能CAB 哈希变了、或者对象顺序变了、或者PathID 漂移了
B 里记的引用指的是”新 A“的结构
你让玩家复用旧 A → 可能看起来正常,也可能随机 crash
这就是为什么 Unity 官方只敢说 “might work, but do not rely on it”。
构建管线的确定性,决定了你整个热更体系的可靠上限。
四、哪些行为会破坏确定性?踩雷清单
下面我把最容易踩的坑按四个层级整理出来。每个坑都用 “现象 → 原因 → 怎么修” 的格式来讲,方便直接对照排查。
A. 构建管线层 —— 你选错了工具或用错了姿势
1. 🔥 搞混了几种 hash把”输入 hash”当成了”内容指纹”
现象明明包内容变了你的版本对比系统却说没变或者反过来内容没变hash 却变了。
原因Unity 内置 BuildPipeline.BuildAssetBundles 生成的 hash 是基于输入估算的,不是基于最终产物的内容。里面其实混着好几种 hash
hash 类型 它代表什么
IncrementalBuildHash 用来判断”要不要重新打这个包”的输入指纹
TypeTreeHash 用来判断”类型结构有没有变”
缓存 version hash 给 Caching 系统用的版本标识符
最终二进制内容 包文件实际的字节
这四个东西完全不是一回事。如果你把前面某个 hash 直接当成 CDN 版本号,或者当成”两个包一不一样”的判断依据,就会出错。
Unity 6.6 手册也明确提醒了:
The AssetBundle input hash isnt an ideal value for tracking file versions.
怎么修:
如果你的发布系统需要精确判断”包内容到底变没变”,优先考虑 SBP 或 Addressables — 它们的 hash 是基于构建输出算的,更准确
如果继续用内置 API就别拿它的 hash 直接当内容校验,自己对产物算一遍 SHA256 更靠谱
2. 以为开了 DeterministicAssetBundle 就万事大吉
现象:明明开了这个 flag不同机器打出来的包还是不一样。
原因BuildAssetBundleOptions.DeterministicAssetBundle 是老时代的知识。它只解决 PathID 分配的确定性问题。但在现代 Unity6.x破坏确定性的主要原因早已不是这个 flag而是
收集资源时没排序
构建脚本里塞了时间戳、随机数
不同机器的导入缓存不一致
构建环境OS、Unity 版本)不一样
怎么修:不要只盯这一个开关。真正要盯的是整个构建流程的输入稳定性。
3. 打包前忘了切 Build Target
现象CI 上打 Android 包,但编辑器的 Active Target 还停留在 iOS。打出来的包和手动打的不一致。
原因:如果你调用 BuildPipeline.BuildAssetBundles 时指定的平台和当前 Active Target 不一样Unity 会悄悄触发资源重导入和脚本重编译。更坑的是,正在跑的编辑器脚本(比如你的打包工具、构建回调)是按旧 Target 编译的,可能出现平台条件判断错乱。
怎么修CI 脚本里,打包之前先显式切换 Active Target
EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Android, BuildTarget.Android);
B. 资源数据层 —— 你的资源本身就不稳定
4. AB 名字里带了日期或构建编号
现象每天打包即使资源没变包名都在变hash 自然跟着变。
坏例子 vs 好例子:
❌ ui_mainmenu_20260417.bundle ← 每天都变
❌ ui_mainmenu_build_2841.bundle ← CI 编号会变
✅ ui_mainmenu ← 稳定标识
✅ ui_mainmenu_v1.2.3 ← 语义化版本
Unity 6.36.6 文档的原话:
Avoid timestamps or build-date suffixes in AssetBundle names and use static identifiers or semantic versions.
5. ⭐ 收集资源时没排序(最常见的坑!)
现象:同一台机器连续打两次,包的 hash 居然不一样。更常见的场景是 A 电脑打出来的包和 B 电脑的不一样。
原因AssetDatabase.FindAssets() 和 Directory.GetFiles() 返回的顺序不保证一致。不同机器、不同文件系统、甚至同一台机器在不同时间调用顺序都可能飘。一旦资源添加顺序飘了序列化数据的排列就飘了hash 自然就变了。
坏写法:
// ❌ 直接遍历,顺序不可控
var guids = AssetDatabase.FindAssets("t:Prefab", new[] { "Assets/UI" });
foreach (var guid in guids)
{
group.AddAsset(guid);
}
好写法:
// ✅ 加一行排序,问题消失
var guids = AssetDatabase.FindAssets("t:Prefab", new[] { "Assets/UI" })
.OrderBy(x => x, StringComparer.Ordinal)
.ToArray();
记住这条规则:凡是涉及 FindAssets、GetFiles、EnumerateFiles 的地方,必须手动排序。
6. 往 ScriptableObject 里塞数据时,塞入顺序不稳定
现象:和上面一样,不同机器或不同时间构建出的包不一致。
原因:如果你在构建前用 IPreprocessBuildWithReport 之类的回调,动态往 SO 的 List<Object> 字段里塞东西,塞的顺序不稳定,序列化出来的字节就不稳定。
Unity 6.6 文档说得很明白:
If the order of objects in that array isnt explicitly sorted, the serialized data might differ between machines or consecutive builds.
怎么修:喂给 SO 的数据,在写入之前先排好序。
7. 资源里写入了随机值、时间戳、机器名
现象:每次构建,某些 SO 文件的内容必定不同。
坏写法:
// ❌ 每次构建都不一样
so.buildGuid = Guid.NewGuid().ToString();
so.buildTime = DateTime.UtcNow.Ticks;
so.machine = Environment.MachineName;
这类字段一旦进了序列化数据,确定性就直接被你自己亲手打穿了。
C. 环境与工具链层 —— 你以为机器都一样,其实不一样
8. Unity 版本不一致
一句话哪怕只差一个小版本号序列化格式、导入器行为、Shader 编译都可能有细微差异。
怎么修CI 锁死 Unity 版本,精确到补丁号(比如 6000.0.32f1),团队所有人用同一个版本。
9. 操作系统或 CPU 架构不一致
现象Windows 的 CI 和 Mac 的 CI 打出来的包不一样,尤其是包含动画、粒子的包。
原因:浮点数运算在不同 CPU 架构上的舍入行为不同。Unity 6.6 文档原话:
Floating-point rounding behavior differs between architectures, which can change serialized float values especially in AnimationClips or imported Mesh data.
怎么修:所有 CI 构建机用同一种 OS + 同一种 CPU 架构。
10. Git 自动换行没关掉
现象Windows 开发者提交的文本文件是 CRLFMac 开发者的是 LF。文本资源的 hash 莫名其妙对不上。
怎么修:
git config --global core.autocrlf false
再在 .gitattributes 里统一声明所有文本文件用 LF。
11. 不同机器的 Library 缓存状态不同
现象同样的项目A 机器是全新 cloneLibrary 是新生成的B 机器已经用了很久Library 有大量缓存)。两台机器打出来的包不一样。
原因Unity 的资源导入结果会受 Library 缓存状态影响。Unity 曾修过一个著名 bugUUM-114616Shader AB 在”干净 Library”和”有缓存 Library”下产出不同。
怎么修:用 Unity Accelerator 让所有构建机共享同一份导入结果。但注意Accelerator 只缓存导入产物imported assets不缓存打出来的 AB 包本身。它帮你统一了导入阶段,但不是万能保险。
D. 脚本与代码层 —— 改了代码,资源也跟着动
12. 脚本改动的涟漪效应
现象:明明没动资源,一堆 AB 的 hash 都变了。
原因:脚本的某些改动会导致 MonoScript 身份信息变化,进而影响引用了这些脚本的 AB。但具体是哪些改动有影响需要搞清楚
会影响 AB 的脚本改动 不会影响 AB 的脚本改动
脚本移到另一个 asmdef 下 只改注释
asmdef 改名 只改方法内部实现(不涉及序列化字段)
改类名或命名空间 只改 private 字段(非序列化的)
改 [SerializeField] 字段的类型/名称
丢失 .meta 文件后重新生成
13. 构建回调里偷偷写入了变化数据
现象:每次构建的 Scene AB 都不一样,但场景文件明明没动。
原因:你(或某个插件)在 IProcessSceneWithReport 之类的回调里写了类似这样的代码:
// ❌ 每天构建出来的 name 都不一样
public void OnProcessScene(Scene scene, BuildReport report)
{
foreach (var go in scene.GetRootGameObjects())
{
go.name = $"Built_{DateTime.Now:yyyyMMdd}";
}
}
怎么修:构建回调里严禁使用 DateTime.Now、Guid.NewGuid()、Environment.MachineName 等非确定性 API。
14. Shader 变体集合不稳定
现象不同机器或不同时间打的包里Shader 变体数量不一样。
原因:如果你的 Shader Variant Collection (SVC) 是通过运行时录制收集的,那它完全取决于”测试的人跑了哪些路径”。不同人、不同时间跑出来的变体集合自然不同。
怎么修:大型项目应该用离线枚举 + 手动维护的方式管理 SVC而不是依赖”录制式收集”。
五、如何保障确定性:一份能落地的清单
工程约定
[ ] 所有自动化脚本收集到的资源集合,统一做稳定排序
[ ] 禁止把时间戳、构建编号、机器名写进 AB 名称或序列化资源
[ ] 明确区分输入 hash、缓存 version hash、内容校验 hash避免混用
[ ] Git 关闭自动换行转换,并用 .gitattributes 固定文本换行策略
[ ] 构建回调中禁止使用 DateTime.Now、Guid.NewGuid 等非确定性来源
[ ] 若项目强依赖内容级哈希语义,优先评估 SBP 或 Addressables
[ ] Addressables 项目里catalog 是依赖身份的权威来源,不要手工替换 bundle
CI/CD 约定
[ ] 锁定 Unity Editor 版本,精确到补丁号
[ ] 固定构建机的 OS 与 CPU 架构
[ ] 构建前对齐 active target 或 build profile
[ ] 使用 Unity Accelerator 统一 imported assets
[ ] 发布构建尽量采用 clean build
[ ] ProjectSettings、构建配置全部纳入版本控制
Code Review Checklist
所有 FindAssets、GetFiles、EnumerateFiles 的结果是否稳定排序
所有写入 SO 的数组、列表、映射是否有稳定顺序
是否写入了时间、随机数、机器相关元数据
是否有 build callback 在构建时改写资源
是否把某种 hash 误当成了内容校验或发布版本号
六、最后的防线:双跑比对
在 CI 里做双跑比对:
不修改任何资源
在相同参数下连续构建两次
对每个 AB 文件计算 SHA256
任何哈希不一致,立刻告警并定位差异
定位阶段,用 UnityDataTools 的 textdumper 把两个版本的 SerializedFile 导出成可读文本后直接 diff。
七、一些延伸思考
写到这里,回头看 Unity 那篇原帖里一段意味深长的话:
The reason I initially missed the point is that this question is only interesting when that assumption breaks. (我一开始没 get 到这个问题的点,因为这个问题只有在”确定性假设被打破时”才有意义。)
这句话其实在说一个很工程哲学的事情:
构建的确定性是一种”隐形的契约”。它平时不存在、不被感知,但一旦破裂,会带着你整个热更体系一起塌方。
很多商业项目上线多年都没踩过这个坑,不是因为管线真的确定性,而是因为:
每次版本更新都全量重推所有依赖包(成本掩盖了问题)
或者依赖关系极简(运气好到没引用跨包的老资源)
但一旦你想要做差分热更、按需下载、跨版本依赖复用这些更精细的运营动作,确定性就是你绕不开的地基。
八、结语
一篇帖子引出的概念,最后会延展成一整套工程规范。回到最初的问题:
打包出来的 AB 完全没变,就是确定性管线吗?
答案是:
“输出没变”是确定性管线的一种观测现象;”确定性管线”是只要输入不变就保证输出不变的架构能力。在热更场景下,后者才是你能信赖的东西。
如果你负责的是一个需要长期运营的 Unity 项目,强烈建议今天就做两件事:
在 CI 上加一次”双跑比对”,看看你们的管线现在到底是什么状态
把本文的”踩雷清单”打印出来,贴在构建平台的 PR 模板里
地基打牢之前,所有的热更优化都是在流沙上盖楼。
参考资料
Unity 官方讨论Understanding Old Dependency Reuse in Unity AssetBundles
Unity 6.3 LTS 手册AssetBundle and Addressables determinism
Unity 6.6 手册Deterministic builds introduction
工具UnityDataTools
Scriptable Build Pipeline
如果这篇内容对你有帮助,欢迎点赞/收藏。

View File

@@ -0,0 +1,100 @@
---
title: 回放系统让你的游戏时光倒流 - 知乎
source: https://zhuanlan.zhihu.com/p/2031265691286947108
created: 2026-05-09 17:43
tags: [zhihu, article, game-dev, replay-system, sync-mechanism]
---
# 回放系统让你的游戏时光倒流 - 知乎
**来源:** [https://zhuanlan.zhihu.com/p/2031265691286947108](https://zhuanlan.zhihu.com/p/2031265691286947108)
---
打一盘很爽快的游戏或者遇到了恼人的bug此时你一定想要一个“月光宝盒”能回放你的游戏过程。然而在很多游戏的初始开发阶段回放系统的优先级都是比较低的等到真正要去实现回放系统时发现现有的一些架构会带来很多困难不免感叹“如果当初...”。
我们不妨假设拥有了“月光宝盒”,回到游戏最初开发的阶段,看下怎么设计好一个回放系统。
回放深度绑定同步机制
回放的前提是录制游戏运行数据然后根据数据重新执行游戏流程。录制时的性能消耗、数据的存储大小以及重新运行数据的复杂程度都是必须考虑的因素。再考虑到为了复现bug的目的回放时要尽可能走正常游戏时一样的数据处理逻辑。稍加思考就能发现不同的游戏同步机制下这些问题的解决方案会大相径庭。所以我们也必须区分讨论。
状态同步下的回放方案
采用状态同步机制的游戏,客户端表现主要是通过与服务器的交互状态数据包驱动。那么,直接将客户端收发的数据按照时间顺序保存下来,然后重新创建一场游戏去加载这些数据包,能实现回放吗?很遗憾,这种方案是行不通的。
1P困境
因为1P玩家的往来数据包并不能完全还原当时的操作比如最基础的位置信息客户端通常是先依据操作计算出位置然后将位置发送给服务器服务器进行一定的校验后如果通过则不会返回任何数据给客户端可以看出1P玩家的位置完全是由本地事件驱动的先不考虑弱网情况
为了极致的手感很多操作都是1P本地先行触发然后上报服务器进行校验和广播。既然只保存1P的交互协议数据是不完整的那能不能同时记录本地操作的事件呢只能说原理上可行但实现上很难。
游戏中有很多的操作输入口你需要重构这些输入层统一汇总到一个管线然后在管线中执行录制操作录制的信息格式要能反映出多种类型的输入后续的响应逻辑也要按照约定的参数进行设计。想一想就知道涉及面很广涉及的人很多如果版本迭代多年后才要开发回放系统这种情况下很难推动方案的落地。况且你也不想Bug缠身天天加班不是最后如果游戏逻辑中事件响应还有随机逻辑你必将面临随机数的确定性问题估计又要打一个很大的补丁。
换个观察者视角
揉一揉疲惫的脑袋想一下游戏比赛中转播的画面是怎么做的主持人选择一个目标角色画面就能切换到这个玩家的视角。实际上服务器会为主持人创建一个observer设定其观战某个target玩家所有要转发给target的数据包都会转发给observer。
假如给开启回放的玩家创建一个隐藏的observer然后把target设置为自己可行么这绝对是可行的。客户端只要保存observer相关的数据包就能用来回放。
数据包回放
保存数据包时同时记录其时间再回放时可以设定一定的帧率比如30帧驱动客户端Update。网络层并不发起真正的socket连接而是直接设定为已连接状态网络模块Update改为从回放数据包中取数据。依照时间取出所有33ms内的数据包数据包处理走正常3P一样的处理逻辑。
在移动设备上如果每条数据包都立刻落盘到文件累积会有很大的IO消耗。可以采用批量写入的方案积累到一定条数的数据包以后统一写入文件。写入文件的操作可以放到单独的线程中执行。
性能“打脸”
当你将功能自测完毕,交由性能测试时,无情的报告单显示"数据流量增长、发热出现增长"。是啊多出一个observer的数据发送必然会导致这样的结果。
你揪着越来越少的头发漫无目的地对比1P普通情况下和开启replay情况下的数据包日志文件。突然发现observer的数据包和1P数据包绝大部分都是重合的只是多了些1P没有必要的数据包。你突然有了精神能不能使用1P的数据包伪造出observer的数据包呢
基于差分的缝合怪
经过一番代码排查最终确认只要为1P补发一些observer初始化数据以及几大类1P操作对应的广播数据包就行。那些广播数据包通常都有集中的逻辑流管线处理起来并不麻烦。
此方案完美地解决了流量增长和发热增加的性能问题。
功能交付QA测试后又报过来一个新的问题总是感觉角色移动和一些关键操作慢了一拍这是为什么呢问题在于observer下发数据包自带的延迟网络延迟+处理延迟)!
如果简单地为这些关键数据包统一做延迟修正,能有所改善,但是延时设置为多少是个问题。设置过大可能会早于实际的操作发生时间,就会与其他正常的数据包时间错位,产生“穿帮”,设想下被击中者还没有走到位置,你的击中操作已经显示了,这是无法接受的。
此时就要采用非常规的手段了能不能将这些关键的数据包对应的IP发送包C2S包处理成S2C包呢这样时间肯定是正确的避免强行修正延迟导致的数据包之间的时间错乱问题。数据包格式的转换也并不复杂大部分字段都是复用的仅需要做简单的头部调整即可。
快进和回退的难处
在回放时,快进和回退是必不可少的功能。要实现快进,只要在极短的时间里快速处理跳过时间段里的所有数据包即可。很显然,如果是小时间段的快进,处理会很顺畅,但是如果跳过的时间段非常大,那么快进消耗的时间就很明显了,必须考虑做遮罩处理避免看起来画面卡住。
虽然通过一定时间间隔保存全量快照的方式可以缓解长时间段快进的耗时(直接调到最近的快照点),但这会给录制带来计算和存储压力,不一定划算。
回退的问题更大,因为你无法从当前状态通过向后回退数据包而把场景也回退了。唯一的方法只能是从头重新播放,然后以快进的方式调到回退点,让玩家看起来在回退。
帧同步就比较简单了
因为帧同步天然的“只同步输入不同步状态”只要输入一致客户端演算的结果就一致所以录像就比较简单了只要全部录制发送和接收的操作指令即可。而且因为输入指令的数据量很小所以整场比赛的录像数据也很小存储和IO压力可以忽略不计。
至于快进和回放面临的问题与状态同步下的问题本质一样,这里不再赘述。不过,采用帧同步的游戏,场景实体数量通常较少,所以可以更多地考虑关键帧快照的优化方式。
更酷的死亡回放
战斗中被人击杀了你一定很想立刻知道“TM谁杀了我”。死亡回放可以让你查看死亡前几秒内发生的事情一定对你的“复仇大业”很有帮助。
死亡回放的关键是要服务器时刻为每个玩家保存一段可回放数据包因为你不知道自己会被谁杀死只有在被击杀的时候你才能确定要回放的“凶手”视角。毫无疑问直接为所有玩家保存回放数据包服务器的压力会很大。好在通常也只需要保存不到10s的时间段所以还能接受。显然这种不完整的录像数据段必须配合全量快照才能工作。
以10s为例要设计一套双缓冲存储机制。假设命名为P缓冲和N缓冲。当P写满后开始写入N如果N写满后再次写入P如此往复。每次写入新的缓冲时都生成服务器全量快照。当死亡点发生再N中时 N_d 则从P的全量快照开始恢复游戏场景然后播放录像到N_d。
关键是断线重连
对于有复活机制的玩法,播放死亡回放时玩家还在游戏对局中,那么服务器怎么看待这个玩家的状态呢?如果当作在线的玩家,一些广播的数据包就还要通知客户端,这必然导致和正在播放的死亡回放场景冲突。另外,玩家死亡回放播放结束后,还要回到正在进行的游戏场景中。
这段时间在服务器看来如同客户端发生了断线重连一样。是的,关键就是断线重连!依靠断线重连,如同为死亡回放在客户端构建了一个平行宇宙,完全不会对服务器架构和逻辑产生过多的影响。而且,重连机制通常是游戏的基础设施之一,直接拿来用“何乐而不为”。
当然,死亡回放是模拟断线重连的表现,但是并不能真的完全断线,一些重要的即时数据还是要接收的,比如被复活的消息。可以制定协议白名单,处理这些特殊的逻辑,既保证不影响死亡回放的场景,又能让玩家不漏掉重要信息。
清理场景的脏活儿
为了死亡回放而清理场景中的实体以及HUD资源并非想象中容易对于迭代了几年的游戏来说并不一定有统一的卸载逻辑收口难免需要人工排查清理还有一些全局的数据状态都要特别处理后续添加的新逻辑也都要考虑死亡回放的情况。因进出死亡回放引发的bug也经常发生此为头痛之事尚没有好的解决办法。
性能优化的好帮手
性能优化的一大难点是如何验证优化是有效的,可重现的基准场景能提供极大的帮助,而回放系统就能提供可重现的基准场景。以同样的录像数据包,在优化前和优化后的客户端中播放录像,对比性能数据能有力的验证优化的效果,因为能排除玩家数量、操作行为、时序等变量的干扰。所以,早日实现回放系统能给你带来很多意想不到的好处。

View File

@@ -0,0 +1,42 @@
# 从需求到交付:一套基于 AI 辅助的高质量代码生产实践
**来源:** [微信公众号 - OLDLIE](https://mp.weixin.qq.com/s/V8AR1ooSgrafZgH6KgEEOw)
**作者:** oldlie
**日期:** 2026年4月11日 19:32
**标签:** #AI编码 #代码质量 #交付流程 #OpenSpec #Superpowers
---
## 核心流程
### 1. 需求分析与关键点识别
使用 `openspec explore` 指令向 AI 提出概要需求。核心目的是借助 AI 的信息处理能力,快速识别需求中的关键点、潜在风险和边界条件。
### 2. 制定分阶段实现路线图
利用 `superpower` 技能,要求 AI 将需求转化为清晰、可执行的路线图Roadmap将整个项目拆解为多个可管理的阶段。
### 3. 前置条件确认与详细设计
进入每个新阶段前,让 AI 确认所有前置条件是否满足。确认后协作进行详细设计,要求 AI 输出包含后台代码详细设计和关键过程时序图的设计文档,并严格参考既定的代码规范。
### 4. 设计审查与规范对齐
设计文档完成后进行严格审查,确保实现方案完全符合代码规范。**"先设计,后编码"** 的模式让问题在早期被发现和解决,效率远高于在代码写完后再去分散阅读源文件。
### 5. 代码实现与自动化审查
AI 完成代码编写后立即执行 `/review` 指令。`/review` 模式关注的维度(安全性、健壮性)与默认编码模式不同,要求更高,能发现单元测试难以覆盖的逻辑问题。
此外AI 有时倾向于使用最简单而非最高效的方式实现功能,或在处理长上下文时出现"偷懒"现象——人工触发的全面审查必不可少。
### 6. 查漏补缺与迭代循环
`/review` 之后让 AI 根据路线图再次检查当前阶段是否存在遗漏,确认无遗漏且满足进入下一阶段的条件后,再开启新一轮循环。
---
## 流程设计的深层思考
| 设计要素 | 价值 |
|---------|------|
| **路线图** | 将宏大目标拆解为具体步骤,减少单次交互的上下文信息量,确保整体目标不偏离 |
| **详细设计文档** | 集中审核设计逻辑比分散阅读代码更高效,更容易发现深层次问题 |
| **分步设计** | 管理上下文窗口长度,确保 AI 在每个环节保持高效和精准 |
**核心理念:** 通过精心设计的步骤、指令和审查机制,引导 AI 成为"结对编程"伙伴,共同交付高质量的代码。

View File

@@ -0,0 +1,80 @@
---
title: 基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践
source: https://mp.weixin.qq.com/s/ygQGSH5c7GHYDvkqWoQTXQ
author: 盖伦 / 得物技术
date: 2026-05-06
tags: [AI开发, 全栈, SDD, Harness, Cursor, Claude Code]
---
# 基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践|得物技术
## 一、核心理念Harness 思维 — 让 AI 模仿,而不是凭空创造
### 全栈AI开发最容易踩的坑
让AI从零开始写代码产生"外星代码"风格不一致、复用率低、采纳率低。AI生成了代码但Review成本和返工成本反而更高了。
### Harness 思维的核心:给 AI 一个"模仿对象"
给AI一个已有的实现作为参照让它照着复刻一份而不是凭空创造。
**四条原则:**
| 原则 | 说明 | 举例 |
|------|------|------|
| 找相似实现 | 在代码库中找到功能最相似的已有实现作为参照 | "结束语"参照"场景化欢迎语" |
| 复用优先 | 能复用的组件、接口封装、数据结构直接复用 | 复用greetingExtendInfo数据结构 |
| 模仿着复制 | "抄一份改一改"比用新方式好 | Controller/Service/Repository按已有模仿 |
| 约束生成范围 | 提示词中明确指定参考文件/参考接口 | 前端修改入口@FeatureTable/index.tsx:53-58 |
### 提示词体现 Harness
- ❌ 不推荐:`请实现一个结束语管理的 CRUD 接口`
- ✅ 推荐:明确指定参考文件、数据结构和接口路径,如"参照场景欢迎语功能(后端/api/v1/feature/list前端FeatureTable/index.tsx:53-58实现"
## 二、全栈工作区搭建与 Codebase Indexing
将前后端代码放在同一个工作区下的三个核心价值:
1. **Codebase Indexing**Cursor对工作区内所有代码进行向量化嵌入建立语义索引AI能跨仓库理解代码关系
2. **上下文完整**AI同时能看到前后端代码接口字段、命名风格自然对齐
3. **SDD文档集中管理**前后端SDD文档在同一工作区便于接口契约对齐
### Cursor vs Claude Code 实测对比
| 功能维度 | Cursor | Claude Code |
|---------|--------|-------------|
| 代码库语义索引 | 支持grep+语义检索,速度快 | 仅支持grep依赖模型能力 |
| 代码生成速度 | 极速平均1-3分钟 | 中速平均3-30分钟 |
| 代码采纳率 | 两者相当 | 两者相当 |
| 文件/代码段引用 | 快捷键、拖拽即可引用 | 需手动@文件路径,无法引用代码段 |
| 多Agent | 默认开启多Tab并行 | 需手动注册子Agent |
| 费率模型 | 失败任务不收费 | 失败任务耗时长容易浪费Token |
| 历史会话恢复 | 仅能查看当前项目会话记录 | 可查看全局会话记录 |
| 综合评价 | 快速迭代首选推荐Composer2模式 | 长链路复杂任务可用 |
## 三、SDD 驱动的全栈代码生成流程
- 全栈SDD需同时覆盖前后端
- 提示词编写范式:明确需求、参考实现、数据结构、接口契约
- 前后端需求点清单分工示例
- SDD文档产出与指令使用说明
## 四、多 Agent 协作:前后端并行开发
- Cursor中使用多Tab并行默认开启
- Claude Code中使用Subagent能力需手动注册
- 建议前端Agent专注UI/交互后端Agent专注API/数据
## 五、前后端联调Mock 数据与分阶段验证
- 三阶段验证策略
- Mock数据编写要点
- 后端独立构建验证
- 前后端联调步骤
## 六、警惕 SDD 陷阱:测试如何介入全栈研发
- SDD不等于需求文档
- 关注隐性功能(异常处理、边界情况、性能要求)
- 测试应尽早介入
## 七、综合效益与总结
核心公式:**Harness约束 + SDD规格 + 多仓(上下文) = 高质量AI全栈代码**

View File

@@ -0,0 +1,78 @@
# 天猫新品团队AI编码实战指南
**来源:** [微信公众号 - 大淘宝技术](https://mp.weixin.qq.com/s/iRkxznDYhE-kXjbIHlrnNA)
**作者:** 天猫新品营销技术
**日期:** 2026年5月8日 16:07
**标签:** #AI编码 #天猫 #全栈化 #知识库 #实战指南
---
## 背景
团队开始了后端向前,前端向后的全栈化转型运动。后端承担小二工作台与研发工具开发(需求驱动型),前端承担 C 端 solution 编写。
**核心思想:** 作为业务团队,重点应该是沉淀自己团队的工作流与 AI 资产——通过**最大化复用**来提高整体效能(代码、知识、工作流、工具的复用)。
### 场景分类
| 严苛程度 | 典型场景 | 错误容忍 | 交互问题容忍 | 代码要求 | 视觉还原要求 |
|----------|---------|---------|-------------|---------|-------------|
| 最为严苛 | C 端频道 | 0 容忍 | 明显则 0 容忍 | 高 | 高 |
| 较为严苛 | B 端商家平台 | 0 容忍 | 特别明显则 0 容忍 | 中 | 中 |
| **交付分割线** | | | | | |
| 普通严苛 | 小二端工作台 | 0 容忍 | 影响主链路则 0 容忍 | 低 | 低 |
| 低严苛 | 研发自用工具 | 一定程度容忍 | 无 hack 绕过则 0 容忍 | 无 | 无 |
| 不严苛 | 研发 DEMO | 能意会则容忍 | 怎么都能容忍 | 无 | 无 |
---
## 小二端 - AI 主导的对话生码
特点:无视觉还原要求,实现形式自由,页面独立性强,适合 AI 编码完成全部需求。
### 初期 - 统一生成方案
- 提供标准化的代码规范与视觉规范文档
- 提供高度封装的代码模版(一行代码唤起页面组件)
### 中期 - 辅助补齐前端经验短板
- **需求描述不准确**搭建「AI案例实践中心」标准化 prompt 模板;提供 MCP 速查工具「天猫新品业务编码助手」
- **垂类场景无经验**:将 AI 生码省下的时间用于生码沉淀,详细记录实现过程与踩坑心得
### 后期 - 更简单、无感、一致的方案
- 开发轻量级团队知识库,以类 Skill 形式封装开发规范与代码模板
- 知识库用 git 仓库管理npm 包作为资源承载与版本管理工具
---
## C 端 - 交付质量要求的 AI 提效
C 端场景复用机制复用分为五个级别:
1. **代码复用**对组件、布局、逻辑进行封装RCG——布局/组件/脚手架粒度递进)
2. **知识复用**:团队知识库 + 逐层加载
3. **工作流复用**:固定 AI 工作流 + 兜底方案
4. **工具复用**:通过 MCP 协议 + 内部工具获取业务数据
5. **人机分工**:固定重复工作交 AI关键环节人把控
### 视图分离方案
**核心思想:** 把一份 PRD 分成"给 AI 的结构化描述"和"给人看的说明文档",各自优化。
- 在 C 端,过复杂的 prompt 和过长的上下文都会带来性能问题
- 提出了结构化的 prompt 写法,包含场景分析、关键数据、交互与动效说明
### 知识库建设
对标 OpenAI 的 `prompt.md` + `--preamble` 的标准化管理:
1. 定义优先级规则
2. 使用 script 进行文件注入(含自动 chunk、优先命中机制
3. 统一文件结构和索引
---
## 实用技巧集锦
- **UI 重构**:利用 prompt 对图片转结构化描述
- **复杂 Prompt 构建**:结构化多段式
- **多方案选优**:让 AI 给出多个方案并对比
- **文档生成**:代码完成后自动生成说明文档
- **严厉语气 + 合理质疑**:实验表明严厉语气能提升准确率

View File

@@ -0,0 +1,13 @@
# 微信文章(未抓取到内容 - 触发验证码)
**来源:** [微信公众号文章 (未知公众号)](https://mp.weixin.qq.com/s?__biz=MzAxNDEwNjk5OQ==&mid=2650543356&idx=1&sn=c460ef2f9e36ffbdc1083dd36c2595b6)
**日期:** 2026年未知具体日期
**标签:** #微信文章
---
> ⚠️ 该文章在抓取时触发了微信的 CAPTCHA 验证码保护,未能获取到内容和标题。
>
> 原始 URL 参数__biz=MzAxNDEwNjk5OQ==, mid=2650543356, idx=1, sn=c460ef2f9e36ffbdc1083dd36c2595b6
>
> 建议在微信客户端内手动打开,或使用 WeChat 官方 API 获取。

View File

@@ -0,0 +1,20 @@
---
title: 测试笔记 - 共享目录转移
date: 2026-03-20
tags: [测试, 共享目录]
---
# 测试笔记
这是一篇测试笔记,用于验证共享目录转移流程。
## 创建信息
- 创建时间: 2026-03-20 03:01
- 来源: Mac mini 共享目录
- 目标: zanepc Obsidian InBox
## 测试内容
如果这篇笔记能成功转移到 zanepc 的 Obsidian 中,说明流程配置正确。
---
*自动创建用于测试共享目录转移*

View File

@@ -0,0 +1,86 @@
# 淘天营销中后台生码工作流最佳实践
**来源:** [微信公众号 - 大淘宝技术](https://mp.weixin.qq.com/s/VjTyHFr17l_bObG6x8-Mmw)
**作者:** 营销前台技术团队(大淘宝技术)
**日期:** 2026年4月27日 16:16
**标签:** #淘天 #营销中后台 #AI生码 #云端托管 #工作流 #大淘宝技术
---
## 升级路径总览
核心决策:从"本地+云端双路径" → **统一收敛至云端托管生码**(基于 AoneSuper
**三个核心工程:**
1. 跨仓库工作区git submodule + turborepo
2. 可编排场景化工作流
3. 知识自动沉淀(功能树 + 领域 Skill
**核心方法论:**
- 给恰好够用的精确知识
- 确定性逻辑交工程
- 知识建正向循环
---
## 为什么弃用本地研发
| 问题 | 具体表现 |
|------|---------|
| 环境配置难统一 | 系统版本、Node 版本、网络代理差异巨大,排查困难 |
| AK 管理困难 | 生态用工需明文存储 AK 在个人设备,分发/轮换/回收无管控 |
| 执行易中断 | 电脑息屏/网络断开导致长任务中断,需手动续跑 |
## 为什么选 AoneSuper 而非自建
S1 自建了基于 LangGraph 的多 Agent 架构,但发现:
- 基建维护成本高
- CodeAgent CLI 社区生态Skills、MCP、SubAgent迅速成熟
- 自建 LangGraph 方案边际收益递减
**结论:** 接入 AoneSuper投入重心从基建打磨转向业务效果优化。
---
## 跨仓库工作区
### 设计思路
1. **聚合需求仓库**:创建"需求工作区"文件夹,聚合所有相关仓库
2. **引入 git submodule**:外层文件夹作为独立 git 空间,用于存放 Agent 配置Skills、MCP、SubAgent和中间产物需求理解、方案设计、任务列表等
3. **消除副作用**:通过脚本自动化 submodule 操作,降低同学理解成本
### 研发调试优化
利用 **turborepo** 的 monorepo 构建能力,实现:
- 一键启动所有需求子仓库服务
- 自动配置子仓库间的依赖 link
- 解决多层依赖(基础组件 → 业务组件 → 前端业务)的调试问题
---
## 可编排场景化工作流
### 两种场景的差异化策略
**场景一:迁移/重构(高确定性)**
- 已有明确的"A 迁移到 B"的确定性逻辑
- 架构说明文档 + 领域 Skill 固化规则
- 将迁移/重构的逻辑转化为可复用的领域能力
**场景二:日常迭代(低确定性)**
- 需求边界模糊,需要大量上下文
- 引入**功能树**实现精准查表式知识供给
- 辅助 D2CDesign-to-Code/ API 还原优化
### 功能树
核心思想将一个项目的结构化知识路由、组件、数据流、API提取为树形索引Agent 在接到需求时可以快速"查表"定位到代码位置,而不是大海捞针。
### 知识自动沉淀
通过持续积累,形成**提效飞轮**
1. 生码过程中发现知识盲区
2. 补充功能树 / 领域 Skill
3. 下次生码质量提升
4. 释放人力持续补充更多知识

View File

@@ -0,0 +1,24 @@
# 清华大学:驾驭工程 (Harness Engineering) 研究报告
> 来源GIS极客 · 微信公众号
> 日期2026年4月10日
> 原文https://mp.weixin.qq.com/s/EdVjZuBVcXjd30TpxyLsXQ
> 完整报告下载:关注公众号 **GIS极客**,后台回复 **"清华HarnessEngineering"** 获取下载链接
---
## 核心观点
驾驭工程 (Harness Engineering) 的核心是**围绕高自治、长时程 AI 构建可治理的操作系统层**,将提示词、上下文、智能体等能力制度化为机械可验证的契约、状态恢复与审计体系,从而从 **"让AI听懂"** 升级为 **"让AI系统可信、可控、可持续运行"**。
---
## 报告概述
本文为清华大学发布的研究报告,主要内容以图片形式呈现(报告正文截图)。需要阅读完整版请按上述方式获取 PDF。
报告关注的关键问题:
- 高自治 AI 系统的治理与可控性
- 长时程 AI 运行的操作系统层设计
- 提示词、上下文、智能体的制度化
- 机械可验证的契约、状态恢复与审计体系

View File

@@ -0,0 +1,12 @@
---
source: 知乎专栏
url: https://zhuanlan.zhihu.com/p/2033520572144030920
date_saved: 2026-05-02
tags: [zhihu, inbox]
---
# 知乎专栏文章p/2033520572144030920
**链接:** [https://zhuanlan.zhihu.com/p/2033520572144030920](https://zhuanlan.zhihu.com/p/2033520572144030920?utm_psn=2033977981434114693)
> 待阅读。文章内容因知乎反爬保护未能自动抓取,请手动打开链接查看。