update: workspace 계층 재정의, RAG 문서 평가, ClawRouter 리서치, 증분인덱싱 워크로그

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
happybell80 2026-03-22 22:57:33 +09:00
parent ecd2cc0b75
commit 70c306385a
12 changed files with 578 additions and 39 deletions

View File

@ -41,6 +41,46 @@ tags: [workspace, team, project, database, slack, architecture]
- `slack_channel`은 채널 단위 권한/용도/프로젝트 연결을 표현합니다.
- 채널은 workspace 공용일 수도 있고, 특정 project 전용일 수도 있습니다.
## 4-1. 접근 권한 모델 (260322 추가)
### 권한 주체
- `user`: 사람 사용자 (기존)
- `agent`: 서버 에이전트, 로빙 등 자동화 주체 (user와 동일 레벨로 team에 소속)
- 에이전트도 user처럼 여러 workspace/team에 중복 소속 가능
### 권한 상속 규칙
- workspace 소속 → 하위 모든 team/project 문서 접근 가능
- team 소속 → 해당 team 문서만 접근
- 역할(role): OWNER / ADMIN / MEMBER / GUEST
### enforcement
- API 레이어에서 요청자의 workspace/team 소속을 검증
- `team_document.team_id`가 곧 접근 기준 (team 소속 확인으로 문서 접근 제어)
- MD front matter의 `access` 필드는 선언적 메타데이터 (검색·필터용, 강제력은 API에서)
### 멀티 워크스페이스
- 사용자/에이전트는 여러 workspace에 소속 가능 (M:N)
- workspace 간 문서는 격리됨
- workspace A의 문서를 workspace B 소속 사용자가 볼 수 없음
## 4-2. Goose Council CEU 연결 (260322 추가)
### CEU-Agent 매핑
- TheGooseCouncil의 CEU(Connection Event Unit)는 로빙 시스템에서 `user(is_agent=true)`에 매핑됩니다.
- CEU의 3가지 존재 구분(개인/팀/조합)은 로빙의 workspace/team 계층과 대응합니다:
- 개인 CEU = 단일 agent user
- 팀 CEU = team 소속 agent 그룹
- 조합 CEU = 문제 단위로 workspace_member를 동적 추가/제거
### 거버넌스 정합
- Goose Council 원칙 "책임은 인간, 운영은 접속 단위에 위임"
- 로빙 시스템: workspace OWNER(인간)가 책임 보유, agent(CEU)가 운영 수행
- 최소 통제 권한(긴급 정지, 정책 롤백)은 OWNER/ADMIN role로 구현
### 참조
- [Connection_Unit_Ontology](/home/admin/TheGooseCouncil/DOCS/00_Philosophy/00_IDENTITY/Connection_Unit_Ontology.md)
- [Governance_and_Delegation_Principles](/home/admin/TheGooseCouncil/DOCS/00_Philosophy/01_PRINCIPLES/Governance_and_Delegation_Principles.md)
## 5. 적용 예시
- `Company-X``workspace`로 해석합니다.
- `Company-X` 내부에서 실제 실행 조직은 `team`으로 분리합니다.

View File

@ -91,6 +91,7 @@
- 로빙 에이전트 루프·스킬 훅·LLM 실행 구조 리서치 `research/orchestration_tools/260312_로빙_에이전트루프_스킬훅_LLM실행구조_리서치.md`
- 로빙 LLM API·Agent API·모델 선정·비용 비교 리서치 `research/orchestration_tools/260312_로빙_LLM_API_Agent_API_모델선정_비용비교_리서치.md`
- ClawRouter 멀티 LLM 라우팅 적용성 리서치 `research/260322_ClawRouter_멀티LLM_라우팅_적용성_리서치.md`
### LLM 출력 계약 / 안정화

View File

@ -1,4 +1,4 @@
tags: [workspace, team, project, database, slack, ideas]
tags: [workspace, team, project, database, slack, ideas, access-control, agent, multi-workspace]
# workspace-team-project 계층 재정의 아이디어
@ -28,15 +28,110 @@ tags: [workspace, team, project, database, slack, ideas]
- 특히 `user`, `robeing`, `slack_workspace`, `team_document`, 관리자 집계 경로는 영향 범위가 넓습니다.
- 따라서 이 아이디어는 즉시 치환안이 아니라, 병행 운영 가능한 목표 모델로 먼저 검증돼야 합니다.
## 아이디어 확장: 접근 권한·에이전트·멀티 워크스페이스 (260322 추가)
### 문제 인식 (260322)
- RAG 문서(`team_document`)에 접근 권한 개념이 없습니다. 누가 어떤 문서를 볼 수 있는지 제어 불가합니다.
- 서버 에이전트(23서버 클로드, 24서버 클로드, Codex, Cursor)가 DB에 등록되어 있지 않아 권한 주체로 식별할 수 없습니다.
- 로빙(`Main Robeing`)은 Company-X 팀에 소속되어 있지만, 에이전트들은 OS 레벨 직접 접근만 하고 있습니다.
- MD front matter에도 접근 권한 필드가 없습니다.
### 접근 권한 아이디어
- workspace 소속이면 하위 team/project 문서 전체 접근 가능 (상위 권한 상속)
- team 소속이면 해당 team 문서만 접근 (하위 격리)
- 사용자는 여러 workspace, 여러 team에 중복 소속 가능 (M:N)
- 에이전트도 user와 동일 레벨로 team에 소속
### 트리 구조
```
workspace (Company-X)
├── team (투자팀)
│ ├── user (김종태)
│ ├── agent (로빙)
│ └── project (xvaluelab)
├── team (운영팀)
│ ├── user (문정현)
│ └── project (X-COURSE)
└── team (인프라)
├── agent (23서버 클로드)
├── agent (24서버 클로드)
└── project (RAG 파이프라인)
workspace (Robeing)
├── team (코어)
│ ├── user (김종태)
│ └── agent (로빙)
└── ...
```
### 멀티 워크스페이스
- 현재 DB에 이미 Company-X, Robeing(→ GooseFarmInvesting) 2개 company가 존재합니다.
- `company``workspace`로 재정의하면 자연스럽게 멀티 워크스페이스가 됩니다.
- 워크스페이스 이름/slug: `GooseFarmInvesting` / `goosefarminvesting`
- 김종태는 3개 계정(jtkim@, goeun2dc@, info@ro-being.com) → 1개로 통합 후 양쪽 workspace 소속
- Jo Lee(조리)는 GooseFarmInvesting 소속
### 에이전트 등록
- 23서버 에이전트(Claude Code, Codex, Cursor), 24서버 에이전트를 `user` 테이블 또는 별도 `agent` 테이블에 등록해야 합니다.
- 에이전트가 team에 소속되면 해당 team의 문서에 접근 가능합니다.
- CompanyX workspace에 소속된 에이전트만 CompanyX 문서에 접근할 수 있습니다.
### 프론트메타 반영
- MD front matter에 `access` 필드 추가: `access: [companyx-team, robeing]`
- 이 필드는 선언적 메타데이터(표시용)이며, 실제 enforcement는 API 레이어에서 workspace/team 소속 검증으로 합니다.
## 설계 검증 피드백 (260322)
### 강점: "에이전트의 시민권 획득"
- `user.is_agent` 플래그로 에이전트를 user 모델에 통합하면, 권한 검사 미들웨어에서 "사람인가 AI인가"를 분기할 필요 없이 동일한 보안 인터페이스를 적용할 수 있습니다.
- 향후 Goose Council의 CEU(Connection Event Unit)들이 멀티 에이전트 환경에서 권한을 주고받는 시나리오로 확장할 때, 별도 권한 체계를 중복 설계할 필요가 없습니다.
- 에이전트도 팀의 일원으로서 상속·배제 규칙을 동일하게 적용받는 구조이므로 도메인이 깔끔합니다.
### 우려: "복합 권한의 늪"
- workspace > team > project 계층에서 **에이전트가 생성한 프로젝트**에 대한 팀원의 접근 권한, **팀 단위 권한 vs 개별 에이전트 권한** 충돌 시 우선순위(Enforcement Rule)가 도메인 모델에서 정교하게 정의되어야 합니다.
- 예외 케이스: 퇴사한 유저가 만든 에이전트의 권한 처리, 에이전트가 여러 workspace에 걸쳐 작업할 때의 데이터 격리 등.
### 제안: "상태(State) 중심의 검증"
- Phase 1에서 DB 스키마를 건드리기 전에, 실제 API 호출 시점에서 `context.user.active_workspace_id``target.access_field`를 비교하는 간단한 시뮬레이션을 먼저 돌려야 합니다.
- 권한 모델은 머리로 그릴 때보다 실제 데이터가 얽힐 때 예외 케이스가 많이 발생하기 때문입니다.
## Goose Council CEU와의 연결 (260322)
### 맥락
- [TheGooseCouncil](../../../../TheGooseCouncil/DOCS/README.md)은 멀티 에이전트 오케스트레이션 시스템입니다.
- CEU(Connection Event Unit)는 "접속이라는 사건을 통해 존재를 생성·확정하는 최소 지능 단위"입니다.
- CEU는 개인/팀/조합 단위로 구분되며, 접속 적합성과 재조합 능력으로 가치가 측정됩니다.
### workspace-team-project에서의 CEU 해석
- **CEU = agent(user.is_agent=true)**로 매핑됩니다.
- CEU도 workspace/team에 소속되어 문서 접근 권한을 상속받습니다.
- CEU 팀(팀 접속 단위) = 로빙 시스템의 `team`에 자연스럽게 대응합니다.
- CEU의 라이프사이클(선택→모집→수행→평가→해산)은 `workspace_member` 소속 추가/제거로 표현 가능합니다.
### Goose Council 거버넌스와의 정합
- [Governance_and_Delegation_Principles](../../../../TheGooseCouncil/DOCS/00_Philosophy/01_PRINCIPLES/Governance_and_Delegation_Principles.md): "책임은 인간이, 운영은 접속 단위에 위임"
- 이 원칙은 workspace OWNER(인간)가 책임을 보유하고, agent(CEU)에 운영을 위임하는 구조와 일치합니다.
- 최소 통제 권한(긴급 정지, 정책 롤백, 진화 루프 중단)도 workspace OWNER/ADMIN role로 구현 가능합니다.
### 확장 시나리오
- CEU가 여러 workspace를 넘나들며 작업하는 경우: `workspace_member` M:N으로 처리
- CEU 간 권한 위임: team 내 role 변경으로 처리 (MEMBER → ADMIN)
- CEU 해산: `workspace_member` is_active=false로 소프트 삭제
## 이 문서를 닫기 위해 필요한 질문
- 현재 `team`이 상위 조직처럼 쓰이는 경로와 실행 조직처럼 쓰이는 경로는 각각 어디인가
- `workspace`, `team`, `project`를 도입할 때 기존 `team_id` FK를 어떤 순서로 분리할 것인가
- Slack 채널은 workspace 공용 채널과 project 전용 채널을 어떤 컬럼 조합으로 구분할 것인가
- 에이전트를 `user` 테이블에 넣을지 별도 테이블로 분리할지
- 접근 권한은 workspace 단위로 충분한지, team/project 단위까지 필요한지
## 이 문서에서 아직 확정하지 않는 것
- 새 테이블 이름과 최종 FK 이름
- 기존 `company`, `team`, `workspace_member`와의 정확한 통합 방식
- 데이터 이관 일정과 서비스별 전환 순서
- 에이전트 식별 방식 (user.is_agent 플래그 vs 별도 agent 테이블)
- 접근 권한의 세분화 수준 (읽기/쓰기/관리 구분 여부)
## 관련 문서
- [Workspace-Team-Project 도메인 모델](../../book/300_architecture/390_workspace_team_project_%EB%8F%84%EB%A9%94%EC%9D%B8_%EB%AA%A8%EB%8D%B8.md)

View File

@ -1,4 +1,4 @@
tags: [workspace, team, project, database, slack, auth, gateway, rag, migration, plans]
tags: [workspace, team, project, database, slack, auth, gateway, rag, migration, plans, access-control, agent]
# workspace-team-project 계층 재정의 전환계획
@ -41,14 +41,58 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, migration,
- `workspace has many teams`
- `team belongs to one workspace`
- `team owns many projects`
- `user belongs to many teams` (M:N via workspace_member)
- `user belongs to many workspaces` (workspace 소속 = 하위 team 문서 전체 접근)
- `agent belongs to many teams` (user와 동일 레벨)
- `slack_workspace belongs to one workspace`
- `slack_channel``workspace` 소속을 기본으로 하고, 필요 시 `project`를 선택적으로 참조
### 3. 초기 운영 매핑
#### 워크스페이스
| company.name (현재) | workspace 이름 | slug (변수명) |
|---------------------|---------------|---------------|
| Company-X | Company-X | companyx |
| Robeing | GooseFarmInvesting | goosefarminvesting |
- 표기 규칙: 표시용 `GooseFarmInvesting` (대문자 포함), 변수/slug `goosefarminvesting` (전소문자)
- `company.name='Robeing'``GooseFarmInvesting`으로 rename
#### 사용자 통합
| 이름 | 현재 계정 | 통합 후 |
|------|----------|---------|
| 김종태 | ① jtkim@company-x.partners (Company-X) | 1개 user로 통합 |
| | ② goeun2dc@gmail.com (Robeing) | → CompanyX + GooseFarmInvesting 양쪽 workspace_member |
| | ③ info@ro-being.com (Robeing) | 대표 이메일 확정 필요 |
| Jo Lee (조리) | joanne.ge.lee@gmail.com (Robeing) | GooseFarmInvesting 소속 |
#### 팀·프로젝트
- `Company-X``workspace`로 승격
- 현재 `Company-X Team`은 임시로 `Company-X 실행팀` 성격의 `team`으로 재정의
- `xvaluelab``project`로 등록
- `Robeing`도 같은 기준으로 `workspace`와 하위 `team`을 분리할 수 있게 설계
- `GooseFarmInvesting`도 같은 기준으로 하위 `team`을 분리할 수 있게 설계
### 4. 에이전트 등록 (260322 추가)
- 서버 에이전트를 `user` 테이블에 `is_agent=true`로 등록하거나, 별도 `agent` 테이블을 신설
- 초기 등록 대상:
- `Main Robeing` (이미 `robeing` 테이블에 존재, user로도 등록 필요)
- `23서버 Claude Code`
- `23서버 Codex`
- `23서버 Cursor`
- `24서버 Claude Code`
- `24서버 Codex`
- 에이전트는 team에 소속시켜 해당 team의 문서 접근 권한을 부여
- CompanyX workspace 소속 에이전트만 CompanyX 문서에 접근 가능
### 5. 접근 권한 모델 (260322 추가)
- 권한 상속: workspace 소속 → 하위 team/project 문서 전체 접근
- 권한 격리: team 소속 → 해당 team 문서만 접근
- 역할(role): OWNER / ADMIN / MEMBER / GUEST (기존 workspace_member.role 확장)
- enforcement: API 레이어에서 요청자의 workspace/team 소속 검증
- 프론트메타: MD front matter에 `access` 필드 추가 (선언적, 검색·필터용)
- DB: `team_document`에 접근 단위 컬럼 추가 불필요 — 기존 `team_id` FK가 곧 접근 기준
## 목표 ERD 초안
@ -113,18 +157,26 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, migration,
## 작업 단계
### Phase 0. 사전 고정
### Phase 0. 사전 고정 + 권한 시뮬레이션
- `workspace`, `team`, `project` 정의를 본 문서 기준으로 동결
- Company-X, Robeing 초기 매핑을 표로 확정
- `workspace_member`를 계속 쓸지 대체할지 결정하지 말고, 우선 `workspace_id` 추가를 기준안으로 둠
- 에이전트 식별 방식 확정: `user.is_agent=true` (별도 테이블 불필요)
- **권한 시뮬레이션 (260322 추가)**:
- DB 변경 전에 실제 API 호출 시점의 권한 검증을 시뮬레이션
- `context.user.active_workspace_id` vs `target.team_id` 비교 로직 설계
- 예외 케이스 목록: 에이전트가 생성한 프로젝트 접근, 퇴사자 에이전트 권한, 크로스 workspace 작업
- Goose Council CEU 시나리오 포함: CEU 라이프사이클(소속→수행→해산)에서의 권한 전이
### Phase 1. DB 병행 지원 준비
- `workspace` 테이블 신설
- `project` 테이블 신설
- `team.workspace_id` 추가
- `workspace_member.workspace_id` 추가
- `workspace_member.team_id` 추가 (user ↔ team M:N 매핑)
- `slack_workspace.workspace_id` 추가
- `slack_channel.workspace_id`, `slack_channel.project_id` 추가
- `user.is_agent` 플래그 추가 (또는 별도 `agent` 테이블 신설 — Phase 0에서 확정)
- 필요 시 `project_name`은 유지하되 FK 전환 완료 후 보조 메타 필드로만 사용
### Phase 2. 기초 데이터 이관
@ -134,6 +186,8 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, migration,
- `slack_workspace.workspace_id`를 채우고 기존 `team_id`는 유지
- `slack_channel.workspace_id`를 채우고, `xvaluelab` 채널에 `project_id` 연결
- `workspace_member.workspace_id`를 사용자 소속 기준으로 채움
- 에이전트 user 레코드 생성 (23서버 Claude/Codex/Cursor, 24서버 Claude/Codex)
- 에이전트를 적절한 workspace/team에 workspace_member로 등록
### Phase 3. 읽기 경로 병행 지원
- `auth-server`
@ -157,12 +211,15 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, migration,
- 새 채널/Canvas/프로젝트 연결 시 `project_id` 우선 기록
- 운영 로그에 `workspace_id`, `team_id`, `project_id`를 함께 남겨 비교 가능하게 함
### Phase 5. 서비스별 전환
### Phase 5. 서비스별 전환 + 접근 권한 적용
- `auth-server`에서 `workspace`를 실제 `workspace` 엔터티로 전환
- `robeing-gateway`에서 사용자 컨텍스트 기본 축을 `workspace + team`으로 변경
- `robeing-gateway`에서 요청자의 workspace/team 소속 검증 미들웨어 추가 (접근 권한 enforcement)
- `rb8001`에서 Company-X 전용 로직을 `workspace/project` 기반으로 재작성
- `skill-rag-file`는 현 단계에서는 `team_document.team_id`를 유지하되, API 계약과 내부 검색 필터에서 `workspace/project` 메타를 병행 지원
- `skill-rag-file` 업로드/검색 API에 workspace 소속 검증 추가
- `admin-dashboard`는 기존 팀 통계와 새 워크스페이스 통계를 함께 검증
- MD front matter에 `access` 필드 일괄 추가 (기존 인덱싱된 문서 대상)
### Phase 6. 정리 단계
- 더 이상 사용하지 않는 `Workspace = Team` alias 제거
@ -180,12 +237,18 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, migration,
- `slack_workspace.slack_team_id='T09C98KB933'`는 새 Company-X workspace에 연결
- `slack_channel.channel_id='C0ALCV5S0FL'`는 Company-X workspace + `xvaluelab` project에 연결
### 2. Robeing
- `company.name='Robeing'` 기준 `workspace` 1건 생성
### 2. GooseFarmInvesting (구 Robeing)
- `company.name='Robeing'` `GooseFarmInvesting`으로 rename 후 `workspace` 전환
- 기존 `Robeing` team은 해당 workspace 하위 team으로 유지
- Jo Lee(조리)는 GooseFarmInvesting workspace 소속
- 하위 project는 후속 운영 구조 확정 후 추가
### 3. 레거시 보존
### 3. 김종태 계정 통합
- 현재 3개 user 레코드 → 1개로 통합
- 통합 후 CompanyX + GooseFarmInvesting 양쪽 workspace_member에 등록
- 대표 이메일 확정 후 나머지 2건은 `oauth_providers` 또는 alias로 보존
### 4. 레거시 보존
- 이행 기간 동안 기존 UUID는 가능한 한 재사용합니다.
- 신규 엔터티 추가 때문에 기존 `team.id`를 바꾸지 않습니다.
- old/new 매핑 테이블 또는 migration note를 남겨 추적성을 확보합니다.

View File

@ -21,22 +21,23 @@ closed_reason: 3중 검색(벡터+키워드+그래프) 동작 + 샘플 16개 전
- [260315 계획 (닫힘, 본 계획으로 흡수)](./260315_companyx_rag_답변합성_시나리오동시종결_계획.md)
- [계획 통합 워크로그](../worklog/260320_companyx_rag_계획통합_260315닫기_260320흡수.md)
## 현재 상태 (260320 확인)
## 현재 상태 (260323 갱신)
| 항목 | 상태 |
|------|------|
| 대상 파일 리스트 | `/tmp/latest_200_companyx.txt` (200개) |
| 인덱싱 스크립트 | `skill-rag-file/scripts/reindex_companyx_latest_200.py` |
| team_id | `79441171-3951-4870-beb8-916d07fe8be5` |
| DB 테이블 | `team_document` (1,121 completed / 51 processing), `team_document_chunk` (3,095건) |
| 임베딩 | Gemini Embedding 2, 768차원, HNSW cosine 인덱스 |
| MD 파생본 | `6.Company X_md/` 48,906개 생성 (front matter만, 본문 미추출) |
| NAS 문서 저장 | `documents/companyx/` (로빙 수집 원본), `documents/companyx_md/` (로빙 생성 MD) |
| 항목 | 260320 | 260322 1단계 완료 후 |
|------|--------|---------------------|
| 대상 파일 리스트 | 200개 (`latest_200_companyx.txt`) | 2,000개 (mtime 2026-01-28 이후) |
| 인덱싱 스크립트 | `reindex_companyx_latest_200.py` | + `reindex_companyx_batch.py` |
| team_id | `79441171-3951-4870-beb8-916d07fe8be5` | 동일 |
| team_document | 1,121 completed / 51 processing | **2,369 completed / 136 failed / 0 processing** |
| team_document_chunk | 3,095건 | **19,991건** |
| 임베딩 | Gemini Embedding 2, 768d, HNSW cosine | 동일 |
| MD 파생본 | 48,906개 (front matter만) | 동일 (본문 미추출) |
- 1차(MD 생성): front matter 완료, 본문 미추출
- 2차(DB 적재): 200개 대상 텍스트 추출 + 청크 + 임베딩 완료
- 2차(DB 적재): **1단계 2,000개 완료** (260322)
- 3차(OCR/관계/동기화): 미착수
- **4차(로빙 연결): 미착수 ← 현재 목표**
- **4차(로빙 연결): 완료** (260321, hybrid 17/17 PASS)
- **미해결**: keyword 단독 검색 전 질의 0건 ([트러블슈팅](../troubleshooting/260323_companyx_rag_keyword_단독검색_전질의_0건.md))
## 적용 범위
@ -55,12 +56,12 @@ closed_reason: 3중 검색(벡터+키워드+그래프) 동작 + 샘플 16개 전
## 추가 필요한 검색 경로
| 검색 방식 | 현재 | 목표 |
|-----------|------|------|
| PGVector 벡터 검색 | ✅ 구현됨 | 유지 |
| TSVECTOR 키워드 검색 | ❌ 미구현 | 추가 |
| 하이브리드 점수 합산 (RRF) | ❌ 미구현 | 추가 |
| Apache AGE 그래프 관계 확장 | ❌ 미설치 | 추가 |
| 검색 방식 | 상태 (260323) | 비고 |
|-----------|-------------|------|
| PGVector 벡터 검색 | ✅ 구현·운용 | 17/17 PASS |
| TSVECTOR 키워드 검색 | ⚠️ 구현됨, 한국어 한계 | simple 토크나이저 → MeCab-ko 필요 |
| 하이브리드 점수 합산 (RRF) | ✅ 구현·운용 | prefix + threshold 분리 + RRF 정규화 완료 |
| Apache AGE 그래프 관계 확장 | ✅ 구현·운용 | companyx_docs 그래프 운용 중 |
## 샘플 검증 질문 (200개 파일 기준)

View File

@ -126,6 +126,22 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, research]
- [251015_slack_install_workspace_id_error.md](../troubleshooting/251015_slack_install_workspace_id_error.md)와 [251016_troubleshooting_summary.md](../troubleshooting/251016_troubleshooting_summary.md)는 실제 `workspace_member.workspace_id`가 없어서 `user.team_id`를 대신 사용했다고 기록합니다.
- 즉 이번 문제는 새로 생긴 문제가 아니라, 문서와 구현이 서로 다른 방향으로 누적된 상태입니다.
### 16. 문서 접근 권한 체계가 존재하지 않습니다. (260322 추가)
- `team_document`에 접근 권한 컬럼이 없습니다. `team_id`가 유일한 격리 기준이지만, 이는 "누가 볼 수 있는가"가 아니라 "어디에 속하는가"만 표현합니다.
- `workspace_member.role`에 OWNER/MEMBER/GUEST가 있지만 문서 단위 ACL은 아닙니다.
- MD front matter에도 접근 권한 필드가 없습니다.
- 서버 에이전트(23서버 Claude/Codex/Cursor, 24서버 Claude/Codex)는 DB에 미등록이며, OS 레벨 직접 접근만 합니다.
- `robeing` 테이블에 `Main Robeing` 1건이 Company-X Team에 등록되어 있지만, `user` 테이블에는 에이전트 레코드가 없습니다.
- 2026-03-22 기준 `team_document` 2,505건, `team_document_chunk` 19,991건이 모두 `Company-X Team` 단일 team_id에 묶여 있어, workspace/team 분리 없이는 세분화된 접근 제어가 불가합니다.
### 17. 멀티 워크스페이스 구조는 데이터 레벨에서 이미 존재합니다. (260322 추가)
- `company` 테이블에 Company-X, Robeing(→ GooseFarmInvesting으로 rename 예정) 2건이 있습니다.
- `team` 테이블에 Company-X Team, Robeing 2건이 각 company 하위에 존재합니다.
- 김종태는 3개 user 레코드가 있습니다: ① jtkim@company-x.partners (Company-X), ② goeun2dc@gmail.com (Robeing), ③ info@ro-being.com (Robeing). 동일인이므로 1건으로 통합 필요합니다.
- Jo Lee(조리)는 GooseFarmInvesting 소속입니다.
- 따라서 `company``workspace`로 재정의하면 멀티 워크스페이스가 자연스럽게 성립합니다.
- workspace 이름: `GooseFarmInvesting`, slug: `goosefarminvesting`
## Interpretation
### 1. 이번 문제는 단순 테이블 추가가 아니라 도메인 기준 복구 문제입니다.
@ -150,7 +166,12 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, research]
- 코드도 이를 일관되게 다루지 못하고 `workspace_member`를 사용자-로빙 매핑처럼 쓰는 구간과, `user.team_id`를 workspace처럼 대체하는 구간으로 나뉘어 있습니다.
- 따라서 계획 문서에서는 `workspace_member`를 유지/교체/재정의 중 무엇으로 갈지 먼저 고정해야 합니다.
### 6. 문서 SSOT도 함께 교정하지 않으면 재발 가능성이 큽니다.
### 6. `user.is_agent` 통합이 Goose Council CEU 확장에 유리합니다. (260322 추가)
- 에이전트를 `user` 테이블에 통합하면, CEU(접속 단위)도 동일한 workspace/team 소속·권한 상속 체계를 재사용할 수 있습니다.
- 별도 agent 테이블을 만들면 권한 검사 로직을 이중으로 관리해야 하므로 기술 부채가 됩니다.
- 다만, 에이전트가 생성한 프로젝트에 대한 팀원 접근 권한, 팀 단위 vs 개별 에이전트 권한 충돌 시 우선순위(Enforcement Rule)를 도메인 모델에서 정의해야 합니다.
### 7. 문서 SSOT도 함께 교정하지 않으면 재발 가능성이 큽니다.
- 현재 DOCS 안에서도 `company -> workspaces 통합 완료`처럼 남아 있는 문서와, 실제 DB 현실이 다릅니다.
- 이번 문제를 푸는 동안 코드를 고쳐도 상위 해석 문서와 하위 구조 문서가 계속 엇갈리면 같은 혼선이 다시 발생할 가능성이 높습니다.
@ -168,6 +189,12 @@ tags: [workspace, team, project, database, slack, auth, gateway, rag, research]
### 6. 관리자 화면에서 보여줄 기본 조직 축을 `team` 중심으로 둘지 `workspace + team` 2계층으로 바꿀지는 아직 미확정입니다.
### 7. 에이전트를 `user` 테이블에 `is_agent` 플래그로 넣을지, 별도 `agent` 테이블로 분리할지는 아직 미확정입니다. (260322 추가)
### 8. 동일인 중복 user 레코드(김종태: Company-X + Robeing)를 하나로 통합할지, M:N 매핑으로 유지할지는 아직 미확정입니다. (260322 추가)
### 9. 접근 권한의 세분화 수준(workspace/team/project/document 단위, 읽기/쓰기/관리 구분)은 아직 미확정입니다. (260322 추가)
## 계획 수립 시 반드시 참고할 내용
### 1. 병행 지원 순서가 필요합니다.

View File

@ -0,0 +1,83 @@
---
tags: [research, llm, gpt-5.4, benchmark, cost, robeing, model-routing]
---
# GPT-5.4 / mini / nano 벤치마크 요약 리서치
**작성일**: 2026-03-18
**목적**: 스크린샷·블로그에 흔한 GPT-5.4 계열 벤치 수치의 출처를 구분하고, 로빙의 모델·에이전트 설계에 쓸 수 있는 해석만 SSOT로 남긴다.
**상위 원칙·근거**: [312_writing-principles.md](../../book/300_architecture/312_writing-principles.md) (리서치 문서 규칙)
**관련 문서**:
- [로빙 LLM·Agent API 모델선정·비용비교 리서치](./orchestration_tools/260312_로빙_LLM_API_Agent_API_모델선정_비용비교_리서치.md)
- [LLM 모델 비교 분석](./LLM_모델_비교_분석.md)
---
## 1. 사실 (Facts)
### 1.1 수치 출처 계층
| 구분 | 설명 |
|------|------|
| **1차(공식)** | OpenAI가 모델 공개 글에서 제시한 벤치마크 수치 |
| **2차(집계·요약)** | BenchLM, SWE-bench 블로그, 개인/에이전시 분석 글 등 |
| **캡처 표** | 위 자료를 재배열한 이미지·슬라이드. **파일 형식이 PDF가 아니어도** “공식 수치의 재인용”일 수 있음 |
### 1.2 SWE-Bench Pro (코딩) — 공식 글과 맞는 대표 수치
아래는 [OpenAI, GPT-5.4 mini·nano 소개](https://openai.com/index/introducing-gpt-5-4-mini-and-nano/)에서 인용 가능한 계열 비교로 정리한 것이다. (스크린샷과 동일 대역)
| 모델 | SWE-Bench Pro (대표 인용값) |
|------|-----------------------------|
| GPT-5.4 (full) | 57.7% |
| GPT-5.4 mini | 54.4% |
| GPT-5.4 nano | 52.4% |
| GPT-5 mini (이전 세대) | 45.7% |
### 1.3 사용자 메시지에 있던 기타 벤치 (출처는 2차 요약 위주)
다음 항목은 **공식 PDF 단일 표**보다는 블로그·리포트에서 자주 같이 인용된다. 수치를 제품 결정에 쓸 때는 **해당 글 또는 OpenAI 원문의 표를 직접 대조**할 것.
| 벤치 | mini / nano / GPT-5 mini (메시지 기준) | 비고 |
|------|----------------------------------------|------|
| OSWorld | 72.1% / 39.0% / 42.0% | 컴퓨터 사용·UI 자동화 계열 |
| GPQA Diamond | 88.0% / 82.8% / 81.6% | 지식·추론 |
| Toolathlon (tool use) | 42.9% / (nano 별도 확인) / 26.9% | 도구·에이전트 계열에서 mini 대비 이전 세대 격차가 큼 |
### 1.4 참고 링크 (요약문 하이퍼링크, [312 §출처 표기](../../book/300_architecture/312_writing-principles.md) 준수)
- [OpenAI 공식: GPT-5.4 mini·nano 소개](https://openai.com/index/introducing-gpt-5-4-mini-and-nano/)
- [Adam Holter: 벤치·가격·용도 정리](https://adam.holter.com/gpt-5-4-mini-and-nano-benchmarks-pricing-and-what-theyre-actually-good-for/)
- [Beam.ai: 멀티모델·에이전트 아키텍처 관점 요약](https://beam.ai/agentic-insights/gpt-54-mini-and-nano-openai-just-validated-the-multi-model-agent-architecture)
- [BenchLM: GPT-5.4 nano 모델 페이지(집계형)](https://benchlm.ai/models/gpt-5-4-nano)
- [SWE-bench 블로그: GPT-5·mini 비용·성능](https://swebench.com/SWE-bench/blog/2025/08/08/gpt5)
---
## 2. 해석 (Interpretation) — 로빙 프로젝트에의 함의
1. **라우팅·비용**
- full → 최고 품질·고비용 경로.
- **mini**: full 대비 SWE-Bench Pro 손실이 작고(57.7→54.4), 이전 세대 mini 대비 큰 폭 개선 → **“기본 업무 LLM” 후보**로 문서·코드·스킬 오케스트레이션 균형에 적합.
- **nano**: SWE 쪽은 여전히 GPT-5 mini보다 우수할 수 있으나, **OSWorld 등 일부 축에서 급락**이 보고되므로 UI/멀티스텝 자동화에는 검증 후 배치.
2. **툴·에이전트**
- Toolathlon 식 지표에서 **mini vs GPT-5 mini** 격차가 크다는 해석은, 로빙의 **스킬 호출·의도분석·서브에이전트**에 “세대 교체” 이득이 있을 수 있음을 시사한다. (실제 파이프라인에서는 자체 eval 필요)
3. **문서화 원칙**
- 슬랙/노션 **캡처 표만 SSOT로 삼지 말 것**.
- 수치 변경·모델 패치 시 **OpenAI 원문 + 내부 측정**을 한 쌍으로 맞출 것.
---
## 3. 미확정 (Unresolved)
- OSWorld / GPQA / Toolathlon의 **정확한 정의·버전·평가 세트**는 글마다 다를 수 있음 → 수치 단정은 원문 표 기준으로만.
- 로빙 현재 스택(Gemini 등)과 **직접 경쟁 비교는 아님**. “외부 LLM 제품군의 trade-off 패턴” 참고용.
---
## 4. 한 줄 요약
**공식 소개 글에 SWE-Bench Pro 수치가 명시되어 있고, 스크린샷 표는 그 요약·재구성일 가능성이 크다. 로빙에는 mini=균형·nano=저비용(축별 검증)·툴/에이전트는 세대 교체 이득 가설로만 반영하고, 실서비스는 자체 eval과 OpenAI 원문 대조를 병행한다.**

View File

@ -0,0 +1,132 @@
---
tags: [research, robeing, llm, routing, ClawRouter, OpenClaw, cost-optimization]
---
# ClawRouter 멀티 LLM 라우팅 적용성 리서치
## 관련 문서
- [OpenClaw 기반 로빙 개선 아이디어](../ideas/260309_openclaw_기반_로빙_개선_아이디어.md)
- [OpenClaw 컨텍스트·메모리 리서치](./260317_OpenClaw_컨텍스트_메모리_리서치.md)
- [모델 SSOT 하드코딩 분산과 workspace-config 로컬이식 통합 리서치](./260315_모델SSOT_하드코딩_분산과_workspace_config_로컬이식_통합리서치.md)
- [260316 gpt-5-mini 전환과 skill-news provider-agnostic 정리](../worklog/260316_gpt5_mini_전환과_skill_news_provider_agnostic_정리.md)
## 목적
- `BlockRunAI/ClawRouter`를 실제 1차 자료 기준으로 확인하고, 로빙에 도움이 되는 요소와 바로 쓰기 어려운 요소를 분리합니다.
- 이번 문서는 외부 레포 소개가 아니라 `로빙이 어떤 레이어를 흡수해야 하는가`를 닫기 위한 리서치입니다.
- 구현 범위 고정과 우선순위는 후속 `plans`에서 다룹니다.
## Facts
### 1. ClawRouter는 실제 공개 오픈소스이며, 2026-03-22 기준 빠르게 성장 중입니다
- GitHub API 기준 저장소는 `BlockRunAI/ClawRouter`, 기본 브랜치는 `main`, 라이선스는 `MIT`입니다.
- GitHub API 기준 스타는 `6155`, 포크는 `491`, 공개 이슈는 `26`입니다.
- 저장소 생성일은 `2026-02-03`, 마지막 푸시는 `2026-03-21T23:54:11Z`입니다.
### 2. 이 프로젝트의 실제 핵심은 "OpenAI 호환 프록시 + 로컬 라우터 + x402 결제"입니다
- `README.md`, `docs/architecture.md`, `src/proxy.ts` 기준으로 ClawRouter는 `localhost`에 OpenAI 호환 프록시를 띄우고, 그 앞단에서 요청을 분류한 뒤 BlockRun API로 보냅니다.
- `src/proxy.ts`에는 `Dedup`, `route`, `fallback chain`, `balance monitor`, `response cache`, `session pinning`, `context compression`이 한 프록시 경로 안에 묶여 있습니다.
- 즉 단순 SDK 래퍼가 아니라 `모델 선택 + 비용 계산 + 결제 + 재시도 + 세션 정책`을 같이 소유하는 인프라 레이어입니다.
### 3. "차원 수"와 "지원 모델 수" 설명은 문서마다 일관되지 않습니다
- 저장소 메인 README는 `15 dimensions`, `44+ models`를 말합니다.
- `docs/smart-llm-router-14-dimension-classifier.md``14 weighted dimensions`, `46 models`를 말합니다.
- `openclaw.plugin.json``skills/clawrouter/SKILL.md``41+ models`를 말합니다.
- 따라서 이 저장소는 빠르게 진화 중이지만, 마케팅 문구와 기술 문서 수치가 아직 완전히 수렴한 상태는 아닙니다.
### 4. 현재 확인 가능한 실제 라우팅 코어는 규칙 기반 분류 + 일부 LLM 보조 분류입니다
- `src/router/selector.ts`는 티어별 primary/fallback 모델 체인, 비용 추정, baseline 대비 savings 계산을 수행합니다.
- `src/router/llm-classifier.ts`는 규칙 기반 분류가 애매할 때만 저가 모델로 `SIMPLE/MEDIUM/COMPLEX/REASONING` 재분류를 수행합니다.
- `docs/smart-llm-router-14-dimension-classifier.md` 기준 분류축은 reasoning, code, multi-step, technical terms, token count, creative, question complexity, agentic, constraint, imperative, output format, simple indicators, reference complexity, domain specificity입니다.
- 즉 "모든 요청을 LLM이 판단"하는 구조가 아니라, 로컬 룰을 우선하고 애매한 경우에만 작은 비용의 보조 분류를 붙이는 구조입니다.
### 5. OpenClaw 플러그인 결합은 강하지만, 로직 대부분은 OpenAI 호환 프록시 패턴으로 분리 가능합니다
- `openclaw.plugin.json``skills/clawrouter/SKILL.md` 기준으로 배포 표면은 OpenClaw 플러그인입니다.
- 하지만 실제 핵심 기능은 `src/proxy.ts`, `src/router/*`, `src/response-cache.ts`, `src/retry.ts`, `src/session.ts`, `src/compression/*`에 있으며, OpenClaw 전용으로만 묶인 것은 아닙니다.
- 즉 설치 UX는 OpenClaw 플러그인 중심이지만, 기술 아이디어 자체는 일반 프록시/게이트웨이에도 이식 가능합니다.
### 6. ClawRouter는 라우팅 외에도 운영 안정화 장치를 많이 가지고 있습니다
- `src/proxy.ts`에는 요청 중복과 이중과금을 막기 위한 deduplication이 있습니다.
- `docs/features.md`에는 response cache, tool detection, context-length-aware routing, free-tier fallback, session persistence가 정리돼 있습니다.
- `src/compression/index.ts`에는 7단계 context compression이 있습니다.
- `src/journal.ts`에는 세션별 핵심 행동을 따로 남기는 경량 journal 계층이 있습니다.
### 7. 로빙은 이미 "provider 직접 호출 제거"와 "모델 SSOT 수렴"을 일부 시작한 상태입니다
- [260316 gpt-5-mini 전환과 skill-news provider-agnostic 정리](../worklog/260316_gpt5_mini_전환과_skill_news_provider_agnostic_정리.md) 기준으로 `skill-news`의 Gemini 직접 호출은 제거됐고, `rb8001 /api/llm/generate` 공용 경로가 도입됐습니다.
- 같은 worklog 기준으로 `workspace-config/runtime.env``DEFAULT_LLM_MODEL`을 중심으로 런타임 수렴을 확인했습니다.
- 즉 로빙은 아직 멀티 모델 자동 라우팅은 없지만, 적어도 "중앙 LLM 경로"와 "모델 SSOT"로 이동하는 방향 자체는 이미 시작됐습니다.
### 8. 로빙과 ClawRouter의 차이는 결제보다 "라우팅 소유권 위치"에 있습니다
- ClawRouter는 요청 직전 프록시에서 모델 선택을 수행합니다.
- 로빙은 현재 `DEFAULT_LLM_MODEL` 중심 단일 기본값 운용이 강하고, 서비스별 잔존 분기 제거를 계속 정리하는 단계입니다.
- 따라서 로빙 관점 핵심 질문은 "USDC 결제를 붙일 것인가"보다 "모델 선택 규칙을 어디에 둘 것인가"입니다.
## Interpretation
### 1. 로빙에 가장 유용한 것은 결제 레이어가 아니라 `라우팅 정책 계층`입니다
- 로빙은 현재 OpenClaw 단일 개인 에이전트보다는 `rb8001 + skill-* + gateway` 중심의 내부 서비스 구조입니다.
- 따라서 `wallet signature + x402 + USDC`는 현재 문제의 직접 해법이 아닙니다.
- 반대로 아래 세 가지는 바로 도움이 됩니다.
- 요청 난이도/행동성 기반 tier 분류
- tier별 primary/fallback 체인
- tool/vision/context-length 조건에 따른 모델 필터
### 2. ClawRouter의 기본 모델 매핑을 그대로 가져오면 안 되고, 로빙 트래픽으로 다시 벤치마크해야 합니다
- ClawRouter의 티어 매핑은 BlockRun의 가격표, OpenClaw 사용 패턴, x402 결제 지연, 특정 유지율 가정 위에 놓여 있습니다.
- 로빙의 실제 요청은 슬랙 응답, 이메일 분석, RAG 요약, 내부 문서 질의, 스케줄·브리핑 등으로 구성돼 있어 분포가 다릅니다.
- 따라서 로빙에 필요한 것은 "ClawRouter의 모델 목록 복제"가 아니라 "로빙 요청 유형별 분류축과 비용·품질 벤치마크"입니다.
### 3. 로빙에는 `ClawRouter 전체 도입`보다 `rb8001 공용 LLM 경로 앞단 라우터`가 맞습니다
- 현재 로빙은 이미 `rb8001 /api/llm/generate`로 일부 수렴 중이므로, 가장 자연스러운 위치는 이 공용 경로의 앞단입니다.
- 즉 구조는 `skill-* -> rb8001 공용 LLM 호출 -> 라우터 -> provider adapter` 쪽이 맞습니다.
- 이 방식이면 서비스별 직접 SDK 호출을 다시 늘리지 않고, 중앙 라우팅 정책만 독립 계층으로 키울 수 있습니다.
### 4. 1차 적용 범위는 "4티어 + 3~5개 검증 모델 + 명시적 폴백" 정도가 적절합니다
- ClawRouter처럼 처음부터 40개 이상 모델을 열면 운영 표면이 너무 넓어집니다.
- 로빙 1차는 `SIMPLE / MEDIUM / COMPLEX / REASONING` 4티어만 두고, 각 티어별 1개 primary + 1~2개 fallback 정도가 적절합니다.
- 이때 최소 검증 포인트는 아래가 적합합니다.
- 일반 응답용 저비용 모델
- 코드/분석용 상위 모델
- reasoning 전용 모델
- tool-calling 안정 모델
### 5. 로빙에 특히 유용한 부가 아이디어는 `fallback`, `cache`, `context filter`입니다
- fallback 체인은 현재 provider 장애나 429, 모델별 호환성 차이를 가시적으로 흡수할 수 있습니다.
- response cache와 dedup은 브리핑, 반복 질의, 재시도 경로에서 비용과 지연을 같이 줄일 수 있습니다.
- context-length-aware routing은 긴 내부문서/RAG 응답에서 "토큰 초과 후 실패"를 줄이는 데 직접 도움이 됩니다.
### 6. 반대로 ClawRouter의 세션 journal과 compression은 바로 이식하기보다 별도 검토가 필요합니다
- journal은 현재 로빙의 conversation log, 자기개선 루프, 메모리 방향과 일부 겹칩니다.
- compression도 provider별 시스템 프롬프트 처리 차이, 한국어 문맥 보존, RAG 근거 인용 품질에 미치는 영향을 따로 검증해야 합니다.
- 따라서 이 둘은 1차 적용 항목이 아니라 2차 검토 항목으로 두는 편이 맞습니다.
### 7. 결론적으로 ClawRouter는 "참고 가치 높음, 직접 채택 범위는 제한적"입니다
- 참고 가치가 높은 이유는 `로컬 규칙 기반 분류 -> 티어별 모델 선택 -> 조건 기반 필터 -> 명시적 폴백`을 실제 코드로 보여주기 때문입니다.
- 직접 채택 범위가 제한적인 이유는 결제·지갑·OpenClaw 플러그인 UX가 로빙의 현재 운영 문제와 직접 맞닿지 않기 때문입니다.
- 따라서 로빙에는 `ClawRouter식 멀티 LLM 라우팅 계층`이 유효하고, `ClawRouter 자체`를 그대로 붙이는 것은 우선순위가 낮습니다.
## Unresolved
- 로빙의 실제 요청 로그를 기준으로 티어 분류축을 어떻게 정의할지
- 1차 검증 모델 풀을 어떤 provider 조합으로 고정할지
- `rb8001 /api/llm/generate` 앞단에 둘지, 별도 `llm-router` 서비스로 분리할지
- fallback 발생, savings, latency를 어떤 메트릭 스키마로 남길지
- response cache를 user/session/context hash 기준으로 둘지, 요청 body hash 기준으로 둘지
## 추천 다음 단계
1. `plans` 문서에서 `rb8001 공용 LLM 경로 앞단 4티어 라우터` 1차 도입 범위를 고정합니다.
2. 지난 2주 운영 로그 기준으로 로빙 요청을 `simple / medium / complex / reasoning / tool-using / long-context`로 샘플링합니다.
3. 각 샘플에 대해 3~5개 후보 모델의 비용·지연·출력품질을 같은 프롬프트셋으로 비교해 로빙 전용 티어 매핑을 만듭니다.
4. 1차 구현은 `라우팅 + fallback + metrics`까지만 두고, `compression``journal`은 2차로 분리합니다.
## 1차 자료 링크
- [ClawRouter GitHub 저장소](https://github.com/BlockRunAI/ClawRouter)
- [ClawRouter README](https://github.com/BlockRunAI/ClawRouter/blob/main/README.md)
- [ClawRouter Architecture](https://github.com/BlockRunAI/ClawRouter/blob/main/docs/architecture.md)
- [ClawRouter 14-Dimension Classifier](https://github.com/BlockRunAI/ClawRouter/blob/main/docs/smart-llm-router-14-dimension-classifier.md)
- [ClawRouter Features](https://github.com/BlockRunAI/ClawRouter/blob/main/docs/features.md)
- [ClawRouter Plugin Manifest](https://github.com/BlockRunAI/ClawRouter/blob/main/openclaw.plugin.json)
## 한 줄 결론
- ClawRouter는 로빙에 그대로 붙일 제품이라기보다, `rb8001 공용 LLM 경로 앞단에 멀티 LLM 라우팅 계층을 세우는 방법`을 보여주는 강한 벤치마크 대상입니다.
## 상위 원칙
- [writing-principles](../../../../0_VALUE/20_Governance/writing-principles.md)

View File

@ -20,6 +20,8 @@
- [임베딩 1차 로빙 현황 SSOT (260316)](./rag/260316_임베딩_1차_로빙_현황_SSOT_리서치.md)
- [임베딩 2차 StarsAndI·GooseCouncil 현황 (260316)](./rag/260316_임베딩_2차_StarsAndI_GooseCouncil_현황_리서치.md)
- [임베딩 전체 프로젝트 현황 및 SSOT (260316, 인덱스)](./rag/260316_임베딩_전체프로젝트_현황_및_SSOT_리서치.md)
- [GPT-5.4 mini·nano 벤치마크 요약 리서치 (260318)](./260318_GPT_5_4_mini_nano_벤치마크_요약_리서치.md)
- [ClawRouter 멀티 LLM 라우팅 적용성 리서치 (260322)](./260322_ClawRouter_멀티LLM_라우팅_적용성_리서치.md)
### [기억(Memory)](./memory/README.md)
- 장단기 기억 메커니즘

View File

@ -0,0 +1,71 @@
---
tags: [worklog, rag, companyx, indexing, batch]
type: worklog
status: closed
closed_date: 2026-03-22
---
# CompanyX RAG 1단계 2,000개 증분 인덱싱 완료
**작성일**: 2026-03-22
**작성자**: 23서버 클로드
## 배경
- 0단계(200개) 검증 완료 후, NAS 최신 문서 2,000개를 대상으로 증분 인덱싱 실행
- 23서버(4코어/29GB)와 24서버(16코어/31GB)에서 병렬 배치 처리
- 임베딩 서비스는 24서버(192.168.0.106:8515)에서만 운영
## 실행 결과
### 인덱싱 실적
| 항목 | 값 |
|------|-----|
| 대상 파일 | ~2,000 (NAS mtime 기준 최신) |
| completed | 2,369 (기존 200 + 신규 ~1,635 + processing 재처리 38 + 기타) |
| failed | 136 |
| processing | 0 |
| 전체 청크 | 19,991 |
### 데이터 품질 수정 (`fix_data_quality.py`)
| 문제 | 수정 전 | 수정 후 |
|------|---------|---------|
| file_size/mime 누락 | 2,370 | 252 (원본 파일 없음) |
| 청크 없는 completed | 118 → 125 | 0 |
| 빈 chunk_text (<10자) | 12 | 0 |
| 임베딩 누락 | 0 | 0 |
| tsvector 누락 | 0 | 0 |
### failed 136건 내역
| 원인 | 건수 | 설명 |
|------|------|------|
| 원본 파일 없음 | 122 | `/mnt/51123data/documents/` 웹 업로드 후 삭제된 구 데이터 |
| 빈 서식 파일 | 7 | hwp 조합 등록 신청서 등 텍스트 없는 서식 |
| 텍스트 없는 pptx | 7 | 이미지만 있는 프레젠테이션 |
## 수정 이력 (이번 배치에서 해결한 문제)
1. **xlrd 미설치** → 23/24서버 모두 `xlrd-2.0.2` 설치 (.xls 127건 해소)
2. **hwpx 미지원**`text_extractor.py``_extract_hwpx()` 추가
3. **Thumbs.db 등 비문서 파일**`.db`, `.ini`, `.lnk`, `.tmp` 파일 목록에서 제외
4. **UniqueViolationError** → 동시 실행 시 file_hash 충돌 처리 (rollback + 재조회)
5. **5% 실패율 중단 로직** → 제거, 끝까지 실행 후 실패 목록 별도 저장
6. **file_size/mime_type 누락 2,370건** → NAS os.stat 기반 일괄 채움
7. **빈 chunk_text 12건** → 삭제 + 문서 재분류
## 남은 작업 (2단계 이후)
- failed 136건 중 원본 없는 122건: DB 정리 또는 삭제 판단 필요
- file_size/mime 누락 252건: 원본 파일 없어 채울 수 없음, 동일 판단 필요
- hwpx 14건: text_extractor에 추가됨, 배치 재실행 시 처리 가능
- processing 51건 → 재처리 완료 (38 성공, 7 빈 pptx failed, 6 파일 없음 failed)
## 관련 문서
- [Front Matter 메타데이터 설계 리서치](../research/rag/260320_FrontMatter_메타데이터_설계_리서치.md)
- [CompanyX RAG 문서 완벽도 평가](../../valuation/260322_companyx_rag_문서_완벽도_평가.md)
- [MD 중간표현 SSOT 설계 리서치](../research/rag/260320_MD_중간표현_SSOT_설계_리서치.md)
- [다형식문서 RAG 1차 계획](../plans/260320_다형식문서_RAG_1차_MD_메타_정규화_계획.md)

View File

@ -76,18 +76,19 @@ research_target: 열린 Company X RAG 문서 10개의 문서-현실 괴리 평
- 48,906개 MD 중 48,744건이 text_length: 0
- 후속 행동(원인 분석, 재처리 방안)이 계획에 없음
## 실제 구현 상태 기준값 (260322)
## 실제 구현 상태 기준값 (260322 → 260323 갱신)
| 항목 | 값 |
|------|-----|
| team_document (Company X) | 1,174건 |
| team_document_chunk | 3,474건 |
| MD 파생본 (6.Company X_md) | 48,906개 |
| tsvector + GIN | 구현 완료 |
| 하이브리드 검색 (vector+keyword+hybrid) | 구현 완료 |
| Apache AGE 그래프 | companyx_docs, document_graph 2개 운용 중 |
| 배치 스크립트 | reindex_companyx_latest_200.py, 300.py, multimodal.py 등 14개 |
| 증분 인덱싱 워크플로우 | companyx_incremental_indexing_workflow.md 존재 |
| 항목 | 260322 초기 | 260322 1단계 완료 후 |
|------|------------|---------------------|
| team_document (Company X) | 1,174건 | 2,369 completed + 136 failed |
| team_document_chunk | 3,474건 | 19,991건 |
| MD 파생본 (6.Company X_md) | 48,906개 | 48,906개 (변동 없음) |
| tsvector + GIN | 구현 완료 | 구현 완료 (단, keyword 단독 검색은 한국어 한계로 0건) |
| 하이브리드 검색 (vector+keyword+hybrid) | 구현 완료 | hybrid 17/17 통과, keyword 축 미해결 |
| Apache AGE 그래프 | companyx_docs, document_graph 2개 운용 중 | 동일 |
| 배치 스크립트 | reindex_companyx_latest_200.py 등 14개 | + reindex_companyx_batch.py (2,000개용) |
| 증분 인덱싱 워크플로우 | 존재 | 1단계 완료 반영됨 |
| **keyword 단독 검색** | — | **미해결 (MeCab-ko 도입 필요)** |
## 관련 문서

View File

@ -14,7 +14,7 @@ tags: [workflow, rag, companyx, indexing, batch, incremental]
| 단계 | 대상 수 | mtime 컷오프 | 상태 |
|------|--------:|--------------|------|
| 0단계 | 200 | 수동 선정 (`latest_200_companyx.txt`) | 완료 |
| 1단계 | 2,000 | `2026-01-28` 이후 | 미착수 |
| 1단계 | 2,000 | `2026-01-28` 이후 | 완료 (260322) |
| 2단계 | 5,000 | `2025-11-30` 이후 | 미착수 |
- mtime 컷오프 근거: [NAS 정보 종합 리서치](../../../../infra/DOCS/journey/research/260321_companyx_nas_정보_종합_리서치.md)
@ -55,9 +55,32 @@ tags: [workflow, rag, companyx, indexing, batch, incremental]
- grounding 11/18 성공
- 상세: [로빙 다형식문서 RAG 적용 1차 계획](../../journey/plans/260320_로빙_다형식문서_RAG_적용1_계획.md)
## 1단계 (2,000개) 실행 결과 (260322)
| 항목 | 값 |
|------|-----|
| completed | 2,369 (기존 200 + 신규 ~1,635 + 재처리 38 + 기타) |
| failed | 136 |
| 전체 청크 | 19,991 |
- 데이터 품질 수정 완료: file_size/mime 채움, 빈 청크 삭제, 청크 없는 completed 재처리
- 상세: [1단계 2,000개 증분 인덱싱 워크로그](../../journey/worklog/260322_companyx_rag_1단계_2000개_증분인덱싱_완료.md)
### 검색 품질 상태 (260323 기준)
- **hybrid 검색**: 17/17 통과 (벡터가 보완)
- **keyword 단독 검색**: 전 질의 0건 — PostgreSQL `simple` 토크나이저의 한국어 구조적 한계
- **미해결 이슈**: [keyword 단독 검색 전질의 0건](../../journey/troubleshooting/260323_companyx_rag_keyword_단독검색_전질의_0건.md)
- **근본 해결**: MeCab-ko 형태소 분석기 도입 필요
### 2단계 진입 조건
- keyword 단독 검색 품질이 미해결이므로, 2단계 진입 전 keyword 축 해결이 선행되어야 함
- hybrid는 통과하지만 keyword 축이 죽어 있으면 대량 확장 시 검색 품질 저하 위험
## 관련 문서
- [RAG 업로드·인덱싱 파이프라인](./rag_upload_indexing_pipeline.md)
- [RAG 검색·Grounding 요청](./rag_search_grounding_request.md)
- [Company X Grounding 파이프라인](./companyx_grounding_pipeline.md)
- [NAS 정보 종합 리서치](../../../../infra/DOCS/journey/research/260321_companyx_nas_정보_종합_리서치.md)
- [하이브리드검색 품질개선 계획](../../journey/plans/260321_하이브리드검색_품질개선_계획.md)
- [1단계 2,000개 증분 인덱싱 워크로그](../../journey/worklog/260322_companyx_rag_1단계_2000개_증분인덱싱_완료.md)
- [keyword 단독 검색 전질의 0건 트러블슈팅](../../journey/troubleshooting/260323_companyx_rag_keyword_단독검색_전질의_0건.md)