@delta-infra/cli 1.0.41 → 1.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/checksums.txt +5 -5
- package/package.json +1 -1
- package/skills/delta-sandbox/SKILL.md +192 -18
- package/skills/delta-sandbox/references/recipes.md +129 -0
package/checksums.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
01c924760059de2f76b8cca8d8d49abd4906eb7dde1e25f3341e708db1ed4b7a delta-cli-darwin-amd64.tar.gz
|
|
2
|
+
d57aea05d9adac03c06c26c3c6e516aa3c753177fee441e9b99acece0d5815b4 delta-cli-darwin-arm64.tar.gz
|
|
3
|
+
397294c5f8b452bb594c7cc69244cbaae9e90f8ce0eb6304087d63d333324ee2 delta-cli-linux-amd64.tar.gz
|
|
4
|
+
6f7b4d9bcd8284bf75860e3607de41b98f9634751a0cf4702e6998401ad2c65f delta-cli-linux-arm64.tar.gz
|
|
5
|
+
3e432374d15fda2e1b0bc0cd15cc37bfe9b78531761aa20bd5dfeaf01f2bc2fc delta-cli-windows-amd64.zip
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: delta-sandbox
|
|
3
|
-
version: 1.
|
|
4
|
-
description: "
|
|
3
|
+
version: 1.2.0
|
|
4
|
+
description: "在 Delta Sandbox Linux 容器中运行任意命令或脚本。适用于训练、推理、编译、数据处理等任意需要 sandbox 的计算任务,支持 Python / Node.js / Go / Java / Rust 等语言。所有任务通用同一套输出约定:命令在 stdout 末尾输出结构化 JSON,skill 提取为本地 result.json 的 summary,并生成一行 RESULT: 结论。Planner 调用本 skill 时,请在 plan step 的 required_outputs 中声明 [{kind: 'file', extensions: ['.json']}]。请求中用中性动词(运行/执行)描述命令,只有真的会落盘文件时,才使用创建/写入/保存等动词并带上扩展名。认证/配置/权限错误转 delta-shared。"
|
|
5
5
|
metadata:
|
|
6
6
|
requires:
|
|
7
7
|
bins: ["delta-cli"]
|
|
@@ -62,6 +62,67 @@ metadata:
|
|
|
62
62
|
|
|
63
63
|
9. **每个 `run-bg` 生成独立 `execution_id`**:每次调用 `sandbox run-bg` 都会返回一个唯一的 `execution_id`,多个后台任务之间通过它区分。务必保存每次返回的 `execution_id` 并与任务对应,后续通过 `sandbox logs <id> --execution-id <exec_id>` 分别查询各任务的结果。同步 `sandbox run` 无需 `execution_id`,结果直接返回。
|
|
64
64
|
|
|
65
|
+
10. **执行 delta-cli 命令必须使用 `bash` 工具,禁止用 `python_repl` 包装 `subprocess`**
|
|
66
|
+
- `delta-cli` 返回的是结构化 JSON,用 `bash` 直接执行最清晰,也便于 `result_file` 提取。
|
|
67
|
+
- ❌ **禁止**:在 `python_repl` 里写 `subprocess.run(['delta-cli', ...])`。这会把输出混在 Python 代码块中,既难读又多走一步解析。
|
|
68
|
+
- ✅ **正确**:`bash` 工具直接执行 `delta-cli sandbox ...`。
|
|
69
|
+
- 只有在**解析 JSON**(例如从 `sandbox read` 的信封中提取 `summary` 并写入 `result.json`)时,才使用 `python3`/`python_repl`。
|
|
70
|
+
|
|
71
|
+
11. **代码/数据必须经由 `delta-cli sandbox write` 进入 sandbox**
|
|
72
|
+
- 所有要送进 sandbox 执行的脚本、配置、数据文件,**必须**通过 `delta-cli sandbox write <id> --path /workspace/<文件名> --source <本地文件名>` 写入。
|
|
73
|
+
- 不要把脚本先写到宿主 workspace 再依赖同步;宿主 workspace 的文件对 sandbox 内部不可见。
|
|
74
|
+
- 本规则关注的是“入口统一为 `sandbox write`”,不针对任何特定宿主工具。无论宿主提供何种文件操作接口,最终都要把内容送到 sandbox 内部。
|
|
75
|
+
|
|
76
|
+
12. **任务完成标准是执行结果,而不是脚本文件存在**
|
|
77
|
+
- 本 skill 的交付物是**命令在 sandbox 中执行后的结果摘要**(本地 `result.json` 及其 `result_summary`),而不是 `.py`、`.sh` 等脚本文件本身。
|
|
78
|
+
- 仅把脚本写入 disk 不代表任务完成;必须完成 `write → run → read result_file → create result.json → kill sandbox` 整个生命周期,才能调用 `step_finish`。
|
|
79
|
+
- 因此,`skill_request` 中不要用“写出/保存/创建某某文件并执行”这类把文件落盘当成里程碑的措辞,而是直接要求“运行某某命令并返回结果摘要”。
|
|
80
|
+
|
|
81
|
+
13. **`result.json` 是完成前的必要条件**
|
|
82
|
+
- 在调用 `step_finish` 之前,必须确认:
|
|
83
|
+
1. `delta-cli sandbox run` / `run-bg --wait` 已返回且 `finished=true`;
|
|
84
|
+
2. 已从 `result_file` 生成本地 `result.json`(包含 `summary` 与 `result_summary`);
|
|
85
|
+
3. 已执行 `sandbox kill <id>` 销毁 sandbox;
|
|
86
|
+
4. `final_response` 只有一行 `RESULT: <result_summary>`。
|
|
87
|
+
|
|
88
|
+
14. **避免冗余检查与验证**
|
|
89
|
+
- 如果 `skill_request` 或用户请求已经明确指定了镜像与资源,**不要**在 `sandbox create` 前先调用 `sandbox providers` 或 `sandbox images`。
|
|
90
|
+
- 文件写入 sandbox 后,只需要 `sandbox stat`(可选)确认 size 正常即可。**禁止**用 `sandbox ls` + `sandbox read` 把刚写入的文件读回宿主再验证内容;这会产生一次无意义的往返。
|
|
91
|
+
- 不要在 `sandbox create` 成功后反复调用 `sandbox status` 轮询;create 返回时 sandbox 已就绪。
|
|
92
|
+
|
|
93
|
+
## 请求措辞约定
|
|
94
|
+
|
|
95
|
+
为降低被 host 的 Phase-10B 文件扩展名校验误判的概率,构造 `skill_request` 时遵守:
|
|
96
|
+
|
|
97
|
+
1. **运行/执行命令时,用中性动词**
|
|
98
|
+
优先使用 `运行`、`执行`、`调用`。
|
|
99
|
+
- 正确:`在 GPU sandbox 中运行 PyTorch CUDA 自检脚本`
|
|
100
|
+
- 不推荐在请求里直接写代码并带“输出”动词,例如
|
|
101
|
+
`脚本需输出:1) torch.cuda.is_available();...`
|
|
102
|
+
其中的 `torch.cuda` 会被正则误判为承诺输出 `.cuda` 文件。
|
|
103
|
+
|
|
104
|
+
2. **只有真正会创建文件时,才用承诺动词 + 扩展名**
|
|
105
|
+
`创建`、`写入`、`保存`、`输出`、`生成` 这类词只在你确实会让 skill 落盘文件时使用,并显式写出扩展名。
|
|
106
|
+
- 正确:`创建 check_cuda.py 并运行`
|
|
107
|
+
- 正确:`训练完成后将指标写入 result.json`
|
|
108
|
+
|
|
109
|
+
3. **不要把完整代码块写进 `skill_request`**
|
|
110
|
+
用自然语言描述任务目标,具体代码由 skill 内部写入 sandbox。
|
|
111
|
+
- 正确:`运行标准 PyTorch CUDA 可用性检查`
|
|
112
|
+
- 不推荐:在 `skill_request` 里粘贴 `import torch; print(torch.cuda.is_available())`。
|
|
113
|
+
|
|
114
|
+
### required_outputs 声明
|
|
115
|
+
|
|
116
|
+
构造调用本 skill 的 plan step 时,**必须**在 `required_outputs` 中声明会落盘一个 `.json` 文件:
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
required_outputs:
|
|
120
|
+
- kind: file
|
|
121
|
+
extensions: [".json"]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
原因:本 skill 运行命令后会从 sandbox 读取 `result_file` 并写入本地 `result.json`。host 的 Phase-10B deliverable 校验是“或”语义(任意一个 required 扩展名被真实文件满足即可);显式声明 `.json` 可以避免 `torch.cuda` 等代码 token 被误判为 `.cuda` 文件承诺,从而防止 `VERIFICATION_FAILED` 导致的重复执行。
|
|
125
|
+
|
|
65
126
|
## 快速路由
|
|
66
127
|
|
|
67
128
|
> ⚠️ **`list` 与 `ls` 区分**:`sandbox list` 列出用户的 **沙箱实例**(与 `docker ps` 类似),`sandbox ls <id>` 列出 **沙箱内目录**(与 `ls` 命令类似)。Tab 补全时注意区分。
|
|
@@ -103,20 +164,23 @@ metadata:
|
|
|
103
164
|
|
|
104
165
|
## 完整生命周期
|
|
105
166
|
|
|
106
|
-
1. **选择 Provider
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
167
|
+
1. **选择 Provider 和镜像(按需)**:
|
|
168
|
+
- 如果请求里已经明确指定了镜像(例如 `--image image.yangtzeailab.com/opensandbox/pytorch-cuda13`)和资源(cpu/memory/gpu),**直接跳到步骤 2 创建 sandbox**,不要再调 `sandbox providers` / `sandbox images` / `sandbox recommend`。
|
|
169
|
+
- 只有在用户要求“推荐一个配置”或需要查询可用镜像/Provider 时,才调用:
|
|
170
|
+
- `delta-cli sandbox providers` — 可用的计算后端
|
|
171
|
+
- `delta-cli sandbox images` — 服务端支持的镜像列表
|
|
172
|
+
- `delta-cli sandbox recommend --cpu N --memory XGi [--gpu N]` — 资源配置推荐
|
|
173
|
+
2. **创建**:`delta-cli sandbox create --image <img> --cpu 4 --memory 16Gi --gpu 1 --gpu-mem 8000 --max-life 120`。**返回的 JSON 信封中是 `data.sandbox_id`,不是 `data.id`;后续所有命令必须使用这个真实的 `sandbox_id`。**(创建后 sandbox 立即可用,无需额外连接)。**同一次任务若已有 `sandbox_id`,禁止再次 create,必须优先复用。**
|
|
174
|
+
- --max-life 指定 sandbox 最大存活时间(分钟),默认 30。长任务请调高,确保 sandbox 在命令执行期间不被回收。
|
|
175
|
+
- 这是 `sandbox create` 支持的完整资源参数集合,不存在其它“更正确”的资源 flag,不要发明不存在的参数。
|
|
176
|
+
- **禁止在 create 成功后反复调用 `sandbox status` 轮询**。`sandbox create` 返回时 sandbox 已经就绪,直接用它返回的 `data.sandbox_id` 执行 `write`/`run` 即可。多余的轮询会增加工具调用次数且没有任何收益。
|
|
113
177
|
3. **写入代码/数据**:
|
|
114
178
|
- **单个文件**:`delta-cli sandbox write <id> --path /workspace/<filename> --source <文件名>` — **必须**使用相对路径(如 `--source train.py`),**禁止**使用 `"$WORKSPACE_ROOT/train.py"` 或 `$(pwd)/train.py` 等 Shell 变量路径。`--source` 让 CLI 自行读取本地文件,不会经过 Shell 展开,是最安全的方式。写入后返回的 `size` 字段是实际磁盘字节数(来自 stat 验证),可对比确认写入完整性。少量配置(<20 行)可用 `--data "..."`。文件路径和扩展名由镜像中的运行时决定。
|
|
115
179
|
- **批量写入**:`sandbox write-multiple <id> --entry <远程路径>=<本地路径> [--entry ...]`(远程路径在 `=` 左边,本地路径在右边,`--data` 批量写入不可用)
|
|
116
180
|
- **上传目录**:`sandbox upload <id> --source <本地目录> --target <沙箱路径>` — CLI 将本地目录打包为 tar.gz,通过 multipart/form-data 上传,服务端自动解压到 target 目录。返回每个文件的路径、大小、模式。上传后 CLI 自动对比本地和远程文件清单做完整性校验(大小不匹配、多余文件等会告警)。
|
|
117
181
|
- **注意**:`--source` 是**本地目录路径**,`--target` 是**沙箱内的目标目录**,target 目录不存在会自动创建。
|
|
118
182
|
- 支持嵌套目录,空目录也会被创建。
|
|
119
|
-
|
|
183
|
+
- **写后验证(可选)**:`sandbox stat <id> --path <path>` 确认文件存在且 size 符合预期即可。**不要**用 `sandbox ls` + `sandbox read` 把刚写入的文件读回宿主再逐字对比;无异常时不需要读回。
|
|
120
184
|
4. **运行命令**:
|
|
121
185
|
- **短任务(预计 ≤ 60 秒)**:`delta-cli sandbox run <id> --command "<命令>" --timeout <秒>` 同步执行,返回 `stderr` / `exit_code` / `result_file`,完整 `stdout` 在结果文件中,**不要**再调用 `sandbox logs`。可通过 `--result-file <路径>` 自定义结果文件路径;默认值为 `/tmp/delta-result-{execution_id}.json`。根据镜像中的运行时构造命令,常见示例:
|
|
122
186
|
- Python:`python /workspace/train.py`
|
|
@@ -126,22 +190,132 @@ metadata:
|
|
|
126
190
|
- **长任务(预计 > 60 秒,如下载模型、训练、编译、大规模数据处理)**:`delta-cli sandbox run-bg <id> --command "<命令>" --timeout <秒> [--result-file <路径>]` 提交后台任务,获得 `execution_id` 后通过以下命令轮询:
|
|
127
191
|
- `delta-cli sandbox logs <id> --execution-id <execution_id>` — 返回 `cursor`、`running`、`finished`、`exit_code`、`result_file`(完成后)。当 `finished=true` 时认为完成,完整输出需读取 `result_file`。
|
|
128
192
|
- `delta-cli sandbox status bg <id> --execution-id <execution_id>` — 返回 `running`、`finished`、`exit_code`。
|
|
129
|
-
|
|
130
|
-
|
|
193
|
+
禁止对长任务使用同步 `sandbox run`
|
|
194
|
+
|
|
195
|
+
**推荐实践**:让 sandbox 脚本在 `stdout` 末尾打印一个独立的结构化 JSON 对象(例如 `{"status":"ok", ...}`), SKILL 步骤 5 可直接把它提取为 `result.json` 的 `summary`。这样即使 `stdout` 前面是大量训练/下载日志,skill 也无需让大模型去“读整段日志再摘要”。
|
|
196
|
+
5. **读取 result_file 并生成精简本地副本**:从 `sandbox run` / `sandbox run-bg --wait` / `sandbox logs` 返回数据中获得 `result_file` 路径。
|
|
197
|
+
- `sandbox read` 返回的是 CLI 信封 `{"ok":true,"data":{"content":"..."}}`,真实结果 JSON 在 `data.content` 字段里。
|
|
198
|
+
- **不要把 CLI 信封或完整长 `stdout` 原样写入本地 `result.json`**;应该解析后生成一份精简的结构化摘要。
|
|
199
|
+
- **推荐做法(避免 heredoc 引号失败)**:先用 `bash` 把信封写入临时文件,再用 `python3`(或 `python_repl`)读取该文件并生成 `result.json`。**不要**把 `delta-cli sandbox read` 的输出通过管道直接喂给内联 heredoc,管道+heredoc 的组合极易因 Shell 转义/引号问题失败。
|
|
200
|
+
1. `bash` 保存信封:
|
|
201
|
+
```bash
|
|
202
|
+
delta-cli sandbox read <sandbox_id> --path <result_file> > /tmp/_delta_result_envelope.json
|
|
203
|
+
```
|
|
204
|
+
2. `python3` / `python_repl` 生成 `result.json`:
|
|
205
|
+
```python
|
|
206
|
+
import json, os
|
|
207
|
+
|
|
208
|
+
env = json.load(open("/tmp/_delta_result_envelope.json", encoding="utf-8"))
|
|
209
|
+
raw = json.loads(env["data"]["content"])
|
|
210
|
+
|
|
211
|
+
# 精简到用户关心的极简字段,避免 host read_file 预览截断
|
|
212
|
+
concise = {
|
|
213
|
+
"exit_code": raw.get("exit_code"),
|
|
214
|
+
"finished": raw.get("finished"),
|
|
215
|
+
"summary": {},
|
|
216
|
+
"error": raw.get("error"),
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
# 优先提取 stdout 末尾的独立 JSON 对象作为 summary
|
|
220
|
+
stdout = raw.get("stdout", "")
|
|
221
|
+
for line in reversed(stdout.strip().splitlines()):
|
|
222
|
+
s = line.strip()
|
|
223
|
+
if s.startswith("{") and s.endswith("}"):
|
|
224
|
+
try:
|
|
225
|
+
concise["summary"] = json.loads(s)
|
|
226
|
+
break
|
|
227
|
+
except Exception:
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
# 构造 result_summary:一行字符串,最终回答的 RESULT: 行直接用它
|
|
231
|
+
parts = [f"exit_code={concise['exit_code']}", f"finished={concise['finished']}"]
|
|
232
|
+
for key, value in concise["summary"].items():
|
|
233
|
+
# 避免把长文本塞进 result_summary
|
|
234
|
+
if isinstance(value, (str, int, float, bool)) and len(str(value)) < 200:
|
|
235
|
+
parts.append(f"{key}={value}")
|
|
236
|
+
concise["result_summary"] = ", ".join(parts)
|
|
237
|
+
|
|
238
|
+
ws = os.environ.get("WORKSPACE_ROOT", ".")
|
|
239
|
+
with open(os.path.join(ws, "result.json"), "w", encoding="utf-8") as f:
|
|
240
|
+
json.dump(concise, f, indent=2, ensure_ascii=False)
|
|
241
|
+
print(concise["result_summary"])
|
|
242
|
+
```
|
|
243
|
+
3. 如果当前环境没有 `python3`,用 `jq`、`node` 或任何可解析 JSON 的工具实现**相同逻辑**:1)读取 `/tmp/_delta_result_envelope.json`;2)解开 CLI 信封取 `data.content`;3)解析内部 JSON;4)从 `stdout` 末尾提取 summary JSON;5)生成 `result_summary` 并写入 `result.json`。
|
|
244
|
+
- 如果 `stdout` 非常大(训练日志、下载日志等),不要把整段 `stdout` 写进 `result.json`;只保留关键指标和 preview。
|
|
245
|
+
- 写入本地副本的目的是让 host 的 deliverable 校验识别到真实的 `.json` 文件;由于校验是“或”语义,`.json` 文件会盖过 `torch.cuda` 等 token 被误判出的 `.cuda` 文件承诺。
|
|
246
|
+
- 完整原始输出仍保留在 sandbox 的 `result_file` 中,必要时可再次 `sandbox read` 获取。
|
|
131
247
|
6. **销毁**:`delta-cli sandbox kill <id>`(如需保存结果,用 `sandbox finish --results '{...}'` 替代 kill,finish 会自动销毁 sandbox)
|
|
132
248
|
|
|
133
249
|
详细步骤见 [lifecycle.md](references/lifecycle.md)。
|
|
134
250
|
|
|
251
|
+
## 通用结构化输出约定
|
|
252
|
+
|
|
253
|
+
本约定适用于**所有** `delta-sandbox` 任务(GPU/CPU、训练/推理/编译/数据处理等),目的是让 Runner 能直接从 `result.json` 读到结论,无需再次解析长日志。
|
|
254
|
+
|
|
255
|
+
### sandbox 脚本/命令应该输出的内容
|
|
256
|
+
|
|
257
|
+
命令执行完毕后,推荐在 `stdout` 末尾打印一行**独立的结构化 JSON**。例如:
|
|
258
|
+
|
|
259
|
+
- CUDA 检查:`{"status":"ok","torch_version":"2.5.1+cu121","cuda_available":true,"device_name":"NVIDIA H100 80GB HBM3"}`
|
|
260
|
+
- 训练任务:`{"status":"ok","epochs":10,"final_loss":0.12,"final_accuracy":0.94,"model_file":"/workspace/model.pt"}`
|
|
261
|
+
- 数据处理:`{"status":"ok","input_rows":10000,"output_rows":9876,"output_file":"/workspace/output.csv"}`
|
|
262
|
+
|
|
263
|
+
这样 SKILL 可以用同一套代码把它提取到 `result.json` 的 `summary` 字段,再生成 `RESULT:` 行。
|
|
264
|
+
|
|
265
|
+
- **禁止**在 stdout 中打印 `FINAL_ANSWER: ...` 这类冗余标记行;多余的标记会让 Runner 把普通文本误认为结果字段。
|
|
266
|
+
- `summary` 中**不要**使用 `final_answer` 这类与 schema 重复的关键字。统一用语义字段表示结果,例如推理任务用 `generated_text` / `output` / `result`,训练任务用 `final_loss` / `final_accuracy`,数据处理用 `output_file` / `output_rows`。
|
|
267
|
+
|
|
268
|
+
### 本地 `result.json` 通用 Schema
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"exit_code": 0,
|
|
273
|
+
"finished": true,
|
|
274
|
+
"summary": {},
|
|
275
|
+
"result_summary": "exit_code=0, status=ok, torch_version=..., ...",
|
|
276
|
+
"error": null
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
关键字段:
|
|
281
|
+
- `summary`: 命令输出的结构化结果对象。
|
|
282
|
+
- `result_summary`: **一行字符串**,与最终回答的 `RESULT:` 行内容一致,方便 Runner 直接读取。
|
|
283
|
+
- `error`: 命令失败时的错误信息;成功时一般为 `null`。
|
|
284
|
+
- **不要把完整 `stdout` 塞进来**。完整日志仍保留在 sandbox 的 `result_file` 中。
|
|
285
|
+
|
|
135
286
|
## 输出阅读与最终回答格式
|
|
136
287
|
|
|
137
288
|
1. **`sandbox run` / `sandbox run-bg --wait` / `sandbox logs` 返回的 JSON 中包含 `data.result_file`**(沙箱内结构化结果文件的路径)。
|
|
138
|
-
2. **只要 `data.result_file` 存在,必须优先使用 `delta-cli sandbox read <id> --path <result_file>`
|
|
289
|
+
2. **只要 `data.result_file` 存在,必须优先使用 `delta-cli sandbox read <id> --path <result_file>` 读取该文件,并解析 CLI 信封得到真实结果 JSON。**
|
|
139
290
|
- 结果文件包含完整 `stdout`、`stderr`、`exit_code`、`finished`、`command`、`error`。
|
|
140
|
-
3.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
291
|
+
3. **读取 result_file 后,生成本地精简 `result.json`**(见“完整生命周期”步骤 5 和“通用结构化输出约定”)。本地副本只应包含关键字段和摘要,**不应包含完整长 `stdout`**。
|
|
292
|
+
4. **最终回答必须且只能是 `RESULT:` 开头的一行。**
|
|
293
|
+
- 优先直接复用 `result.json` 里的 `result_summary` 字段:
|
|
294
|
+
```text
|
|
295
|
+
RESULT: <result.json 中的 result_summary>
|
|
296
|
+
```
|
|
297
|
+
- 如果 `result_summary` 缺失,则从 `summary` 对象构造一行,例如:
|
|
298
|
+
```text
|
|
299
|
+
RESULT: exit_code=0, status=ok, torch_version=2.7.0+cu128, cuda_available=True, device_name=NVIDIA GeForce RTX 3090.
|
|
300
|
+
```
|
|
301
|
+
5. **绝对禁止任何前缀、后缀、说明、过渡句或内心独白**
|
|
302
|
+
- 正确:`RESULT: exit_code=0, cuda_available=True, torch_version=2.5.1+cu121, device_name=NVIDIA H100 80GB HBM3`
|
|
303
|
+
- 错误:`Sandbox killed successfully. Final answer with result summary. RESULT: ...`
|
|
304
|
+
- 错误:`Sandbox killed. Task done. Need final answer exactly RESULT: line from result_summary. RESULT: ...`
|
|
305
|
+
- 错误:`The user wants me to verify CUDA... RESULT: ...`
|
|
306
|
+
- 错误:`Summary: ... RESULT: ...`
|
|
307
|
+
- 错误:在 `RESULT:` 后追加 `Let me know if you need anything else.` 等多余句子。
|
|
308
|
+
- **规则**:`final_response` 里出现的字符,必须是 `RESULT:` 及其后的内容,不允许其它任何自然语言。
|
|
309
|
+
6. **不要依赖或被截断的 `stdout`/`stderr` 字段**,关键结论必须来自 `result.json` 的 `summary` / `result_summary`。
|
|
310
|
+
7. **`sandbox kill` 成功后不再调用任何工具**。kill 命令返回 `{ok:true}` 即表示任务已收尾,下一回合直接输出一行 `RESULT: <result_summary>`。禁止再调 `bash`/`read_file`/`ls` 等工具,也不要以 "Need final answer exactly..."、"Sandbox killed." 等独白开头。
|
|
311
|
+
|
|
312
|
+
## 宿主 / Planner 调用提示
|
|
313
|
+
|
|
314
|
+
本 skill 设计成“结论自包含”:执行结束后,**`result.json` 的 `result_summary` 与 `final_response` 已经包含最终面向用户的结论**。因此:
|
|
315
|
+
|
|
316
|
+
- **Planner** 调用本 skill 的 plan step 时,`required_outputs` 必须声明 `.json`(见上方“请求措辞约定”)。
|
|
317
|
+
- **宿主(host / Runner / finalize 阶段)** 在收到 skill 返回后,应直接把 `final_response` 或 `result.json` 里的 `result_summary` 作为最终答案,**不要再让大模型去读取 result.json、验证文件内容或重新推理**。
|
|
318
|
+
- 如果宿主担心内容不可信,可以读取 `result.json` 核对,但**最终输出仍必须是 `RESULT:` 开头的一行**,不允许把“我需要先读取文件验证”、“Wait, I don't have...”等思考过程暴露给用户。
|
|
145
319
|
|
|
146
320
|
## 常见恢复
|
|
147
321
|
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# 标准任务请求模式
|
|
2
|
+
|
|
3
|
+
本文件提供 `delta-sandbox` 处理常见任务时的推荐请求写法。这些示例是语言无关的模板,实际代码由 skill 在 sandbox 内部生成或写入。
|
|
4
|
+
|
|
5
|
+
## Planner 调用本 skill 时的 required_outputs
|
|
6
|
+
|
|
7
|
+
所有直接调用 `delta-sandbox` 的 plan step 都应该声明会落盘一个 `.json` 文件。这样 skill 运行命令后把 sandbox `result_file` 写入本地 `result.json` 时,host 可以正确通过 Phase-10B deliverable 校验。
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
required_outputs:
|
|
11
|
+
- kind: file
|
|
12
|
+
extensions: [".json"]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
> 说明:这是声明 skill 会创建 `.json` 结果文件,不是要求用户请求中出现 `.json`。用户请求仍按下面的模板使用中性动词。
|
|
16
|
+
|
|
17
|
+
## 通用脚本输出模板
|
|
18
|
+
|
|
19
|
+
为了让 skill 用同一套流程生成 `RESULT:` 并避免大模型去摘要长日志,推荐任何 sandbox 脚本在**执行结束时**打印一行结构化 JSON:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{"status":"ok","key_metric_1":"value_1","key_metric_2":123}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
SKILL 会把它提取为 `result.json` 的 `summary`,并生成 `result_summary` 与最终 `RESULT:` 行。
|
|
26
|
+
|
|
27
|
+
**不要**再输出 `FINAL_ANSWER: ...` 这样的标记行,也不要在 JSON 里使用 `final_answer` 字段。summary 里的语义字段(如 `output`、`result`、`generated_text`、`final_accuracy`)已经足够表达结果。
|
|
28
|
+
|
|
29
|
+
不同任务的关键字段示例:
|
|
30
|
+
|
|
31
|
+
- **CUDA 检查**:`status`, `torch_version`, `cuda_available`, `device_name`
|
|
32
|
+
- **训练任务**:`status`, `epochs`, `final_loss`, `final_accuracy`, `model_file`
|
|
33
|
+
- **推理任务**:`status`, `input_samples`, `output_file`, `avg_latency_ms`
|
|
34
|
+
- **数据处理**:`status`, `input_rows`, `output_rows`, `output_file`
|
|
35
|
+
- **编译/构建**:`status`, `build_time_s`, `output_binary`, `tests_passed`
|
|
36
|
+
|
|
37
|
+
## 1. GPU / CUDA 可用性检查
|
|
38
|
+
|
|
39
|
+
用户请求示例:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
在 GPU sandbox 中运行标准 PyTorch CUDA 自检脚本,返回 exit_code、torch 版本、CUDA 是否可用、CUDA/cuDNN 版本、GPU 名称与显存信息。
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
说明:
|
|
46
|
+
|
|
47
|
+
- 不要在请求里出现 `torch.cuda.is_available()` 等完整代码 token,避免被 host 误判为 `.cuda` 文件承诺。对应的 plan step 仍按上面模板声明 `.json` 输出。
|
|
48
|
+
- 推荐让脚本在 `stdout` 末尾输出一行结构化 JSON,例如:
|
|
49
|
+
```json
|
|
50
|
+
{"torch_version":"2.7.0+cu128","cuda_available":true,"device_count":1,
|
|
51
|
+
"device_name":"NVIDIA GeForce RTX 3090","tensor_op":"[101.0]",
|
|
52
|
+
"memory_before_mb":{"allocated":0,"reserved":0,"max_allocated":0},
|
|
53
|
+
"memory_after_mb":{"allocated":0.0005,"reserved":2.0,"max_allocated":0.001}}
|
|
54
|
+
```
|
|
55
|
+
- skill 会从 `result_file` 提取这个 JSON 作为本地 `result.json` 的 `summary`,最终只输出一行 `RESULT: ...`。
|
|
56
|
+
- 完整 `nvidia-smi` 原始输出保留在 sandbox 的 `result_file` 中。
|
|
57
|
+
|
|
58
|
+
## 2. 运行用户已有的脚本
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
在 sandbox <sandbox_id> 中运行 /workspace/train.py,参数为 --epochs 10 --batch-size 32。
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
说明:文件已存在,用中性动词 `运行`,不使用 `创建` 等承诺动词。
|
|
65
|
+
|
|
66
|
+
## 3. 安装依赖并执行命令
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
在 sandbox 中运行 pip install -r /workspace/requirements.txt,然后运行 python /workspace/app.py。
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
说明:依赖安装和命令执行都没有落盘新文件,使用中性动词描述。
|
|
73
|
+
|
|
74
|
+
## 4. 训练并将指标落盘
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
在 GPU sandbox 中运行训练脚本(例如基于 PyTorch 的 MNIST 训练),训练完成后在 stdout 末尾打印包含 epochs、final_loss、final_accuracy、model_file 的结构化 JSON。
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
说明:
|
|
81
|
+
|
|
82
|
+
- 训练日志可能很长,不要让 skill 去读整段日志再摘要;让脚本自己输出关键指标。
|
|
83
|
+
- 推荐脚本最终打印:`{"status":"ok","epochs":10,"final_loss":0.023,"final_accuracy":0.992,"model_file":"/workspace/model.pt"}`
|
|
84
|
+
- skill 会把它提取为 `result.json` 的 `summary`,最终输出 `RESULT: exit_code=0, status=ok, epochs=10, ...`。
|
|
85
|
+
- 如需保存完整模型文件,可再用 `sandbox read` 或 `sandbox upload` 处理,不属于 `result.json` 的摘要范围。
|
|
86
|
+
|
|
87
|
+
## 5. 通用数据处理
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
在 sandbox 中运行数据处理命令,读取 /workspace/input.csv,输出 /workspace/output.csv,并在 stdout 末尾打印包含 input_rows、output_rows、output_file 的结构化 JSON。
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
说明:
|
|
94
|
+
|
|
95
|
+
- 推荐脚本最终打印:`{"status":"ok","input_rows":10000,"output_rows":9876,"output_file":"/workspace/output.csv"}`
|
|
96
|
+
- skill 会把它提取为 `result.json` 的 `summary`,最终输出 `RESULT: exit_code=0, status=ok, input_rows=10000, output_rows=9876, output_file=/workspace/output.csv`。
|
|
97
|
+
|
|
98
|
+
## 6. 模型推理(Qwen / LLM / 视觉等)
|
|
99
|
+
|
|
100
|
+
用户请求示例:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
在 GPU sandbox 中用 ModelScope 上的 Qwen/Qwen2.5-0.5B-Instruct 运行一次推理,输入 "100+10",返回模型的输出结果及 CUDA 可用性摘要。
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
说明:
|
|
107
|
+
|
|
108
|
+
- 请求里不要贴完整 Python 代码,也不要指定宿主文件路径(如 `@ROOT/inference.py`、本地绝对路径等),更不要要求脚本输出 `FINAL_ANSWER:` 标记行。脚本内容、模型下载、执行路径都由 skill 内部通过 `delta-cli sandbox write` 写入 sandbox 后运行。
|
|
109
|
+
- 推荐让脚本在 `stdout` 末尾打印一行结构化 JSON,例如:
|
|
110
|
+
```json
|
|
111
|
+
{"status":"ok","cuda_available":true,"device":"cuda","model":"Qwen/Qwen2.5-0.5B-Instruct","input":"100+10","generated_text":"110"}
|
|
112
|
+
```
|
|
113
|
+
- skill 会把它提取为 `result.json` 的 `summary`,最终输出 `RESULT: exit_code=0, status=ok, cuda_available=True, generated_text=110, ...`。
|
|
114
|
+
|
|
115
|
+
## 注意事项
|
|
116
|
+
|
|
117
|
+
- 尽量用自然语言描述任务,完整代码由 skill 内部处理。
|
|
118
|
+
- 只有在 skill 会真实创建文件时,才在请求中显式写出 `*.py` / `*.json` / `*.csv` 等扩展名。
|
|
119
|
+
- 不要使用 `脚本需输出...` 这类把代码片段直接跟在承诺动词后的句式。
|
|
120
|
+
- **任务完成的标准是执行结果,不是脚本文件存在**。Planner 和 skill 都要以本地 `result.json` 的生成作为完成标志;`required_outputs` 必须声明 `.json`,不要只声明 `{"kind": "file"}`。
|
|
121
|
+
- **`skill_request` 里不要出现完整代码块或宿主文件路径概念**(如 `@ROOT/...`、`/Users/...`)。脚本应通过 `delta-cli sandbox write` 进入 sandbox 内部路径 `/workspace/...`。
|
|
122
|
+
|
|
123
|
+
## 本地 `result.json` 的内容约定
|
|
124
|
+
|
|
125
|
+
- 本地 `result.json` 是一份**精简摘要**,用于 host deliverable 校验,不是完整日志存档。
|
|
126
|
+
- 必须包含 `result_summary` 字段,内容与最终 `RESULT:` 行一致,方便 Runner 直接读取结论。
|
|
127
|
+
- 只写入关键字段(`exit_code`、`finished`、`summary`、`result_summary`、`error`)。**不要**额外添加 `final_answer` 等字段。
|
|
128
|
+
- 不要把完整原始 `stdout` 塞进 `result.json`,否则 host 的 `read_file` 工具预览时会截断,Runner 可能误以为文件被截断。
|
|
129
|
+
- 完整原始输出保留在 sandbox 的 `result_file` 中,需要时再 `sandbox read`。
|