2026-05-03 周报
自然周:2026-04-27 至 2026-05-03
本周主线
这一周的主线不是某一个项目的连续开发,而是围绕“工具如何被正确接入、复用和约束”展开:MCP Server 的工具过滤、Claude Code 的记忆与 thinking 配置、Superpowers 的技能触发规则,以及不同 agent 协议的分层关系,都在回答同一个问题:自动化系统要可靠,不能只看表层命令或 UI 开关,而要看入口、协议层、注册机制和运行时边界。
第二条线是工程分发体系里的“坐标语义”。Docker 镜像引用、Maven 坐标、GitHub Actions reusable workflow/composite action、workflow_dispatch 和 JetBrains Marketplace 上传,看似分散,其实都涉及“标识、执行环境和发布位置是否解耦”。这些差异直接影响可复现性、CI 复用方式、失败检测和发布链路的可靠性。
第三条线落在运行时模型:React hook 依赖比较、Node.js 模块系统、Promise 异常传播和跨模块错误识别,都是对“代码看起来连在一起”和“运行时实际怎么判定”的拆解。可复用的结论是:遇到框架或平台行为时,优先找它真正比较、解析、缓存和调度的边界。
主题一:AI 工具链的入口、注册与控制面
核心脉络
- 问题起点:本周先从 Jina MCP 的配置入手,问题不是“某个 URL 返回了什么”,而是 MCP 客户端实际连接后会注册哪些工具,以及过滤是在服务端还是客户端发生。
- 推进关系:随后扩展到 Claude Code 的 MEMORY.md 和 thinking 配置,再到 Superpowers 的技能触发机制。三者共同说明:AI 工具链往往有显式入口、隐式默认值和运行时裁剪,不理解这些层次就容易把静态文件、UI 开关或命令参数误当成真实行为。
- 最终判断:这类系统要按“入口层、注册层、执行层、约束层”拆开看。URL、配置文件、技能说明、记忆索引都只是入口或控制面;真正影响模型上下文和行为的是客户端连接后的工具注册、系统提示词注入、默认 thinking 解析和技能触发纪律。
沉淀认知
- 工具注册边界:MCP 工具过滤要看客户端连接后的注册结果,因为服务端静态首页可能只展示原始工具列表;只有连接协商后的工具清单才代表模型实际可见的能力边界。
- 服务端裁剪优先:用
include_tools、exclude_tools、include_tags、exclude_tags在服务端过滤工具,比客户端逐个忽略更节省上下文,因为被过滤掉的工具不会注册到客户端。 - 记忆入口分层:Claude Code 的
MEMORY.md同时承担行为手册和索引入口,但具体记忆内容应拆到主题文件;这样每次会话只加载薄索引和规则,避免把长期记忆膨胀成上下文负担。 - 记忆需再验证:记忆是写入时刻的快照,适合提示“可能存在某事实”,不等于事实当前仍然成立;基于记忆推荐前要回到项目文件、函数或配置中验证。
- Thinking 双旋钮:
alwaysThinkingEnabled是是否启用 thinking 的开关,effortLevel是启用后投入多少推理资源的旋钮;把二者混成一个配置,会误判 UI 开关和/effort命令的职责。 - 技能先于行动:Superpowers 的触发规则强调“有相关可能就先检查技能”,本质是在把经验流程前置成约束,避免 agent 用“这个问题很简单”“我先看看代码”绕过本该执行的工作流。
- 协议层级区分:MCP 解决 agent 调工具,A2A/ACP 解决 agent 之间协作;比较这些协议时要先确认抽象层级,否则会把工具调用协议和协作协议混为一谈。
适用边界
这些结论适用于分析 AI 工具、agent 技能、MCP Server、记忆系统和模型配置的行为边界。不要把它套到所有 Web API 或 CLI 配置上;普通命令行工具可能没有客户端注册阶段,也不一定存在模型上下文成本。涉及第三方服务当前行为时,还需要重新查官方文档或实际连接结果,不能只依赖当时记录。
来源
- 2026-04-27:Jina MCP Server 配置与工具过滤
- 2026-04-27:Claude Code MEMORY.md 原理与架构
- 2026-04-28:Superpowers 技能体系
- 2026-04-29:Claude Code thinking 控制:alwaysThinkingEnabled vs effortLevel
- 2026-05-03:AI Agent 通信协议对比(MCP/A2A/ACP)
主题二:工程分发体系中的坐标、环境与复用
核心脉络
- 问题起点:Docker 镜像和 Maven 依赖都像“坐标”,但一个把 registry 位置编码进引用,一个把仓库位置放在外部配置里。这个差异会影响可迁移性、解析歧义和版本语义。
- 推进关系:GitHub Actions 的手动触发、表达式语法、reusable workflow/composite action 进一步把问题推进到 CI 层:同样是复用,究竟复用的是调用方 job 内的一组步骤,还是独立 workflow 和运行环境。
- 最终判断:工程分发链路要同时看三件事:标识是否包含物理位置、执行环境是否独立、失败是否能被平台感知。Docker、Maven、Actions 和 Marketplace 上传的坑,本质都来自这三件事没有被显式区分。
沉淀认知
- 坐标不等价:Maven 坐标是逻辑标识,仓库地址由外部配置决定;Docker 镜像引用把 registry、namespace、repo 和 tag 混在一个字符串里,所以同一软件在不同 registry 上就是不同引用。
- Tag 不是版本:Docker tag 是可变指针,不能天然提供 Maven version 那类不可变发布语义;部署链路要避免把
latest或普通 tag 当作强一致版本。 - 启发式有代价:Docker 通过第一段是否包含
.或:判断 registry host,这让docker pull nginx足够短,但也让内网 registry、命名空间和仓库名在边界场景下容易产生歧义。 - 复用粒度不同:Composite action 嵌入调用方 job,适合纯步骤复用;reusable workflow 拥有独立 job 和 runner,适合需要 checkout、独立构建环境或明确 secrets 传递的场景。
- Workflow 版本耦合:tag/push 事件使用被触发 ref 上的 workflow,
workflow_dispatch使用默认分支上的 workflow;如果 CI 逻辑和业务代码强耦合,旧 tag 可能跑旧 CI。 - 表达式分层:
${{ }}是 GitHub 服务端先替换,替换后的文本才交给 runner shell;if:条件和 shell 变量属于不同解析层,混淆后很容易写出看似合法但语义错误的 workflow。 - 上传要显式失败:JetBrains Marketplace HTTP 上传只靠
curl时必须使用--fail-with-body,否则 HTTP 400 也可能让 Actions 显示成功,发布链路会出现“平台拒绝但 CI 绿”的假象。
适用边界
这组认知适用于容器引用、依赖坐标、CI 复用、插件上传和发布自动化设计。不要简单推导为“所有 CI 都应该拆到独立仓库”:单项目、小规模发布把 reusable workflow 独立仓库化可能过度设计。真正的判断标准是 CI 逻辑是否需要跨仓库复用、是否需要独立执行环境,以及旧 ref 跑旧 workflow 是否会造成实际风险。
来源
- 2026-05-02:Docker 镜像坐标 vs Maven 坐标
- 2026-05-02:Docker 镜像引用的启发式解析规则
- 2026-05-02:GitHub Actions workflow_dispatch
- 2026-05-02:GitHub Actions 表达式语法
- 2026-05-03:GitHub Actions reusable workflows vs composite actions
- 2026-05-03:JetBrains Marketplace 插件上传
主题三:运行时判定比表面写法更重要
核心脉络
- 问题起点:React
useEffect的依赖数组常被记成几条背诵规则,但真正统一的解释是 render 后比较新旧依赖,变化才执行。 - 推进关系:Node.js 模块系统、Promise 异常传播和跨模块错误类判断继续强化同一个视角:运行时不是按“看起来像同一段代码”处理,而是按文件后缀、
package.json type、Promise 链、模块缓存 key 和对象属性来判定。 - 最终判断:框架行为的可靠理解来自底层判定条件。依赖数组、模块格式、异常传播和
instanceof都不能只靠表面语法推断,要看实际比较算法、加载规则和异步边界。
沉淀认知
- 依赖数组统一:
[]、[deps]和不传依赖不是三套规则,而是“能否比较依赖”的三种结果;空数组每次比较 0 个元素,所以更新时永远没变化,不传依赖则无法比较,只能每次执行。 - 首次执行必然:
useEffect第一次 mount 必定执行,因为没有旧依赖可比,语义上等价于从无到有;这个模型也能迁移理解useMemo、useCallback和useLayoutEffect。 - 模块格式看声明:
.mjs固定是 ESM,.cjs固定是 CJS,.js取决于最近package.json的type;CLI 脚本若不需要 tree shaking、live binding 和 top-level await,CJS 往往更直接。 - 异步异常要收口:Promise 链里
.then()回调抛出的同步异常会变成 rejection,不会被外层同步try/catch捕获;链尾必须有.catch()或等价处理。 - 跨模块别迷信 instanceof:同一文件如果被不同路径加载,可能产生两份构造函数,导致
instanceof失效;跨模块错误识别更稳的是使用显式属性标记。
适用边界
这些结论适用于解释 React hook 行为、Node.js CLI 脚本、Promise 链和跨模块库边界。不要把“CJS 更适合 CLI”泛化为“ESM 不适合 Node”;当项目需要浏览器构建、静态分析、top-level await 或与 ESM-only 依赖协作时,ESM 仍可能是更好的选择。React 依赖数组的结论也依赖当前 hook 语义,具体 lint 建议仍应结合代码闭包和副作用边界判断。
来源
- 2026-04-29:React useEffect 依赖机制
- 2026-05-03:Node.js 模块系统
- 2026-05-03:Promise 与跨模块健壮性
其他杂项
- ls 时间排序:
ls -lt按修改时间降序展示文件,-l负责详情格式,-t负责按时间排序;如果要从旧到新看,加-r反转即可。来源:2026-04-27,ls 按时间排序。 - gitignore 后匹配优先:
.gitignore不是第一个匹配就停止,而是最后匹配生效;如果要重新放行被忽略的文件,!规则必须写在忽略规则之后。gradle-wrapper.jar没提交的问题就来自*.jar覆盖了前面的放行规则。来源:2026-05-02,.gitignore 规则优先级。
修正报告
- 无