mcpField
P
plannotator-compound

plannotator-compound

github.com/backnotpropAgent 工作流9.7k11.8k 次安装今天更新
代码仓库

关于 plannotator-compound

plannotator-compound 用于分析 Plannotator 归档中的被拒计划,也可在缺少归档时分析 Claude Code 拒绝记录。它提取反复出现的反馈,并生成带版本的 HTML 报告。

主要功能

  1. 01选择 Plannotator 或 Claude Code 数据
  2. 02统计计划数量和归档日期范围
  3. 03提取范围内所有文件的拒绝原因
  4. 04归纳反馈类别和重复模式
  5. 05支持增量或完整报告分析

适用场景

  1. 01查找计划被拒的常见原因
  2. 02跟踪评审反馈随时间的变化
  3. 03根据新增归档条目生成更新报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/backnotprop/plannotator --skill plannotator-compound

安装后在 Claude Code 中输入/plannotator-compound确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
report-template.html
references/
claude-code-fallback.md
scripts/
extract_exit_plan_mode_outcomes.py

详细介绍

Compound Planning 分析

你正在对用户的 Plannotator 计划归档进行全面研究分析。目标:从被拒绝的计划中提取模式,将其归纳为可执行的见解,并生成精美的 HTML 仪表板报告。

这是一个多阶段流程。每个阶段都必须完整完成后,才能开始下一阶段。 研究完整性至关重要——必须读取每个文件,不得跳过。

源选择

开始分析之前,确定有哪些数据源可用。

  1. Plannotator 模式(优先) — 确定 Plannotator 数据目录: 如果设置了 $PLANNOTATOR_DATA_DIR,则使用该目录;否则使用 ~/.plannotator。检查其中的 plans/ 子目录。如果该目录存在且包含 *-denied.md 文件,则使用此模式。以下整个 工作流均针对 Plannotator 数据。

  2. Claude Code 备用模式 — 如果 Plannotator 归档不存在或 不含被拒绝的计划,则检查 ~/.claude/projects/。如果该目录存在,继续之前请先阅读 references/claude-code-fallback.md。 该参考文件说明如何使用随附的解析器 scripts/extract_exit_plan_mode_outcomes.py,从 Claude Code JSONL 转录中提取拒绝原因。以下每个阶段都有简短说明,介绍备用模式下的变化——详细信息请参阅该参考文件。

  3. 两者均不可用 — 请用户提供其 Plannotator 计划目录或 Claude Code 项目目录。不要猜测。

阶段 0:定位计划并检查先前报告

使用上文“源选择”中选定的模式。

Plannotator 模式: 验证计划目录中包含 *-denied.md 文件。如果 不存在,则停止前切换到 Claude Code 模式。

Claude Code 备用模式: 按照备用模式参考文件运行随附的解析器,以 构建拒绝原因数据集。必要时创建 /tmp/compound-planning/。

无论使用哪种模式,都继续执行下文的“先前报告检测”。

先前报告检测

定位计划目录后,检查是否已有报告:

ls ${PLANNOTATOR_DATA_DIR:-~/.plannotator}/plans/compound-planning-report*.html

报告采用带版本号的命名规则:

  • 首份报告:compound-planning-report.html
  • 后续报告:compound-planning-report-v2.html、compound-planning-report-v3.html 等。

如果存在一份或多份报告,请确定最新的一份(版本号最高)。 使用 stat 获取其文件系统修改日期(macOS:stat -f %Sm -t %Y-%m-%d, Linux:stat -c %y | cut -d' ' -f1)。此日期即为截止日期。

请用户选择:

“我找到了一份先前的报告(compound-planning-report-v{N}.html),上次更新日期为 {CUTOFF_DATE}。你可以选择:

  1. 增量分析 — 仅分析日期晚于 {CUTOFF_DATE} 的文件,节省令牌并基于先前发现继续分析
  2. 完整分析 — 从头重新分析整个归档

你倾向于哪种方式?”

等待用户回复后再继续。

如果选择增量分析: 后续所有阶段都只处理截止日期之后的文件。新报告的标题说明中应注明报告涵盖从 {CUTOFF_DATE} 至今的时期,并引用先前报告中的更早发现。清单(阶段 1)仍应统计所有文件的 总体数据,但要明确区分“自上次报告以来新增”的数量。

如果选择完整分析: 按常规处理所有文件,但输出文件名仍使用下一个版本号。

如果不存在先前报告: 按常规继续。输出文件名为 compound-planning-report.html(首份报告不带版本后缀)。

第 1 阶段:清点

统计并报告数据集。无论是增量运行还是完整运行,都要统计所有文件,以获取整体统计数据:

- *-approved.md files (count)
- *-denied.md files (count)
- Date range (earliest to latest date found in filenames)
- Total days spanned
- Revision rate: denied / (approved + denied) — this is the "X% of plans
  revised before coding" stat used in dashboard section 1

**注意:**完全忽略 *.annotations.md 文件。被拒绝的文件已经包含完整的计划文本,以及追加在 --- 分隔符之后的所有审核反馈。注释文件是这些内容的冗余子集——同时读取会导致反馈被重复统计。

**如果是增量模式:**报告总数后,另行报告仅针对截止日期之后文件的数量:

New since {CUTOFF_DATE}:
- *-denied.md files: X (of Y total)
- New date range: {CUTOFF_DATE} to {LATEST_DATE}
- New days spanned: N

如果自截止日期以来新增的被拒绝文件少于 3 个,请提醒用户:

“自上次报告以来,只有 {N} 个新拒绝的计划。增量分析可能不够充分。您想继续,还是切换到完整分析?”

还要对所有 *-approved.md 文件运行 wc -l,以获取每份已批准计划的平均行数。这可以让用户了解计划是保持精简,还是随着时间推移变得臃肿。无需读取已批准计划的内容,只需统计行数。如果可能,按时间段(例如按月)细分,以展示计划大小是否发生变化。

文件名中的日期格式为 YYYY-MM-DD,有时作为前缀(2026-01-07-name-approved.md),有时嵌在文件名中(name-2026-03-15-approved.md)。从所有文件名中提取日期。

告知用户你发现的情况,并说明即将开始提取。

**Claude Code 回退模式:**上述 Plannotator 清点字段不适用。请改为遵循 references/claude-code-fallback.md 中的清点说明——报告解析器整理出的拒绝原因数据集。

第 2 阶段:整理映射——并行提取

这是最耗时的阶段。必须读取范围内的每个 *-denied.md 文件。不要跳过文件。不要提前总结。

范围内指:运行完整分析时的所有被拒绝文件,或增量运行时仅包含截止日期之后的被拒绝文件。在增量模式下,仅处理嵌入日期严格晚于截止日期的文件。

**Claude Code 回退模式:**解析器输出是干净的源数据集。请阅读回退参考文档,了解适用于 JSON 分片文件的提取提示词和批处理策略。除非解析器失败,或用户要求进行审计级验证,否则不要回头读取原始 .jsonl 日志。

**重要:**只读取 *-denied.md 文件。不要读取已批准的计划、注释文件或差异文件。每个被拒绝的文件都包含完整的计划文本,后面接着 --- 分隔符和审核者的反馈——分析所需的全部内容都在一个文件中。

批处理策略

所有提取 Agent 都应使用 model: "haiku"——它们只需直接读取文件并提取结构化信息,不需要推理。Haiku 执行这项工作更快、成本也更低。

具体方法取决于数据集大小:

**极小数据集(≤ 10 个文件):**由主 Agent 直接读取所有文件,无需使用子 Agent。按顺序读取后,直接进入第 3 阶段。

**小型数据集(11-30 个文件):**启动 2-3 个并行 Haiku Agent,大致平均分配文件。

**中型数据集(31-80 个文件):**启动 4-6 个并行 Haiku Agent,每个 Agent 处理约 10-15 个文件。按文件类型和/或时间段拆分。

**大型数据集(80 个以上文件):**按需启动尽可能多的并行 Haiku Agent,使每个批次约有 10-15 个文件。根据数据中自然形成的时间边界(月、季度或其他能均衡分配批次的分组)进行拆分。如果某一时间段的文件特别多(例如,最近一个月的文件数量是其他时段的 3 倍),则将该时段拆分成多个批次。

使用 Agent 工具并设置 run_in_background: true 和 model: "haiku",并行启动所有提取 Agent。

输出文件

每个提取 Agent 都必须将结果写入一个干净的输出文件,而不是依赖 Agent 任务输出(其中包含难以解析的交错 JSONL 框架日志)。要求每个 Agent 写入:

/tmp/compound-planning/extraction-{batch-name}.md

启动 Agent 前,先创建 /tmp/compound-planning/ 目录。第 3 阶段的归并 Agent 将直接读取这些干净的文件。

提取提示词

每个 Agent 都会收到以下指令(调整时间段、文件列表和输出路径):

You are extracting structured data from denied plan files for a pattern analysis.

Directory: [PLANS DIRECTORY]
Files to read: [LIST OF SPECIFIC *-denied.md FILES]
Output: Write your complete results to [OUTPUT FILE PATH]

Each denied file contains two parts separated by a --- line:
1. The plan text (above the ---)
2. The reviewer's feedback and annotations (below the ---)

Read EVERY file in your list. For EACH file, extract:
- The plan name/topic (from the plan text above the ---)
- The denial reason or feedback given (from below the --- — capture the actual
  words used)
- What was specifically asked to change
- The type of feedback (let the content determine the category — don't force-fit
  into predefined types. Common types include things like: scope concerns,
  approach disagreements, missing information, process requirements, quality
  concerns, UX/design issues, naming disputes, clarification requests,
  testing/procedural denials — but the user's actual patterns may differ)
- Any specific phrases or recurring language from the reviewer
- Individual annotations if present (numbered feedback items with quoted text
  and reviewer comments)
- The date (extracted from the filename)

Do NOT skip any files. One entry per file.

Format each entry as:
**[filename]**
- Date: ...
- Topic: ...
- Denial reason: ...
- Feedback type: ...
- Specific asks: ...
- Notable phrases: ...
- Annotations: [count, with brief summary of each]
---

After processing all files, write the complete results to [OUTPUT FILE PATH].
State the total file count at the end of the file.
Agent 运行期间

跟踪完成情况。每个 Agent 完成后,记录它处理的文件数。确认总数与第 1 阶段的清单一致。如果某个 Agent 处理的文件数不足,请标记并考虑针对缺失文件重新启动它。

如果 Agent 超时(大批次时可能发生——128 个文件的批次可能需要 8 分钟以上),请针对尚未处理的文件重新启动它。检查输出文件,了解它超时前处理到了哪里。

第 3 阶段:归并——模式分析

所有提取 Agent 均已完成(或小型数据集的所有文件均已读取)后,开始归并。归并 Agent 应使用 model: "sonnet"——此阶段需要真正的分析推理,而不仅仅是读取文件。

归并策略

具体方法取决于生成了多少个提取文件:

标准(≤ 20 个提取文件): 启动一个 Sonnet Agent,读取所有提取文件并生成完整分析。这适用于大多数数据集。

大型(21 个以上提取文件): 分两阶段归并:

  1. 第 1 阶段——部分归并: 将提取文件分成每组 4-6 个。并行启动 Sonnet Agent,每个 Agent 读取一组文件,并按照下文列出的相同章节生成部分分析。每个 Agent 将结果写入 /tmp/compound-planning/partial-reduce-{N}.md。

  2. 第 2 阶段——最终归并: 启动一个 Sonnet Agent,读取所有部分归并文件,并综合生成最终的完整分析。该 Agent 将合并分类体系、汇总数量、去除重复模式,并协调各部分中相互冲突的分类。

Claude Code 后备模式: 归并阶段相同。唯一的上游差异是,提取文件源自标准化的拒绝原因 JSON,而不是 Plannotator Markdown 文件。

归并提示词

向每个归并 Agent 提供以下提示词(根据单阶段或多阶段归并调整文件路径):

You are a data scientist conducting the reduction phase of a map-reduce analysis
across a user's denied plan archive.

Read ALL extraction files at [FILE PATHS]

These files contain structured extractions from every denied plan file. Each
extraction includes the plan topic, denial feedback, annotations, and reviewer
language. Your job: aggregate everything, find patterns, cluster into a taxonomy,
and produce a comprehensive analysis.

Be exhaustive. Use real counts. Quote real phrases from the data. This is
research — no hand-waving, no fabrication.

Write your complete results to [OUTPUT FILE PATH].

Produce the following sections:
[... sections listed below ...]

归并 Agent 的任务是让数据自己说话。不要强加预设框架——要发现数据中实际存在的内容。分析必须包括:

1. 拒绝原因分类体系

将每条拒绝意见归入数据中自然呈现的有限类别。统计出现次数并显示百分比。每种类型都提供真实的示例引文。目标是 8-15 个类别——既要具体,也要便于快速浏览。类别应由用户的实际反馈决定。

2. 主要反馈模式(按频率排序)

列出最常见的 5-10 种模式。每种模式都要说明审阅者始终要求什么,提供来自不同文件的 3 条以上示例引文,并指出该模式是否随时间发生变化。

3. 常用短语

列出审阅者反复使用的原话短语、出现次数及其所表达的意思。这些是审阅者的惯用词汇——他们表达关注点的简写。

4. 审阅者看重什么(隐含偏好)

根据模式推断:这个人最看重什么?质量、速度、叙事、架构、流程还是简洁性?按证据强度排序。本节应像一份关于审阅者标准的个性画像。

5. Agent 经常犯的错误

从反面来看——哪些反复出现的错误会导致拒绝?Agent 应避免为这位审阅者做什么?

6. 结构要求

审阅者始终要求计划采用什么结构?必需章节、顺序、格式偏好以及预期的详细程度。

7. 随时间的演变

分析反馈模式在这段时间内如何变化。根据数据中自然存在的时间界限分组(时间跨度较短时按周,较长时按月)。预期是否逐渐成熟?是否出现了新模式?发生了哪些变化?如果数据集跨度不足一个月,请说明演变分析受到限制,但仍要观察较早与较晚文件之间是否存在进展。

8. 可执行的提示词指令

这是最重要的输出。根据所有模式,列出具体的编号指令,可嵌入规划提示词,以避免最常见的拒绝原因。将这些指令写成 Agent 可以遵循的实际要求。要针对这位用户的具体模式——“写好计划”之类的通用建议毫无用处。每条指令都应对应一种真实且频繁出现的拒绝模式。

写完指令后,计算这些指令能够解决的拒绝占比(统计落入指令所涵盖类别的拒绝数量,并除以拒绝总数)。报告该百分比——不同用户的结果各不相同。

阶段 4:生成 HTML 仪表板

构建一个独立、完整的 HTML 文件,作为最终交付物。使用带版本号的文件名,将其保存到用户的 plans 目录:

  • 首次报告:compound-planning-report.html
  • 第二份报告:compound-planning-report-v2.html
  • 第三份报告:compound-planning-report-v3.html
  • 以此类推。

版本号已在阶段 0 中根据现有报告确定。

如果这是增量报告,标题中应标明分析时段(例如“2026 年 3 月 15 日 – 2026 年 3 月 31 日”),并添加副标题“增量分析——此前的发现请参阅 v{N-1}。”第 1 节的叙述应着重说明相较上一份报告有哪些新增内容或变化,而不是呈现完整情况。标题中的总体统计数据(文件数量、修订率)仍应反映完整档案,以供参考。

阅读 assets/report-template.html,但仅用于了解设计风格。模板包含此前分析的示例数据——忽略模板中的所有数据值、引文和百分比。只采用其视觉设计:颜色、字体、间距、组件样式和布局模式。

设计风格(来自模板)
  • 配色方案: 浅色模式,暖调米白色(#FDFCFB),文字使用石板灰色阶,琥珀色用于高亮和强调,翠绿色表示积极内容,玫瑰色表示负面内容,靛蓝色用于操作元素
  • 字体: Playfair Display(衬线字体,用于叙述性标题)、Inter(无衬线字体,用于正文和数据)、JetBrains Mono(等宽字体,用于代码和短语)——通过 Google Fonts CDN 加载
  • 布局: 单列布局,最大宽度 1024px,留白充足(主要章节之间相隔 128px),采用编辑式、叙述优先的美学风格
  • 语气: 平和、沉思、权威。像一篇个人回顾日志,而不是监控仪表板。
页面框架(页眉 + 页脚)

在 7 个章节之前,页面包含:

  • 页眉: 左侧为报告标题(Playfair Display,约 36px),下方以浅色元信息文字显示项目名称和日期范围。右侧以等宽字体显示文件数量(例如“223 条拒绝 · 71 天”)。页眉底部添加分隔线,并在第 1 节之前留出充足的底部内边距。

  • 页脚: 位于第 7 节之后。顶部添加分隔线,居中显示斜体 Playfair Display 标语,总结语料库(例如“对 Plannotator 档案中的 X 个被拒计划进行分析。”)。

仪表盘章节顺序(7 个章节)

报告严格按照以下顺序展开。每个章节都在前一个章节的基础上深入分析——从“发生了什么”到“为什么”,再到“该怎么做”:

  1. 数据背后的故事 — 一段编辑式叙述(Playfair Display 衬线字体,约 26px),以文字点明核心发现。不要使用项目符号——要写成一段真正的文字,读起来像文章的开篇。旁边放置一个 KPI 侧栏,展示 3 项关键指标(最高拒绝百分比、整体修订率以及发现的不同拒绝类别数量)。在叙述中最引人注目的数字上使用琥珀色行内高亮。

  2. 计划为何被拒绝 — 以排名列表呈现分类结果。每一行包括:排名数字(等宽字体)、类别标签、4px 细进度条(首项使用 amber-500,其余使用 slate-300)、百分比(等宽字体),以及位于标签下方的真实斜体引文(适用于排名靠前的类别)。展示排名前 10 的类别,或数据能够支持的类别数量(至少 5 个)。

  3. 预期如何演变 — 每个自然时间段一张卡片。每张卡片包括:衬线字体的时期名称、彩色大写主题短语(每个时期使用不同颜色,以展示变化)、描述段落,以及底部的统计行(例如,“X 次拒绝 · Y 条叙述请求”)。如果数据涵盖的不同时间段少于 3 个,则使用 2 张卡片,或者使用一张卡片并注明内部的演变过程。

  4. 哪些有效,哪些无效 — 两张并排卡片。左侧:绿色调(emerald-50/50 背景,emerald-100 边框),列出适用于这位审核者的成功计划特征。右侧:红色调(rose-50/50 背景,rose-100 边框),列出 Agent 反复出错的地方。两者均根据归纳分析得出。使用带小型彩色圆点的项目符号列表。每张卡片包含 5–8 项。

  5. 可直接采取行动的结果 — 展示诊断分析的实际价值。以 Playfair Display 叙述句开篇,说明得出了多少条提示词指令,以及预计这些指令能解决多少比例的拒绝问题(使用第 3 阶段实际计算出的百分比,不要使用笼统数字)。然后按编号列出影响最大的 3 项改进,每项包含琥珀色编号、粗体标题和一句说明。本章节承接分析结果,并引出后续的完整提示词。

  6. 你最常用的短语 — 以词条标签网格呈现(移动端 2 列,桌面端 3 列)。每个词条左侧为等宽字体的带引号短语,右侧为出现频次。白色背景、slate-200 边框、12px 圆角。展示最常出现的 9–12 个短语。这些短语应是审核者的原话——体现其语言习惯。

  7. 纠正用提示词 — 深色面板(slate-900 背景、白色文字、rounded-3xl、shadow-xl)。以 Playfair 介绍句开篇,说明这些指令的作用。接着使用深色代码块(slate-800/80 背景、amber-200 等宽字体文本),展示第 3 阶段生成的完整编号提示词指令。加入可用的复制到剪贴板按钮(包含 JS)。代码块下方放置渐变光晕卡片(白色卡片后方带有从靛蓝到紫色的模糊光晕),并附上一段结束语,说明这些指令是为用户量身定制的——源自用户自己的反馈、语言和标准。

适配规则
  • 如果用户的数据不足 3 个月,则减少演进部分的卡片数量
  • 如果大多数被拒绝的文件在 --- 下方都没有反馈(即只有拒绝,没有批注),则在叙述中说明这一点——分析内容会比较有限
  • Claude Code 回退模式: 明确标注报告来源为 Claude Code ExitPlanMode 拒绝原因。不要编造仅适用于 Plannotator 的字段,例如批注数量或已批准计划的行数。KPI 替代指标以及页脚/来源信息的说明请参见回退参考。
  • 如果最终归纳出的拒绝类别少于 5 个,则将分类体系和模式部分合并为一节
  • 如果数据集非常小(少于 20 个文件),叙述中应承认样本量有限,并将发现表述为初步结论
  • 每位用户的提示词指令数量会有所不同,可能是 8 条,也可能是 20 条。不要强行限定为 17 条。应由数据决定数量。
  • 第 5 节中的 3 项优先行动建议,必须是覆盖拒绝原因占比最高的 3 项,而不是听起来最有说服力的 3 项
关键规则
  1. 每个数字都必须来自真实分析,不得编造数据
  2. 每条引用都必须是真实文件中的原文
  3. 分类体系中的百分比必须根据真实数量计算
  4. 提示词指令必须能追溯到实际的拒绝模式
  5. 提示词区块中的复制按钮必须正常工作(包含 JS)

生成后,在用户的浏览器中打开该文件。

第 5 阶段:总结

告知用户:

  • 分析了多少个被拒绝的文件
  • 如果是增量分析:自上次报告以来新增了多少个文件
  • 发现的 3 种主要拒绝模式
  • 提示词指令预计能解决的拒绝原因占比
  • 最具影响力的一项提示词改进
  • 报告的保存位置(包括版本号)
  • 如果是增量分析:提醒用户之前的发现见上一份报告

Claude Code 回退模式: 根据回退参考调整总结内容——报告分析的人为拒绝原因数量,以及扫描的 ExitPlanMode 尝试总次数,而不是 Plannotator 文件数量。

阶段 6:改进钩子

呈现摘要后,询问用户是否要启用改进钩子——此钩子会将报告第 7 节中的纠正提示词说明写入文件,供 Plannotator 的 EnterPlanMode 钩子自动注入今后的每次规划会话。

“您想启用改进钩子吗?这会将纠正提示词说明保存到一个文件中,并自动注入今后的所有规划会话——这样 Claude 在编写任何计划之前,就能看到您的反馈模式。”

如果是:

钩子文件位于:

${PLANNOTATOR_DATA_DIR:-~/.plannotator}/hooks/compound/enterplanmode-improve-hook.txt

如果数据目录中不存在 hooks/compound/ 目录,则创建该目录。

文件内容应为阶段 3 中的纠正提示词说明——也就是 HTML 报告第 7 节中显示的同一份编号列表。将其写为纯文本,每行一条说明,并在前面加上编号。不要添加 HTML、Markdown 代码围栏或前言——只保留说明本身。钩子系统会将此文件的内容原样注入规划上下文。

如果文件已存在:

读取现有文件,并让用户选择:

“之前的分析已创建改进钩子。我可以:

  1. 替换——用新说明覆盖(旧说明将被删除)
  2. 合并——合并两者,去除重复内容,并保留每条说明的最佳版本
  3. 保留现有内容——保持当前钩子不变,跳过此步骤

您希望怎么做?”

  • **替换:**用新说明覆盖文件。
  • **合并:**读取现有说明,与新说明进行比较,并生成合并后的内容。删除重复项(即使措辞不同,只要意图相同也视为重复)。如果两条说明针对同一种模式,则保留更具体或更具可操作性的版本。按顺序重新编号最终列表。将合并后的结果写入文件。告知用户变更内容(新增 N 条、删除 N 条冗余说明、保留 N 条现有说明)。
  • **保留现有内容:**不做任何更改,继续后续流程。

**如果否:**完全跳过此阶段。

重要说明

  • **数据源优先级:**Plannotator 是首选路径。对于没有 Plannotator 归档的用户,Claude Code 日志分析是备用路径。
  • **研究完整性:**必须读取每个文件。此分析的价值来自完整性。抽样或跳过文件会削弱分析结果。
  • **仅使用真实数据:**绝不可捏造引述、百分比或模式。如果数据没有显示明确模式,应如实说明,而不是凭空编造。
  • **以数据为依据:**分类体系、模式和说明应从文件中的实际内容得出。不同用户的拒绝模式可能完全不同。开发移动应用的用户,其反馈会与开发 API 的用户不同。不要预设可能出现哪些模式。
  • **Agent 并行处理:**对于大型数据集,尽可能增加并行 Agent,以减少总耗时。瓶颈在于最大的批次——应将其拆分。
  • **结构化提取格式:**要求提取 Agent 返回带有统一分隔符的结构化文本,以便汇总 Agent 可靠地解析。
  • **报告就是最终成果:**HTML 仪表板是用户会保留的内容。它应当美观、真实且实用。每个部分都应让人感觉是专门为该用户撰写的,因为确实如此。

评论

支持 Markdown