Python·Colab에서 만든 결과를 연구팀이 읽고, 코드 출처를 확인하고, 보고서에 재사용하는 방법을 처음부터 설명합니다. 이 안내의 Python 문법은
luna_repro SDK 0.3.0, 결과 계약 luna.repro.page.v1 기준입니다.1. 이 기능으로 무엇을 하나요?
연구 코드는 Colab·내 PC·자체 서버 등 현재 사용하던 곳에서 실행합니다. 코드가 만든 숫자, 표, 이미지, 설명 중 필요한 것만 골라 LUNA에 보냅니다. LUNA는 선택한 내용을 섹션으로 정리하고 고유한 결과 페이지 주소와 결과 버전을 만듭니다. 같은 연구실의 여러 결과에서 섹션을 골라 보고서를 작성할 수 있습니다.
예를 들어 추론 코드가
metrics, comparison_df, figure를 만들었다면, 뒤에 등록 셀을 추가하여 정량 평가·비교표·시각 결과를 한 페이지에 모읍니다. 실제 계산 위치의 링크를 함께 넣으면 동료가 코드와 노트북을 확인할 수 있습니다. 모델·원본 데이터·노트북 전체를 올릴 필요는 없습니다.결과 등록은 학습·추론·GPU·독립 검증을 실행하지 않습니다. 실행용 링크를 열어도 코드가 자동 실행되는 것은 아닙니다. 외부 실행 환경의 계정·데이터·모델·의존성과 실행 절차는 연구자가 준비합니다. 결과를 등록했다는 사실과 연구가 성공했다는 판단은 구분합니다.
처음에는 다음 순서를 권합니다.
1. 완성 예시에서 페이지 모양과 섹션을 확인합니다.
2. 설치 없는 합성 예제를 자신의 프로젝트에 만들어 봅니다.
3. SDK를 설치하고 오프라인 따라하기를 실행합니다.
4. 결과 연결의 연결 셀 복사를 실행하고 브라우저에서 승인합니다. 마지막에
repro.select()로 필요한 합성 결과를 고릅니다.5. 결과의 섹션을 모아 보고서를 저장합니다.
6. 자신의 연구 코드에서 작은 결과 하나부터 등록합니다.
2. 먼저 알아둘 이름과 접근 권한
| 이름 | 의미 | 예 |
|---|---|---|
| 프로젝트 UUID | 결과를 보낼 프로젝트의 식별자. 비밀 키와 다릅니다. | 연결 화면에 표시되는 UUID |
| 연결 키 | 발급자와 한 프로젝트 범위로 등록·조회하는 비밀 값 | 숨김 입력창으로만 전달 |
| 결과 페이지 | 한 묶음의 설명·지표·표·이미지 | 한 추론 실행의 결과 |
| 섹션 | 페이지 안에서 링크·보고서 선택의 단위 | quality, render |
| 블록 | 섹션 안의 개별 내용 | 텍스트, 지표, 표, 이미지 |
| 결과 버전 | 등록 당시 내용을 보존한 불변 스냅샷 | v1, v2 |
| run_id | 생산자가 구분하는 실행 식별자 | 새 실행이면 새 UUID |
| request_id | 전송 재시도를 구분하는 요청 식별자 | SDK가 관리 |
| 조합 보고서 | 여러 고정 버전 섹션을 모은 보고서 | 두 실험의 평가와 그림 비교 |
| outbox | 아직 전송하지 못한 선택 결과를 보관하는 로컬 폴더 | .luna-repro/outbox |
새 결과는 나만 보기로 시작합니다. 링크를 복사했다고 다른 사람이 자동으로 볼 수 있지는 않습니다. 열람자는 자신의 로그인과 현재 프로젝트·자료 접근 권한을 사용합니다. 작성자의 연결 키를 팀원에게 나눠주지 마세요. 운영자가 계정·프로젝트 이용을 허용한 사용자만 해당 기능을 사용할 수 있습니다.
하나의 연결 키는 같은 프로젝트의 여러 결과에 재사용할 수 있습니다. 보고서마다 새로 발급하지 않습니다. 프로젝트가 다르면 그 프로젝트의 연결 키가 필요합니다. 프로젝트 관리자가 되어도 다른 사람이 발급한 키를 볼 수 있는 것은 아닙니다.
3. 설치 없이 완성 모양부터 확인하기
1. 완성 예시 보기를 엽니다. 표시된 데이터는 합성 교육용입니다.
2. 지표, 그래프, 표, 설명이 각각 어떻게 나타나는지 확인합니다.
3. 결과 연결에서 자신의 프로젝트를 고르고 선택을 누릅니다.
4. 합성 예제로 체험하기를 누릅니다. 선택한 프로젝트에 나만 볼 수 있는 결과 두 개를 만드는 명시적인 동작입니다. 연결 키나 SDK 설치는 필요하지 않습니다.
5. 안내에 나타난 baseline과 smoothed 결과 링크를 각각 엽니다.
6. 각 결과에서 결과 선택으로 필요한 섹션을 담고 선택 바를 통해 보고서 작성으로 진행합니다.
이 브라우저 예제는 잡음이 섞인 신호와 이동평균을 비교합니다. 표본120개, seed20261011이며 baseline RMSE는 약0.26832629, smoothed는 약0.11535325입니다. 숫자는 실제 합성 CPU 계산 결과이고 Pasa·Teeth3DS+의 연구 성능이 아닙니다. 같은 계정·프로젝트에서 다시 체험하면 기존 예제를 재사용합니다.
아래에서 실행하는 walkthrough 예제는 다른 합성 계산입니다. 6개 값의 오프셋을 보정하며 MAE/RMSE가0.5에서 약0.1로 바뀝니다. 두 예제의 수치를 서로 비교하지 마세요.
4. 프로젝트와 연결 키를 준비하기
연구 코드가 실행되는 환경에서 한 번 연결하고, 같은 프로젝트의 여러 결과에 재사용합니다. 브라우저 승인 연결이 기본이며 키를 노트북에 복사할 필요가 없습니다.
1. 보고서 → 재현성 결과 → 결과 연결에서 프로젝트를 선택합니다.
2. 연결 셀 복사를 눌러 기존 노트북의 첫 셀 또는 Python 파일의 시작 부분에 붙여 넣습니다. 이 셀은 해시가 고정된 SDK를 준비하고 선택한 프로젝트의 브라우저 연결을 시작합니다. 설치를 직접 관리하려면 접힌 설치 도움말의 명령을 사용합니다.
3. SDK가 이미 준비되었다면 아래 코드로도 연결할 수 있습니다. 프로젝트 UUID는 선택한 프로젝트 값으로 바꿉니다.
import luna_repro as repro
repro.connect("실제-프로젝트-UUID", label="내 Colab")4. 표시된 승인 링크를 브라우저에서 엽니다. 현재 로그인 계정, 프로젝트와 확인 코드를 대조한 뒤 승인합니다. Colab·원격 서버에서는 자동으로 탭이 열리지 않아도 표시된 링크를 직접 열 수 있습니다.
5. 실행 중인 Python이 승인 완료를 받아 연결합니다. 연결만으로 결과를 전송하지 않습니다. 연결 키는 현재 Python 메모리에 보관되며 노트북 출력에 표시하지 않습니다. 같은 프로세스의 유효한 연결은 재사용합니다.
런타임·Python 프로세스를 다시 시작하면 다시 연결해야 합니다. 만료·해제·프로젝트 접근 종료 때도 현재 권한을 확인합니다. 승인 대기 종료는 연결 성공이 아니며, 결과 전송도 별도로 성공 영수증을 확인해야 합니다. 모르는 프로그램에서 시작된 승인이나 코드가 일치하지 않는 요청은 승인하지 않습니다.
브라우저 승인을 사용할 수 없는 비대화형 서버는 기존 수동 키 방식을 사용합니다. 연결 관리 → 새 연결 키 만들기에서 이름·만료를 지정하고 원문이 한 번 표시될 때 안전한 비밀 저장소에 보관합니다. 수동 키의 기본 유효 기간은 30일이며 1–90일로 선택합니다. 키를 노트북 코드·출력·Git·스크린샷·보고서·공유 채팅에 적지 않습니다. 승인된 비밀 관리 도구가
LUNA_REPRO_TOKEN 환경 변수로 주입하도록 하거나 getpass.getpass()로 숨김 입력을 받으세요. 이 방식의 Page/Section 예제도 계속 동작합니다.import getpass
import luna_repro as repro
repro.configure(project="실제-프로젝트-UUID",
endpoint="https://lunalab-ai.com",
token=getpass.getpass("LUNA 연결 키: "))configure()는 로컬 설정이며 브라우저 승인·권한 검증·전송을 대신하지 않습니다. connect()는 브라우저 승인으로 연결하고, publish()는 선택한 결과를 전송합니다.키 관리 위치는 설정 → 재현성 연결, 재현성 결과 → 연결 관리, 프로젝트 설정 → 연결·연구 도구 → 연결 관리입니다. 발급자와 프로젝트에 묶인 키를 여러 결과에 재사용하며 보고서마다 새로 만들지 않습니다. 프로젝트 관리자라는 이유로 다른 사람의 키를 볼 수는 없습니다. 해제해도 기존 결과·보고서·버전은 보존됩니다. 최근 사용·최근 결과 등록은 실제 성공 시각이며 키 발급만으로 채워지지 않습니다.
5. 공개 SDK와 실습 파일 준비하기
SDK의 공개 저장소는 lunalab-ai/luna-repro-sdk입니다. 일반 설치에는 플랫폼 전체 소스나 GitHub 로그인이 필요하지 않습니다. SDK 코드·합성 예제 공개와 내 연구 결과 공개는 별개입니다. 연결 키, 프로젝트 자료, 연구 결과와 데이터는 이 저장소에 포함되지 않습니다. 기존 연결 키·결과 ID·버전·보고서·현재 권한은 그대로 사용합니다.
플랫폼에서 검증한 SDK 0.3.0 릴리스와 아래 SHA-256이 포함된 wheel 설치 명령을 사용하세요.
pip install은 SDK를 설치할 뿐 예제를 실행하거나 결과를 전송하지 않습니다. 공개 SDK 다운로드에는 인터넷이 필요하지만 LUNA 연결 키는 필요하지 않습니다. 플랫폼에 결과를 보낼 때만 본인 프로젝트의 키와 현재 권한을 사용합니다.가장 간단한 시작 방법은 Colab 예제 열기입니다. PC·서버에서는 walkthrough.py를 열어 Download raw file로 저장할 수 있습니다. wheel에는 예제가 설치되지 않으므로 코드 파일은 따로 준비하세요. SDK 설치·업그레이드 안내에서 SDK만의 설치 문제를 확인하고, 이 매뉴얼에서는 플랫폼 연결·결과·보고서·Notion까지 이어갑니다.
별도 보관용 설명서는 국문 HTML, 국문 Markdown, 한영 가이드·예제 ZIP으로 내려받습니다. 가이드 ZIP을 풀면
examples/walkthrough.py와 examples/walkthrough.ipynb가 있습니다. HTML은 인터넷 없이 읽고 인쇄할 수 있습니다. 안내 파일에는 실제 키나 연구 데이터가 없습니다.5.1 기존 ZIP 방식도 계속 사용할 수 있습니다
Python SDK ZIP은 기존 로그인 경로에서 제공합니다. 로컬 파일 설치가 필요한 환경은 이 ZIP을 내려받아
python -m pip install ./luna-repro-sdk.zip으로 설치할 수 있습니다. Colab에서는 파일 패널에 ZIP을 올린 뒤 %pip install /content/luna-repro-sdk.zip을 사용합니다. 매번 ZIP을 업로드할 필요가 없는 위 공개 wheel 방식이 기본 안내입니다.SDK ZIP을 풀면
luna-repro-sdk/ 아래 설치 코드와 examples/walkthrough.py, walkthrough.ipynb, toy.py, last_cell.ipynb, incremental.ipynb, pasa_adapter.py가 있습니다. 가이드 ZIP은 examples/, SDK ZIP은 luna-repro-sdk/examples/이므로 실제 푼 위치에 맞춰 실행 경로를 고르세요. 아래 PC 실습은 가이드 ZIP의 examples/ 경로를 사용합니다.6. Colab에서 따라하기
새 간편 흐름은 quickstart 노트북과 29절을 먼저 사용하세요. 기본 실행은 CPU 합성 값·실패한 검사 예시·로컬 미리보기 저장입니다. 실제 프로젝트 UUID로 바꾼 뒤
CONNECT=True를 명시해야 브라우저 승인을 시작하며, PUBLISH=True는 별도의 전송 선택입니다. 체크박스를 보려면 SHOW_SELECTOR=True를 사용합니다. 아래의 기존 walkthrough는 두 결과를 비교하며 수동 키 입력도 연습하는 호환 실습입니다.6.1 설치
1. SDK 0.3.0 Colab 예제를 엽니다. 필요하면 본인 Drive에 사본을 저장합니다. 본인 사본에 키를 기록하지 마세요.
2. 첫 설치 셀을 실행합니다. SDK 0.3.0이 이미 있으면 건너뛰고, 없거나 다른 버전이면 고정 wheel을 인터넷으로 설치합니다. 이미 다른 버전을 import했다면 런타임 재시작 안내가 나옵니다. ZIP 파일 업로드는 필요하지 않습니다. 직접 설치하거나 기존 연구 노트북에 적용할 때는 새 코드 셀에서 아래 명령을 사용하세요.
%pip install --disable-pip-version-check --no-deps "https://github.com/lunalab-ai/luna-repro-sdk/releases/download/v0.3.0/luna_repro-0.3.0-py3-none-any.whl#sha256=4fc3b6a0ff1d78dbb2ace0ea08dcedc3794e14f3930d0c60f29c42fbb04e2489"3. 아래 셀로 같은 런타임의 설치를 확인합니다.
0.3.0이 표시되어야 합니다.import luna_repro
print(luna_repro.__version__)4. 다른 버전이 표시되면 파일과 outbox를 먼저 보존하고 런타임을 재시작한 뒤 설치·확인을 다시 합니다. 이미 import한 모듈은 설치만 바꿔도 메모리에 남을 수 있습니다.
5. 노트북을 위에서 아래로 실행합니다. 기본
PUBLISH = False, RETRY = False이므로 계산과 로컬 저장만 진행합니다. 설치는 인터넷을 쓰며, 이 합성 실습은 CPU로 실행하므로 GPU 선택이 필요하지 않습니다.6.2 결과 확인
baseline은 MAE/RMSE 0.5, corrected는 약 0.1, samples는 6이어야 합니다.
0.09999999999999998처럼 표시되는 것은 이 예제의 부동소수점 표현 차이입니다. 출력에 Saved:와 .luna-repro/walkthrough-notebook/.../baseline.json, corrected.json 경로가 나타납니다. 새 실행마다 하위 폴더를 만들어 이전 저장 파일을 보존합니다.6.3 실제 플랫폼으로 보내기
1. setup 셀의
PROJECT_ID를 연결 화면의 실제 프로젝트 UUID로 바꿉니다. 연습용 UUID 그대로는 전송하지 않습니다.2. setup·계산·저장 셀을 다시 실행하여 그 프로젝트에 해당하는 Page 객체를 만듭니다.
3. 선택적 등록 셀의
PUBLISH = False를 True로 바꾸고 그 셀만 실행합니다.4. 숨김 입력창에 연결 키를 넣습니다. 키가 출력되지 않는 것이 정상입니다.
5.
Published:와 URL·버전이 나타나는지 확인합니다. Pending:이면 아직 플랫폼 등록 성공이 아닙니다.6. URL을 열어 지표·그래프·6행 표·해석을 확인합니다.
7. 실습 후
PUBLISH = False로 되돌려 나중의 모두 실행에서 의도하지 않은 전송을 피합니다.Colab의
/content와 환경 변수는 런타임 재시작·종료 때 사라질 수 있습니다. 필요한 결과 JSON과 outbox를 종료 전에 본인이 허용한 비공개 위치로 보존하고 키는 별도로 관리하세요. Colab의 localhost는 내 PC의 서버가 아니므로 endpoint에는 실제 LUNA HTTPS 주소를 사용합니다. Colab의 무료 자원·가용 시간·GPU 제공을 보장하지 않습니다.7. 내 PC·자체 서버에서 따라하기
Python 3.10 이상을 사용합니다. 기존 연구 환경이 있다면 활성화한 같은 Python에 아래 한 줄로 설치하세요. 기존 연구 코드의 마지막 셀에 등록 코드를 붙이려고 새 프로젝트나 가상환경을 의무적으로 만들 필요는 없습니다.
python -m pip install --disable-pip-version-check --no-deps "https://github.com/lunalab-ai/luna-repro-sdk/releases/download/v0.3.0/luna_repro-0.3.0-py3-none-any.whl#sha256=4fc3b6a0ff1d78dbb2ace0ea08dcedc3794e14f3930d0c60f29c42fbb04e2489"python -c "import luna_repro; print(luna_repro.__version__)"예상 버전은
0.3.0입니다. 시스템 Python에 무작정 설치하지 말고 python이 본인 연구 환경을 가리키는지 먼저 확인하세요. Windows도 활성화한 환경에서는 python -m pip를 사용합니다. 새 환경에서 시작하려면 다음 선택 단계를 따릅니다.7.1 처음 시작할 때만: 프로젝트 가상환경
새 실습 폴더에서 Windows PowerShell:
py -m venv .venv
.\.venv\Scripts\Activate.ps1Linux/macOS 셸:
python3 -m venv .venv
source .venv/bin/activate이후 위 설치 명령을 실행하세요. PowerShell 활성화가 차단되면 설치·실행 명령의
python을 .\.venv\Scripts\python.exe로 바꾸면 됩니다. 실행 정책을 바꿀 필요는 없습니다. Linux는 .venv/bin/python을 직접 사용할 수도 있습니다.7.2 합성 실습 실행
가이드 ZIP을 현재 폴더에 풀었다면:
python ./examples/walkthrough.pyPython 파일만 저장했다면
python ./walkthrough.py를 사용합니다. SDK ZIP을 풀었다면 python ./luna-repro-sdk/examples/walkthrough.py입니다. 기본 실행은 네트워크 없이 두 결과 JSON을 .luna-repro/walkthrough/새실행폴더/에 저장합니다. baseline MAE/RMSE 0.5, corrected 약 0.1을 확인합니다.7.3 실제 플랫폼으로 보내기
endpoint와 프로젝트 UUID를 지정하고
--publish를 붙일 때만 전송합니다. 아래 실제-프로젝트-UUID를 연결 화면 값으로 바꿉니다. 연결 키는 명령 인수에 넣지 마세요.$env:LUNA_REPRO_ENDPOINT = "https://lunalab-ai.com"
python ./examples/walkthrough.py --project "실제-프로젝트-UUID" --publishexport LUNA_REPRO_ENDPOINT="https://lunalab-ai.com"
python ./examples/walkthrough.py --project "실제-프로젝트-UUID" --publish토큰 환경 변수가 없으면 숨김 입력을 받습니다. 비대화형 서버는 승인된 비밀 관리 도구로 환경 변수를 주입합니다. CLI 종료 코드 0과
Published를 함께 확인합니다. 일부 결과가 pending이면 CLI는 1을 반환하며 outbox를 보존합니다.7.4 SDK·플랫폼·결과 버전과 업그레이드·복구
| 구분 | 이 안내의 기준 | 의미 |
|---|---|---|
| SDK 버전 | 0.3.0 | 내 Python에 설치한 클라이언트 코드 |
| 결과 데이터 계약 | luna.repro.page.v1 | SDK와 플랫폼이 주고받는 결과 형식 |
| 플랫폼 버전 | 앱 소개의 배포 버전 | 웹·API 서버의 릴리스; SDK와 독립적으로 관리 |
화면의 결과
v1, v2는 별도로 저장한 결과 내용 버전입니다. SDK를 설치하거나 바꾼다고 기존 결과·키·보고서가 삭제되거나 자동 갱신되지 않습니다.새 SDK 릴리스가 생겨도 위 명령은 자동으로 따라가지 않습니다. 변경 전에
luna_repro.__version__과 설치에 사용한 wheel URL·SHA-256 또는 이전 ZIP을 기록·보관하세요. 새 가상환경에서 합성 예제를 먼저 확인한 다음, 검증한 새 릴리스의 해시 고정 명령을 사용합니다. main 브랜치에서 바로 설치하거나 버전을 생략하여 갱신하지 마세요.이후 다른 버전을 시험하다가 이 안내의 0.3.0로 돌아오려면, 결과 JSON·outbox를 보존하고 같은 환경에서 아래 명령으로 다시 설치합니다. 실행 중인 Python 프로세스·노트북 커널은 파일을 보존한 뒤 다시 시작하세요.
python -m pip install --force-reinstall --disable-pip-version-check --no-deps "https://github.com/lunalab-ai/luna-repro-sdk/releases/download/v0.3.0/luna_repro-0.3.0-py3-none-any.whl#sha256=4fc3b6a0ff1d78dbb2ace0ea08dcedc3794e14f3930d0c60f29c42fbb04e2489"그보다 이전 버전으로 복구할 때는 실제로 보관한 해당 버전의 wheel·SHA-256 또는 ZIP을 사용하고, 그 버전이 새 코드 출처 기능을 지원하는지 확인해야 합니다. SDK 복구는 서버 데이터베이스나 이미 저장된 결과를 과거로 되돌리는 작업이 아닙니다. 기존 로컬 결과를 지우거나 키를 새로 발급할 필요는 없습니다.
공개 SDK와 CPU 합성 실습을 시작하려고 Hugging Face·GitHub Actions·RunPod 같은 별도 유료 실행 서비스를 연결할 필요는 없습니다. 본인의 서버·네트워크·저장 공간·선택한 Colab 자원과 AI 분석 비용은 별도입니다.
8. 가장 작은 완전한 Python 예제
SDK 설치 후 아래 셀은 외부 파일·pandas·matplotlib 없이 그대로 실행할 수 있습니다. 연습용 UUID로 오프라인 저장만 합니다.
from pathlib import Path
import math
import luna_repro as repro
project_id = "12345678-1234-5678-1234-567812345678" # 오프라인 연습용
reference = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]
prediction = [value + 0.5 for value in reference]
errors = [actual - expected for actual, expected in zip(prediction, reference)]
metrics = {
"MAE": sum(abs(error) for error in errors) / len(errors),
"RMSE": math.sqrt(sum(error ** 2 for error in errors) / len(errors)),
"samples": len(reference),
}
rows = [[i, target, actual] for i, (target, actual)
in enumerate(zip(reference, prediction))]
page = repro.page(
project_id,
"첫 합성 결과",
description="6개 합성 값으로 등록 문법을 연습합니다.",
metadata={"tags": ["synthetic", "practice"]},
evidence={"origin": "synthetic", "execution_status": "completed",
"evaluation_status": "completed"},
)
page.section("conditions", "계산 조건").text("기준 값에 0.5를 더했습니다.")
page.section("quality", "정량 결과").metrics(metrics).table(
["index", "reference", "prediction"], rows
)
output = Path(".luna-repro") / ("practice-" + page.page_id + ".json")
page.save(output)
print(metrics) # MAE=0.5, RMSE=0.5, samples=6
print("로컬 저장:", output)실제로 보내려면 첫 줄의
project_id를 실제 UUID로 바꾸고 Page 생성부터 다시 실행합니다. 다음 연결 셀은 사용자가 명시적으로 실행할 때 플랫폼 전송을 합니다.if page.project_id == "12345678-1234-5678-1234-567812345678":
raise ValueError('실제 프로젝트 UUID로 Page를 다시 만들어 주세요.')
repro.connect(page.project_id, endpoint="https://lunalab-ai.com")
receipt = repro.publish(page)
if receipt["status"] == "published":
print("Published:", receipt["url"], "revision:", receipt["revision"])
else:
print("Pending:", receipt["code"], receipt["message"])
print("Preserved:", receipt.get("outbox_path"))9. 기존 연구 코드의 마지막 셀에 붙이기
기존 계산 코드를 실행한 뒤 마지막 셀에서 결과를 고릅니다. 앞에서
repro.connect()로 프로젝트를 연결했다면 기본 흐름은 다음과 같습니다.import luna_repro as repro
selection = repro.select()추천 목록에서 필요한 결과만 선택하고 전체 미리보기로 지표·표·그림·설명과 출처를 확인합니다. 추천과 미리보기는 로컬 단계이며 자동 전송이 아닙니다. 전체 전역 변수나 원본 데이터 폴더를 업로드하지 않습니다. 후보로 보인다는 이유만으로 연구 자료가 게시되지는 않습니다. 선택·전송의 자세한 문법과
.py 차이는 29절을 참고하세요.보낼 결과를 이미 알고 있다면 명시형 한 줄도 사용할 수 있습니다. 아래
metrics, comparison_df, figure는 기존 연구 코드가 만든 객체입니다. 없는 변수는 제거하세요. 이 줄은 실제 전송입니다.receipt = repro.publish(metrics, comparison_df, figure, title="내 실험 결과")
print(receipt["status"], receipt.get("url"))섹션 이름·설명·실행 상태·계산 코드 출처를 정교하게 지정하려면 기존 Page/Section 문법을 그대로 사용합니다.
page = repro.page(project_id, "내 실험 결과")
page.section("quality", "정량 평가").metrics(metrics)
page.section("comparison", "방법 비교").table(comparison_df)
page.section("render", "시각 결과").figure(figure, "선택한 결과 그림")
receipt = repro.publish(page) # connect/configure의 현재 연결 사용기본 결과는 실행·평가 성공을 자동 단정하지 않습니다. 실제 이번 실행을 기록했다면
evidence={"origin": "executed", "execution_status": "completed", "evaluation_status": "not_run"}처럼 Page에 명시하고, 실제 평가까지 수행한 경우에만 평가 상태를 바꿉니다. 예전 산출물을 불러왔다면 origin="imported"입니다.마지막 셀은 이미 닫힌 그림, 사라진 변수, 저장하지 않은 출력, 실제 계산 위치를 복원하지 못합니다. 필요한 Tensor 값은 숫자로 변환하고 원하는 이미지 파일을 선택하세요. 나중에 닫힐 matplotlib 그림은 계산 전에 선택적
capture() 범위를 열거나 Figure 객체·파일을 직접 보존해야 합니다. 자동 추천은 실행 환경에 남은 지원 객체의 후보를 찾는 기능이며 과거 셀 전체 수집이나 정확한 계산 셀 추론이 아닙니다.10. 실행 중 여러 셀에서 쌓고 중간 버전 남기기
처음에 Page 객체를 만들고 여러 셀에서 같은 객체에 추가합니다. 아래는 오프라인으로도 실행 가능한 독립 예제입니다.
import luna_repro as repro
project_id = "12345678-1234-5678-1234-567812345678" # 전송 전 실제 UUID로 교체
page = repro.page(project_id, "단계별 합성 실험", evidence={
"origin": "synthetic", "execution_status": "unknown",
"evaluation_status": "not_run",
})
page.section("setup", "준비").text("기준 [1, 2, 3], 예측 [1.2, 1.8, 3.1]")
page.save(".luna-repro/incremental-example-partial.json")
reference = [1.0, 2.0, 3.0]
prediction = [1.2, 1.8, 3.1]
mae = sum(abs(a - b) for a, b in zip(reference, prediction)) / len(reference)
page.section("quality", "평가").metrics({"MAE": mae})
page.evidence.update(execution_status="completed", evaluation_status="completed")
page.save(".luna-repro/incremental-example-complete.json")연결을 준비한 실제 프로젝트에서 중간·최종 시점에
page.publish()를 각각 실행하면 같은 페이지에 새 결과 버전이 쌓입니다. save()만 실행한 파일은 플랫폼 버전이 아닙니다.같은 섹션 key는 내용 교체가 아니라 블록 추가입니다.
page.section("quality").metrics(...) 셀을 두 번 실행하면 지표 블록도 두 개 생깁니다. 새 실험은 새 Page로 기록하거나 새 명시적 섹션 key를 사용합니다. 셀 재실행으로 중복 블록을 만들었으면 아직 필요한 자료를 확인한 뒤 Page 생성 셀부터 다시 구성합니다. SDK는 기존 블록을 자동 삭제하지 않습니다.새 Python 세션에서 같은 페이지의 새 실행을 남기려면 보관한
page_id를 전달하고 새 run_id를 사용합니다. 이때 새 객체의 섹션은 비어 있으므로 최종 버전에 포함할 내용을 모두 다시 구성해야 합니다. 이전 버전은 보존되지만 자동으로 새 객체에 복사되지 않습니다.import uuid
# saved_page_id는 이전 성공 영수증의 page_id입니다.
next_run = repro.page(project_id, "후속 실행", page_id=saved_page_id,
run_id=str(uuid.uuid4()))
next_run.section("notes", "이번 실행 범위").text("이번에 선택해 등록할 결과입니다.")11. 블록별 문법과 실무 예시
다음 예시는 Page를 만든 뒤 호출하는 문법입니다. 각 메서드는 같은 Section을 반환하므로
.text(...).metrics(...).table(...)처럼 이어 붙일 수 있습니다.11.1 설명
page.section("notes", "설명", description="독자가 먼저 알아야 할 조건").text(
"입력 6개를 사용했습니다.\n이 값은 합성 예제입니다."
)text는 일반 텍스트입니다. HTML 실행이나 임의 Markdown 차트 렌더링을 제공하지 않습니다. 줄바꿈은 보존됩니다. 단위·입력·전처리·평가 범위·실패 조건을 적어 두면 숫자 해석에 도움이 됩니다.
11.2 지표
page.section("quality", "정량 평가").metrics({
"MAE (mm)": 0.25,
"samples": 24,
"inference_seconds": 1.8,
})이름은 단위가 드러나게 정합니다. 유한한 숫자만 허용합니다. 문자열
"0.25", bool, NaN, Infinity는 거절합니다. Tensor 값은 연구 코드에서 float(value.item())처럼 필요한 스칼라로 바꾸어 전달합니다. 시간 일부만 측정했다면 전체 파이프라인 시간이라고 표시하지 않습니다.11.3 표와 pandas
page.section("table", "사례별 결과").table(
["case", "score", "passed", "comment"],
[["A", 0.25, True, "확인"], ["B", None, False, "평가 미실시"]],
)행마다 열 개수가 같아야 합니다. 숫자·문자열·bool·None만 들어갈 수 있습니다. 표 안에 리스트·딕셔너리·Tensor 객체를 직접 넣지 않습니다.
pandas는 연구 코드에서 이미 사용할 때만 필요한 선택 의존성입니다.
table(df)는 index를 자동 포함하지 않습니다. 다음 예시는 기존 df가 있을 때 적용합니다.import pandas as pd # pandas를 사용하는 연구 환경에서만 필요
selected = df[["case", "score"]].copy()
selected = selected.astype(object).where(pd.notna(selected), None)
page.section("comparison", "비교표").table(selected)
# index 자체가 중요하면 selected.reset_index()를 전달합니다.누락 수치를0으로 바꾸어 평가한 것처럼 보이게 하지 마세요. None 또는 별도 설명으로 남깁니다. 화면 미리보기·복사는 처음100행·20열까지만 보이며 전체 표는 AI 검토 자료 JSON에서 확인할 수 있습니다.
11.4 PNG·JPEG 이미지
from pathlib import Path
image_path = Path("selected_render.png") # 실제 존재하는 선택 이미지
page.section("render", "정면 렌더").image(image_path, "정면에서 본 복원 결과")메모리의 PNG/JPEG bytes도 가능합니다.
# image_bytes는 연구 코드가 만든 PNG 또는 JPEG bytes입니다.
page.section("preview", "미리보기").image(image_bytes, "선택 결과", name="preview.png")폴더·SVG·HTML·PDF·동영상·3D 모델 파일을
image()에 전달하지 않습니다. 원본에 개인정보·민감 정보가 들어 있다면 연구자가 적절한 선택·가림 처리를 마친 이미지만 등록합니다. SDK가 자동 익명화하지 않습니다.11.5 matplotlib 그래프
import matplotlib.pyplot as plt # matplotlib을 사용하는 연구 환경에서만 필요
fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0.5, 1.5, 2.5], marker="o")
ax.set(xlabel="sample", ylabel="value", title="Synthetic values")
page.section("plot", "합성 그래프").figure(fig, "3개 합성 값")
plt.close(fig)figure(fig) 또는 별칭 chart(fig)는 넘긴 figure 하나를 PNG로 내보냅니다. 이미지 등록 후 figure를 닫아도 등록 객체에는 선택 이미지가 남습니다. 인터랙티브 Plotly·HTML을 직접 지원하지 않습니다. 그런 도구는 연구 코드에서 PNG/JPEG로 내보낸 파일을 선택하세요.12. 코드·노트북 셀·실행 환경 링크를 정확히 넣기
코드 출처는
source에 명시합니다. Page의 출처는 새 섹션에 사본으로 상속되고, 섹션별 출처를 주면 그 섹션이 별도 출처를 가집니다. 상속 후 Page 출처를 수정해도 이미 만든 섹션의 출처는 자동 변경되지 않습니다.등록 함수 호출 줄과 실제 계산 줄은 다릅니다. 아무것도 지정하지 않으면 SDK는 가능한 경우 등록한 파일명과 줄만 기록합니다. 노트북 셀이나 Git 커밋을 자동 추측하지 않습니다.
아래는 실제 Git 저장소 폴더에서 현재 커밋을 읽는 출처 구성 예시입니다. 프로젝트 저장소 주소와 실제 상대 경로·줄은 본인 코드에 맞춰야 합니다. dirty 상태의 수정분은 commit에 포함되지 않으므로 별도로 설명하고 필요한 소스 스냅샷을 보존합니다.
import subprocess
commit = subprocess.check_output(
["git", "rev-parse", "HEAD"], text=True
).strip()
repository_url = "https://github.com/ORG/REPO" # 실제 저장소 주소로 교체
source = {
"repository_url": repository_url,
"commit": commit,
"file": "src/inference.py", # 실제 계산 파일의 저장소 상대경로
"line_start": 40,
"line_end": 63,
"url": repository_url + "/blob/" + commit + "/src/inference.py#L40-L63",
}
page.section("quality", "정량 평가", source=source)commit에는 main, latest, EXACT-COMMIT-SHA 같은 설명용 문구를 넣을 수 없습니다. 실제 소문자40자리 또는64자리16진수만 허용합니다. 모르면 해당 필드를 생략하고 미확인 상태를 설명합니다. 나중에 검토한 최신 commit을 과거 실행 commit이라고 대신 적지 않습니다.노트북 예시는 다음과 같습니다.
NOTEBOOK-ID, REAL-CELL-ID는 실제 값으로 교체합니다.notebook_url = "https://colab.research.google.com/drive/NOTEBOOK-ID"
page.section("render", "복원 결과", source={
"file": "experiment.ipynb",
"cell_id": "REAL-CELL-ID",
"url": notebook_url + "#scrollTo=REAL-CELL-ID",
"execution_url": notebook_url,
})cell_id만 적으면 클릭 가능한 셀 주소가 자동 생성되지 않습니다. 실제 셀 링크를 url로 지정합니다. Colab 노트북의 저장된 셀 ID·링크를 확인하고 변경될 수 있는 노트북은 별도 스냅샷 hash도 보존합니다. 셀 번호18과 셀 ID는 반드시 같은 값이 아닙니다.| source 필드 | 의미·제약 |
|---|---|
| url | 해당 계산 코드·셀의 HTTPS 링크 |
| repository_url | HTTPS 저장소 링크 |
| execution_url | 사용자가 열 실행 환경 링크. 자동 실행 아님 |
| commit | 실제40/64자리 소문자16진수 commit |
| file | 저장소 상대경로. / 구분, ..·절대경로 금지 |
| line_start, line_end | 1이상10,000,000이하 정수. 끝이 시작보다 작을 수 없음 |
| cell_id | 실제 노트북 셀 식별자,160자 이하 |
| snapshot_sha256 | 실제 선택 소스 스냅샷의64자리 SHA256 |
URL에는 인증정보·query string을 넣지 않습니다. 공유 URL의
?usp=... 등도 제거한 영속 주소를 사용합니다. HTTPS 공개 호스트 이름을 사용하며 내부 IP·localhost·.local은 출처 URL로 허용하지 않습니다. 외부 링크를 기록해도 그 자료의 읽기 권한이 자동으로 공유되지는 않습니다.13. 등록 성공·결과 버전·수치 비교 확인하기
SDK의 성공 영수증에는
status, page_id, request_id, revision, url이 있습니다. status="published"가 수신 성공입니다. url은 페이지 주소이므로 보고서 근거를 고정하려면 플랫폼에서 특정 버전의 섹션 링크를 복사합니다.1. 결과 URL을 엽니다.
2. 합성/기존/실행 결과 표시와 실행·평가 상태를 확인합니다.
3. 지표의 단위, 표의 행, 이미지 캡션, 코드·실행 출처를 확인합니다.
4. 버전과 공유 설정에서 결과 버전을 선택합니다.
5. 같은 페이지의 다른 버전이 있으면 비교 버전을 선택하고 보기를 누릅니다.
수치 비교는 같은 섹션 key와 지표 이름의 현재 값에서 비교 값을 뺍니다. 어떤 지표는 낮을수록 좋고 어떤 지표는 높을수록 좋으므로 시스템이 차이를 성능 향상이라고 판정하지 않습니다. 입력·데이터 분할·단위·정렬·평가 대상이 같은지 사람이 확인해야 합니다.
기존 요청의 동일 내용 재전송은 중복 버전을 만들지 않습니다. 그러나 새 Page 객체나 새 요청 ID로 새 콘텐츠를 만들면 새 결과·버전이 될 수 있습니다. 복구 목적이라면 원본 JSON을 수정하기보다
sync를 먼저 사용합니다.14. 여러 결과로 하나의 보고서 만들기
1. 보고서 → 재현성 결과에서 첫 결과를 엽니다.
2. 필요한 섹션의 결과 선택을 누릅니다. 표시가 선택됨으로 바뀌는지 확인합니다.
3. 다른 결과 페이지로 이동하고 필요한 섹션을 더 선택합니다.
4. 선택 바에서 선택 내용을 검토하고 보고서 작성으로 이동합니다.
5. 보고서 제목과 설명·해석을 적습니다. 원본 사실과 자신의 해석을 구분합니다.
6. 위로/아래로 버튼으로 순서를 바꾸고 필요 없는 항목은 선택에서 빼기로 제거합니다.
7. 결과 미리보기를 열어 원본 페이지·프로젝트·버전·섹션을 확인합니다.
8. 플랫폼 보고서 저장을 누릅니다. 초안은 작성자 전용으로 저장됩니다.
한 보고서에는 같은 연구실의 여러 프로젝트 결과를 함께 넣을 수 있습니다. 최대40개 섹션이며 원본의 현재 접근 권한을 계속 검사합니다. 보고서 공유만으로 원본 결과의 접근 제한을 우회할 수 없습니다. 원본이 다른 사람에게 비공개이면 공유 전에 필요한 원본 공유 범위도 검토합니다.
기존 조합 보고서에 추가하려면 편집에서 결과 더 선택을 누르고 결과를 더 고른 뒤 이 보고서에 추가로 돌아옵니다. 제목·설명·순서 초안을 확인한 후 저장합니다. 섹션을 고르는 동안 기존 저장 보고서가 즉시 바뀌는 것은 아닙니다.
보고서가 참조하는 결과는 선택한 버전으로 고정됩니다. 원본에 v2가 등록되어도 v1을 담은 보고서가 자동으로 v2로 바뀌지 않습니다. 새 결과를 반영하려면 원하는 버전을 직접 선택해 보고서를 저장합니다.
15. 공유 범위와 자료 메타데이터 정리하기
결과 상세의 버전과 공유 설정 → 보기 범위에서 작성자가 나만 보기 또는 프로젝트 참여자를 선택하고 저장합니다. 프로젝트 공유도 공개 인터넷 게시가 아니며 현재 계정·프로젝트 접근 검사를 따릅니다.
과제·연구원·태그 편집에서는 기존 자료 메타데이터 관리 흐름을 사용합니다. 태그·관련 프로젝트·연구원 표시는 자료 탐색을 돕지만 그 자체로 읽기 권한을 주지는 않습니다. 결과는 자료의 재현성 분류에서도 찾을 수 있습니다.
SDK
metadata는 현재 tags만 받습니다. 과제·연구원 등 임의 필드를 추가하면 거절됩니다. 첫 결과의 태그는 자료 목록에 반영되며 이후 SDK 등록은 플랫폼에서 사람이 편집한 분류 태그를 자동 덮지 않습니다. 버전별 생산자 태그는 해당 결과 manifest에 보존됩니다.키를 해제하거나 프로젝트 접근이 종료되어도 기존 결과와 버전을 자동 삭제하지 않습니다. 이미 내려받거나 Notion에 전달된 사본은 LUNA의 접근 철회만으로 회수되지 않습니다.
16. 복사·붙여넣기와 Notion 직접 전달
16.1 복사로 옮기기
1. 섹션에서 내용·출처 복사를 누릅니다.
2. 플랫폼 보고서 편집기 또는 Notion의 원하는 위치에 붙여넣습니다.
3. 제목·표·설명·출처 링크가 원하는 형태인지 확인합니다.
4. 링크만 필요하면 공유·AI 검토 → 링크 복사를 사용합니다.
수신 앱·브라우저에 따라 HTML·이미지 붙여넣기 결과가 다릅니다. 복사 HTML의 이미지 주소는 로그인 권한이 필요한 LUNA 주소이므로 Notion에 영구 첨부가 되었다고 볼 수 없습니다. 표 미리보기와 복사도100행·20열 범위입니다. 이미지까지 외부에 보존하려면 직접 전달 흐름을 사용합니다.
16.2 Notion에 직접 넣기
1. 원하는 결과·섹션 또는 조합 보고서에서 Notion에 게시를 선택합니다. 같은 화면 안에 게시 창이 열립니다.
2. Notion 대상의 과제·프로젝트·페이지 이름을 확인합니다. 같은 프로젝트의 연결이 하나라면 미리 선택됩니다. 여러 대상이 있으면 고릅니다. 제목은 현재 결과·보고서에서 채워지고 미리보기는 자동으로 준비됩니다.
3. 그림·표·설명과 대상 페이지를 확인한 뒤 Notion에 게시를 누릅니다. 기본은 새 하위 페이지입니다. 제목 변경이나 기존 페이지 추가는 게시 옵션에서 선택합니다.
4. 같은 창에서 진행 상태를 확인하고 Notion에서 열기로 실제 페이지를 확인합니다. 창을 여는 것과 미리보기는 전송하지 않습니다.
직접 전달은 선택 이미지 원본을 올리고 Notion의 제목·문단·표·이미지 블록을 만듭니다. 기존 사람 본문을 덮어쓰지 않습니다. Notion 연결에 콘텐츠 삽입 권한이 있고 대상 페이지가 해당 연결에 공유되어 있어야 합니다. 한 번에40섹션·10이미지, 표당99행·40열 범위이며 더 큰 내용은 나누어 보냅니다. 미리보기는10분 뒤 만료되므로 만료되면 내용을 다시 검토합니다.
대기·전송 중·확인 완료·거절·불확실 상태를 구분합니다. 결과가 불확실하면 같은 내용을 반복 전송하지 말고 Notion을 먼저 확인합니다. 화면의 게시 상태 확인에 확인한 페이지 ID를 넣는 복구 절차를 따릅니다. 이미지 업로드만 중단된 경우처럼 자동 대조할 수 없는 상황도 있습니다. Notion으로 전달한 사본의 공개 범위는 Notion에서 별도로 관리합니다.
17. AI 상담·ChatGPT·Codex에서 분석 이어가기
섹션의 공유·AI 검토 → AI로 검토로 플랫폼 상담에 연결하거나 AI 검토 자료를 내려받습니다. 전체 결과 상단의 AI 검토 자료 내려받기는 고정 버전의 지표·표·설명·출처·상태를 담은 JSON입니다. 이미지 bytes·외부 소스 전체·모델을 자동 포함하지 않습니다. 이미지 주소는 현재 플랫폼 권한을 따릅니다.
다음과 같이 질문할 수 있습니다.
이 결과의 고정 버전과 코드 출처를 먼저 확인해 주세요.
평가한 입력, 단위, 누락된 조건, 실패 기록을 정리하고
숫자만으로 주장할 수 없는 결론을 구분해 주세요.
접근 가능한 실제 코드를 확인한 뒤 다음 실험과 수정안을 제안해 주세요.
아직 학습·GPU 실행·외부 게시를 시작하지 마세요.ChatGPT·Codex에서는 사용 가능한 연결 도구 또는 직접 첨부로 결과 자료를 전달합니다. 호스트에 실제로 제공되는 도구를 확인해야 하며, 링크 하나로 비공개 GitHub·Drive의 접근 권한이나 전체 코드가 자동 전달되지는 않습니다. 분석에 필요한 소스 commit·파일·관련 함수와 데이터 설명을 허용된 범위에서 함께 제공합니다.
조회·내려받기 자체는 AI를 호출하지 않습니다. 실제 AI 상담은 기존 계정 권한·예산을 사용합니다. 생성된 코드, 합성 검사, 실제 연구 실행, 독립 검증을 각각 기록합니다. AI가 제안한 수정안을 연구자가 확인하고 기존 개발 환경에서 검증한 후 새 결과 페이지로 연결하는 흐름이 좋습니다.
18. 오프라인 저장·실패 복구·키 교체
18.1 저장과 전송은 별개입니다
page.save("result.json")은 파일만 저장합니다. page.publish()는 먼저 선택 결과를 outbox에 원자적으로 저장하고 전송을 시도합니다. endpoint·키가 없거나 네트워크가 실패하면 보통 pending과 경로를 반환합니다. 유효하지 않은 표·출처·체크섬 등은 저장 전에 예외로 거절될 수 있습니다.outbox와 JSON에는 선택한 연구 내용·이미지가 들어 있습니다. 비공개 연구자료로 보관하고 Git에 넣지 않습니다. SDK는 토큰·endpoint를 결과 묶음에 저장하지 않지만 선택한 모든 데이터의 비밀을 자동 탐지하는 도구는 아닙니다. 무엇을 보낼지는 사용자가 확인합니다.
18.2 같은 요청 재전송
연결을 바로잡은 같은 Python 세션에서 다음을 명시적으로 실행합니다.
import luna_repro as repro
outcomes = repro.sync(".luna-repro/outbox")
for receipt in outcomes:
print(receipt["status"], receipt.get("url") or receipt["code"])walkthrough는 실행별 outbox를 사용하므로 출력에 나온
.../새실행폴더/outbox를 전달합니다. 노트북에서는 repro.sync(run_folder / "outbox")입니다. 폴더가 틀리면 빈 목록이 나올 수 있으므로 저장 경로를 확인하세요.CLI도 가능합니다. 토큰은 현재 세션 환경에서 읽으며 명령 인수로 받지 않습니다.
python -m luna_repro sync --outbox .luna-repro/outbox
python -m luna_repro publish selected-result.jsonsync는 성공 영수증이 없는 outbox JSON만 재시도합니다. publish 파일.json은 지정 파일을 직접 전송하고 CLI 성공·실패를 반환하며 outbox 영수증을 별도 생성하지 않습니다. SDK는 무한 재시도나 자동 대기를 하지 않습니다. 성공 원본과 영수증도 자동 삭제하지 않습니다.파이프라인에서 전송 실패를 예외로 처리하려면
page.publish(strict=True)를 사용합니다. 오류의 원격 응답 원문·토큰은 표시하지 않도록 처리되어 있습니다. HTTP redirect는 거절하므로 endpoint는 최종 HTTPS 주소여야 합니다.18.3 키 만료·분실·교체
새 키 발급 → 실행 환경의 비밀 설정 교체 → 실제 결과 수신 확인 → 이전 키 해제 순서로 진행합니다. 저장된 결과 JSON을 새 키 때문에 다시 만들 필요는 없습니다. 만료·해제·현재 프로젝트 접근 불가를 구분하고, 접근을 잃은 본인 키도 연결 관리에서 해제할 수 있습니다. 키를 해제하면 이후 API 사용이 막히며 이미 등록된 결과는 보존됩니다.
19. Pasa의 기존 출력에 적용하기
기존 결과 가져오기와 새 Colab 실행을 구분하세요. Pasa adapter가 기존 출력 폴더를 읽어 만든 페이지는 SDK 등록 검증이며, 수정 Colab의 새 추론·학습 실행이나 독립 재현 성공을 증명하지 않습니다. 새 실행용 사본은 원본과 기존 결과 버전을 보존하고 별도 실행 ID·새 출력 폴더·실제 사본의 셀 ID를 사용해야 합니다. 계산 셀, 결과 등록 셀, 원본 참고 코드를 구분합니다. 사본 준비·합성 검사·실제 GPU 실행·플랫폼 등록은 각각 영수증을 확인한 범위만 완료로 표시합니다. 데이터·모델·자원 접근이나 무료 GPU 확보가 확인되지 않았다면 실제 실행은 미검증입니다.
이 어댑터는 Pasa 추론을 새로 실행하지 않습니다. 이미 생성된 출력 폴더에서 선택 결과를 가져옵니다. 원래 노트북·모델·데이터를 자동 다운로드하거나 수정하지 않습니다.
1. 기존
VGGT_Gaussian_Surfels_Colab.ipynb를 자신의 환경에서 실행하고 실제 출력 폴더를 확인합니다.2. SDK를 설치하고 다운로드 예제의
pasa_adapter.py를 import할 수 있는 폴더에 둡니다.3.
RUN_DIR에 실제 기존 출력 폴더를 넣습니다. 폴더에는 run_manifest.json이 있어야 합니다.4. 프로젝트 UUID와 연결을 준비합니다.
5. 먼저 로컬 JSON 저장까지 실행하여 선택 범위를 확인합니다.
6. 필요하면 명시적으로
publish()를 실행합니다.from pasa_adapter import build_page
RUN_DIR = "/content/my-existing-pasa-run" # 실제 출력 폴더로 교체
project_id = "12345678-1234-5678-1234-567812345678" # 실제 프로젝트 UUID로 교체
page = build_page(RUN_DIR, project=project_id)
page.save(".luna-repro/pasa-selected-result.json")
# 연결·프로젝트·선택 결과를 확인한 뒤 명시적으로 실행:
# receipt = page.publish()
# print(receipt["status"], receipt.get("url") or receipt["message"])선택하는 파일은 다음과 같습니다.
| 경로 | 처리 |
|---|---|
| run_manifest.json | 필수. 제한된 실행 상태·조건과 hash만 기록 |
| camera_checks.json | 있으면 진단 표와 실패 기록 보존 |
| method/case/renders/003_render.png | manifest에 지정된 method/case의 해당 이미지만 선택 |
| evaluation/comparison.csv | 있으면 비교 표를 가져옴 |
전체 manifest·원본 데이터·checkpoint·소스 트리를 업로드하지 않습니다. 선택 폴더 밖으로 나가는 경로·파일 링크를 거절합니다. manifest에 없는 성능·시간·VRAM을 만들어 넣지 않습니다.
GT를 실제 설정하여 평가했고 유효한 비교 CSV가 있는 경우에만
gt_available=True를 명시합니다. 그렇지 않으면 평가 상태는 not_run입니다. pipeline의 완료 상태는 연구 검증 완료가 아닙니다. 카메라 진단 실패는 이후 렌더가 생성되어도 그대로 남습니다.정확히 알고 있을 때만
notebook_url, repository_url, commit, notebook_sha256을 추가합니다. 같은 프로젝트·manifest hash는 같은 page/run ID를 만듭니다. 다른 소유자가 동일 출력을 자기 페이지로 가져오려면 새 page_id=str(uuid.uuid4())를 명시하고 출처·가져오기 범위를 설명합니다. 실제 새 CUDA 실행과 독립 재현 검증은 별도 절차로 확인해야 합니다.20. 전체 API 참조
처음 사용하는 경우 4·9·29절의
connect() → select() → 미리보기·전송 흐름을 사용하세요. 아래 Page/Section은 섹션 구성과 출처·실행 상태를 세밀하게 지정하는 호환 API입니다. SDK만의 최신 고정 문법은 SDK 0.3.0 사용법을 참고하세요.20.1 Page
repro.page(project, title, *, description="", endpoint=None, token=None,
page_id=None, run_id=None, metadata=None, evidence=None,
source=None, outbox=None)위 표기는 함수 인자 설명입니다. 실제 래퍼는
page(project, title, **kwargs)이고 Page 생성자에 전달합니다. project, page_id, run_id는 UUID입니다. page/run ID 생략 시 새로 만듭니다. metadata={"tags": [...]} 외 필드는 지원하지 않습니다. endpoint·token을 객체에 직접 지정할 수도 있지만, 공유 소스에 실제 값을 쓰지 말고 세션 환경·숨김 입력을 사용합니다.| 메서드 | 반환·주의 |
|---|---|
| section(key, title=None, description="", source=None) | Section. description/source는 키워드 인자. 같은 key는 추가 대상 재사용 |
| bundle() | 검증된 dict 사본. request_id 포함 |
| save(path) | 저장 Path. 네트워크 호출 없음 |
| publish(endpoint=None, token=None, strict=False, timeout=30) | 키워드 인자만 사용. 성공 또는 pending 영수증 |
20.2 Section
| 메서드 | 입력 |
|---|---|
| text(text) | 일반 텍스트 |
| metrics(values) | 이름→유한 숫자 dict |
| table(columns, rows=None) | 열+행 또는 pandas 호환 DataFrame |
| image(path_or_bytes, caption="", name=None) | PNG/JPEG 파일·bytes. name은 키워드 인자 |
| figure(figure, caption="") | 명시 figure의 PNG 내보내기 또는 이미지 경로 |
| chart(figure, caption="") | figure의 별칭 |
20.3 파일과 재전송
bundle = repro.load_bundle("selected-result.json")
# dict를 읽습니다. Page 객체를 복원하는 함수는 아닙니다.
receipt = repro.publish_bundle(bundle, timeout=30)
outcomes = repro.sync(".luna-repro/outbox", timeout=30)이 코드는 두 번째 줄부터 실제 전송을 시도하므로 연결과 파일을 준비한 뒤 실행합니다.
publish_bundle·sync에도 endpoint, token, timeout 키워드를 지정할 수 있습니다. 연결 값을 생략하면 LUNA_REPRO_ENDPOINT, LUNA_REPRO_TOKEN에서 읽습니다. PublishError는 code, 선택적 retry_after와 고정 오류 안내를 갖습니다.직접 HTTP를 구현할 때는
POST /api/repro/v1/pages/, GET /api/repro/v1/pages/{page_id}/, GET /api/repro/v1/pages/{page_id}/versions/{number}/를 사용합니다. 프로젝트 bearer 전용이며 브라우저 쿠키·Origin을 포함한 요청은 거절합니다. 일반 사용자는 SDK를 권장합니다. 구 ReproKit 이벤트 v1과 이 결과 페이지 스키마를 섞지 않습니다.21. 크기·비용·상태 한도
| 항목 | 현재 SDK·플랫폼 한도 |
|---|---|
| Python | 3.10 이상 |
| 페이지·섹션 제목 | SDK300자 |
| 페이지·섹션 설명 | 12,000자 |
| 텍스트 블록 | SDK20,000자 |
| 섹션 key | 1–80자, 영문·숫자로 시작, 영문·숫자·밑줄·하이픈 |
| 지표 블록 | 1–100개, 이름160자, 유한 숫자 |
| 표 | 1–100열,0–2,000행, 열 이름160자, 문자열 셀4,000자 |
| PNG/JPEG | 개당8MiB, 한 변8192, 총16M pixels, 단일 프레임 |
| 페이지 전체 | base64 포함 JSON16MiB,100섹션·500블록·100고유이미지 |
| 태그 | 최대30개, 각100자 |
| 전송 timeout | 기본30초,0초 초과120초 이하 |
| 키 | 기본30일,1–90일; 사용자당 활성30개 |
| 결과 페이지 버전 | 최대10,000 |
| 기본 프로젝트 저장 | 결과 JSON+이미지 원본 합계1GiB |
| 기본 쓰기 빈도 | 사용자120회/프로젝트600회,15분 기준 |
| 기본 읽기 빈도 | 사용자300회/프로젝트1,500회,15분 기준 |
| 조합 보고서 | 같은 연구실의40섹션, 선택 JSON1MiB, 본문150,000자 |
| Notion | 20섹션·10이미지, 표99행·40열, native JSON400KB |
저장·요청 한도는 운영 정책에 따라 달라질 수 있습니다.1GiB는 논리적 결과 보관 합계이며 실제 DB 디스크나 청구량과 같다는 뜻은 아닙니다. base64는 이미지 크기를 늘리므로8MiB 이미지 두 장이16MiB JSON 안에 반드시 들어가지는 않습니다.
등록·조회·보고서 조합·Notion 전달 자체는 추가 AI·GPU 작업을 시작하지 않습니다. 서버 저장·전송·외부 서비스의 기존 요금은 별도입니다. 실제 AI 상담과 연구 실행은 해당 환경의 예산·권한을 따릅니다.
22. 자주 막히는 상황과 해결 순서
| 증상 | 확인·해결 |
|---|---|
| ModuleNotFoundError: luna_repro | 현재 노트북/가상환경에 SDK가 설치됐는지 확인. Colab %pip, 로컬 해당 Python의 -m pip 사용 |
| ZIP 파일을 찾을 수 없음 | Colab Files에 런타임 파일 업로드를 했는지 확인. 노트북 업로드만으로 ZIP은 생기지 않음 |
| UUID 오류 | 프로젝트 이름·키 대신 연결 화면의 UUID 사용 |
| 프로젝트 목록이 비어 있음 | 현재 계정·프로젝트 참여·운영 이용 범위를 관리자에게 확인 |
| 키를 다시 볼 수 없음 | 정상 동작. 보관한 키 사용 또는 새 키 발급 후 교체 |
| 활성 키30개 오류 | 사용하지 않는 본인 연결을 해제한 뒤 발급 |
| pending / connection_required | endpoint·키·timeout 형식 확인. 보존 JSON 경로 확인 후 명시 재전송 |
| authorization_required /403 | 프로젝트 UUID와 키 프로젝트 일치, 키 만료·해제, 현재 계정·참여 상태 확인 |
| transport_error | 최종 HTTPS endpoint·인터넷·서버 상태 확인. redirect 주소 사용 금지 |
| 413 또는 request_limit | 이미지 해상도/압축·선택 블록을 줄이거나 페이지 분리 |
| storage_quota | 프로젝트 저장 정책과 선택 크기 확인. 기존 자료를 임의 삭제하지 않음 |
| rate_limited /429 | retry_after가 있으면 그 초만큼 지난 뒤 직접 재시도. 자동 반복 금지 |
| NaN/Infinity 오류 | 누락·무한 값을 확인. 지표에서 제외하고 이유 설명; 표는 None 허용 |
| 표 행 길이 오류 | 모든 행의 셀 수가 columns 길이와 같은지 확인 |
| SVG/HTML 이미지 오류 | PNG/JPEG로 내보낸 작은 결과 사용 |
| source commit 오류 | 실제 소문자40/64자리 hash 사용. 모르면 생략 |
| source URL 오류 | query·인증정보·내부 주소 제거, 공개 호스트 HTTPS 영속 링크 사용 |
| 셀 링크가 다른 위치로 감 | 실제 notebook cell ID·공유 범위 확인. cell_id만으로 링크가 생성되지 않음 |
| 지표 블록이 중복됨 | 같은 섹션 추가 셀을 재실행했는지 확인. 새 Page 구성 또는 새 명시 key 사용 |
| 같은 실험이 새 페이지로 생김 | Page 생성 셀을 다시 실행하면 새 ID 생성. 복구는 sync 사용 |
| sync 결과가 빈 목록 | 올바른 outbox인지, 이미 성공 영수증이 있는지 확인 |
| request_conflict / page_conflict | 저장 요청 ID·페이지 소유자·프로젝트 일치 확인. 원본 JSON의 ID를 임의 수정해 재시도하지 않음 |
| version_limit | 기존 페이지를 보존하고 새 페이지를 만들어 설명에 이전 결과 링크 명시 |
| 팀원이 링크를 열지 못함 | 로그인·현재 프로젝트 접근·원본 보기 범위 확인. 키 공유로 우회하지 않음 |
| 보고서 저장 실패 | 섹션 수·같은 연구실 여부·원본 접근·본문 크기·동시 수정 확인 |
| Notion에 이미지가 안 붙음 | 복사 HTML 대신 허용된 연결의 Notion 직접 전달 사용 |
| Notion 대상이 없음 | 기존 Notion 연결·현재 관리 범위·대상 공유 및 삽입 권한 확인 |
| Notion 결과가 불확실 | 대상 페이지를 먼저 확인하고 원격 발행 기록 확인. 무작정 재전송하지 않음 |
| AI가 코드를 읽지 못함 | 실제 소스 접근 도구·권한·commit·파일을 별도 제공. 결과 링크가 전체 코드가 아님 |
문제 문의에는 화면 URL, 발생 시각, SDK 버전, 오류 code, 기대 결과와 실제 결과를 적습니다. 연결 키·개인정보·비공개 연구 원문·전체 환경 변수·인증 헤더는 보내지 않습니다.
23. 첫 실습 완료 확인
1. 오프라인 예제에서 MAE/RMSE0.5와 약0.1을 확인했습니다.
2. 실제 프로젝트 UUID와 본인 연결 키로
published 영수증을 받았습니다.3. 플랫폼에서 두 결과의 지표·그래프·표·코드 출처를 확인했습니다.
4. 서로 다른 결과의 섹션을 담아 보고서를 저장했습니다.
5. 원본 결과와 보고서의 보기 범위를 확인했습니다.
6. 섹션 링크 또는 AI 검토 자료를 통해 후속 검토할 수 있음을 확인했습니다.
7. 다음에는 실제 연구에서 작은 표·그림 하나를 선택하여 같은 방식으로 등록합니다.
이 과정은 결과 등록과 보고 흐름을 익히는 실습입니다. 실제 연구의 재현성은 실행 코드·데이터·모델·환경·평가 명세를 정확히 고정하고, 별도 실행과 검토 증거를 남겨 확인합니다.
24. SDK 0.3.0으로 계산 줄·셀과 선택 코드를 보존하기
파일명만 있는 예전 결과는 원래 저장된 정보가 부족한 상태입니다. 기존 고정 버전은 덮어쓰지 않습니다. 새 결과를 등록할 때 아래 helper로 위치와 선택한 본문을 함께 넣으세요. 웹의 합성 예제를 다시 만들면 같은 예제 페이지 ID에 CPU 계산과 코드 출처를 포함한 새 버전이 추가됩니다. 이전 버전의 본문·해시·보고서 참조는 그대로 남으며 동일 내용의 반복 요청은 중복 버전을 만들지 않습니다. 휴지통의 예제는 자동 복원하지 않습니다. 공개 완성 예시에서도 각 섹션의 계산 코드 출처 → 계산 코드 보기로 실제 교육용 파일의 해당 줄을 열 수 있습니다.
24.1 무엇이 자동이고 무엇을 선택하나요?
기본 SDK는 결과를 등록한 Python 호출 위치만 기록할 수 있습니다. 결과를 계산한 앞선 함수·셀을 추측하지 않습니다. 가상 노트북 실행 프레임에서는 파일 위치가 비어 있을 수 있습니다.
source.function(...), source.file(...), source.notebook(...)으로 계산 관련 위치를 직접 선택하세요. snapshot=False가 기본이며 코드 본문은 저장하지 않습니다. snapshot=True라고 명시할 때 선택한 코드만 bundle에 들어갑니다. helper 호출 자체는 파일 저장·플랫폼 전송·코드 실행을 하지 않습니다.| 화면의 표시 | 실제 의미 |
|---|---|
| 결과 등록 위치 | SDK를 호출한 줄입니다. 앞서 계산한 코드와 다를 수 있습니다 |
| 사용자가 지정한 계산 코드 | 사용자가 연결한 계산 범위입니다. 실행 성공 증명은 아닙니다 |
| 함수·클래스 또는 셀 정의 | 저장된 정의의 위치입니다. 실제 호출 여부는 별도입니다 |
| 참고 코드 · 실행본 동일성 미확인 | 검토에 사용할 사본이며 과거 실행과 같은 코드인지 확인되지 않았습니다 |
| 선택한 코드 본문·해시 보존 | 고정 결과 버전에 선택 텍스트와 SHA256을 저장했습니다 |
| 등록자가 로컬 파일과 commit 일치를 관측 | 선택 파일의 바이트가 해당 로컬 Git commit과 일치했습니다. 서버가 GitHub나 실행을 독립 검증한 것은 아닙니다 |
| 링크 구성됨 · 외부 접근·실행 미검증 | 이동할 주소를 만들었습니다. 로그인 권한, 외부 서비스의 응답과 실행 결과는 확인하지 않았습니다 |
24.2 그대로 실행할 수 있는 Python 파일 예제
SDK 0.3.0을 설치한 뒤 아래 코드를 새
source_example.py에 저장하고 python source_example.py로 실행하세요. __file__을 쓰므로 노트북 셀에 그대로 붙이는 예제가 아닙니다. 세 합성 값의 MAE 0.5와 계산 함수의 실제 줄·본문을 로컬 JSON에 저장합니다. 예제 UUID는 연습용이며 네트워크·GPU·AI 호출은 없습니다. 매번 새 페이지 ID의 파일을 만들어 이전 결과를 보존합니다.from pathlib import Path
import luna_repro as repro
def calculate():
reference = [0.0, 1.0, 2.0]
prediction = [value + 0.5 for value in reference]
return sum(abs(a - b) for a, b in zip(prediction, reference)) / len(reference)
selected = repro.source.function(
calculate, root=Path(__file__).resolve().parent, snapshot=True,
)
page = repro.page(
"12345678-1234-5678-1234-567812345678", "Source selection practice",
evidence={"origin": "synthetic", "execution_status": "completed",
"evaluation_status": "completed"},
)
page.section("metric", "Computed MAE", source=selected).metrics({"MAE": calculate()})
saved = page.save(Path(".luna-repro") / (page.page_id + ".json"))
print("Saved locally:", saved)
print("Source:", selected["file"], selected["line_start"], selected["line_end"])
print("Selected code SHA256:", selected["snapshot_sha256"])JSON의
sections[0].source.provenance.snapshot.text에서 선택한 함수만 들어갔는지 확인하세요. 코드 본문에 비밀·원문 데이터·개인정보가 있다면 전송하기 전에 제외합니다. 플랫폼에 올리려면 4~7절대로 실제 프로젝트 UUID와 본인 연결을 설정하고 명시적으로 publish()를 호출해야 합니다. 등록 후 섹션의 코드·실행 출처 → 보존된 코드 보기에서 해당 줄로 이동합니다. 이 읽기 화면은 현재 결과 권한을 다시 검사하며 코드를 실행하지 않습니다.기존 내려받은
walkthrough.py도 python walkthrough.py --include-source로 실행하면 지표·그림 등 관련 함수 정의를 선택해 보존합니다. 이 옵션도 기본은 로컬 저장입니다. 실제 프로젝트로 보내려면 --project와 --publish를 명시합니다.24.3 helper 전체 문법과 초기값
| 호출 | 기본값과 계약 |
|---|---|
repro.source.file(path, *, root, line_start=1, line_end=None, snapshot=False, repository_url=None, role="computation") | 실제 .py 파일에서 지정 범위를 선택합니다. line_end=None은 마지막 줄입니다. root 안의 파일만 가능하며 범위가 실제로 존재해야 합니다 |
repro.source.function(function, *, root, snapshot=False, repository_url=None) | 실제 파일이 있는 함수 또는 클래스의 저장된 정의를 선택합니다. role은 definition입니다. 동적/가상 셀 정의는 직접 저장한 셀로 지정합니다 |
repro.source.registration(*, root, snapshot=False, repository_url=None) | 이 helper를 부른 현재 줄을 registration으로 표시합니다. 계산 출처를 찾는 도구가 아닙니다 |
repro.source.notebook(path, cell_id, *, root, provider="jupyter", notebook_url=None, snapshot=False, repository_url=None, role="definition") | 저장한 .ipynb에서 실제 ID가 일치하는 코드 셀 하나를 선택합니다. provider="colab"도 지원합니다. 과거 실행 동일성이 불확실하면 role="reference"를 사용합니다 |
root는 접근 범위를 명시하는 실제 디렉터리입니다. 경로와 symlink를 해석했을 때 그 밖으로 나가면 거절합니다. 디렉터리 전체를 탐색하거나 업로드하지 않습니다. 파일 하나는 최대 1 MiB, 보존 본문은 출처당 32 KiB·1,000줄, 페이지·섹션에 복사된 모든 출처를 합쳐 최대 256 KiB입니다. 페이지 source의 상속 사본도 합산하므로 필요한 섹션에만 작은 범위를 지정하세요. JSON 전체 16 MiB와 프로젝트 보관 한도도 함께 적용됩니다.24.4 GitHub의 정확한 줄 링크
root를 Git 저장소의 실제 최상위 폴더로 지정하고 repository_url="https://github.com/조직/저장소"에 실제 주소를 넣습니다. helper는 로컬 Git의 HEAD와 선택 파일을 읽고 바이트가 일치할 때만 자동 고정 commit 링크를 만듭니다. Python은 .../blob/<정확한 commit>/<파일>#L시작-L끝 형태입니다. 수정된 파일·Git 없는 폴더·알 수 없는 상태에는 자동 고정 링크를 만들지 않으며, 선택 snapshot을 보존하면 플랫폼에서 그 내용을 계속 읽을 수 있습니다. Git remote 인증정보를 자동 수집하지 않습니다. 같은 텍스트여도 CRLF/LF 등 바이트 차이가 있으면 일치로 주장하지 않습니다.GitHub의 노트북 파일 링크를 노트북의 정확한 실행 셀 링크라고 표시하지 않습니다. 저장된 notebook 파일과 선택 셀 본문·셀 ID를 확인할 수 있지만, 실제 실행 환경의 셀 이동은 별도 provider 주소를 사용합니다. 외부 저장소 권한은 LUNA 결과 공유와 별개입니다.
24.5 Colab·Jupyter의 실제 셀 선택
현재 노트북을 저장해 실행 환경에서 읽을 수 있는
.ipynb 사본을 준비합니다. Jupyter는 셀의 최상위 id, Colab은 셀 metadata.id를 사용합니다. 두 값은 서로 다를 수 있으며 화면상 셀 번호나 실행 순번으로 대체하면 안 됩니다. 아래는 준비한 파일과 실제로 존재하는 ID를 입력하는 형태입니다. 모든 파일·ID·URL은 본인의 사본에 맞춰야 합니다.from pathlib import Path
import luna_repro as repro
notebook_path = Path("saved_notebook.ipynb")
selected = repro.source.notebook(
notebook_path, "ACTUAL-COLAB-CELL-ID",
root=notebook_path.resolve().parent,
provider="colab",
notebook_url="https://colab.research.google.com/drive/ACTUAL-NOTEBOOK-ID",
snapshot=True,
role="reference",
)Colab에서는 실제 저장된 셀 ID가 확인되면
#scrollTo=<metadata.id>를 구성합니다. notebook_url은 query·기존 fragment가 없는 주소여야 합니다. helper는 Colab 내부 API로 현재 실행 셀 ID를 몰래 알아내지 않으며, 링크를 만들었다고 브라우저 이동까지 검증했다고 표시하지 않습니다. 셀 ID가 없거나 중복이면 실패합니다. 저장되지 않은 편집·다른 사본·셀 삭제 이후에는 원래 실행본과 달라질 수 있으므로 snapshot과 명확한 상태를 함께 남기세요.walkthrough.ipynb의 INCLUDE_SOURCE는 기본 False입니다. 저장한 notebook을 실행 환경에 올리고 SOURCE_NOTEBOOK, SOURCE_PROVIDER, SOURCE_CELL_ID를 실제 값으로 바꾼 뒤 True로 설정하고 계산·저장 셀을 실행하세요. SOURCE_NOTEBOOK_URL=None이면 외부 실행 링크를 추측하지 않습니다. 노트북 출력·첨부·실행 중 전역변수는 선택 코드 snapshot에 포함하지 않습니다.24.6 기존 결과, AI, 복구에서 확인할 것
기존 결과의 파일명·줄 정보는 그대로 보존하고 새 코드 snapshot이 있는 척하지 않습니다. 페이지 고정 버전마다 해당 snapshot을 열 수 있습니다. 일반 AI 컨텍스트·자료 내려받기·Notion 전달은 코드 본문을 자동 포함하지 않습니다. 보고서 AI에서 코드 본문 포함을 선택한 경우에만 현재 권한으로 읽은 선택 snapshot을 분석 근거로 추가합니다. 코드가 없으면 없다고 표시하며 외부 URL을 임의로 가져오지 않습니다. 과거 실행 동일성, 데이터 일치, 독립 재현과 연구 성공은 별도 검증 사항입니다.
invalid_source_snapshot이면 선택 줄·본문·해시를 다시 구성하고, source_snapshot_limit이면 작은 함수·셀만 선택하세요. 휴지통 결과의 SDK 재전송은 result_trashed로 보류되며 자동 복원되지 않습니다. 플랫폼에서 본인 결과를 복원한 다음 저장된 outbox를 명시적으로 다시 전송합니다. 권한 철회·휴지통 상태에서는 예전 코드 링크도 현재 권한 검사에 따라 열리지 않습니다.25. 결과와 설명 셀로 보고서 구성하기
1. 보고서 → 재현성 결과에서 결과 페이지를 엽니다.
2. 필요한 그림·표·지표 섹션을 선택합니다. 다른 결과 페이지에서도 선택할 수 있습니다.
3. 선택 표시줄에서 선택 검토를 열고 보고서 만들기로 진행합니다.
4. 보고서 제목을 입력합니다. 각 결과 앞뒤의 + 설명 셀을 누릅니다.
5. 설명 칸에 Markdown을 입력합니다. 예:
## 연구 배경, ## 방법, ## 결과 해석, ## 한계.6. 도구 모음의 미리보기로 서식을 확인합니다. 위·아래 버튼으로 결과와 설명의 순서를 바꿉니다. 데스크톱에서는 이동 손잡이를 끌 수도 있습니다.
7. 결과 더 선택으로 다른 페이지의 결과를 추가합니다. 돌아와 제목과 설명이 유지됐는지 확인합니다.
8. 플랫폼 보고서 저장을 누릅니다. 나만 볼 수 있는 초안으로 저장됩니다.
아래처럼 자유롭게 배치할 수 있습니다. 모든 항목을 채울 의무는 없습니다.
연구 배경과 질문 ← 설명 셀
실험 A의 렌더 이미지 ← 결과 셀: 고정된 원본 버전
데이터 구성·평가 방법 ← 설명 셀
실험 B의 정량 지표 ← 다른 페이지의 결과 셀
결과 비교·한계·다음 실험 ← 설명 셀제거는 현재 보고서의 셀만 제거합니다. 원본 결과는 바뀌지 않습니다. 결과 카드의 수치를 고치려면 실제 연구 결과를 수정·검토하고 새 결과 버전으로 등록해야 합니다. 보고서는 선택한 과거 버전을 계속 참조합니다.
저장 후 버전 이력에서 이전 제목·셀 순서·본문을 확인하고 복원할 수 있습니다. 복원은 현재 보고서를 지우는 대신 새 버전을 추가합니다. 다른 브라우저 창에서 이미 수정했다면 현재 버전을 다시 확인하세요. 원본 결과나 배경자료를 볼 권한이 사라지면 이를 참조하는 보고서도 읽기 전에 현재 권한을 검사합니다.
26. 연구 맥락으로 AI 초안 만들기
1. 편집 화면에서 저장 후 AI 초안을 누릅니다. 현재 셀과 제목을 먼저 저장합니다.
2. 연구 배경에 필요한 이전 자료·보고서를 선택합니다. 같은 연구실에서 현재 접근 가능한 자료만 사용합니다. 필요하면 검색어로 찾습니다.
3. 추가 지시를 구체적으로 적습니다. 예: “학습 시점의 PSNR과 별도 평가 성능을 구분하고 카메라 진단 실패를 한계에 포함해 주세요.”
4. 실제 이미지나 저장된 코드 내용을 검토해야 할 때만 해당 포함 옵션을 선택합니다. 이미지 최대 3장과 선택 코드 최대 24,000자를 사용하며 선택 수와 범위를 미리 보여 줍니다. 코드 링크만 등록한 경우 본문을 읽었다고 간주하지 않습니다.
5. 미리보기에서 보고서 버전, 근거 선택, 전달 범위와 기존 AI 사용 정책을 확인합니다. 미리보기만으로 AI가 실행되지는 않습니다.
6. 요청을 확정하면 기존 AI 작업 대기열에서 초안이 생성됩니다. 페이지는 실제 작업 상태를 표시합니다. 탭을 숨기면 상태 조회를 쉬고 오류가 나면 조회 간격을 늘립니다.
7. 제안된 제목·설명 셀을 읽습니다. 원하는 셀만 선택해 적용하거나 모두 선택합니다. 적용은 결과 이미지·수치 원본을 변경하지 않습니다.
8. 편집 화면에서 사람이 수정하고 저장합니다. 설명 셀 하나만 다듬으려면 이 셀 AI 보완을 사용합니다.
제안 범위는 연구 배경, 방법, 데이터 구성, 실험 조건, 결과 해석, 한계와 토의입니다. 자료가 부족한 부분은 확인할 사항으로 남깁니다. AI 문장을 근거 없이 연구 성과로 확정하지 마세요. 실제 실행·통계 검증·독립 재현과 AI 해석은 구분합니다.
비용과 정보 전달: 실제 생성 요청은 기존 AI 권한·일일 할당량·요청 정책을 사용합니다. 단순 조회, 편집, 미리보기에는 추가 AI 호출이 없습니다. 이미지·코드 포함은 선택한 내용이 설정된 AI 제공자에게 전달된다는 뜻입니다. 전체 저장소, 환경 변수, 키, 데이터셋을 자동 수집하지 않습니다. 외부 URL에 접근하려면 별도 도구와 현재 권한이 필요합니다.
중간에 내용이 바뀌었다면: 초안을 만든 뒤 보고서나 근거가 변경되면 이전 초안을 그대로 덮어쓰지 못하게 합니다. 변경된 현재 내용을 확인하고 새로 요청하세요. 오류·시간 초과는 성공으로 표시하지 않으며 추가 요청은 예산을 다시 확인합니다.
27. 결과를 휴지통으로 이동·복원하기
1. 본인 결과 카드 오른쪽 ⋯ 또는 결과 상세의 ⋯를 엽니다.
2. 휴지통으로 이동을 선택합니다.
3. 참조 보고서 수와 Notion 전송 상태 등 영향을 확인하고 이동합니다.
4. 결과 목록·검색의 기본 화면에서 사라지는지 확인합니다.
5. 결과 목록의 휴지통을 열어 해당 결과를 복원합니다. 같은 URL·ID·버전·이미지로 돌아옵니다.
이미 보고서에 들어간 결과를 휴지통에 넣어도 보고서 본문과 참조 이력을 삭제하지 않습니다. 현재 원본 접근을 다시 검사하므로 숨겨진 원본을 보고서나 AI 경로로 우회해 읽을 수는 없습니다. 외부 Notion 사본은 자동으로 삭제되지 않습니다.
SDK가
result_trashed를 반환하면 자동 재전송을 반복하지 마세요. 본인이 플랫폼에서 명시적으로 복원한 다음 같은 outbox 요청을 재전송합니다. SDK가 삭제 상태를 자동 해제하거나 새 버전으로 결과를 되살리지는 않습니다.실제 전송 중인 Notion 작업이 있다면 먼저 그 결과를 확인합니다. 대기 작업은 중지되지만 이미 외부로 나간 작업의 취소·삭제를 보장하지 않습니다. 재현성 증거의 완전 삭제는 제공하지 않으며 기존 보관 한도도 휴지통 이동만으로 줄어들지 않습니다.
28. ChatGPT·개인 AI에서도 같은 보고서 이어 쓰기
이 기능은 실제 제공되는
consultant_thread_prepare와 consultant_thread_commit 도구를 통해 연결합니다. 호스트에서 이 도구가 보이는지 먼저 확인하세요. 서버 지원과 현재 ChatGPT 연결의 도구 노출은 별도입니다. 이름이 없는 도구를 만들어 호출하거나 아직 실행하지 않은 작업을 완료했다고 표시하면 안 됩니다. 도구가 없으면 같은 웹 보고서 편집 링크에서 계속할 수 있습니다.모든 요청의 공통 바깥 형식은
operation="save", values={"repro":{"operation":"아래 작업명","values":{...}}}입니다. 실제 검색·조회에서 얻은 ID만 사용합니다.| 안쪽 작업명 | 값과 효과 |
|---|---|
read | page_id, 선택적 revision, section_key, offset. 기존 고정 결과 조회이며 코드 본문은 기본 제외합니다 |
source | page_id, revision, section_keys 배열, include_code=true, 선택적 offset. 명시적으로 선택한 보존 코드만 읽으며 외부 URL을 가져오거나 실행하지 않습니다 |
report_read | report_id, 선택적 revision, offset. 같은 보고서의 셀·Markdown·현재 버전·이력을 읽습니다. body는 JSON 텍스트이며 next_offset이 있으면 이어 읽습니다 |
report_save | title, cells, 새 요청의 안정적인 UUID인 request_key. 기존 보고서를 수정하려면 report_id, 조회한 현재 revision도 지정합니다. 새 보고서는 revision=0입니다. 플랫폼 AI 호출 없이 준비한 해설과 결과 참조를 저장합니다 |
ai_prepare | report_id, base_revision, request_key. 선택적 sources는 record:UUID 또는 report:UUID 배열, images=false, code=false, target은 해설 셀 UUID, instruction은 600자 이내, language는 ko/en입니다. 추가 플랫폼 AI 사용량을 확인하는 미리보기입니다 |
ai_read | run_id. 대기·진행·실패·준비된 초안을 읽습니다. 조회는 AI 재시도가 아닙니다 |
ai_apply | run_id, 적용할 초안 셀 UUID 배열 selected, 안정적인 request_key, 선택적 use_title=true. 선택 해설을 기존 보고서에 반영하는 미리보기입니다 |
결과 셀은
{"id":"셀 UUID","kind":"result","selection":{"page_id":"결과 UUID","revision":1,"section_key":"metrics"}} 형태이며 지표나 이미지를 복사해 수정하지 않습니다. 해설 셀은 {"id":"셀 UUID","kind":"markdown","text":"해석 내용","origin":"human 또는 ai","references":["record:자료 UUID"]}입니다. 실제 UUID로 바꾸고 기존 셀의 ID는 유지합니다. 웹과 같은 100셀·결과 40개·해설당 12,000자·해설 합계 80,000자 한도가 적용됩니다.변경 미리보기가 반환한 정확한 review와 preview_token을
consultant_thread_commit으로 전달합니다. 현재 권한과 luna:consultant:write, luna:report:write를 다시 검사하고 같은 요청 재전송은 중복 버전을 만들지 않습니다. 보고서나 근거가 바뀌면 현재 내용을 다시 읽고 새 미리보기를 준비합니다. ChatGPT에서 이미 작성한 해설을 report_save로 보존하는 작업에는 두 번째 플랫폼 AI 호출이 없습니다. ai_prepare 후 commit은 별도의 추가 AI 작업이므로 같은 것으로 오해하지 마세요. AI가 만든 해설은 자동 채택하지 않고 ai_apply에서 선택합니다. 어느 경로도 공유 권한을 확대하거나 Notion 발행·GPU 실행·독립 재현 검증을 완료하지 않습니다.29. 한 번 연결하고 마지막 셀에서 결과 고르기
29.1 기본 흐름: 연결 셀 → 계산 → 선택 → 미리보기 → 전송
결과 연결에서 프로젝트를 선택하고 연결 셀 복사를 누르세요. 처음 셀에서 SDK 준비와 브라우저 승인을 마친 뒤 기존 계산 코드를 실행합니다. 마지막 셀의
repro.select()는 현재 호출 위치에 남아 있는 지원 객체를 로컬 후보로 추천합니다. 노트북의 전역 범위에서 호출하면 그 범위를, 함수 안에서 호출하면 함수의 지역 범위를 사용합니다. 닫힌 이전 커널이나 다른 프로세스의 변수를 읽지는 않습니다.노트북에서 선택 UI를 지원하면 체크박스가 표시됩니다. 추천 항목이 미리 체크될 수 있지만 전송된 것은 아닙니다. 필요한 항목을 확인하고 제목·설명·순서·변환 옵션을 조정하세요. 미리보기로 실제 선택한 값·표·그림을 확인한 뒤 검토한 결과 전송을 누릅니다. 선택이나 옵션을 바꾸면 다시 미리보기를 해야 합니다. 후보 목록만 나타나거나
ipywidgets가 없으면 아래 코드 방식으로 같은 기능을 사용합니다. SDK가 표시용 패키지를 자동 설치하지는 않습니다.SDK 미리보기는 로컬 결과를 고정합니다. 미리보기 후 원래 변수의 값이 바뀌어도 검토한 묶음은 바뀌지 않습니다. 새 계산값을 보내려면 새로 선택하고 다시 미리봅니다. 같은 Selection의 전송 재시도는 같은 요청 ID를 사용하지만
repro.select()를 다시 호출해 새 객체를 만들면 새 선택입니다.29.2 추가 라이브러리 없이 그대로 실행하는 로컬 실습
SDK 설치 뒤 아래 예제를 그대로 실행하세요. 연습용 프로젝트 UUID를 사용하며 인증·네트워크·플랫폼 생성 없이 HTML 미리보기와 JSON만 저장합니다.
from pathlib import Path
import luna_repro as repro
repro.configure(project="12345678-1234-5678-1234-567812345678")
metrics = {"MAE": 0.5, "samples": 3}
comparison = [[0, 0.0, 0.5], [1, 1.0, 1.5], [2, 2.0, 2.5]]
selection = repro.select(
namespace={"metrics": metrics, "comparison": comparison},
title="로컬 선택 실습", show=False,
)
print(selection.summary()) # 후보 이름·종류·추천 이유; 전체 원문 출력 아님
selection.choose("metrics", "comparison")
selection.option("comparison", columns=["index", "reference", "prediction"])
selection.edit(description="합성 값 3개입니다. 실제 연구 성능이 아닙니다.",
order=["comparison", "metrics"])
folder = Path(".luna-repro") / "selection-practice"
selection.preview(folder / "preview.html")
selection.save(folder / "selected.json")
print("로컬 미리보기:", folder / "preview.html")preview.html을 브라우저에서 열어 순서와 숫자를 확인합니다. 실제 등록은 실제 프로젝트로 repro.connect()한 다음 그 프로젝트의 새 Selection을 만들고 검토한 후 selection.publish()를 호출해야 합니다. 연습용 UUID를 실제 등록에 사용하지 마세요. SDK 미리보기 파일과 outbox에도 선택한 비공개 결과가 들어갈 수 있으므로 비공개로 보관합니다.29.3 표·배열·이미지 변환을 명시하기
| 결과 | 기본 처리와 필요한 선택 |
|---|---|
| 숫자·숫자 지표 사전 | 지표로 변환. 성공·성능 향상 여부를 판정하지 않음 |
| 행 목록·pandas DataFrame/Series | 표로 변환. 필요한 열·행 수·index 포함 여부를 선택 |
| NumPy 배열 | 제한된 1차원/2차원은 표. 이미지로 해석하려면 as_image=True와 필요한 범위·배치를 명시 |
| PyTorch Tensor | 자동 CPU 복사하지 않음. 작은 부분을 선택하고 allow_cpu=True를 명시 |
| PNG/JPEG Path·PIL Image·matplotlib Figure | 선택한 이미지/그림만 변환. 디렉터리 전체를 탐색하지 않음 |
| Plotly Figure | 환경에 사용 가능한 정적 이미지 exporter가 필요. 없으면 PNG/JPEG로 직접 저장한 파일을 선택 |
예를 들어 이미 존재하는
results_df를 줄여 보냅니다. score와 method는 실제 열 이름으로 바꾸세요.selection = repro.select(namespace={"results": results_df}, show=False)
selection.choose("results")
selection.option("results", rows=50, columns=["method", "score"], index=False)
selection.preview(".luna-repro/results-preview.html")행 수를 줄인 표는 전체 데이터가 아닙니다. 빠진 행·실패 사례·경고를 확인하고 해석에 명시하세요. 자동 추천은 로컬 형식·크기·이름을 활용하며 과학적 중요도나 유리한 결과만 판정하는 AI가 아닙니다.
purpose="accuracy comparison"은 후보 이름과 목적의 단어 일치를 돕는 로컬 정렬 힌트입니다. 기본 추천에 AI 호출·비용은 없습니다.29.4 .py 파일과 닫히는 그림
일반 Python 파일·터미널에서는 노트북 체크박스 대신 후보 요약을 출력합니다.
show=False와 choose()로 선택하고 preview("경로.html")로 확인하세요. 서버가 브라우저를 열지 못해도 승인 URL은 본인의 브라우저에서 열 수 있습니다. 무인 작업은 이미 승인된 비밀 관리·선택 규칙을 사용합니다. 설치·미리보기·읽기만으로 발행하지 않습니다.matplotlib 그림이
show()·close() 때 사라진다면 계산 전에 범위를 열 수 있습니다. 이 기능은 제한된 그림과 경고 종류별 수·실패 상태를 보존하며 전체 stdout·오류 원문·데이터를 수집하지 않습니다. 동시에 여러 캡처 범위를 열지 마세요.import matplotlib.pyplot as plt
with repro.capture(max_figures=4) as captured:
plt.plot([0, 1, 2], [0, 1, 4])
plt.show()
plt.close()
captured_selection = captured.select(show=False)
captured_selection.preview(".luna-repro/captured-preview.html")지원 환경과 한도를 넘긴 그림은 빠질 수 있으므로
capture_status의 경고·누락·실패 상태를 함께 검토합니다. 범위 전에 사라진 그림은 복원할 수 없습니다. 실제 계산 코드의 셀·줄을 지정하려면 12·24절의 sources={"후보이름": source_ref} 또는 Page/Section 출처를 사용하세요. 자동 등록 위치는 계산 위치가 아닙니다.29.5 반복 실행 규칙은 선택 사항입니다
한 번 검토한 변수 이름·종류·순서·변환 옵션은
selection.save_rule("선택규칙.json")으로 보관할 수 있습니다. 규칙 저장 자체는 전송하지 않습니다. 이후 repro.select(namespace=..., rule="선택규칙.json")으로 적용하고 다시 검토합니다. 변수가 사라지거나 종류·프로젝트가 달라지면 중지하므로 이전 규칙을 새 연구에 무심코 적용하지 마세요.무인 전송은 규칙을 저장할 때
auto_publish=True, 실행할 때 auto=True를 둘 다 명시한 경우에만 한 번 실행됩니다. 스케줄러나 무한 재시도를 만드는 기능이 아닙니다. 규칙에는 결과 원문·키가 포함되지 않지만 사용자 지정 제목·설명이 포함되므로 연구자료와 같은 보관 정책을 적용하세요.29.6 플랫폼에서 결과 확인·보고서·Notion으로 이어가기
등록 성공 URL을 열어 전체 미리보기에서 선택한 결과를 순서대로 확인하세요. 결과 카드의 간단한 출처에서 코드로 이동하고, 필요할 때 상세 정보를 펼칩니다. 출처가 없거나 원본 노트북의 참고 링크뿐인 경우 실행 코드가 확인된 것으로 해석하지 않습니다. 링크 열기는 코드 실행이 아닙니다.
여러 결과의 섹션을 보고서에 담고 설명 셀로 배경·방법·분석을 작성할 수 있습니다. Notion에 게시에서 대상과 자동 미리보기를 확인하고 게시합니다. 원격 게시 성공은 영수증으로 확인하고 불확실한 전송은 자동 반복하지 않습니다. 연결·추천·보고서 미리보기는 유료 AI/GPU 실행이 아니며, AI 초안은 26절의 별도 사용 정책과 선택한 근거를 따릅니다.
30. 결과 읽기·셀 AI 보완·간편 Notion 게시
30.1 같은 위치에서 읽고 공유하기
결과 페이지 상단의 공유, 인쇄·내보내기, 즐겨찾기를 사용합니다. 번역 도구는 제목·설명·캡션을 번역하며 코드, URL, 표의 측정값을 바꾸지 않습니다. 원문 보기로 돌아갈 수 있고 기존 무료 번역·AI 번역 정책을 따릅니다. 과거 버전을 보고 있다면 그 버전의 공유·즐겨찾기·인쇄 링크가 유지됩니다. 링크 복사는 열람 권한을 추가하지 않습니다.
일반 보고서와 결과 보고서의 제목 아래에는 편집, Notion에 게시가 있습니다. 코드 파일명·해시·등록 위치의 반복 설명은 생성 보고서의 기본 본문에서 제외하고 결과·코드 보기로 연결합니다. 결과 페이지의 코드 보기는 지정된 줄·셀로 이동하고, 출처 상세에는 원래 파일명·보존 코드·해시가 남습니다. 링크를 여는 것만으로 코드를 실행하지 않습니다. 기존 보고서의 수동 편집 본문과 버전 이력은 보존합니다.
30.2 한 셀만 AI로 보완하기
1. 결과를 선택해 보고서를 만들거나 기존 결과 보고서의 편집을 엽니다.
2. + 설명 셀을 누르고 적습니다. 예: “두 조건의 RMSE 차이를 설명하고 표본이 작다는 한계를 포함해 주세요.”
3. 근거가 필요하면
[[를 입력해 자료·보고서를 검색해 선택합니다. @로 연구원 멘션을 선택할 수 있습니다.4. 이 셀 AI 보완을 누릅니다. 기존 AI 권한·예산·일일 할당량을 사용하는 요청 한 번입니다. 빠른 셀 보완은 이미지와 코드 본문을 자동 전송하지 않습니다.
5. 셀에서 실제 대기·생성·완료 상태와 경과 시간을 확인합니다. 숨긴 탭의 상태 조회는 쉬고, 새로고침 후 같은 작업을 이어 확인합니다. 반복 클릭으로 새 유료 요청을 만들지 않습니다.
6. 입력이 그대로라면 해당 편집 초안 셀에만 반영됩니다. 제목·다른 셀·결과 순서는 바뀌지 않습니다. 되돌리기로 원래 문장을 복구할 수 있습니다. 생성 중 직접 고친 내용이 있으면 비교 후 적용합니다.
7. 전체 미리보기로 확인한 뒤 플랫폼 보고서 저장을 누릅니다. AI 보완만으로 새 보고서나 개정이 저장되지는 않습니다.
보고서 전체의 배경·방법·분석·한계를 구성하려면 별도의 저장 후 AI 초안을 사용합니다.
[[자료]]·[[보고서]]는 현재 접근 가능한 원문을 실제 AI 근거로 읽고 저장 시 접근 의존성으로 보존합니다. 선택한 결과의 프로젝트·과제 목적도 문맥으로 사용합니다. 다른 프로젝트의 목적이나 아직 지원하지 않는 문서 종류는 해당 프로젝트의 자료·보고서를 인용하도록 안내합니다. @연구원은 사람을 식별하며 그 사람의 비공개 자료를 읽는 권한이 아닙니다. 지원하지 않거나 읽을 수 없는 인용은 수정할 안내를 표시합니다.30.3 한 게시 창에서 끝내기
아래 이미지·표 변환과 기존 페이지 추가 옵션은 재현성 결과와 결과 기반 보고서에 적용됩니다. 일반 보고서도 같은 게시 창을 사용하지만 지원되는 옵션과 미리보기 범위는 화면에 표시된 내용을 따릅니다.
Notion에 게시 → 대상과 자동 미리보기 확인 → Notion에 게시 순서입니다. 제목은 자동으로 채워지고 그림·표·설명까지 미리 볼 수 있습니다. 게시 옵션에서 제목·설명과 새 하위 페이지/기존 페이지 추가를 바꾸면 미리보기도 다시 준비됩니다.
새 전송은 최대 40섹션, 이미지 10개(각 8MiB), 표 40열·데이터 99행을 지원합니다. 긴 본문은 최대 20개 묶음으로 나뉘고 각 전송 확인 기록을 보존합니다. 이미지 준비·업로드 요청은 별도입니다. 이미지 준비·본문 게시의 실제 진행을 표시하며 창을 닫아도 접수된 작업은 유지됩니다. 대상 권한·이미지·표 한도·미리보기 만료는 화면 안내에 따라 해결합니다. 확인 필요 상태는 이미 반영되었을 수 있어 자동 반복하지 않습니다. 화면에 표시되는 확인 행동을 따르세요. 게시 위치가 확인된 경우 Notion에서 열기 또는 게시 상태 확인을 제공합니다. Notion 사본의 열람 범위는 대상 페이지를 따르며 LUNA 권한 해제로 사본이 삭제되지 않습니다.