Initial commit: ABAP indexing pipeline (ingest, parser, summarize, index, query, wiki)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
# 질의 확장용 도메인 용어 사전 초기 시드 (계획서 §5.6)
|
||||
# 형식 — 용어: [동의어/관련 테이블/T-Code ...]
|
||||
#
|
||||
# 이 사전은 두 곳에서 같이 쓰인다 (config/glossary.py):
|
||||
# 1) query/expand.py — 검색 질의 확장 ("입고"로 물어도 GR·MSEG·101 로 색인된 문서를 찾는다)
|
||||
# 2) wiki_out/run.py — concepts/ 위키 문서 생성
|
||||
# 양방향으로 동작한다: 대표어로도, 동의어 중 아무거나로도 질의가 걸린다.
|
||||
총계정원장: [G/L, GL, 원장, ACDOCA, ACDOCT, SKAT, FAGLL03, FS10N]
|
||||
전표: [회계전표, BKPF, BSEG, ACDOCA, FB03]
|
||||
반제: [클리어링, 미결정리, BSIS, BSAS, F-03, F.13]
|
||||
제조원가: [원가계산, CO-PC, 오더결산, COEP, COSS, CKMLHD, KKS1, KO88]
|
||||
코스트센터: [CCTR, CSKS, KSB1]
|
||||
회계단위: [회사코드, BUKRS, T001]
|
||||
계정과목: [계정, RACCT, SAKNR, SKA1, SKAT]
|
||||
사업영역: [BUSA, GSBER]
|
||||
기능영역: [FAREA, RFAREA]
|
||||
손익: [P/L, 손익계산서, GVTYP]
|
||||
잔액: [기말잔액, 이월, HSL, BALANCE]
|
||||
# MM — 샘플에 ZMMR* 프로그램이 있어 함께 시드한다 (계속 확장 대상)
|
||||
입고: [GR, Goods Receipt, 101, MSEG, MKPF, MB51, MIGO]
|
||||
출고: [GI, Goods Issue, 201, 261, MSEG, MB1A]
|
||||
자재: [품목, 자재마스터, MATNR, MARA, MAKT, MM03]
|
||||
자재문서: [물자문서, MBLNR, MKPF, MSEG, MB51]
|
||||
구매오더: [PO, Purchase Order, EBELN, EKKO, EKPO, ME23N]
|
||||
구매요청: [PR, Purchase Requisition, BANFN, EBAN, ME53N]
|
||||
재고: [재고수량, LABST, MARD, MBEW, MMBE]
|
||||
이동유형: [BWART, 이동타입, movement type]
|
||||
플랜트: [WERKS, 사업장, T001W]
|
||||
저장위치: [LGORT, 창고, T001L]
|
||||
공급업체: [벤더, LIFNR, LFA1, XK03]
|
||||
송장: [인보이스, Invoice, RBKP, RSEG, MIRO]
|
||||
@@ -0,0 +1,67 @@
|
||||
"""도메인 용어 사전 로더 (계획서 §5.6, 수정사항 4번).
|
||||
|
||||
`config/domain_glossary.yaml` 은 의존성을 늘리지 않으려고 YAML 파서 없이 읽는다.
|
||||
지원 형식은 한 줄 리스트뿐이다:
|
||||
|
||||
총계정원장: [G/L, GL, 원장, ACDOCA, SKAT, FAGLL03]
|
||||
|
||||
질의 확장(query/expand.py)과 concepts 위키 생성(wiki_out/run.py)이 같은 사전을 쓰도록
|
||||
로딩을 여기로 모았다 (이전에는 wiki_out/run.py 안에 인라인 정규식으로만 있었다).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
from .settings import ROOT
|
||||
|
||||
# "용어: [동의어, 동의어]" — 주석(#)·빈 줄·중첩 키(tags:)는 건너뛴다
|
||||
GLOSSARY_LINE = re.compile(r"^([^#:\s][^:]*):\s*\[(.*)\]\s*$")
|
||||
|
||||
DEFAULT_PATH = ROOT / "config" / "domain_glossary.yaml"
|
||||
|
||||
|
||||
def parse_glossary(text: str) -> dict[str, list[str]]:
|
||||
"""사전 텍스트 → {대표어: [동의어...]}"""
|
||||
out: dict[str, list[str]] = {}
|
||||
for line in text.splitlines():
|
||||
m = GLOSSARY_LINE.match(line.strip())
|
||||
if not m:
|
||||
continue
|
||||
term = m.group(1).strip()
|
||||
syns = [t.strip() for t in m.group(2).split(",") if t.strip()]
|
||||
if term:
|
||||
out[term] = syns
|
||||
return out
|
||||
|
||||
|
||||
@lru_cache(maxsize=4)
|
||||
def load_glossary(path: Path | None = None) -> dict[str, list[str]]:
|
||||
p = path or DEFAULT_PATH
|
||||
if not p.exists():
|
||||
return {}
|
||||
return parse_glossary(p.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
@lru_cache(maxsize=4)
|
||||
def synonym_map(path: Path | None = None) -> dict[str, list[str]]:
|
||||
"""양방향 동의어 맵 — 대표어로도, 동의어로도 질의가 들어올 수 있다.
|
||||
|
||||
"입고" → [GR, MSEG, 101 …] 뿐 아니라 "GR" → [입고, MSEG …] 도 성립해야 한다.
|
||||
키는 대문자 정규화(한글은 그대로)해 비교한다.
|
||||
"""
|
||||
glossary = load_glossary(path)
|
||||
groups: list[set[str]] = [{term, *syns} for term, syns in glossary.items()]
|
||||
out: dict[str, list[str]] = {}
|
||||
for group in groups:
|
||||
for member in group:
|
||||
key = member.upper()
|
||||
others = [m for m in group if m.upper() != key]
|
||||
if not others:
|
||||
continue
|
||||
bucket = out.setdefault(key, [])
|
||||
for o in others:
|
||||
if o not in bucket:
|
||||
bucket.append(o)
|
||||
return out
|
||||
@@ -0,0 +1,57 @@
|
||||
"""전역 설정. 모든 외부 접점(LLM/임베딩/DB/서버)은 환경변수로만 결정한다."""
|
||||
from pathlib import Path
|
||||
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_file=ROOT / ".env", env_file_encoding="utf-8", extra="ignore")
|
||||
|
||||
# DB — 기본은 SQLite(개발/폐쇄망 무의존). PostgreSQL 전환은 ASSUMPTIONS.md 참고.
|
||||
database_url: str = f"sqlite:///{ROOT / 'data' / 'index.db'}"
|
||||
|
||||
# LLM (Stage 3 요약) — OpenAI 호환 엔드포인트 가정
|
||||
llm_base_url: str = ""
|
||||
llm_api_key: str = ""
|
||||
llm_model: str = "glm-5.2"
|
||||
# 요약 배치의 동시 LLM 호출 수. DB 쓰기는 메인 스레드에 남기고 호출만 병렬로 돈다.
|
||||
llm_concurrency: int = 4
|
||||
llm_timeout_s: int = 180
|
||||
# 429/5xx 재시도 — 동시성을 올리면 429 가 늘어나므로 백오프와 같이 써야 한다
|
||||
llm_max_retries: int = 5
|
||||
llm_backoff_base: float = 2.0
|
||||
llm_backoff_max: float = 60.0
|
||||
# /ingest 가 뒤이어 돌리는 요약의 백엔드:
|
||||
# api — 환경변수 키로 호출 (키가 유효할 때)
|
||||
# file — 프롬프트를 data/llm_jobs/ 에 쌓아두고 사람·에이전트가 채운다 (키 불필요)
|
||||
# off — 자동 요약을 하지 않는다 (배치로만 돌린다)
|
||||
summarize_backend: str = "api"
|
||||
|
||||
# 임베딩 — 모델 미정(§10). 비워두면 벡터 검색 비활성(FTS만 사용).
|
||||
embed_base_url: str = ""
|
||||
embed_api_key: str = ""
|
||||
embed_model: str = ""
|
||||
|
||||
# 질의 서비스
|
||||
index_host: str = "127.0.0.1"
|
||||
index_port: int = 8100
|
||||
|
||||
# 데이터 디렉토리
|
||||
data_raw: Path = ROOT / "data" / "raw"
|
||||
data_normalized: Path = ROOT / "data" / "normalized"
|
||||
data_parsed: Path = ROOT / "data" / "parsed"
|
||||
data_summaries: Path = ROOT / "data" / "summaries"
|
||||
# file 백엔드의 프롬프트/응답 큐 — LLM 키 없이 요약을 돌리는 입구 (summarize/jobs.py)
|
||||
data_llm_jobs: Path = ROOT / "data" / "llm_jobs"
|
||||
|
||||
# 위키 (계획서 v4 §5.7 — OKF v0.2 출력, 의미 검색의 1차 대상)
|
||||
wiki_dir: Path = ROOT / "wiki"
|
||||
# 위키 검색 백엔드: qmd | pg (M3.5 파일럿으로 확정 — 계획서 §6.5)
|
||||
# "pg" 는 내장 DB 검색 경로를 뜻함. 현 구현은 SQLite FTS5 (ASSUMPTIONS.md §1).
|
||||
wiki_search_backend: str = "pg"
|
||||
qmd_url: str = "http://127.0.0.1:8181"
|
||||
|
||||
|
||||
settings = Settings()
|
||||
@@ -0,0 +1,40 @@
|
||||
# 허용 업무 태그 초기 시드 (계획서 §5.6) — 첫 300본 요약 후 proposed_tags 집계로 확장
|
||||
tags:
|
||||
# FI
|
||||
- 전표
|
||||
- 총계정원장
|
||||
- 계정잔액
|
||||
- 반제
|
||||
- 자동반제
|
||||
- 미결관리
|
||||
- 결산
|
||||
- 월별비교
|
||||
- 채권관리
|
||||
- 채무관리
|
||||
- 지급처리
|
||||
- 세금계산서
|
||||
- 부가세
|
||||
- 원천세
|
||||
- 고정자산
|
||||
- 예산관리
|
||||
- 자금관리
|
||||
- 인사연동
|
||||
- 급여전기
|
||||
- 경비처리
|
||||
# CO
|
||||
- 제조원가
|
||||
- 표준원가
|
||||
- 오더결산
|
||||
- 차이분석
|
||||
- 배부
|
||||
- 코스트센터
|
||||
- 수익성분석
|
||||
- 내부오더
|
||||
# 공통
|
||||
- 인터페이스
|
||||
- 배치작업
|
||||
- 마스터관리
|
||||
- 권한관리
|
||||
- 리포트
|
||||
- 대사작업
|
||||
- 마감작업
|
||||
Reference in New Issue
Block a user