Community코딩 & 개발github.com

aipoch/remote-compute-ssh

SSH 원격 컴퓨팅을 평가하고 활용하여 GPU, 고메모리, 병렬, 배치, 모델 추론, 생물정보학 또는 기타 장기 실행 과학 작업을 실행할 위치를 선택하기 전에 사용합니다. 짧은 원격 명령과 자동 수확 및 분석을 지원하는 비동기 작업을 지원합니다.

remote-compute-ssh란 무엇인가요?

이 스킬은 SSH를 통한 원격 컴퓨팅을 담당하며, 직접 실행과 Slurm 제출을 모두 지원합니다. 호스트 목록 조회, 핸들 생성, 짧은 원격 명령 실행(callCommand), 호스트 지식 문서 읽기/쓰기, 그리고 전체 비동기 작업 수명 주기(제출 → job_id 저장 → ID로 논블로킹 스냅샷 읽기 → 수확 → 분석 턴 → 아티팩트 게시)를 포함합니다. 주로 클로드 코드, 커서, 코덱스 등 AI 에이전트 환경에서 과학 컴퓨팅 워크로드를 관리하는 개발자에게 유용하며, host.compute API를 통해 제어-평면 REPL 커널에서만 작동합니다. 비동기 작업은 submitJob으로 시작되며, 작업 완료 시 자동으로 결과를 수확하고 새로운 분석 턴을 시작하거나 사용자가 저장된 job_id로 상태를 확인할 수 있습니다. Slurm 모드에서는 sbatch를 통해 작업을 제출하며, Open-Science가 스케줄러 상태 폴링, 취소, 수확을 관리하므로 사용자가 직접 squeue나 scancel을 호출할 필요가 없습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/aipoch/open-science/tree/HEAD/resources/skills/remote-compute-ssh

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

이 스킬은 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>')

// 짧은 원격 명령 실행 (승인 거부/호스트 연결 불가/시간 초과 시 오류 발생)
const result = await c.callCommand('<셸 명령>', '<승인 카드용 한 줄 의도>', {
  loginShell: true, // 기본값: true — 로그인 프로필을 실행한 다음 읽을 수 있는 ~/.bashrc를 실행한 후 이 명령 실행
  timeoutSeconds: 60 // 선택 사항 — 생략 시 호스트가 자체 기본값(60초) 적용
})
// result → { exit_code, stdout, stderr, truncated }

// 영구 작업 지침과 독립적인 리소스 프로브 스냅샷을 읽습니다.
// doc은 항상 정확히 저장된 텍스트입니다 (명령어가 저장되기 전에는 '' 포함).
// probe는 이 호스트가 한 번도 프로브된 적이 없으면 명시적으로 null입니다.
const info = await host.compute.details('ssh:<alias>', { mode: 'read' })

// 영구 호스트 지식 문서에 메모 추가 (에이전트가 작성, 32KB 제한 적용).
// 추가는 doc만 변경합니다. 프로브 관찰 내용을 복사하거나 변경하지 않습니다.
await host.compute.details('ssh:<alias>', {
  mode: 'append',
  text: '\n## Note\n<date>에 X를 학습함'
})

// 또는 전체 호스트 지식 문서를 교체합니다. 교체하기 전에 다시 읽으세요.
// 특히 위에서 추가한 경우: oldText는 영구 문서와 정확히 일치해야 합니다.
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는 비대화형 셸에 대해 의도적으로 일찍 반환될 수 있으므로, 이러한 가드 이후에 선언된 변수는 사용할 수 없습니다. .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(
  '<승인 카드용 한 줄 의도>', // 승인 카드에 표시됨
  '<셸 명령>', // 원격으로 실행할 명령
  {
    environment: 'protein-gpu', // 선택적 논리적 이름, 아래 환경 활성화 참조
    timeoutSeconds: 3600, // 선택 사항, 기본값 24시간, 최대 7일
    inputs: [
      { src: 'in.dat', dstFilename: 'in.dat' }, // 에이전트 세션 워크스페이스 파일 스테이징
      { remotePath: 'ssh:<alias>/<abs_path>' } // 원격 파일 링크 (전송 없음)
    ],
    outputs: [
      '*.result', // featured (기본 가시성)
      { glob: '*.json', visibility: 'featured' }, // 명시적으로 featured
      { glob: '*.log', visibility: 'hidden' }, // 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로 제출합니다. 클러스터에 필요한 #SBATCH 지시문을 command 상단에 넣으세요. 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가 포함됩니다. 보류 중인 이유나 지연된 회계 행이 워크로드 실패를 의미하지는 않습니다. 제출이 확인되지 않은 경우 다시 제출할지 결정하기 전에 보고된 작업 ID와 공급자 진단을 사용하세요. Open-Science는 자동으로 중복을 제출하지 않습니다.

환경 활성화

선택적 environment 값은 셸 명령이 아닌 논리적 이름입니다. Open-Science는 직접 및 Slurm 작업의 경우 워크로드 전에 ~/.open-science/environments/<name>.sh를 소싱합니다. 이름은 1~64자의 문자, 숫자, 마침표, 밑줄 또는 하이픈이며 문자나 숫자로 시작해야 합니다. 파일과 파일이 참조하는 모든 소프트웨어/캐시 경로는 실행 노드에 표시되어야 합니다.

이 활성화 파일이 없다고 제출이 보고되면 Compute Environment Setup Skill을 로드하여 사용자 또는 호스트 관리자가 Open-Science 외부에서 실행할 정확한 설정, 복구 및 제거 지침을 준비하세요. 사용자가 계획을 적용한 후 사용자 관리 활성화의 유효성을 검사한 다음 재시도하세요. conda 이름을 추측하거나, 과학 작업에 인라인 설치를 추가하거나, .bashrc에 활성화를 숨기지 마세요. 명령이 의도적으로 호스트의 기본 환경을 사용하는 경우 environment를 생략하세요.

수확 안전 경계

  • 선언된 출력 파일은 stdout 및 stderr보다 먼저 선택됩니다. 로그는 남은 작업별 예산을 사용합니다.
  • 앱은 모델이 제공한 파일당 100MiB 또는 작업당 500MiB를 초과하는 제한을 거부합니다.
  • 수확은 또한 2GiB의 고정된 여유 로컬 디스크 공간을 유지합니다. 맞지 않는 파일은 원격에 남아 있습니다.

동작 경계

  • 작업이 실행되는 동안: 대화는 열려 있습니다. 사용자는 메시지를 보낼 수 있습니다. 다른 작업을 처리할 수 있습니다. 각 상태/결과 쿼리는 현재 로컬 스냅샷으로 즉시 반환됩니다.
  • 작업이 완료되면: 터미널 결과를 적극적으로 읽지 않은 경우 앱이 자동으로 새 분석 턴을 시작합니다. 이 폴백을 트리거하지 않습니다.

작업 상태 확인 (정보 제공용 논블로킹 읽기)

// 논블로킹 DB 읽기 — 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_poll_error?, follow_up_delivery
// }

작업 결과 읽기 (완료 또는 출력이 필요할 때)

const handle = c.attachJob(job.job_id)
const r = await handle.result()
// r → {
//   job_id, scheduler_job_id?, status, result_final, cancellation?, exit_code,
//   error?, last_poll_error?, follow_up_delivery,
//   stdout?, stderr?,
//   output_files: [
//     { filepath, size_bytes, visibility, residency, left_on_remote }
//   ]
// }

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

관련 스킬