docs: 인덱싱 가이드 — FabriX 직결(llm_client 헤더 패치)을 기본으로, -12 게이트웨이는 대안

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
lee-hyeon-cheol
2026-09-21 15:01:44 +09:00
co-authored by Claude Fable 5.1
parent e7158808a1
commit 55e3163695
+47 -43
View File
@@ -3,37 +3,62 @@
2026-09-21. ABAP_INDEXING 레포(팀원 소유)의 Stage 3(로직 조각 추출)을 고객사 -12 컨테이너에서 FabriX 로 돌리는 절차. 2026-09-21. ABAP_INDEXING 레포(팀원 소유)의 Stage 3(로직 조각 추출)을 고객사 -12 컨테이너에서 FabriX 로 돌리는 절차.
결과(`data/index.db`)는 CodeAssist 의 `abap_index_*` 툴이 씀 → `5_django_backend/README.md` "ABAP 소스 인덱스 붙이기". 결과(`data/index.db`)는 CodeAssist 의 `abap_index_*` 툴이 씀 → `5_django_backend/README.md` "ABAP 소스 인덱스 붙이기".
## 핵심: FabriX 에 직접 붙이지 말고 CodeAssist 게이트웨이를 거친다 ## 핵심: FabriX 직결 — 헤더 3종만 붙이면 됨
ABAP_INDEXING 의 LLM 클라이언트(`summarize/llm_client.py`)는 `Authorization: Bearer <키>` 하나만 보낸다. ABAP_INDEXING 의 LLM 클라이언트(`summarize/llm_client.py`)는 `Authorization: Bearer <키>` 하나만 보낸다.
FabriX 는 그걸 안 받고 `x-openapi-token` / `x-generative-ai-client` / `x-llm-model-id` 세 헤더를 요구한다 → 직접 붙이면 **401**. FabriX 는 그걸 안 받고 커스텀 헤더 3종을 요구한다 → 그대로 붙이면 **401**. 아래 패치(10줄)로 직결하면 -12 도 게이트웨이도 필요 없다.
(값·형식은 CodeAssist 게이트웨이 `apps/gateway/fabrix.py` 와 9/18 실측 그대로 — Bearer 접두 필수, `x-generative-ai-client`, body model 고정.)
CodeAssist 백엔드의 `/api/ito/chat/completions` 는 OpenAI 호환 입구고, 저 헤더를 알아서 얹어 FabriX 로 넘긴다(401 시 형식 재시도 포함). ### `summarize/llm_client.py` 패치
그러니 **`LLM_BASE_URL` 을 게이트웨이로** 주면 인덱싱 코드는 한 줄도 안 고쳐도 된다.
``` `_post_once` 에서 body 의 `model` 과 headers 만 바꾼다:
summarize.runner ──OpenAI 호환(Bearer)──▶ Django :8080/api/ito ──FabriX 헤더──▶ FabriX (x-llm-model-id=339)
```python
import os
def _post_once(self, system: str, user: str) -> dict:
body = {
"model": os.environ.get("FABRIX_BODY_MODEL", "/mnt/models"), # FabriX 규격: body 는 고정 경로, 모델은 헤더가 고름
"temperature": 0.1,
"messages": [{"role": "system", "content": system}, {"role": "user", "content": user}],
"response_format": {"type": "json_object"},
}
req = urllib.request.Request(
f"{self.base}/chat/completions",
data=json.dumps(body).encode("utf-8"),
headers={
"Content-Type": "application/json",
"x-llm-model-id": self.model, # LLM_MODEL=339
"x-generative-ai-client": os.environ["FABRIX_CLIENT_KEY"],
"x-openapi-token": "Bearer " + os.environ["FABRIX_OPENAPI_TOKEN"], # Bearer 접두 필수(날것은 401)
"x-generative-ai-user-email": os.environ.get("FABRIX_USER_EMAIL", ""),
},
method="POST",
)
with urllib.request.urlopen(req, timeout=settings.llm_timeout_s) as res:
return json.loads(res.read().decode("utf-8"))
``` ```
## 고객사 PC(윈도우)에서 돌릴 때 — -12 게이트웨이 경유 `.env` (고객사 PC 또는 -12, 어디서 돌리든 같음):
인덱싱은 고객사 PC 에서 돌리고, LLM 호출만 -12 의 CodeAssist 게이트웨이(바깥 포트 8914)로 보낸다. 헤더는 게이트웨이가 얹으니 코드 수정 없음.
(-12 백엔드가 떠 있어야 함: `curl http://10.196.81.34:8914/api/ito/models` 에 모델 3개.)
```ini ```ini
# ABAP_INDEXING/.env (고객사 PC) LLM_BASE_URL=https://<FabriX 호스트>/openapi/llm # CodeAssist .env 의 AAF_FABRIX_BASE_URL 과 같은 값. /chat/completions 는 코드가 붙임
LLM_BASE_URL=http://10.196.81.34:8914/api/ito LLM_API_KEY=unused # 클라이언트 생성자가 비어 있으면 에러 내서 아무 값
LLM_API_KEY=x # -12 .env 의 AAF_GATEWAY_KEY. 비어 있으면 아무 값 LLM_MODEL=339 # x-llm-model-id. GaussO Flash. Gemma(605/580) 금지 — 30~100배 느림
LLM_MODEL=339 # GaussO Flash. Gemma(605/580) 금지 — 30~100배 느림 FABRIX_CLIENT_KEY=... # = AAF_FABRIX_CLIENT_KEY
FABRIX_OPENAPI_TOKEN=... # = AAF_FABRIX_OPENAPI_TOKEN (Bearer 없이 날것. 코드가 붙임)
FABRIX_USER_EMAIL= # = AAF_FABRIX_USER_EMAIL (비어도 됨)
LLM_CONCURRENCY=2 # 429 안 나면 4 LLM_CONCURRENCY=2 # 429 안 나면 4
LLM_MAX_RETRIES=5 LLM_MAX_RETRIES=5
LLM_TIMEOUT_S=180 LLM_TIMEOUT_S=180
SUMMARIZE_BACKEND=api SUMMARIZE_BACKEND=api
``` ```
## 고객사 PC(윈도우)에서 돌리기
```powershell ```powershell
cd ABAP_INDEXING cd ABAP_INDEXING
python -m venv .venv; .venv\Scripts\pip install -e ".[dev]" # 고객사 PC 가 pip 되면. 안 되면 wheels 로 python -m venv .venv; .venv\Scripts\pip install -e ".[dev]" # pip 안 되면 wheels 로
# data # data
aw\*.txt 배치 aw\*.txt 배치
$env:PYTHONUTF8="1" $env:PYTHONUTF8="1"
@@ -45,20 +70,11 @@ $env:PYTHONUTF8="1"
``` ```
끝나면 `data\index.db` 를 -12 로 옮겨 거기서 `query.api`(:8100) 를 띄운다("끝나면" 절). PC 에서 8100 을 띄워도 -12 의 OpenCode 는 못 붙는다(컨테이너 → PC 방향 안 열림). 끝나면 `data\index.db` 를 -12 로 옮겨 거기서 `query.api`(:8100) 를 띄운다("끝나면" 절). PC 에서 8100 을 띄워도 -12 의 OpenCode 는 못 붙는다(컨테이너 → PC 방향 안 열림).
### 코드 못 고치는 상황이면 — -12 게이트웨이 경유 (대안) ### 코드 못 고치는 상황이면 — -12 게이트웨이 경유 (대안)
`summarize/llm_client.py` `_post_once` 의 headers 를 이렇게 바꾸면 -12 없이도 됨. 값은 CodeAssist `.env``AAF_FABRIX_*` 와 같음. CodeAssist 백엔드 `/api/ito` 가 헤더를 대신 얹어준다. 패치 없이 `.env` 만:
`LLM_BASE_URL=http://10.196.81.34:8914/api/ito`, `LLM_API_KEY=x`(-12 의 `AAF_GATEWAY_KEY`), `LLM_MODEL=339`.
```python
headers={
"Content-Type": "application/json",
"x-llm-model-id": self.model, # LLM_MODEL=339
"x-generative-ai-client": os.environ["FABRIX_CLIENT_KEY"],
"x-openapi-token": "Bearer " + os.environ["FABRIX_OPENAPI_TOKEN"], # Bearer 접두 필수(실측)
"x-generative-ai-user-email": os.environ.get("FABRIX_USER_EMAIL", ""),
}
# body["model"] 은 "/mnt/models" 로 고정 (FabriX 규격). LLM_BASE_URL 은 …/openapi/llm 까지.
-12 백엔드가 떠 있어야 하고 호출이 전부 -12 를 지나니 부하가 거기 걸림. 기본은 위 직결. -12 백엔드가 떠 있어야 하고 호출이 전부 -12 를 지나니 부하가 거기 걸림. 기본은 위 직결.
## -12 에서 준비 ## -12 에서 준비
@@ -78,19 +94,7 @@ cd /www/ABAP_INDEXING && python3 -m venv .venv
# 3) .env # 3) .env
cp .env.example .env && vi .env cp .env.example .env && vi .env
``` ```
`.env` 에 이렇게:
```ini
LLM_BASE_URL=http://127.0.0.1:8080/api/ito # CodeAssist 게이트웨이. 뒤에 /chat/completions 를 클라이언트가 붙임
LLM_API_KEY=x # CodeAssist .env 의 AAF_GATEWAY_KEY 값. 비어 있으면 아무 값(x)
LLM_MODEL=339 # x-llm-model-id. 텍스트 요약이라 GaussO Flash(339). 581(Think) 은 4배 느림, Gemma 는 쓰지 말 것
LLM_CONCURRENCY=2 # FabriX 가 429 를 어떻게 주는지 모름 — 2 로 시작해서 429 안 나면 4
LLM_MAX_RETRIES=5
LLM_TIMEOUT_S=180
SUMMARIZE_BACKEND=api
```
`.env` 는 위 "핵심" 절과 같음(직결). -12 안에서 돌리면 `LLM_BASE_URL` 도 FabriX 호스트 그대로. `.env` 는 위 "핵심" 절과 같음(직결). -12 안에서 돌리면 `LLM_BASE_URL` 도 FabriX 호스트 그대로.
## 돌리기 ## 돌리기
@@ -100,7 +104,7 @@ cd /www/ABAP_INDEXING && set -a; . ./.env; set +a
# 소스 수집 파일을 data/raw/*.txt 로 넣은 뒤 # 소스 수집 파일을 data/raw/*.txt 로 넣은 뒤
.venv/bin/python -m ingest.normalize # Stage 1 — LLM 없음 .venv/bin/python -m ingest.normalize # Stage 1 — LLM 없음
.venv/bin/python -m parser.run # Stage 2 — LLM 없음 .venv/bin/python -m parser.run # Stage 2 — LLM 없음
.venv/bin/python -m index.loader # Stage 4 .venv/bin/python -m index.loader # Stage 4
# Stage 3 — 먼저 작게. 프로그램 하나 unit 3개로 FabriX·JSON 응답이 되는지 # Stage 3 — 먼저 작게. 프로그램 하나 unit 3개로 FabriX·JSON 응답이 되는지
.venv/bin/python -m summarize.runner --llm api --program <프로그램명> --limit 3 .venv/bin/python -m summarize.runner --llm api --program <프로그램명> --limit 3
.venv/bin/python -m summarize.jobs stats # failed 없는지 .venv/bin/python -m summarize.jobs stats # failed 없는지
@@ -119,7 +123,7 @@ curl -s http://127.0.0.1:8100/health
3. **한글 출력.** 컨테이너 로케일이 ASCII 라 파이썬이 한글 찍다 죽는다 → 모든 실행 앞에 `PYTHONUTF8=1` (CodeAssist 도 그렇게 띄움). 3. **한글 출력.** 컨테이너 로케일이 ASCII 라 파이썬이 한글 찍다 죽는다 → 모든 실행 앞에 `PYTHONUTF8=1` (CodeAssist 도 그렇게 띄움).
## 하지 말 것 ## 하지 말 것
- 패치 없이 `LLM_BASE_URL` 에 FabriX 주소만 넣기 — 헤더 없어서 401. - 패치 없이 `LLM_BASE_URL` 에 FabriX 주소만 넣기 — 헤더 없어서 401.
- `LLM_MODEL` 에 Gemma(605/580) — 텍스트 요약에 이미지 모델 쓸 이유 없고 30~100배 느림. - `LLM_MODEL` 에 Gemma(605/580) — 텍스트 요약에 이미지 모델 쓸 이유 없고 30~100배 느림.
- -13 의 게이트웨이(8918) 로 붙기 — 컨테이너 간 통신 금지. -12 안의 8080 만. - -13 의 게이트웨이(8918) 로 붙기 — 컨테이너 간 통신 금지. -12 안의 8080 만.