Community코딩 & 개발github.com

pwquint24/org-babel-notebook

Org Babel을 사용하여 Emacs Org Mode에서 대화형 다중 언어 계산 노트북을 작성, 구조화, 실행 및 게시하기 위한 종합 가이드입니다.

org-babel-notebook란 무엇인가요?

이 스킬은 Emacs Org Mode의 Org Babel을 활용하여 Jupyter나 Mathematica 같은 대화형 다중 언어 계산 노트북 환경을 구축하는 방법을 상세히 설명합니다. Org 노트북은 사람이 읽을 수 있는 일반 텍스트로 저장되며, Git을 통한 네이티브 버전 관리, 단일 문서 내 여러 프로그래밍 언어 혼합 지원, 다양한 출력 형식(HTML, PDF, Markdown)으로의 내보내기 기능을 제공합니다. 주요 기능으로는 세션 관리(격리 vs. 지속적), 캐싱, 다양한 결과 처리 방식(value/output, table/scalar, drawer/raw), 시각화(Matplotlib, ggplot2) 및 내보내기 제어가 있습니다. Emacs 키바인딩(`C-c C-c`로 실행, `C-c '`로 전용 편집기 열기 등)을 통해 효율적인 워크플로우를 지원하며, 일반적인 문제점과 해결책을 포함한 체크리스트도 제공합니다. 이 가이드는 데이터 분석, 과학적 컴퓨팅, 재현 가능한 연구 보고서 작성에 이상적이며, Claude Code, Cursor, Codex와 같은 AI 에이전트가 Emacs Org Mode 노트북을 생성하고 이해하는 데 유용합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pwquint24/org-babel-agent-skills/tree/HEAD/skills/org-babel-notebook

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

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

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

문서

Org Babel을 사용한 계산 노트북 작성

Org Babel은 Emacs Org Mode를 대화형 다중 언어 계산 노트북 환경으로 변환합니다. Jupyter나 Mathematica와 마찬가지로 Org Babel은 실행 가능한 코드, 라이브 실행 결과, 그림, 표, 설명 텍스트를 함께 배치합니다. JSON 기반 노트북과 달리 Org 노트북은 일반 텍스트로 사람이 읽을 수 있으며, Git을 통해 네이티브로 버전 관리할 수 있고, 단일 문서 내에서 여러 프로그래밍 언어를 혼합하여 사용할 수 있습니다.


1. 핵심 아키텍처 및 관심사 분리

모든 Org Babel 노트북은 헤더 인수(header arguments)에 의해 제어되는 다섯 가지 구별되는 관심사로 작동합니다. 이들을 혼동하는 것이 Org 노트북 버그의 주요 원인입니다.

관심사주요 헤더 인수제어 대상
실행:session, :eval, :dir, :var, :cache블록이 실행되는지, 어떤 프로세스에서, 어디서, 어떤 입력으로 실행되는지
결과:results (value vs output, 형식, 유형, 처리)실행 결과로 무엇을 캡처하고 버퍼에 어떻게 렌더링할지
내보내기:exports (code, results, both, none)내보낸 보고서(HTML, PDF, Markdown)에 무엇이 나타나는지
탱글링:tangle, :shebang, :noweb디스크의 독립 실행형 소스 코드 파일로 무엇을 추출할지
구성:var, #+CALL:, <<noweb>>, org-sbe블록이 서로 데이터나 코드를 어떻게 주고받는지

2. 노트북 구조 및 서문 설정

Org 노트북 파일(.org)은 문서 메타데이터와 버퍼 전체 기본 설정으로 시작하며, 그 뒤에 계층적 제목 아래 설명 텍스트, 수학 공식, 코드 블록이 옵니다.

2.1 표준 노트북 서문 템플릿

#+TITLE: 실험 X의 계산 분석
#+AUTHOR: 홍길동
#+DATE: [2025-05-18 Sun]
#+OPTIONS: toc:2 num:t ^:{}
#+STARTUP: overview hideblocks inlineimages

# 이 버퍼의 모든 블록에 대한 전역 Babel 기본값:
#+PROPERTY: header-args :eval yes :exports both :results drawer
# 언어별 기본값:
#+PROPERTY: header-args:python :session *py-analysis* :results value :exports both
#+PROPERTY: header-args:R :session *R-analysis* :results value :exports both
#+PROPERTY: header-args:sh :session none :results output :exports both

주요 버퍼 내 설정:

  • #+STARTUP: inlineimages: 결과가 삽입되거나 버퍼가 열릴 때 생성된 플롯/이미지를 자동으로 인라인 표시합니다.
  • #+STARTUP: hideblocks: 코드 블록을 접은 상태로 시작하여, 가독성을 위해 설명 텍스트와 결과만 표시합니다.
  • #+STARTUP: nohideblocks: 모든 코드 블록을 펼쳐서 표시합니다.
  • #+PROPERTY: header-args ...: 버퍼 전체 기본값입니다. header-args+로 추가할 수 있습니다.

2.2 Emacs 설정에서 언어 활성화

Org는 기본적으로 Emacs Lisp 평가만 활성화합니다. 다른 모든 언어는 Emacs 설정에 명시적으로 로드해야 합니다.

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (python     . t)
   (R          . t)
   (shell      . t)
   (sqlite     . t)
   (gnuplot    . t)
   (C          . t)))

신뢰할 수 있는 노트북에 대해 대화형 실행 확인 대화상자를 피하려면:

;; nil은 확인 프롬프트 없이 블록 실행을 허용합니다.
(setq org-confirm-babel-evaluate nil)

3. 코드 블록 구조

#+NAME: <블록_이름>
#+HEADER: <추가_헤더_인수>
#+BEGIN_SRC <언어> <스위치> <헤더_인수>
  <본문>
#+END_SRC
  • #+NAME: <이름>: 선택적 고유 식별자입니다. 블록이 함수로 참조되거나, :var를 통해 다른 블록의 입력으로 전달되거나, #+CALL:을 통해 호출되는 경우 필수입니다.
  • <언어>: Babel이 인식하는 식별자 (python, R, sh, emacs-lisp, sqlite, sql, julia, calc, gnuplot 등).
  • <스위치>: 선택적 스위치입니다 (예: 내보내기 시 줄 번호 매기기를 위한 -n, 레이블 제거를 위한 -r).
  • <헤더_인수>: 실행, 결과 및 내보내기를 제어하는 키-값 쌍입니다.
  • #+HEADER:: 긴 헤더 인수 목록을 깔끔하게 지정하기 위한 보조 줄입니다.

인라인 코드 블록

단락 내에 동적으로 계산된 값을 삽입하려면:

최종 계산 정확도는 src_python[:session *py* :results value]{f"{acc * 100:.2f}%"}였습니다.

4. 헤더 인수 참조

4.1 세션 관리: 대화형 탐색 vs 밀폐형 재현성

  • :session none (기본값): 1회성 외부 인터프리터 프로세스에서 블록을 평가합니다. 밀폐형이며 깔끔하고 상태 오염을 피하지만, 실행할 때마다 임포트와 환경을 다시 초기화합니다.
  • :session <이름>: 지속적인 Emacs 하위 REPL 버퍼(예: *py-analysis*)에서 평가합니다.
    • 변수, 함수 및 임포트된 모듈이 동일한 세션 이름을 공유하는 여러 블록에서 유지됩니다.
    • 대용량 데이터셋, 대규모 모델 가중치 및 탐색적 워크플로우에 필수적입니다.
    • 모범 사례: 프로토타이핑 시 :session <이름>을 사용하고, 최종 검증 시 세션을 다시 시작하거나 주요 섹션을 :session none으로 테스트하여 재현성을 보장합니다.

4.2 작업 디렉토리 및 원격 환경

  • :dir /path/to/project: 지정된 디렉토리 내에서 블록을 실행합니다.
  • :mkdirp yes: 대상 디렉토리가 없으면 생성합니다.
  • 원격 실행 (TRAMP): :dir /ssh:user@gpu-cluster:/workspace/data는 로컬 Emacs 버퍼 내에서 출력을 렌더링하면서 서버에서 블록을 원격으로 실행합니다.

4.3 비용이 많이 드는 계산 캐싱

  • :cache yes: 블록 텍스트, 입력 및 :var 매개변수의 SHA1 해시를 계산합니다.
  • 해시가 #+RESULTS[hash]: 줄에 저장된 해시와 일치하면 평가를 건너뛰고 캐시된 결과를 유지합니다.
  • 외부 부작용이 없는 결정론적이고 순수한 계산에만 사용하십시오.

5. 결과 처리: 중요한 차이점

:results 인수는 최대 4개의 직교 구성 요소를 사용합니다.

:results [수집] [유형] [형식] [처리]

5.1 수집: 함수형 (value) vs 스크립팅 (output)

이 차이점을 이해하면 Babel 혼동의 90%를 없앨 수 있습니다.

수집 모드캡처 대상Python 동작셸 동작
:results value (Python, R, elisp의 기본값)마지막 표현식의 반환 값 또는 명시적 return.명시적 return <val> 문을 사용해야 합니다. 모든 print() 출력은 폐기됩니다.종료 코드 또는 문자열 값을 반환합니다.
:results output (shell, bash의 기본값)실행 중 생성된 stdout 스트림.모든 print() 문을 캡처합니다. 모든 return은 무시됩니다.모든 명령 stdout(echo, ls 등)을 캡처합니다.

Python 함수형 예제 (:results value):

#+BEGIN_SRC python :results value
  data = [1, 2, 3, 4]
  # 함수형 모드에서는 Python에서 명시적 return이 필요합니다:
  return sum(data)
#+END_SRC

#+RESULTS:
: 10

Python 스크립팅 예제 (:results output):

#+BEGIN_SRC python :results output
  for i in range(3):
      print(f"Epoch {i}: loss={0.5/(i+1):.4f}")
#+END_SRC

#+RESULTS:
: Epoch 0: loss=0.5000
: Epoch 1: loss=0.2500
: Epoch 2: loss=0.1667

5.2 결과 유형

  • table / vector: 반환된 리스트/배열을 Org Mode 테이블로 형식화합니다.
  • scalar / verbatim: 출력을 테이블 형식 없이 원시 인용 텍스트로 형식화합니다.
  • file: 출력을 디스크의 파일로 보내고 (:file <파일명>으로 지정) Org 파일 링크를 결과에 삽입합니다.

5.3 결과 형식

  • drawer (권장): 결과를 :RESULTS: ... :END: 구분 기호로 감쌉니다. 여러 줄 출력에 특히 문서를 깔끔하게 유지합니다.
  • raw: 출력을 이스케이프되지 않은 Org 텍스트로 직접 삽입합니다 (동적 제목 또는 테이블 생성에 유용).
  • code: 출력을 #+BEGIN_SRC <언어> ... #+END_SRC로 감쌉니다.
  • link / graphics: 결과를 이미지/파일 경로로 처리하고 [[file:path]]를 생성합니다.

5.4 처리

  • replace (기본값): 이전 #+RESULTS: 블록을 대체합니다.
  • append: 기존 결과 아래에 새 결과를 추가합니다.
  • prepend: 기존 결과 위에 새 결과를 삽입합니다.
  • silent: 결과를 Org 버퍼에 쓰지 않고 Emacs 에코 영역/미니버퍼에 표시합니다.

6. 노트북의 시각화 및 그림

노트북에 직접 렌더링되는 플롯과 그림을 생성하려면:

6.1 Python Matplotlib 플롯

#+NAME: plot-normal-distribution
#+BEGIN_SRC python :session *py-vis* :results graphics file :file figures/normal_dist.png :exports both
  import matplotlib.pyplot as plt
  import numpy as np

  plt.figure(figsize=(6, 3.5))
  x = np.linspace(-3, 3, 200)
  plt.plot(x, np.exp(-x**2 / 2) / np.sqrt(2 * np.pi), color="#2b5c8f", lw=2)
  plt.title("표준 정규 분포")
  plt.xlabel("z")
  plt.ylabel("밀도")
  plt.tight_layout()
  plt.savefig("figures/normal_dist.png", dpi=150)
  plt.close()
#+END_SRC

#+RESULTS: plot-normal-distribution
[[file:figures/normal_dist.png]]

6.2 R ggplot2 플롯

#+NAME: r-scatter-plot
#+BEGIN_SRC R :session *r-vis* :results graphics file :file figures/r_scatter.png :exports both
  library(ggplot2)
  p <- ggplot(mtcars, aes(x=wt, y=mpg, color=factor(cyl))) +
    geom_point(size=3) +
    theme_minimal() +
    labs(title="연비 vs 무게", x="무게 (1000 lbs)", y="MPG")
  ggsave("figures/r_scatter.png", plot=p, width=6, height=4, dpi=150)
#+END_SRC

#+RESULTS: r-scatter-plot
[[file:figures/r_scatter.png]]

팁: Emacs에서 M-x org-toggle-inline-images (C-c C-x C-v)를 실행하여 버퍼 내에서 생성된 그래픽 표시를 전환합니다.


7. 대화형 실행 및 편집 워크플로우

필수 키바인딩

키바인딩명령설명
C-c C-corg-babel-execute-src-block커서 아래 블록을 실행하고 결과를 삽입/업데이트합니다.
C-c 'org-edit-special전용 메이저 모드 버퍼(전체 LSP, 구문 강조, 자동 완성)에서 블록 본문을 엽니다. C-c '을 다시 눌러 저장하고 돌아갑니다.
C-c C-v borg-babel-execute-buffer노트북의 모든 코드 블록을 순차적으로 실행합니다("모든 셀 실행"과 유사).
C-c C-v sorg-babel-execute-subtree현재 제목 아래의 모든 코드 블록을 실행합니다.
C-c C-oorg-open-at-point#+RESULTS: 링크에서 외부 뷰어나 버퍼로 이미지 또는 생성된 파일을 엽니다.
M-<down>org-babel-pop-to-session이 블록의 세션에 대한 대화형 REPL 버퍼로 직접 포커스를 전환합니다.
C-c C-v vorg-babel-expand-src-block완전히 확장된 블록(모든 :var 및 noweb 확장이 해결된 상태)을 미리 봅니다.

8. 보고서 내보내기 및 게시

노트북을 독립형 HTML, PDF 또는 Markdown 문서로 직조할 수 있습니다.

8.1 :exports로 내보내기 콘텐츠 제어

  • :exports code: 코드 블록만 내보냅니다.
  • :exports results: 출력/그림만 내보냅니다(코드를 숨김, 임원 보고서에 이상적).
  • :exports both: 코드와 출력을 모두 내보냅니다(기술 문서에 이상적).
  • :exports none: 내보낸 문서에서 코드와 결과를 모두 숨깁니다(필요한 경우 평가 중에 실행).

8.2 :eval로 내보내기 평가 제어

  • :eval never-export: 내보내기 중에 블록을 다시 실행하지 못하도록 하여 버퍼의 기존 #+RESULTS:를 사용합니다. 내보내기 속도를 높이고 비결정적 변경을 방지합니다.
  • :eval query-export: 내보내기 중 실행 전에 확인을 요청합니다.

8.3 내보내기 명령

  • C-c C-e h h (org-html-export-to-html): HTML 보고서를 생성합니다.
  • C-c C-e h o (org-html-export-to-html-and-open): 생성하고 브라우저에서 HTML을 엽니다.
  • C-c C-e l p (org-latex-export-to-pdf): LaTeX를 통해 조판된 PDF 보고서를 생성합니다.

9. 일반적인 문제점 및 문제 해결 체크리스트

증상 / 오류원인해결 방법
Python 블록이 결과를 반환하지 않음print(...)와 함께 :results value를 사용했지만 return ...을 사용하지 않음print(...)를 return ...로 바꾸거나 헤더를 :results output으로 변경하십시오.
<lang>에 대한 No org-babel-execute function 오류org-babel-load-languages에 언어가 등록되지 않음Emacs 설정의 org-babel-load-languages에 (<lang> . t)를 추가하고 평가하십시오.
이미지 링크는 생성되지만 이미지가 표시되지 않음Org Mode에서 인라인 이미지가 꺼져 있음M-x org-toggle-inline-images (C-c C-x C-v)를 실행하거나 #+STARTUP: inlineimages를 추가하십시오.
세션 출력에 반복적인 프롬프트(>>>)가 포함됨REPL 버퍼에 남아 있는 대화형 프롬프트 텍스트세션 버퍼(*session-name*)를 정리하거나 다시 시작하십시오.
내보내기가 느리거나 중단됨Org가 내보내기 중에 모든 노트북 블록을 다시 실행 중장기 실행 블록에 :eval never-export를 설정하거나 #+PROPERTY: header-args :eval never-export를 통해 전역적으로 설정하십시오.
테이블 입력이 가로 규칙에서 오류를 생성함가로 규칙(`-`)이 원시 행으로 처리됨

10. 완전한 주석 노트북 예제

#+TITLE: 태양 플레어 빈도 분석
#+AUTHOR: Dr. Alex Rivera
#+DATE: [2025-05-18 Sun]
#+OPTIONS: toc:nil num:nil
#+STARTUP: inlineimages nohideblocks
#+PROPERTY: header-args :session *solar* :results drawer :exports both

* 소개
6개월 관찰 기간 동안 기록된 관측 플레어 빈도를 분석합니다.

* 원시 관측 데이터
다음은 기준 측정 테이블입니다:

#+NAME: raw_observations
| 월    | C-Class | M-Class | X-Class |
|-------+---------+---------+---------|
| 1월   |      12 |       3 |       0 |
| 2월   |      19 |       5 |       1 |
| 3월   |      15 |       2 |       0 |
| 4월   |      27 |       8 |       2 |
| 5월   |      31 |      11 |       3 |
| 6월   |      22 |       7 |       1 |

* 데이터 처리 및 요약 통계
Python을 사용하여 총 태양 활동을 계산합니다:

#+NAME: compute_totals
#+BEGIN_SRC python :var obs=raw_observations :colnames yes :results value table
  total_events = []
  for row in obs:
      month = row[0]
      total = sum(row[1:])
      total_events.append([month, total])
  return [["월", "총 이벤트 수"]] + total_events
#+END_SRC

#+RESULTS: compute_totals
:RESULTS:
| 월  | 총 이벤트 수 |
|------+-------------|
| 1월 |          15 |
| 2월 |          25 |
| 3월 |          17 |
| 4월 |          37 |
| 5월 |          45 |
| 6월 |          30 |
:END:

* 시각화
Matplotlib를 사용하여 월별 총 이벤트를 표시합니다:

#+NAME: plot-monthly-totals
#+BEGIN_SRC python :session *solar* :results graphics file :file figures/monthly_totals.png :exports both
  import matplotlib.pyplot as plt

  months = ["1월", "2월", "3월", "4월", "5월", "6월"]
  totals = [15, 25, 17, 37, 45, 30]

  plt.figure(figsize=(8, 4))
  plt.bar(months, totals, color="tab:orange")
  plt.title("월별 총 태양 플레어 이벤트")
  plt.xlabel("월")
  plt.ylabel("이벤트 수")
  plt.savefig("figures/monthly_totals.png", dpi=150)
  plt.close()
#+END_SRC

#+RESULTS: plot-monthly-totals
[[file:figures/monthly_totals.png]]


* 결론
5월에 피크 활동이 관찰되었으며, 45개의 이벤트(주로 C-Class 및 M-Class)가 기록되었습니다. 다음 관찰 기간 동안 X-Class 이벤트를 지속적으로 모니터링해야 합니다.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

관련 스킬