此技能涵蓋透過 SSH 的遠端運算,包括直接執行與 Slurm 提交:
列出主機、建立句柄、執行短暫遠端指令(callCommand)、讀寫主機知識文件,以及完整的非同步任務生命週期 — 提交 → 儲存 job_id → 依 ID 讀取非阻塞快照 → 收集結果 → 分析回合 → 發布成果。
host.compute 的執行位置: host.compute 僅存在於控制平面的 REPL 核心中 — 請使用 repl_execute 工具(JavaScript)執行以下所有範例,即與託管 host.mcp 相同的核心。python/r 資料核心沒有 host.compute(SSH 和審批流程保持在沙盒工作區之外);從 python 或 r 儲存格呼叫它將會失敗,並回報 host.compute is undefined。
選擇執行位置
只會顯示或可呼叫為此次會話啟用的運算主機。在一個目錄中發現它們;每個條目都有 selected(已選)或 available(可用)的角色。非空的已選池是一個執行指令:根據任務需求,在一個或多個已選主機上執行工具支援的工作。該池沒有優先級,也不表示自動多主機排程。如果沒有選中任何主機,請從可用條目中選擇。僅對需要進一步評估的候選者讀取 details()。
切勿猜測或重複使用目錄中不存在的提供者 ID。使用者指定已停用的主機並不能使其可呼叫;請說明該主機必須先為此會話啟用。如果沒有可用的合格主機,請說明阻礙因素並詢問使用者如何繼續。
const hosts = await host.compute.listHosts()
const selectedHosts = hosts.filter((host) => host.role === 'selected')
const candidates = selectedHosts.length > 0 ? selectedHosts : hosts
每個列表項目都是一個簡潔摘要,包含 provider_id、display_name、shape、execution_mode、status 和 role
(last_probe_ok、probe_failed 或 not_probed)。last_probe_ok 表示最近一次持久化探測成功;它並不保證當前的即時連線。知識文件和資源探測快照被刻意排除在發現結果之外。
API 參考
// 列出此會話已啟用的主機,作為一個帶有角色的簡明日錄
const hosts = await host.compute.listHosts()
// 相容性發現名稱仍然可用;兩者都會隱藏已停用的主機。
const visibleHosts = await host.compute.listRegistered()
const selectedHosts = await host.compute.listPreferred()
// 建立特定主機的句柄(無網路呼叫)
const c = host.compute.create('ssh:<alias>')
// 執行短暫遠端指令(如果 approval_denied / host_unreachable / timeout 則拋出異常)
const result = await c.callCommand('<shell command>', '<用於審批卡片的單行意圖>', {
loginShell: true, // 預設值:true — 先執行登入設定檔,然後讀取可讀的 ~/.bashrc,最後執行此命令
timeoutSeconds: 60 // 可選 — 省略時主機將套用其自己的預設值 (60s)
})
// result → { exit_code, stdout, stderr, truncated }
// 讀取持久化的操作說明和獨立的資源探測快照。
// doc 始終是確切儲存的文字(包括儲存說明前的 '')。
// 當此主機從未被探測過時,probe 會明確為 null。
const info = await host.compute.details('ssh:<alias>', { mode: 'read' })
// 將筆記附加到持久化的主機知識文件中(代理寫入;上限 32 KB)。
// 僅附加會更改 doc;它絕不會複製或更改探測觀察結果。
await host.compute.details('ssh:<alias>', {
mode: 'append',
text: '\n## 筆記\n在 <date> 學習到 X'
})
// 或者,取代整個主機知識文件。在取代之前再次讀取,特別是在你上面附加了內容時:
// oldText 必須與持久化的 doc 完全相符。
const latest = await host.compute.details('ssh:<alias>', { mode: 'read' })
await host.compute.details('ssh:<alias>', {
mode: 'replace',
text: '<新的完整文件>',
oldText: latest.doc
})
將 doc 視為操作說明和持久化的主機知識。將 probe 視為一個帶有日期的觀察結果:資源值可能會改變,且偵測到排程器並不授權提交作業或選擇帳戶、分割區或佇列。在發生文件不匹配或 details_conflict 錯誤時,請再次讀取並將你的草稿與最新文件合併後再重試。僅更新資源的探測不會更改 doc 或導致取代衝突。寫入後,再次讀取以驗證儲存的內容。成功的附加或取代結果僅為 { ok: true }。寫入結果不包含 doc 或 probe;務必再次讀取以驗證確切持久化的 doc,而不是從寫入結果中讀取欄位。
使用 loginShell: true 時,遠端 Bash 登入設定檔會先執行,然後 Open-Science 會嘗試在 ~/.bashrc 可讀時載入它。.bashrc 可能會為非互動式 shell 刻意提早返回,因此在這種守衛之後宣告的變數將不可用。缺少 .bashrc 則不執行任何操作。設定 loginShell: false 可在不執行任何初始化步驟的情況下執行命令。初始化失敗會透過正常的命令結果/錯誤行為回報。
API 參考(非同步任務)
對於長時間運算(幾分鐘到幾小時),請使用 submitJob。它會立即返回一個 job_id;該任務會在遠端主機的背景中執行。任務完成時,應用程式會自動收集輸出,並在你尚未讀取最終結果時啟動一個新的分析回合。請在您的工作上下文中保留提交結果中的確切 job_id;故意沒有提供用於重新發現它的歷史任務掃描功能。狀態和結果的讀取僅使用該儲存的 ID,並返回非阻塞的本機快照。
對於本機輸入,src 是相對於代理會話工作區的路徑——與檔案寫入工具使用的路徑相同。在那裡寫入一個腳本或小型生成的輸入,然後傳遞其相對路徑。Open-Science 會在審批和分派之前快照接受的輸入。請勿傳遞任意的絕對本機路徑或將檔案複製到應用程式管理的 notebooks/... 目錄中。僅當 src 是 host.artifactPath(versionId) 返回的確切路徑,或記事本上下文已提供的已註冊會話輸入路徑時,絕對路徑才有效。
// 重複使用上面從會話目錄中選出的 `candidates`。
// 提交一個非阻塞任務 — 在使用者批准後立即返回。
// 運算主機的設定執行模式選擇直接 SSH 或 Slurm。
const c = host.compute.create('ssh:<alias>')
const job = await c.submitJob(
'<用於審批卡片的單行意圖>', // 顯示在審批卡片中
'<shell command>', // 要在遠端執行的命令
{
environment: 'protein-gpu', // 可選的邏輯名稱;請參閱下面的環境啟動
timeoutSeconds: 3600, // 可選;預設 24 小時,最長 7 天
inputs: [
{ src: 'in.dat', dstFilename: 'in.dat' }, // 暫存代理會話工作區的檔案
{ remotePath: 'ssh:<alias>/<abs_path>' } // 連結遠端檔案(不傳輸)
],
outputs: [
'*.result', // 精選(預設可見性)
{ glob: '*.json', visibility: 'featured' }, // 明確精選
{ glob: '*.log', visibility: 'hidden' }, // 隱藏(診斷用,不顯示在卡片中)
{ glob: 'checkpoints/**', residency: 'remote' } // 保留在遠端 — 記錄在 left_on_remote 中
],
harvest: {
exclude: ['work/**'], // 絕不收集這些路徑
maxFileMb: 100, // 單一檔案硬性上限 (100 MiB)
maxTotalMb: 500 // 每個任務的硬性上限,包括 stdout/stderr (500 MiB)
}
}
)
// job → { job_id, provider_id, status: 'submitted' | 'queued', remote_workdir }
const savedJobId = job.job_id // 保留這個確切的 ID 供後續的相依步驟使用
return { ...job, job_id: savedJobId }
讀取已儲存的任務快照
當任務的狀態或結果相關時,使用儲存的 ID。.status() 和 .result() 在所有狀態下都是非阻塞的本機讀取;兩者都不會等待完成、觸發 SSH 或啟動另一次收集。.result() 也包含已收集的檔案清單。兩個呼叫都會回報 follow_up_delivery。最終的 .result() 讀取在它阻止後備方案時會回報 suppressed,或者在該後備方案已越過其分派柵欄時回報 committed。.status() 快照會保持 pending,因為它省略了已收集的檔案清單。請使用提交的確切 ID,而不是搜尋舊的任務。
const snapshot = await c.attachJob(savedJobId).result()
if (!snapshot.result_final) {
return {
job_id: savedJobId,
status: snapshot.status,
result_final: false,
follow_up_delivery: snapshot.follow_up_delivery
}
}
return snapshot
僅將 result_final: true 視為最終結果。這表示自動回應已準備就緒:success、failed 和 timeout 可能仍在等待本機收集,而 cancelled 和 error 則為最終狀態,無需等待部分輸出收集。output_files 僅包含實際在本機可用的檔案;一個空列表並不能證明沒有遠端輸出。應用程式擁有提供者輪詢和背景收集的擁有權。未讀取的最終結果會在後續的代理回合中傳遞。最終的 .result() 快照在它抑制該後備方案時會回報 follow_up_delivery: 'suppressed',或者如果自動傳遞已贏得競爭且仍為權威來源時則回報 committed。.status() 永遠不會消耗完整的結果。
直接 SSH 或 Slurm
運算主機設定的執行模式會選擇如何啟動每個任務。direct_ssh 會將命令作為分離的程序在 SSH 目標上執行。slurm 會使用 sbatch 提交它;請在 command 的頂部放置叢集所需的 #SBATCH 指令。Open-Science 擁有提交、排程器狀態輪詢、取消和收集的擁有權。請勿在 submitJob 周圍自行呼叫 sbatch、squeue 或 scancel。
對於 Slurm 狀態錯誤或取消失敗,請參閱 Slurm 故障排除。在該例外路徑中,compute.callCommand 可以檢查同一個任務及其輸出,並在使用者現有任務授權範圍內執行復原。保持一般的提交在 Compute API 上進行。
讀取 listHosts() 以取得設定的模式,讀取 details() 以取得提供者特定的指令;請勿嘗試覆寫每個任務的模式或僅從工作負載推斷它。如果 Slurm 不可用或拒絕腳本,請回報返回的錯誤以及具體的後續步驟(例如新增帳戶或分割區指令)。請勿在登入節點上直接靜默地重新執行工作負載。
Open-Science 接受一般的單一任務指令,例如分割區、帳戶、CPU、記憶體和 GPU。設定 timeoutSeconds 表示工作負載的執行時間。你可以使用一個 #SBATCH --time=value 指令來設定排程器分配限制;當它不存在時,Open-Science 會從 timeoutSeconds 推導出預設的分配限制。Open-Science 擁有任務名稱、工作目錄、stdout 和 stderr 的指令。避免使用任務陣列,因為一個 Open-Science 任務會追蹤一個排程器任務和一個輸出收集。將獨立的工作作為單獨的任務提交,並在需要時使用會話並發限制。
對於 Slurm,請使用每行一個 #SBATCH --option=value 指令(或無值的旗標,例如 #SBATCH --exclusive)來請求資源。舊版的 resources 選項是描述性元資料;它不會分配 CPU、記憶體或 GPU。timeoutSeconds 限制工作負載的執行時間,而非佇列等待時間;#SBATCH --time 設定排程器分配限制。兩者都不是佇列開始時間的保證。
非阻塞任務 status() 和 result() 快照包含已知時的 scheduler_job_id、任務層級錯誤時的 error: { code, message },以及當觀察或提交復原需要關注時的 last_poll_error。待處理的原因或延遲的會計記錄並不表示工作負載失敗。如果提交未經確認,請使用回報的任務身份和提供者診斷來決定是否再次提交;Open-Science 不會自動提交重複項。
環境啟動
可選的 environment 值是一個邏輯名稱,而不是一個 shell 命令。Open-Science 會在直接和 Slurm 任務的工作負載之前載入 ~/.open-science/environments/<name>.sh。名稱長度為 1–64 個字元,可由字母、數字、句點、底線或連字號組成,且必須以字母或數字開頭。該檔案及其引用的每個軟體/快取路徑都必須在執行節點上可見。
如果提交回報此啟動檔案遺失,請載入運算環境設定技能,為使用者或主機管理員準備確切的設定、修復和移除說明(在 Open-Science 外部執行)。在使用者套用計劃後驗證使用者管理的啟動,然後重試。請勿猜測 conda 名稱、將內聯安裝新增到科學任務中,或將啟動隱藏在 .bashrc 中。當命令刻意使用主機的預設環境時,請省略 environment。
收集安全邊界
- 宣告的輸出檔案會在
stdout和stderr之前被選取;日誌使用剩餘的每個任務預算。 - 應用程式會拒絕模型提供的超過每個檔案 100 MiB 或每個任務 500 MiB 的限制。
- 收集還會保留固定的 2 GiB 可用本機磁碟空間。無法容納的檔案將保留在遠端。
行為邊界
- 任務執行期間: 對話保持開放。使用者可以發送訊息;您可以處理其他任務。每個狀態/結果查詢會立即返回當前的本機快照。
- 任務完成時: 如果您沒有主動讀取其終端結果,應用程式會自動啟動一個新的分析回合。您不會觸發此後備方案。
檢查任務狀態(非阻塞讀取,僅供參考)
// 非阻塞資料庫讀取 — 無 SSH。如果在對話中途需要狀態快照,請使用此方法。
const handle = c.attachJob(job.job_id)
const s = await handle.status()
// s → {
// job_id, scheduler_job_id?, status, result_final, cancellation?, exit_code,
// error?, last_