关于 release-notes-generator
release-notes-generator 是用于 Datex Studio 的技能,可为两个应用分支生成技术版和客户版发布说明。它结合提交、关联工作项与配置差异,并追踪依赖项及未能分析的缺口。
主要功能
- 01比较两个发布分支
- 02枚举变更的依赖项
- 03结合提交、工作项和配置差异
- 04生成技术版与客户版说明
- 05跟踪未解析依赖项及跳过的子树
适用场景
- 01起草 Datex Studio 版本说明
- 02汇总客户应用及其依赖项的变更
- 03找出无法分析的程序包
- 04准备工程版和客户版摘要
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datex/ skills --skill release-notes-generator安装后在 Claude Code 中输入/release-notes-generator确认已加载。
详细介绍
发布说明生成器
通过合并三种来源,生成两个 Datex Studio 分支之间的发布说明:提交(合并了什么)、工作项(原因)和配置差异(实际更改)。生成技术版和客户版两种版本。
参考资料
- ../datex-studio-shared/branch-setup.md — 如果用户尚未提供两个分支 ID,说明如何选择分支
- ../commit-release-notes/SKILL.md — 获取每个提交的工程说明;记录经过验证的读取范围以及 JSON/YAML 保真要求
前置条件
--from分支 ID — 根应用的较旧版本(基线)--to分支 ID — 根应用的较新版本(目标)- dxs ≥ 0.4.9 — 需要
source release-tree和跨组织依赖解析。较旧版本的deps-diff/compare会静默报告依赖更改为零(它们比较的字段已从 AppConfig 负载中移除),且无法解析客户应用自身组织中的软件包。dxs source release-notes在 0.5.5 之前,其依赖部分也有相同的盲点;source deps --tree和source graph也一样,会返回空树。如果dxs source release-tree --help执行失败,请停止并说明情况——不要退回使用有盲点的路径。 - 强烈建议使用 dxs ≥ 0.4.24。 从此版本起,
release-tree会自行解析由 Service-Pack 固定版本的依赖,报告被跳过的子树(subtree_skipped/summary.subtrees_skipped),而不是静默丢弃;指出哪一侧解析失败(resolve_failed_sides);并接受用于索引其他组织代码仓库的--extra-org。使用较旧版本时,这些工作都必须手动完成——参见阶段 1b。 - 如果任何操作会直接调用
dxs source release-notes,则需要 dxs ≥ 0.5.4(本技能自身使用的是release-tree路径,从未受此问题影响)。它的依赖差异比较使用两侧的marketPlaceApplicationVersionId——这是AppConfig迁移时移除的字段——因此它比较的是None和None,依赖升级从未被报告为已更新。从 0.5.4 起,它会通过source compare和deps-diff使用的同一辅助函数,依据解析出的version进行差异比较,因此三者结果一致;无法解析其分支的升级也会报告为未分类,而非直接丢弃。
必须预先提供两个分支 ID。如果用户提供的是版本名称(或日期,或只提供了一个分支 ID),请先解析——参见下文的解析根应用和版本。必须遵守分支 ID 政策:绝不要猜测 ID。
解析根应用与版本
“根应用”指用户要发布的应用,不一定是 Datex 产品。客户部署的应用(例如 Tobin 的 Footprint、tob-footprint)通常只是一个轻量聚合器:它自身几乎没有或完全没有直接提交,其发布内容就是依赖项的版本升级。这是正常情况——实质内容都在依赖项中,release-tree 会枚举这些依赖项。
进入阶段 1 前,需要处理两个解析问题:
-
跨组织包。 客户应用会同时引用共享的 Datex 目录(组织 1)和其所属组织中的包(例如
tob-*)。release-tree会自动检测根应用的组织(通过applicationDefinitionId → repo → organization),并同时为两者建立索引,因此可以解析客户自己的包。旧版 dxs 不具备此功能,这些包会悄然消失。查找客户应用:dxs source repo list --org-name <CODE>。 -
版本名称,包括 Service Pack。 如果给定的是版本名称,需要将其解析为分支 ID。默认组列表不包含 Service Pack,因此像
20260423.145611.SP.20260604.154933这样的 versionName 不会出现在其中:- 默认发布:
dxs source branch list --repo <id> --default-group --status published -n 0→ 匹配versionName - Service Pack:运行
dxs source servicepack list --repo <id>查找 SP 组,然后运行dxs source branch list --repo <id> --group-id <sp_group> --status published -n 0 - (
branch search匹配的是分支名称,而不是versionName——不要使用它。)
这是手动解析根应用自身版本名称的方法。对于依赖项,dxs ≥ 0.4.24 时,
release-tree会自行处理 SP 回退查找——见阶段 1b。 - 默认发布:
工作流
[Phase 1: Enumerate]
dxs source release-tree --from <root_old> --to <root_to> (--recursive if nested)
→ root + every changed dependency, each resolved to from/to branch IDs
(cross-org), plus added / removed packages
|
[Phase 1b: Recover unresolved deps] summary.resolve_failed must reach 0
Usually empty on dxs >= 0.4.24 (SP groups resolved automatically). If not:
no repository for uniqueIdentifier -> re-run with --extra-org <orgId>
still unresolved -> manual lookup (see Phase 1b)
(with --recursive: re-walk each recovered dep — its sub-tree was skipped too)
|
[Phase 2: Commits per package]
For root + each changed dependency (parallel):
dxs source compare --from <pkg_old> --to <pkg_new> --exclude-sync
→ committed_branches (id, title, author, date, changes), workitem_ids
|
[Phase 3: Work Items per commit]
dxs source workitems --branch <commit_branch_id> --description
|
[Phase 4: Source Diffs]
For each created/meaningfully-modified/bug-fix config:
dxs source diff --from <pkg_old> --to <pkg_new> --config <ref_name>
|
[Phase 5: Write Notes]
Compose two variants per the Output Formats below:
• Technical — for developers/support
• Customer — for end users / operations
Deduplicate work items that appear in multiple dependencies. Note added/removed
packages (a newly-included package is a feature; a removed one, a flag).
阶段详情
阶段 1:枚举(release-tree)
dxs source release-tree --from <root_old_branch_id> --to <root_to_branch_id>
# add --recursive only if dependencies have their own changed sub-dependencies;
# a flat aggregator (the common case) is complete in one pass.
此调用取代了旧流程:“比较主应用,再递归地对每个依赖项逐个执行 compare”。它会返回:
root— 正在发布的应用(reference_name、分支 ID)。通常是一个自身没有直接提交的轻量包装器。dependencies— 每个发生变更的依赖项,均已解析出repo_id、from_branch_id、to_branch_id(用于深入分析这些依赖项的 ID),以及from_version/to_version。支持跨组织解析,因此客户应用所属组织的包(例如tob-reports)也会包含在内,而不只是 Datex 目录中的包。任何无法解析的依赖项都会带有resolve_error,并且(dxs ≥ 0.4.24)带有resolve_failed_sides: ["from"|"to"]—— 应从该字段读取未解析的一侧,不要解析以;连接的resolve_error字符串,其中是无法解析的说明性文本。若无法继续向下遍历,未解析的条目还会在--recursive时带有subtree_skipped: true。added/removed— 新纳入发布的包,以及从发布中移除的包。这些包没有可供挖掘的提交差异;在阶段 5 中直接记录即可(新纳入的包是一项功能;移除的包则可能需要标记)。summary— 计数(dependencies_total、resolved_ok、resolve_failed、added_count、removed_count,以及 dxs ≥ 0.4.24 时的subtrees_skipped),还有max_depth_reached和recursive。使用--recursive时,将max_depth_reached与--max-depth(默认值为 10)进行比较——如果两者相等,遍历可能已被截断。subtrees_skipped > 0与resolve_failed > 0同样严重:它表示由于无法继续遍历,某些依赖项的整个变更子树都未被枚举。
为什么不用
compare/deps-diff来枚举? 对于已解析版本的差异,只有 dxs ≥ 0.4.9 时它们才是正确的;旧版本会报告变更依赖项为 0(它们比较的是marketPlaceApplicationVersionId,该字段已从 AppConfig 负载中移除)——因此运行后会得出“没有变化”的结论,并漏掉依赖项中 80% 以上的实质内容。release-tree是权威的枚举工具,也会提供用于深入分析的分支 ID。
阶段 1b:恢复所有 resolve_failed 依赖(不可跳过)
在继续阶段 2 之前,summary.resolve_failed 必须降至 0——否则必须在备注中列出每个剩余故障,说明它们是尚未分析的缺口(见本节末尾)。 未解析的依赖至少缺少一个分支 ID,因此无法比较或生成差异——它会悄无声息地从备注中消失,而这正是此技能要防止的问题。请将非零计数视为阻塞项,而非警告。
在 dxs ≥ 0.4.24 上,本阶段通常无需执行任何操作——检查 summary.resolve_failed 和 summary.subtrees_skipped,如果两者均为 0,则直接进入阶段 2。release-tree 会自行解析固定到 Service Pack 的依赖:_published_version_map 会先合并仓库的 Default 应用组,然后为仍然缺失的版本回退到 Service Pack 组(仅对需要的仓库多列出一次)。包含 .SP. 的 versionName,例如 20260423.145611.SP.20260604.154933,现在可以正常解析。在 dxs < 0.4.24 上则始终无法解析,因为查找只会看到 Default 组——如果使用的是较旧版本,请升级(dxs update),不要手动处理下表。
如果确实发生失败,请按原因恢复:
| 信号 | 原因 | 恢复方法 |
|---|---|---|
resolve_failed_sides: ["to"](或 ["from"]) | 只有一侧缺失——另一侧的分支 ID 有效 | 仅恢复指定的一侧;切勿丢弃已有的 ID。请从此字段读取对应侧,而不要解析由 ; 连接的 resolve_error 文本。 |
no repository for uniqueIdentifier … | 软件包所属组织不在仓库索引中(缺少 repo_id)。release-tree 只会自动检测根应用所属的组织。 | 使用 --extra-org <orgId> 重新运行(可重复指定,并在自动检测到的组织基础上追加)——这是带内修复方式,CLI 自身的帮助也明确说明了此情况。只有在不知道组织 ID 时:从依赖项的 reference_name 前缀推导组织代码(tob-reports → TOB),使用 dxs source repo list --org-name <CODE> 查找该组织,然后使用 --extra-org 重新运行。 |
在 dxs ≥ 0.4.24 上出现 … not found in published releases | 确实未发布,或回退逻辑不支持该组类型 | dxs source servicepack list --repo <repo_id> → 对每个 SP 组 ID 执行:dxs source branch list --repo <repo_id> --group-id <gid> --status published -n 0 → 将 versionName 与条目的 from_version / to_version 匹配。如果这里也找不到,则该版本从未发布——将其记录为尚未分析的缺口。 |
subtree_skipped: true | --recursive 无法继续遍历此条目,因此整个已更改的子树都未加入工作列表 | 根据上面的行恢复其分支 ID,然后重新遍历(见下文)。summary.subtrees_skipped 会统计这类条目。 |
将恢复的分支 ID 输入阶段 2,处理方式与 release-tree 返回这些 ID 完全相同。
如果阶段 1 使用了 --recursive,还必须重新遍历每个恢复的依赖项。 未解析的依赖项不会加入下一深度级别的队列——遍历会跳过任何缺少分支 ID 的条目,因此也不会枚举其自身已更改的子依赖项。恢复分支 ID 可以修复该软件包本身,但其下的所有内容仍不可见,这只是同一种静默遗漏的缩小版:
dxs source release-tree --from <recovered_from> --to <recovered_to> --recursive
将该输出合并到工作列表中——按 unique_identifier + from_version + to_version 去重(与遍历内部使用的键相同),并将其 added / removed 一并带入阶段 5。然后再次检查其 summary.resolve_failed 和 summary.subtrees_skipped,执行阶段 1b:恢复的子树自身也可能包含无法解析的依赖项。
如果依赖项经过这两种途径仍无法解析,请在备注中明确说明(“无法分析 <package> <from> → <to>”),不要将其省略——尚未分析的软件包是已知缺口,不代表没有变化。
服务包是客户应用的常见形式。这类应用通常会基于已发布版本进行热修复,而不是跟踪默认分支。对于客户应用,请预期
resolve_failed > 0,并为此步骤预留预算。
Phase 2:每个包的提交
列出根包 和 Phase 1 中每个已更改依赖项的提交(并行执行,即按包展开):
dxs source compare --from <pkg_from_branch_id> --to <pkg_to_branch_id> --exclude-sync
通过 branch_comparison,你可以按包获取以下信息:
committed_branches— 每个已合并的功能分支:id— 提交的分支 ID(在 Phase 3 工作项中使用)title— 简短的提交标题。仅作为标题使用,绝不能作为发布说明条目的正文;工作项(Phase 3)和差异(Phase 4)会提供这些内容。author— 提交者datechanges— 配置级别的更改(reference_name、type、modification为add/update/delete)
workitem_ids— 整个包时间范围内关联的 DevOps 工作项。releases/release_count— 中间版本(用于标题)。
--exclude-sync 会排除仅用于同步的提交(这些提交只是拉取依赖项更新);这些提交中的实际工作会被记录,因为依赖项本身就是工作列表中的一个独立包。轻量级根应用可能会合理地返回 零个已提交分支——这不是错误,其版本内容就是依赖项升级。
对于每个已提交分支,如果有可用的 commitReleaseNotes,也请通过 commit-release-notes 获取。版本到版本的 source compare 和 source release-notes 不会包含重建后的 committed_branches 中的说明;请从分支详情/历史中补充每个返回的提交 ID。非版本比较可以保留 branch_comparison.commits 中由 API 提供的说明。说明缺失或为 null 均属正常,已有说明也可能只是重复了 API 回退/回填后的描述。即使已有详细文字,仍需分析工作项和差异;说明是辅助证据,而非实现内容的证明。
Phase 3:每个提交的工作项
对于 changes 数组并非无实际内容的每个提交(或在范围允许时处理所有提交),获取其关联的工作项:
dxs source workitems --branch <commit_branch_id> --description
工作项是发布说明中业务背景最有价值的输入。它们包含:
title— 简洁的功能名称(通常比提交标题更具描述性)type— Development / Bug / Wavelength Component / 等state— Done / Committed / 等assigned_to— 作者归属信息description— 完整的需求、复现步骤、模型图、验收标准
如果某个提交没有关联工作项,请标记为“缺少可追溯性”,并根据 Phase 4 的差异重建正文,同时将已存储的提交说明作为辅助背景。使用提交 ID 和 title 作为条目标题。
绝不要默默省略这些提交。
证据的作用:
工作项(Phase 3) — 为什么。业务意图、需求、验收标准。是说明正文的主要输入。
差异(Phase 4) — 如何实现。代码本身;当文字描述与实际提交内容不一致时,它是最终依据。
已存储的提交说明(Phase 2) — 可用时提供工程背景;请根据差异核实其中的说法,并保留可追溯性检查。标题仍然是标题,而不是发布说明正文。
阶段 4:源代码差异
对于每个值得关注的配置,拉取统一差异(使用阶段 1 中所属软件包的 起始和目标分支 ID):
dxs source diff --from <pkg_from_branch_id> --to <pkg_to_branch_id> --config <reference_name>
响应会告诉你:
change_type—created/modified/deleted/unchangedcontent— 完整配置(新建时)diff— 统一差异(修改时)
何时拉取差异:
- 始终对新建的配置执行差异比较。
content会显示新内容的完整结构 (例如中心的选项卡、流程的逻辑、网格的列)。这有助于你在说明中撰写结构描述。 - 对大量修改的配置执行差异比较。 当单个配置出现在许多提交中时,累积差异是了解实际变更的最佳方式。
- 对 Bug 修复执行差异比较。 修复通常只涉及一两行;差异能告诉你修复是否符合工作项中报告的问题。
配置类型 → 查看内容说明:
| 类型 | 描述内容 |
|---|---|
hub | 导航结构、选项卡、操作栏 |
flow / footprintFlow | 后端业务逻辑 |
frontendFlow | UI 交互和导航 |
form / editor | 用户界面屏幕 |
grid | 数据展示、列、筛选器 |
selector | 下拉选项/选择器选项 |
datasource | 数据获取查询 |
storage | 状态管理(通常使用 MongoDB) |
修改类型:
add— 新配置,可能是新功能。始终对其执行差异比较。update— 已修改。可能影响重大,也可能无关紧要;以差异为准。delete— 已移除。可能造成破坏性变更;请标记。
规模:功能位于依赖项中(并非可选项)
根应用自身的提交通常只是同步提交,或者根本没有提交。像“Wave Planning”“Cart Management”“Order Import”这样的实际功能都位于组件软件包中(Waves、Carts、Inventory、FootprintManager 等)。release-tree 已在阶段 1 中枚举并解析这些软件包;接下来要做的是对每一个软件包执行阶段 2–4,而不只是根应用。跳过依赖项分析意味着会漏掉 80% 以上的实际变更。
使用子 Agent 来应对规模。 FootprintManager 级别的发布涉及 20–60 个软件包和数百次提交,单个上下文难以处理。启动并行 Agent(每个软件包一个,或每批约 5 次提交一个)来执行阶段 2–4,然后在编写说明时汇总它们的发现。对于这种繁重且确定性的扇出任务(对预先整理好的工作清单使用低成本模型执行叶节点/归并),请参阅 datex/skills#16 中跟踪的 v2 架构。
阶段 5:撰写说明
同时生成技术版和客户版。
强制要求(两个版本均适用)
每个功能和 Bug 修复条目都必须包含:
- 工作项链接 — 指向 DevOps 的可点击 URL,由工作项的
external_id(而非其内部 ID)构建:[#XXXXXX](https://dev.azure.com/DatexCorporation/_workitems/edit/XXXXXX)(使用_workitems/edit/浏览器路径,而非_apis/wit/workItems/API 端点)。如果不存在工作项,请标记“缺少可追溯信息”,并使用提交 ID。 - 业务背景 — 工作项描述中的原因。
- 作者署名 — 实现者(来自工作项或提交)。
- 技术细节 — 新增/修改的配置(仅限技术版)。
未附工作项链接的发行说明并不完整。它们缺少可追溯性,也无法让读者获取更多背景信息。
去重
同一个工作项可能出现在多个依赖项中(例如,某个功能同时涉及 Waves 和 FootprintManager)。编写最终说明时,请按工作项 ID 去重——只列出一次该功能,并注明其涉及多个模块,而不是在每个依赖项下重复列出。
输出格式
技术版发行说明
# Release Notes — <app> (<from_version> → <to_version>)
## Summary
- Date range: <from_date> → <to_date>
- Intermediate releases: <count>
- Dependencies updated: <count>
## New Features
### <Feature Title from Work Item>
**Work Item:** [#NNNNNN](…/_workitems/edit/NNNNNN)
**Author:** <Name>
<Description from the work item requirements.>
**Structure / Technical Details:**
- <What was created — new configs, tabs, flows>
- <Key structural notes from the diff>
**New configurations:** <count> configs including <brief list>.
---
## Improvements
<same shape as Features, for enhancements to existing functionality>
---
## Bug Fixes
### <Bug Title from Work Item>
**Work Item:** [#NNNNNN](…/_workitems/edit/NNNNNN)
**Author:** <Name>
**Problem:** <What users experienced — from work item description.>
**Fix:** <What was actually changed — from the source diff.>
---
## Dependencies Updated
| Dependency | From | To | Significant Changes |
|---|---|---|---|
| Waves | <ver> | <ver> | Wave planning feature, N bug fixes |
| … | … | … | … |
客户发布说明
- **受众:**最终用户、仓库经理、运营人员。
- **语气:**文字清晰、专业。提供信息,而非营销话术。
- **聚焦“这对你意味着什么”:**说明实际影响。
- **省略:**配置名称、分支 ID、内部技术细节。
# What's New — <app> <from_version> → <to_version>
## New Capabilities
### <Feature Title>
<Two to four sentences in plain language explaining what the user can now do
and why it matters. No config names, no branch IDs.>
---
## Improvements
- <Short sentence per improvement, focused on user-visible impact.>
- <…>
---
## Fixes
- <Short sentence per fix describing the user-visible problem that is no
longer happening.>
- <…>
客户说明中的反面示例——请避免:
- 大量使用表情符号(不适合商业软件)
- 营销话术(“我们很高兴地宣布……”)
- 技术术语(配置名称、分支 ID、流程名称)
- 含糊的描述(“各种改进”“错误修复”)
提示
- **代码才是事实依据。**提交标题和工作项只是线索——代码才包含真实上下文。因此,Phase 4 的差异对比是必需的。
- **每个功能分支都应有一个工作项。**如果没有,请标记为“缺少可追溯性”;不要掩盖这一问题。
- **对比新增配置以了解结构。**中心的选项卡、流程的逻辑、网格的列,都能在
add配置的差异对比中看到。 - **差异对比能揭示错误修复的具体内容。**听起来复杂的错误,修复可能只有一行。在技术说明中展示实际改动。
- **功能往往在依赖项中。**对发布树枚举出的每个包执行 Phase 2–4,往往能发现 80% 的实质内容——对于自身应用没有提交记录的轻量级客户封装尤其如此。
- **使用子 Agent 提高处理规模。**对 60 多个包依次进行依赖项分析会受到时间和上下文限制。并行 Agent 可以解决这个问题。
- **谨慎汇总。**对多个依赖项中出现的工作项进行去重——它们是同一项功能,只是在两个地方有所改动。
示例会话
# Step 1 (Phase 1): Enumerate the worklist — root + every changed dependency,
# each resolved to from/to branch IDs, cross-org.
dxs source release-tree --from 64920 --to 67162
# root + 19 changed deps (e.g. Waves 64876→67102), 0 resolve_failed, 1 added
# Step 2 (Phase 2): Commits for the Waves dependency
dxs source compare --from 64876 --to 67102 --exclude-sync
# 12 committed_branches with wave planning work
# Step 3 (Phase 3): Why — the work item behind a commit
dxs source workitems --branch 67099 --description
# Work item #180436 — wave creation requirements
# Step 4 (Phase 4): How — the new flow's code
dxs source diff --from 64876 --to 67102 --config create_annotation_task_action
# Bug fix: why then how
dxs source workitems --branch 66852 --description # Bug #238852
dxs source diff --from 64919 --to 67159 \
--config outbound_orders_eligible_for_return_grid
# agGrid: null → agGrid: true
常见错误
| 错误 | 修正方法 |
|---|---|
使用 compare/deps-diff 枚举依赖项 | dxs < 0.4.9 时存在盲区(报告变更数为 0)——使用 source release-tree |
| 因根应用提交很少或没有提交,就得出“没有任何变更”的结论 | 薄封装的版本发布就是其依赖项的升级——对枚举出的每个依赖项版本树运行阶段 2–4 |
假设 source compare 包含详细的提交说明 | 检查其实际输出;必要时通过 commit-release-notes 获取 commitReleaseNotes,对于缺失或只有摘要的文本,则改用工作项/差异 |
| 对于客户应用,只解析 Datex-org 软件包 | release-tree 会解析跨组织的依赖;客户自己的 *- 软件包也要计入 |
在 summary.resolve_failed > 0 时继续进入阶段 2 | 这些软件包会悄无声息地从说明中消失——在挖掘提交前,按阶段 1b 逐个恢复 |
在 summary.subtrees_skipped > 0 时继续进入阶段 2 | 整个已变更的子树都未被枚举,而不只是单个条目——按阶段 1b 恢复并重新遍历 |
解析以 ; 连接的 resolve_error 字符串,试图找出哪一侧失败 | 读取 resolve_failed_sides(dxs ≥ 0.4.24);resolve_error 是描述性文本,无法解析 |
| 手动恢复由 Service-Pack 固定版本的依赖项 | dxs ≥ 0.4.24 时,release-tree 会自行解析 SP 组——升级(dxs update),而不是使用恢复表 |
将 no repository for uniqueIdentifier 视为只能手动查找的情况 | 使用 --extra-org <orgId> 重新运行(dxs ≥ 0.4.24)——此标志正是为此而设 |
使用 --recursive 运行时,恢复了某个依赖项的分支 ID,却没有重新遍历它 | 解析失败时,遍历过程就跳过了该子树——对恢复后的 ID 重新运行 release-tree --recursive(阶段 1b) |
| 将提交标题用作功能标题 | 使用关联工作项的标题;提交标题往往比较仓促 |
使用内部 ID / _apis/ URL 构建 DevOps 链接 | 使用 external_id 和浏览器路径 _workitems/edit/ |
| 在多个依赖项下重复列出相同功能 | 编写时按工作项 ID 去重 |
| 为了“保持说明简洁”而省略工作项链接 | 链接是必需的;没有链接,说明就无法追溯 |
| 客户说明中包含配置名称/分支 ID | 删除内部术语——客户版应使用普通描述,不应堆砌配置名 |
| 按顺序分析 50 多个依赖项 | 使用并行 Agent;顺序处理会触及上下文和时间限制 |