哪些内容经过了实际验证
发送提示词前先定好边界
- 01
从已知运行时开始
按 Alpha 快速上手安装 0.1.3-alpha.1 的固定源码,在 Settings → Models 选择已配置模型。凭据放在 Provider 配置里,不放在提示词或测试示例项目中。
- 02
把项目与运行时分开
练习放在独立目录,并在 Web UI 选中它。不要把官方源码运行时放进本站或祖先目录带有冲突 node_modules 的项目里。
- 03
第一次任务保持小范围
检查实际沙箱与审批设置,在一次性工作区完成提示词所需操作。解决三文件问题,无需先加插件或依赖。
创建一个能看见错误的小项目
准备 Node.js 24 和 Bash 终端,在全新的练习目录中操作。命令适用于 macOS/Linux 的 Bash;Windows 可用 Git Bash 或 WSL。harness-lab 目录必须尚不存在。示例项目无需 npm 依赖、账户、私人数据或生产文件。CSV 特意不含引号内逗号,这不是通用 CSV 解析器练习。
create_harness_lab() {
mkdir harness-lab || return
cd harness-lab || return
cat > orders.csv <<'CSV'
id,status,cents
A,paid,1200
B,refunded,700
C,paid,800
D,pending,400
CSV
cat > report.mjs <<'JS'
export function totalPaid(csv) {
const rows = csv.trim().split(/\r?\n/).slice(1);
return rows.map(row => row.split(','))
.filter(([, status]) => status !== 'pending')
.reduce((sum, [, , cents]) => sum + Number(cents), 0);
}
JS
cat > report.test.mjs <<'JS'
const { default: assert } = await import('node:assert/strict');
const { readFileSync } = await import('node:fs');
const { default: test } = await import('node:test');
const { totalPaid } = await import('./report.mjs');
const csv = readFileSync(new URL('./orders.csv', import.meta.url), 'utf8');
test('only paid orders count', () => assert.equal(totalPaid(csv), 2000));
test('refunds alone count as zero', () => assert.equal(totalPaid('id,status,cents\nB,refunded,700\n'), 0));
test('an empty ledger counts as zero', () => assert.equal(totalPaid('id,status,cents\n'), 0));
JS
cp report.mjs report.original.mjs
node --test report.test.mjs
}
create_harness_lab首次运行应有两项断言失败、一项通过。错误实现把已退款订单的 700 分计入,得到 2700,而正确结果是 2000。规则是只统计 status 为 paid 的行;refunded 与 pending 均不计入。金额统一使用整数分。
先要求可复现的诊断
只检查 orders.csv、report.mjs 和 report.test.mjs,先不要改文件。说明测试要求的统计规则,指出已退款行,并执行 node --test report.test.mjs。解释当前筛选为何得到 2700 而不是 2000。无法运行时,请报告实际环境问题,不要编造输出。有效诊断应指出 B 行、status !== 'pending' 条件和两项失败断言。“修改后应该通过”不是测试结果。若 Agent 提议引入 CSV 库或大范围重构,请把它引回现有示例项目和验收条件。
授权小范围修复,再独立检查
在这个一次性练习项目中修复 report.mjs,使 totalPaid 只统计 paid 行。先读 orders.csv 和 report.test.mjs,执行 node --test report.test.mjs 并报告原始失败。不要改 orders.csv、report.test.mjs 或 report.original.mjs;不要安装依赖或访问其他目录。以最小实现修改完成修复,重跑全部三项断言,并根据 orders.csv 计算总额。最后列出修改文件、实际测试结果、总额和局限。命令因环境原因失败时,请与断言失败明确区分。node --test report.test.mjs
node --input-type=module -e "import {readFileSync} from 'node:fs'; import {totalPaid} from './report.mjs'; console.log(totalPaid(readFileSync('orders.csv','utf8')))"
diff -u report.original.mjs report.mjs应看到三项测试通过,并单独输出总额 2000。diff 通常只把筛选条件改为 status === 'paid';其他实现只要遵守相同规则且保留测试,也可以接受。diff 发现文件不同会返回 1,在这里是预期结果,不是测试失败。找不到 Node 或权限不足属于环境失败,不能据此判断计算逻辑错误。
.filter(([, status]) => status === 'paid')本地实测的参考修复只修改筛选条件,输入和测试不变。把单元测试输出与独立计算的总额一起保留;只有一张绿色终端截图、没有命令和相关 diff,不能当作充分验收。
第二个任务:配置已变,缓存仍返回旧实例
在同一个一次性项目中创建两个新文件。account 始终是 demo,mode 从 light 改为 dark。缓存只比较 account,错误地返回了原对象。这个例子用来练习常见诊断:配置变更与已构造实例的失效,是两件不同的事。
create_cache_lab() {
test ! -e cache.mjs && test ! -e cache.test.mjs && test ! -e cache.original.mjs || return
cat > cache.mjs <<'JS'
let cached;
export function getSettings(config) {
if (!cached || cached.account !== config.account) cached = { ...config };
return cached;
}
JS
cat > cache.test.mjs <<'JS'
const { default: assert } = await import('node:assert/strict');
const { default: test } = await import('node:test');
const { getSettings } = await import('./cache.mjs');
test('a changed setting refreshes the instance', () => {
const first = getSettings({ account: 'demo', mode: 'light' });
const second = getSettings({ account: 'demo', mode: 'dark' });
assert.notEqual(second, first);
assert.equal(second.mode, 'dark');
assert.equal(getSettings({ account: 'demo', mode: 'dark' }), second);
});
JS
cp cache.mjs cache.original.mjs
node --test cache.test.mjs
}
create_cache_lab检查 cache.mjs 和 cache.test.mjs,先复现失败。修复缓存,使 account 或 mode 任一变化都会构造新实例,相同值则复用已有实例。保留原测试;需要时单独增加 account 变化断言。不要引入依赖、定时器或全局清缓存。运行 node --test cache.test.mjs,说明哪些输入决定实例身份。if (!cached || cached.account !== config.account || cached.mode !== config.mode) cached = { ...config };执行 node --test cache.test.mjs。经过本地检查的参考修复会通过:mode 变化后得到不同对象且值为 dark,下一次相同调用复用该对象。示例项目只有 account 和 mode;真实服务需枚举全部构造输入、保留读取失败语义,并在不泄露密钥值的前提下测试轮换。本练习不认证生产缓存或支付 Provider。
为什么在练习中这样检查
Anthropic 的上下文工程文章讨论按需获取资料和结构化笔记,评估文章则区分对话记录与最终结果。我们把它们落实为具体操作:从指定文件开始,修改后重新读取,把真实测试输出、总额与 diff 放在一起。HANDOFF.md 记录路径、已执行命令和未完成事项,让继续工作的会话能再次核对当前文件。这把上下文、证据和交接连起来,而不是用更长的提示词或日志证明质量。
让暂停的任务容易接续
保持 report.original.mjs 和 cache.original.mjs 不变。新会话前要求简短交接,记录当前文件、最后执行的命令与未解决事项。恢复时重新读文件、重跑测试,因为会话摘要可能对应旧状态。DSH 的会话记录是历史,不能代替版本控制或文件备份。
为本练习写 HANDOFF.md,包含目标、修改文件、原始失败、实际执行的精确命令及结果、剩余问题(如有)和下一项验证。不要包含凭据,不要声称通过尚未执行的检查。新会话应能凭这份说明和当前文件继续。按观察到的故障恢复
- 01
命令无法执行
核对终端 Node 版本、当前目录与选中的工作区。先修环境,不能通过修改源码来掩盖缺少可执行文件或权限不足。
- 02
Agent 改了测试或无关文件
停止任务,保留尝试结果并查看 diff。只从已知原件恢复受影响的练习文件,再明确验收条件。
- 03
模型或 Provider 不可用
保留本地文件与交接说明,在提示词之外修正 Provider 设置,然后恢复会话或带相同标准新建会话。API 失败不能当作代码测试成功。
cp report.mjs report.attempt.mjs
cp report.original.mjs report.mjs
node --test report.test.mjs恢复后应再次出现原来的两项失败,这是有意进行的恢复检查。保留 report.attempt.mjs 便于比较。在真实仓库中应使用干净分支或工作树,并逐文件审阅恢复;不要把本练习的覆盖命令用于无关工作。
把有效流程整理成一个小型 Skill
完成练习后,再记录检查、复现、修改、测试、交接的流程。DSH 官方本地发现路径包含项目 .dsh/skills 和 .agents/skills,名称与优先级有实际影响。Skill 记录工作流程,不赋予新的系统权限。让文件被发现前先审阅,命令范围保持明确,不要因为未知扩展承诺自动化就直接加载。
带着具体目标继续
阅读一手官方资料
常见问题
修改前需要了解的事项
关于格式、兼容性、证据与回滚的简明说明。
这篇指南核实哪些范围?
本指南覆盖:固定 DSH Alpha 源码与上下文管理、Agent 评估的一手资料;本地实际运行的两个合成 Node 示例项目、参考修复与指定文件恢复;没有声称完成模型横评或真实 Provider 业务任务
我应该先做什么?
用两个小任务建立可重复的习惯:纠正订单总额,再修复忽略配置变化的缓存。每个任务都有输入、可观察的失败、可复制提示词和独立验收。先在下面的一次性项目完成练习,再用于重要工作。
最需要记住的边界是什么?
两个 Node 例子已在本地运行,包含原始失败、参考修复和 report.mjs 统计模块的原始内容恢复。DSH 步骤依据 0.1.3-alpha.1,固定提交 d347e703908d0406b7a7ef80e3a0e594d86b2215。它们供你使用已配置模型练习,不代表已执行过模型任务。
很小的修改也需要完整计划吗?
这两个示例项目只需简短诊断和明确测试命令。较大任务适合分阶段,但每个阶段都应有可审阅产物和检查办法。
Agent 说完成后应保留什么?
保留文件 diff、精确命令输出、预期值、局限与原件备份,并独立重跑测试;文字说明本身不是验证。
提醒模型小心可以代替沙箱吗?
不可以。提示词表达意图,执行器、进程权限和已配置的操作系统边界决定它实际能访问什么。
继续学习
查看验证证据并继续操作
对比已发布制品,或返回安装文档。