jsahnandClaude Fable 5 cdd070749b Backfill guard: a past week's digest only takes papers published by its end
Backfilling an old week used to sweep in undigested papers published later
(stamping them into the wrong week and removing them from the next Monday's
digest); regular weekly runs are unaffected since the collection window
already ends at week_end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-10-20 14:06:25 +09:00
2026-09-02 14:57:29 +09:00
2026-09-02 14:57:29 +09:00
2026-09-02 14:57:29 +09:00
2026-09-02 14:57:29 +09:00

SE-Brief — OA 소프트웨어공학 논문 주간 다이제스트 봇

매주 월요일 아침(07:00 KST), 지난주(월~일)에 발행된 오픈액세스(OA) 소프트웨어공학 논문을 OpenAlex에서 수집하고 MiniMax LLM으로 한국어 다이제스트를 만들어 내부 게시(파일 아카이브 + tailnet 대시보드)하는 상주 프로그램입니다. 설계 문서는 SEBRIEF_PLAN.md를 참고하세요. US2KR의 파이프라인 철학을 그대로 따르는 별도 프로젝트입니다.

수집(OpenAlex · RSS) → SQLite 저장(DOI 중복 방지)
  → 논문별 요약(한줄요약·문제·방법·결과·시사점, DOI당 한 번 생성 후 재사용) + 배치 팩트체크
  → 주간 다이제스트 요약(JSON 스키마) → LLM 교차 검증(초록 대조 팩트체크, major면 1회 자동 수정)
  → Markdown 렌더 → 파일 아카이브 + 대시보드

수집 소스 (sebrief/sources.py)

소스 방식
TOSEM (완전 OA) ISSN 화이트리스트, 전량
TSE (하이브리드, IEEE) ISSN 화이트리스트 + OA 필터. OpenAlex 색인이 2~3개월 늦어 Crossref로 신간 보조 수집(논문 단위 CC 라이선스 = OA 판별). Crossref에는 초록이 없어 신간은 "초록 미제공"으로 실리고, OpenAlex 색인 시 초록이 보강됨
EMSE · IST · JSS (하이브리드) ISSN 화이트리스트 + 논문 단위 is_oa 필터
SoftwareX · JOSS 전량 (도구/소프트웨어 논문)
IEEE Access · PeerJ CS (메가저널) ISSN + OpenAlex Software 토픽(topics.subfield.id:1712) + 키워드 이중 필터
e-Informatica SEJ 등 SEBRIEF_RSS_FEEDS로 RSS 보조 (DOI 없는 항목은 스킵)
MDPI 전 저널 제외 — ISSN 블랙리스트 + 발행사 이름 검사로 이중 차단
  • 한 논문은 DOI 기준으로 한 번만 요약됩니다. 다이제스트에 실린 논문은 동결(frozen)되어 재수집돼도 스킵되고, 수집 창(SEBRIEF_BACKFILL_DAYS)에 늦게 들어온 논문·캡 초과 논문은 다음 주로 이월됩니다.
  • 다이제스트 idempotency 키는 ISO 주차(2026-W36) — US2KR의 krx_date 역할.

설치

# Python 3.12 + uv
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e ".[dev]"

cp .env.example .env   # MINIMAX_API_KEY 필수

사용

.venv/bin/python -m sebrief.cli show-config            # 설정 확인(시크릿 마스킹)
.venv/bin/python -m sebrief.cli next-run               # 다음 다이제스트 주차/시각
.venv/bin/python -m sebrief.cli run-once --dry-run     # 지금 즉시 생성해서 터미널에 출력(발행 X)
.venv/bin/python -m sebrief.cli run-once --dry-run --no-llm   # LLM 없이 논문 목록만(축소 모드)
.venv/bin/python -m sebrief.cli run-once --week 2026-W35      # 특정 주차 생성·발행(끝난 주만)
.venv/bin/python -m sebrief.cli run-once --force       # 이미 발행된 주여도 다시(재발행)
.venv/bin/python -m sebrief.cli test-notify            # 발행 채널 점검(errors.log 기록)
.venv/bin/python -m sebrief.cli daemon                 # 상주 실행(주간 스케줄러)

종료 코드: 0 성공 · 1 오류(발행 채널 실패 포함) · 2 스킵(이미 발행)

아직 끝나지 않은 주를 --week로 지정하면 --dry-run이 아닌 한 거부합니다(늦게 발행되는 논문이 동결돼 누락되고, 데몬의 정규 실행이 "이미 발행"으로 건너뛰기 때문). 발행 테스트는 --week <지난 주> --force로 하세요.

상주 실행(배포)

프로세스 생존은 OS에 맡기고, 프로그램은 "다음 실행 시각 계산 → 대기 → 실행"만 반복합니다. 재시작 후 실행 시각에서 SEBRIEF_CATCHUP_WINDOW_HOURS(기본 72시간) 이내면 놓친 다이제스트를 즉시 따라잡고, SQLite 기록으로 중복 발행을 막습니다. 주 1회 작업이라 월~목 사이 언제 재기동해도 따라잡습니다.

환경 방법
macOS bash deploy/install-launchd.sh (launchd, KeepAlive)
macOS (Apple container) bash deploy/install-apple-container.sh — 데몬+대시보드 빌드·기동. --boot를 붙이면 로그인 시 자동 기동(LaunchAgent) 등록
Linux deploy/sebrief.service → systemctl enable --now sebrief
Docker docker compose -f deploy/compose.yaml up -d --build

data/ reports/ logs/는 호스트 디렉터리를 그대로 마운트하므로 배포 방식과 무관하게 산출물 위치가 같습니다.

설정(.env)

변수 기본값 설명
MINIMAX_API_KEY — 필수. 글로벌 엔드포인트(api.minimax.io) 키
MINIMAX_MODEL / MINIMAX_FALLBACK_MODELS MiniMax-M3 / M2.7,M2.5 실패 시 순차 폴백
SEBRIEF_OPENALEX_MAILTO — 이메일을 넣으면 OpenAlex polite pool (더 빠르고 안정적)
SEBRIEF_BACKFILL_DAYS 7 수집 창을 주 시작보다 며칠 앞당길지 (늦은 색인 보완)
SEBRIEF_MAX_PAPERS 60 다이제스트당 최대 논문 수 — 폭주 방어 안전판 (초과분은 다음 주 이월)
SEBRIEF_PAPER_SUMMARY_ENABLED true 논문 한 편씩 구조화 요약 생성 (초록 없는 논문은 스킵, 실패 배치는 다음 실행에서 재시도)
SEBRIEF_PAPER_SUMMARY_BATCH_SIZE 8 논문별 요약 LLM 호출당 논문 수
SEBRIEF_RSS_FEEDS — 보조 RSS CSV, 항목 이름|URL
SEBRIEF_EXTRA_BLACKLIST_ISSNS — 기본 MDPI 블랙리스트에 더해 차단할 ISSN CSV
SEBRIEF_RUN_WEEKDAY / SEBRIEF_RUN_TIME_KST 0 / 07:00 실행 요일(0=월)·시각
SEBRIEF_CATCHUP_WINDOW_HOURS 72 재시작 시 따라잡기 허용 창
SEBRIEF_VERIFY_ENABLED true 요약 후 LLM 팩트체크(초록과 대조) — 주간 다이제스트와 논문별 요약 배치 모두. major 이슈 발견 시 1회 자동 수정 후 재검증. 검증 실패는 발행을 막지 않고 결과는 JSON·대시보드에 기록
SEBRIEF_LOG_LEVEL INFO 로그 레벨

산출물

  • reports/YYYY-Wnn.md, .json — ISO 주차 기준 아카이브. 주간 총평·하이라이트·주제별 그룹에 더해 논문별 요약 카드(한줄요약·문제·방법·결과·시사점)를 전 논문에 대해 포함
  • data/sebrief.sqlite3 — 논문(DOI 중복 방지·동결)·논문별 요약·다이제스트·발행 기록
  • logs/sebrief.log — 일자별 회전, API 키 마스킹

대시보드 (dashboard/)

쌓인 다이제스트를 보는 웹 대시보드(TypeScript, 런타임 의존성 없는 Node 24 서버 + 번들 클라이언트). reports/*.json만 읽는 읽기 전용 뷰라 데몬의 SQLite(WAL)와 절대 경합하지 않습니다.

  • 선택 주차 요약 타일(논문·저널·하이라이트·주제 그룹·검증 상태), 주차별 논문 수 추이 차트(표 전환 가능)
  • 다이제스트 목록(주차 갭 표시)/본문(Markdown 렌더, sanitize), 수집 결측·오류 로그 표시
  • tailnet 전용, Apple container 배포 시 함께 기동: http://localhost:8091 (포트: SEBRIEF_DASHBOARD_PORT)
cd dashboard
npm install
npm run build        # tsc 타입체크 + esbuild 번들
SEBRIEF_REPORTS_DIR=../reports npm start   # http://localhost:8091

개발

.venv/bin/python -m pytest -q
.venv/bin/ruff check sebrief tests

LLM은 sebrief/llm/base.py의 LLMProvider 인터페이스 뒤에 있으므로, 다른 모델로 바꾸려면 구현체만 추가하면 됩니다. Blogger 공개 발행은 아직 붙이지 않았습니다 — US2KR의 BloggerDeliverer를 그대로 이식해 sebrief/deliver/__init__.py의 build_deliverers에 추가하면 됩니다(Deliverer 프로토콜 동일).

저작권

OA 논문의 한국어 요약 + 출처·DOI 링크 표기입니다. 초록 원문은 전재하지 않고 자기 언어의 요약으로 재구성합니다(내부 게시라 리스크가 낮지만 공개 전환 대비 처음부터 지킵니다).

S
Description
No description provided
Readme
245 KiB
Languages
Python 83.8%
TypeScript 11.1%
CSS 3%
Shell 1.3%
HTML 0.6%
Other 0.2%