文章建议将人工采集的命令记录与模型生成的解释分开保存,并用事实清单限制模型补写内容。校验器应在人工评审前阻止虚构参数、退出码、耗时和重试规则。
要让故障排查页面保持准确,就应由人来维护命令执行记录,模型只负责撰写记录周围的解释文字。模型可以在登记为允许生成草稿的文件中,说明操作意图、执行顺序,以及读者需要了解的上下文。但它不能凭空添加参数、退出码、耗时或使用额度,这些信息必须已经存在于固定的执行记录和事实台账中。在生成的文字进入人工审核队列之前,应由检查器强制落实这条边界。
当证据和草稿放在同一个文件里时,生成的故障排查页面往往会以一种熟悉的方式出错。模型可能把一次失败的命令执行润色成看似合理的成功,也可能添加一条从未有人在 shell 中实际验证过的重试规则。后续编辑者可能会把这段润色后的文字当成操作流程,因为页面看起来已经写完,而最初的操作会话已不复存在。将执行记录单独保存,审核者就能通过 diff 检查采集到的证据,无须重新阅读周围的叙述。
这种职责划分并不等于禁止生成文档。对于已经用模型起草文字的团队来说,这个区别很重要。当需要向没有亲自运行命令的读者介绍同一段操作会话时,生成解释文字依然能节省时间。由人维护的文件通过哈希固定,允许生成草稿的文件则可以在固定的哈希发生变化时轻松重新生成。这种方法不要求模型判断哪些失败是真实的、哪些超时可以接受,或哪些缺失信息可以补全。
这张表是针对单个页面的编辑约定,并不是要求你原样采用的全公司写作规范。只有当一个能够更新该行信息的人已经明确知道其维护者和来源时,才添加这一行。不要因为草稿听起来很具体,或某个空白单元格让页面显得内容单薄,就添加一行。在人记录下属于这一行的证据之前,空白单元格就应保持空白。
只有当人在页面所声称描述的环境中实际运行过一条命令后,这条命令才能进入执行记录。测量值只有附带来源字符串和审核日期,且人日后能重新打开该来源核查时,才能进入台账。叙述文字可以引用这些已登记的值,但不能引入台账中没有列出的数字。即使生成草稿中的每一句话都清楚、具体,没有其他问题,发布状态仍然由人决定。
采集每条命令、合并后的输出和退出状态,然后将日志保存在由人维护的路径下。
在台账中登记是否可以重试、支持标识符,以及任何数值额度,并为每一项提供无需依赖模型就能打开的来源。
将叙述文件标记为唯一允许模型写入的路径,并把 prompt 的任务限定为:在该文件中解释已固定的执行记录。
运行检查器,让哈希不匹配或未登记的数字在任何人投入审核时间之前就使任务失败。
对照日志阅读叙述文字,只有在检查器以退出码 0 结束,且引用的行仍然与日志一致时,才接受草稿。
将执行记录、台账和已接受的叙述文字一起提交;只要两个固定文件中的任意一个发生变化,就重新生成叙述文字。
当命令以非零退出码结束时,采集脚本应默认停止执行,除非台账已经将该状态标记为预期的演示结果。预期失败也必须写入日志,因为隐藏失败会话的页面会教给读者错误的恢复方法。将 prompt 保存在叙述文件旁边,作为构建输入,而不是作为面向读者发布的操作流程。如果 prompt 与叙述文字不一致,最终应以执行记录和台账为准。
下面的采集辅助脚本是一个尚未执行的示例,它假定本地存在一个你可以替换的 demo-job 可执行文件。它会记录命令行,追加合并后的输出,并且即使第一次运行失败,也会写入退出状态。当你开始采集遇到第一次意外退出就应停止的操作流程时,请移除这里对返回状态的覆盖。
#!/usr/bin/env bash
set -u
out="docs/retry/transcript.log"
: > "$out"
run() {
printf '$ %s\n' "$*" | tee -a "$out"
"$@" >>"$out" 2>&1
code=$?
printf 'exit: %s\n' "$code" | tee -a "$out"
return 0
}
run demo-job --once
run demo-job --once
sha256sum "$out"
本节中的文件是尚未执行的教程示例,不是真实的生产事故记录,也不是厂商提供的测量数据。在将这种模式用于真实文档页面之前,请替换每一个来源字符串和每一条示例命令。示例中的日期用于标识这个示例,并不表示任何厂商在那一天发布过这些数值。请将退出状态和尝试次数上限视为占位值,由你自己的台账替换。
# docs/retry/facts.yml
page: docs/retry
human_owner: docs-team
pins:
transcript: docs/retry/transcript.log
transcript_sha256: "replace-with-real-sha256"
draftable:
- docs/retry/narrative.md
facts:
- key: expected_exit
value: 75
source: "fixture://exit-codes"
reviewed: "2026-10-13"
- key: recovered_exit
value: 0
source: "fixture://exit-codes"
reviewed: "2026-10-13"
- key: max_attempts
value: 3
source: "fixture://retry-policy"
reviewed: "2026-10-13"
# docs/retry/transcript.log
$ demo-job --once
temporary upstream failure
exit: 75
$ demo-job --once
ok
exit: 0
The first invocation exits 75, which this page treats as a temporary failure.
A second invocation is the expected recovery, and it exits 0 in the pinned log.
The ledger allows at most 3 attempts, so a further failure should stop the procedure.
下面的 Python 程序是一个尚未执行的示例,适用于你已经拥有控制权的仓库分支。它不会调用模型、为文字质量评分,也不会连接外部文档服务。安装 PyYAML,将占位哈希替换为执行记录的摘要,然后从仓库根目录运行脚本。在你替换占位哈希之前,哈希比较不会生效,因此不要把检查通过当成已强制落实文件固定机制的证据。
#!/usr/bin/env python3
"""Reject drafts that drift from pins or invent measurements."""
import hashlib
import pathlib
import re
import sys
import yaml
LEDGER = pathlib.Path("docs/retry/facts.yml")
NUMBER = re.compile(r"\b\d+(?:\.\d+)?\b")
def sha256(path: pathlib.Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def main() -> int:
ledger = yaml.safe_load(LEDGER.read_text(encoding="utf-8"))
errors = []
transcript = pathlib.Path(ledger["pins"]["transcript"])
pinned = ledger["pins"]["transcript_sha256"]
if pinned != "replace-with-real-sha256" and sha256(transcript) != pinned:
errors.append(f"transcript hash drift: {transcript}")
allowed = {str(item["value"]) for item in ledger["facts"]}
for rel in ledger["draftable"]:
text = pathlib.Path(rel).read_text(encoding="utf-8")
for match in NUMBER.findall(text):
if match not in allowed:
errors.append(f"unregistered number {match} in {rel}")
if errors:
print("\n".join(errors))
return 1
print("ownership check passed")
return 0
if __name__ == "__main__":
sys.exit(main())
python3 -m pip install pyyaml
sha256sum docs/retry/transcript.log
python3 check_doc_ownership.py
正常流程通过后,在叙述文字中追加一个未登记的耗时,再运行一次检查器。这个反向测试应以退出状态 1 结束,因为新增耗时不是已登记的事实值。如果跳过这个测试,示例页面上的一次检查通过就无法证明虚构耗时会被拦截。将这两个测试样例都保存在测试目录中,这样后续修改就无法在不留下可见 diff 的情况下删除这一失败场景。
披露:本文是 MonkeyCode 产品推广活动的一部分。运营方将该项目描述为开源项目,并为本次草稿提供了两项可用性声明:免费模型访问和免费服务器选项。这些声明没有给出具体模型、固定配额、硬件配置或永久有效的时间范围。更具体的商业细节会变化,只有当页面必须陈述这些信息时,才应由人从当前产品文档中复制到台账。
免费模型访问的作用体现在叙述文字生成阶段:根据固定的执行记录和允许使用的数字,生成允许起草的文件。免费服务器选项则适合在你需要一个干净的 shell 来重新采集日志,而又不想使用同事的笔记本电脑时使用。这两个选项都不应成为权威记录的存放处,因为临时机器可能消失,重新生成的草稿也可能偏离事实。后续编辑者应该信任的是已经提交的执行记录、台账和审核记录。
编写 prompt 时,应确保模型无法在生成草稿的过程中扩大自己的写入权限。提供执行记录、允许使用的数字,以及唯一的输出路径,并要求模型保留缺失信息,不要猜测。不要让它改进命令、选择超时时间,或补全采集日志中缺失的退出码。即使生成的段落语法正确、便于浏览,这些请求依然违反了维护权边界。
如果模型返回了一个你没有登记的数字,要么根据你掌控的来源更新台账,要么删除该句。不要把使用额度发布为工具的永久属性,因为可用性数据需要当前的一手来源作为依据。本草稿正是因此省略了 token 数量;审核者应将任何凭记忆得出的配额视为未经核实。
对每一个采用这种职责划分的页面,都执行同样的四项检查,并把答案写入由人维护的审核记录。它们刻意采用机械化的检查方式,让审核者不必从自信的语气中推断意图。缺少答案就意味着拒绝,而不是邀请模型填空的 prompt。将检查器输出附在同一份记录中,让下一位编辑者能够看到草稿获准通过的原因。
确认执行记录的哈希与台账一致,并确认仍然有人能在指定环境中复现该会话。
确认叙述文字中的每一个数字都已登记为事实值,包括退出码、尝试次数上限,以及任何公开的使用额度。
确认本应只包含模型草稿的 commit 没有修改执行记录或台账。
确认有人在审核记录中接受了叙述文字,并将检查器输出与这份接受记录一起保存。
这种模式由文件哈希固定和词法层面的数字扫描组成,不能证明解释中的因果关系正确。叙述文字即使始终使用允许列表中的值,也可能把恢复步骤的顺序写错。不要将这道检查关卡用于安全公告、价格页面、法律条款,或那些文字本身就构成承诺的事故报告。如果团队中没有人能够重新采集执行记录,也应跳过它,因为过时的固定记录比明显的信息缺口更危险。
如果一个团队发布模型输出时没有人工审核者,就无法从这个脚本中获得预期的保护。脚本不会判断文字是否清晰、安全,也不会判断这些建议是否适用于采集环境之外。免费服务器选项不能替代持久保存的仓库、明确的维护者,也不能替代对当前产品条款的重新阅读。如果页面数量很少,而且几乎从不变化,自动化所花费的精力可能超过它消除的风险。
在这种规模较小的情况下,可以保留相同的维护权规则,但不使用脚本,也不安排定时任务。由人编辑执行记录和台账,模型始终不获得这两个路径的写入权限。只有在这些固定文件发生变化后,才重新生成解释文字;对于带有新增测量值的草稿,直接丢弃。这个手动版本更慢,但保留了检查器试图自动落实的同一条边界。
选择一个故障排查页面,固定它的执行记录,并拒绝第一份引入未登记数字的草稿。这次失败才是有用的结果,因为它能显示允许列表是否符合页面实际的写法。当已经有人维护台账时,在检查器合入默认分支之前,仅凭免费模型访问就足以演练叙述文字生成这一步。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。