유저 가이드 AI 기능 기획 — Hereby med (admin · hr-system · employee-app · team-manager)
Notion 검토 페이지: https://app.notion.com/p/3e9c96484a76810c9ccafd97b0bf0d8e 작성: 2026-09-28 · 상태: 초기 기획 기록 — 현재 운영 명세로 사용하지 않습니다. 근거: 로컬 클론 hereby-dhub 4de04b32 (2026-09-28, fix/sheet-filter-status-reset) 코드 조사 + docs/internal/design-ai-architecture.md §5·§7 + docs/ko/features/documentation-workflow.md + docs/product-changes/README.md 관련 기획: claude/sheet-ai-feature-plan.md (AI 시트 E1~E5 — 공용 위젯·tool 루프·searchSheetGuide 를 이번 기획이 확장)
현재 구현과의 차이
2026-10-14 정정: 현재 안내 경로는 AI 문서 안내의 현재 구조와 유지보수를 기준으로 합니다. 아래의 자산 수, 미구현 목록, 비용 추정과 로드맵은 2026-09-28 조사·제안이며 현재 구현이나 운영 검증 결과가 아닙니다.
| 당시 기획 | 현재 코드 기준 |
|---|---|
| 문서 색인 파이프라인이 없다고 기록했습니다. | 공개 가이드 색인 스크립트와 개발 문서 배포 후 실행하는 작업이 있습니다. 실제 인덱스의 최신 여부는 별도 확인 대상입니다. |
| pgvector·문서 마이그레이션·변경 청크만 임베딩을 계획했습니다. | 안내 경로는 S3 Vectors와 voyage-context-4를 사용하고, 현재 스크립트는 실행 시 대상 문서를 모두 임베딩합니다. |
| 전체 가이드·기능 문서 검색을 계획했습니다. | 색인 대상은 가이드 15개이며, 채팅은 등록된 10개 기능의 문서·절만 검색합니다. 기능 문서와 내부 설계 문서는 이 색인 대상이 아닙니다. |
| 자동 평가·확장을 계획했습니다. | 최종 변경은 외부 응답을 대체한 로컬 테스트로 검사합니다. 과거 평가 실험은 PR에서 제외했으며, 정리 과정에서 새 모델 평가·재색인·배포·운영 활성화는 실행하지 않습니다. |
0. 당시 기획 요약
가이드 콘텐츠(가이드 9편·기능 문서 33편·영상 112컷·변경 이력 27건)와 AI 파운데이션(위젯·tool 루프·doc_embeddings 테이블·pgvector)은 이미 있다. 없는 것은 ① 문서를 벡터 DB 로 자동 인제스트해 배포마다 갱신하는 파이프라인(테이블만 있고 인제스트 0건 — 시트 가이드 62절만 정적 키워드 인덱스로 임시 운영 중) ② 그 위에서 "어디 있어?"에 링크·바로가기·화면 하이라이트로 답하는 가이드 모드 ③ employee-app·team-manager 탑재 ④ Cmd+K 통합 검색이다. 사용자 결정: 배포 시 벡터 DB 동기화(G0)가 기술적 최우선.
1. 현황 (코드 기준)
1-1. 가이드 콘텐츠 자산
| 자산 | 위치 | 비고 |
|---|---|---|
| 사용자 가이드 9편 (admin 1,053행·hr 517·employee-app 582·nurse-scheduler 283·dashboard 160·general-affairs 69·team-manager 72·inventory 34·onboarding-playbook 224) | docs/ko/guides/*.md ← 원본은 fragments/guide-*.html(외부 PM 팀 납품), scripts/gen-docs-guides.mjs 가 생성 | 절 앵커 #sN/#sN-M 은 h2/h3 위치 기반 자동 부여. team-manager·inventory 는 UNPUBLISHED_GUIDES(사이트 미공개) |
| 기능 문서 33편 | docs/ko/features/*.md (ai-assistant · sheet-assistant · payroll-sheets · approvals · attendance-leave …) | 개발 기록 겸 사용자 설명, 명시적 앵커({#entry} 등) |
| FAQ · 시트 템플릿 · 한국 급여 · getting-started | docs/ko/guides/faq.md 등 | |
| 기능별 영상 112컷 (번호 안내형) | docs/ko/guides/video-tutorials.md + 각 가이드 절 아래 임베드 | 절 앵커와 1:1 매핑됨 (scripts/docs-section-videos.mjs) |
| 고객 변경 이력 27건 | docs/product-changes/<feature>/<id>.json — codePaths·guides[{page,anchor}]·documentation.status·video.status·status: unreleased/released | 코드 경로 ↔ 가이드 절을 잇는 유일한 매핑 데이터 |
| 문서 사이트 | VitePress → docs.hereby.me/ko (dev: docs.dev.hereby.me/ko), dev-sites.yaml/release-sites.yaml 로 S3+CloudFront 배포 | config.ai.docsBaseUrl 이 절대 링크 생성에 사용 |
| 인앱 도움말 | 단축키 모달 3개 (hr-system 시트 · admin 스케줄러 · team-manager) | 온보딩/투어/코치마크 없음 |
1-2. AI 파운데이션 (시트 기획 이후 진척분 포함)
packages/components/src/components/AiAssistant.ts공용 위젯 — admindashboard.html· hr-systemdashboard.html/시트 사이드바 탑재.getContext()로{app, tab, sheet}주입, 「문제 신고」→ CS 리포트context.ai첨부, 이전 대화·도크 폭 조절.prompts/system.ts안정 프롬프트에현재 앱: / 현재 화면/탭:만 주입 (화면별 조작·버튼 위치 지식 없음).- tool:
employee.tools.ts(5) ·sheet.tools.ts·sheet-change.tools.ts·payroll-cycle.tools.ts. 가이드 검색은services/ai/guide/search.tssearchSheetGuide하나 —sheet-guide-index.generated.ts(hr 가이드·sheet-templates·payroll-sheets 62절,pnpm gen:sheet-guide-index로 빌드 시 TS 로 구움) 를 단어 겹침 점수로 검색. 이유:docs/는 API 이미지에 없다(docker/api/Dockerfile은 packages 만 COPY). AiModule.DOCSenum ·config.ai.models.docs(AI_MODEL_DOCS) 선언됨, 소비처 없음.doc_embeddings테이블 —1847000000000-AddAiFoundation.ts에서 생성(vector(1024) · HNSW cosine · UQ(source, docPath, locale, chunkIndex) ·contentHash), 엔티티doc-embedding.entity.ts. 인제스트 스크립트·검색 쿼리·VOYAGE_API_KEY설정 모두 없음.
1-3. 문서 동기화 — 지금은 어떻게 돌아가나
- 주간 수동 사이클: 지정 PC 의 예약 작업(Codex)이 병합 PR 을 대조 →
product-changes/*.json추가(unreleased,documentation/video: pending) → 문서·영상 PR → 배포 확인 후released. 기능 PR 에 문서 의무 없음 (README.md"Ownership"). - 검사:
pnpm check:product-docs --base <commit>(변경 파일이 기록의codePaths에 잡히는지·이력 보존) ·check:docs-guides(생성물 일치, pre-commit) ·check:sheet-guide-index. - 결론: 코드 → 문서는 주간 사람 루프, 문서 → 검색 인덱스는 시트 62절만 빌드 시 자동. 나머지 문서는 AI 가 전혀 못 본다. 배포 시점과 인덱스 시점의 연결도 없다.
1-4. 앱 네비게이션 (바로가기·투어의 기반)
| 앱 | 라우팅 | 딥링크 가능성 |
|---|---|---|
| admin | router.ts 해시 라우터 — VALID_TABS 15개(employees teams organization wards roles settings leaves leave offsite esign payroll scheduler embed documents attendance parameters) + 하위 키 `#settings/<org | myinfo |
| hr-system | 시트 워크북 (월·시트 slug·폴더) | 중간 — 시트 id/slug 기반 진입은 있으나 열 설정 등 모달은 상태 기반 |
| employee-app | router.ts 경로 라우터 — `Section: shifts | messenger |
| team-manager | router store navigate('/<tab>'), tabFromPath() | 높음 |
2. 격차 (이번 기획이 채우는 것)
- [최우선] 문서 → 벡터 인덱스 자동 동기화 없음.
doc_embeddings는 빈 테이블. 배포와 인덱스가 연결돼 있지 않아 기능이 나가도 AI 는 옛 문서(또는 무지)로 답한다. - 코드 변경 → 문서 갱신은 주간 사람 루프 — "문서가 아직 안 따라온 기능"을 AI 가 모르고 자신 있게 틀리게 답할 위험.
product-changes의pending상태를 답변에 쓰는 장치 없음. - 가이드 검색 tool 이 시트 62절뿐. admin·employee-app·team-manager 가이드·FAQ·기능 문서는 검색 불가.
- 위젯이 admin·hr-system 에만. employee-app(모바일)·team-manager 미탑재.
- "어디 있어?"에 위치로 답하는 수단 없음 — 화면 레지스트리(탭·하위탭·버튼 ↔ 가이드 절) 부재, 딥링크 카드·하이라이트 없음.
- 메뉴·설정·문서 통합 검색(Cmd+K) 없음.
- 미해결 질문(답 못 한 것)을 문서 백로그로 되돌리는 루프 없음.
3. 설계 원칙
| 원칙 | 내용 |
|---|---|
| 인덱스 = 배포물의 일부 | 가이드 코퍼스는 코드처럼 빌드 시 생성·검사(--check)·배포 시 인제스트된다. 사람이 "인덱스 갱신" 버튼을 누르는 운영은 두지 않는다. 배포된 코드 버전 ≠ 인덱스 버전인 상태를 시스템이 감지·표시한다. |
| 증분·저비용 | contentHash 로 변경 청크만 임베딩(Voyage voyage-3, 1024d 확정). 코퍼스 ~5천 행 ≈ 수백 청크 — 전량 재임베딩도 수십 원 단위지만, 원칙적으로 diff. |
| 모르면 모른다고 | 검색 점수 하한 미달·documentation.status = pending 기능은 "문서 준비 중 — 화면 위치만 안내"로 답한다. 절차를 지어내지 않는다. |
| 답은 링크+행동 | 모든 답변 카드에 ① 가이드 절 링크(절대 URL) ② 영상 링크(있으면) ③ 「바로 가기」(딥링크) ④ 「화면에서 보기」(하이라이트) 중 가능한 것을 붙인다. 산문은 3~5문장. |
| 읽기 전용 | 가이드 AI 는 데이터를 바꾸지 않는다. 딥링크 이동·하이라이트는 UI 상태 변경일 뿐 서버 mutation 없음. 변경 제안은 시트 AI(Change Set) 영역. |
| 권한 존중 | 딥링크 대상 화면에 권한이 없으면 "권한 필요 — 관리자에게 요청" 으로 답한다(레지스트리에 필요 권한 기재). |
| 코드 의존 · 수기 목록 금지 | 화면 레지스트리는 router.ts 의 VALID_TABS/Section 과 data-guide-id 속성에서 생성한다(gen-sheet-guide-index 와 같은 원칙). 수기 매핑은 --check 로 드리프트를 잡는다. |
| 토큰 | 검색은 서버(pgvector), 모델엔 top-k 청크(각 ≤1,400자)만. AiModule.DOCS 는 경량 모델 후보(설계 §1-3). 프롬프트 캐싱 유지. |
4. 기능 구조 — 에픽 6건
G0 매뉴얼 → 벡터 인덱스 동기화 파이프라인 (배포마다 자동 갱신) ← 최우선 · 기술 기반
├─ G1 가이드 AI 어시스턴트 (DOCS 모듈 · searchDocs · 전 앱 탑재 · 링크 답변)
│ ├─ G2 화면 레지스트리 & 바로가기 (딥링크 카드 · 앱 간 이동 · 권한)
│ │ └─ G3 화면 내 위치 하이라이트 (data-guide-id · 스포트라이트 · 단계 투어)
│ └─ G4 통합 검색 팔레트 (Cmd+K: 메뉴·설정·가이드·최근)
└─ G5 품질 루프 (미해결 질문 → 문서 백로그 · 피드백 · eval · 사용량)권장 순서: G0 → G1 → G2 → G4 → G3 → G5. G5 의 로그 수집은 G1 과 동시에 켠다. G4 는 G2 레지스트리만 있으면 AI 없이도 동작하므로 앞당길 수 있다.
G0. 매뉴얼 → 벡터 인덱스 동기화 파이프라인 ★최우선
목표: 기능 배포(백엔드·프런트·문서 어느 쪽이든)마다 doc_embeddings 가 배포된 문서 버전과 일치하고, 불일치는 시스템이 감지한다.
코퍼스 (v1)
docs/ko/guides/*.md생성물(= fragments 원본 그대로) — 절 단위(h2/h3, 앵커 = 생성 규칙과 동일) ·UNPUBLISHED_GUIDES는 제외 또는published=false플래그docs/ko/features/*.md— h2 단위, 명시 앵커faq.md·getting-started.md·korean-payroll.md·sheet-templates.mdvideo-tutorials.md의 절↔영상 매핑 → 청크 메타(videoIds)docs/product-changes/**.json중status=released의 title/summary →source='change'청크 (최근 변경 안내용).unreleased+documentation.status=pending은pending_features메타로 별도 적재(§G1 "문서 준비 중" 판단용)- 제외:
docs/internal/**,spec/**, 영문 문서(v2)
빌드 단계 — 코퍼스는 문서 사이트 배포물이다 (API 이미지에 넣지 않는다 · 2026-09-28 사용자 결정: 문서 PR 만으로 API 재배포 없음)
scripts/gen-guide-corpus.mjs를 docs 패키지 빌드(@hereby/docsprebuild) 에 붙여docs/.vitepress/dist/_corpus/guide-corpus.json을 생성:{corpusVersion, docsRevision(git sha), builtAt, chunkerVersion, chunks:[{source, docPath, locale, anchor, heading, text, contentHash, meta:{app, page, videoIds, featureId, pending}}]}. 기존gen-sheet-guide-index.mjs의 청킹·앵커 규칙을 공용 모듈로 추출해 같은 절 id 를 낸다(시트 인덱스는 G1 후 이 코퍼스의 부분집합 뷰로 대체).- 생성물은 커밋하지 않는다(빌드 산출물). 대신
pnpm check:guide-corpus가 PR CI 에서 코퍼스 생성이 깨지지 않는지·앵커가 생성 가이드와 일치하는지만 검사한다. - 배포: 기존
dev-sites/stg-sites/release-sites의 Deploy Docs 가 dist 를 S3 sync 할 때 코퍼스도 함께 올라간다 — 환경별 docs 버킷({env}-hereby-works-tools-docs)에_corpus/guide-corpus.json. 즉docs.dev.hereby.me/_corpus/guide-corpus.json↔ dev API,docs.hereby.me/…↔ 운영 API 로 환경이 자연스럽게 짝지어진다(config.ai.docsBaseUrl과 같은 루트). CloudFront 캐시는 해당 경로만 짧은 TTL(또는 invalidation 목록에 추가). - Dockerfile·
dev-backend경로 필터 변경 없음. 문서 PR → docs 배포만 → 인제스트 트리거(아래).
인제스트 단계 (배포 시 자동) — 스키마 마이그레이션과 분리된 「문서 마이그레이션」 트랙 (2026-09-28 사용자 결정)
- 스키마 마이그레이션(
packages/database/src/migrations, TypeORMmigrations테이블, 타임스탬프 파일)과 별도 버전 체계로 관리한다. 문서 마이그레이션은 파일 단위가 아니라 코퍼스 버전 단위다.- 버전 키 =
corpusVersion=sha256(전 청크 contentHash 정렬 결합 + embeddingModel + chunkerVersion). 코퍼스가 바뀌면 버전이 바뀌고, 같으면 no-op.docsRevision(git sha)은 표시·추적용 부가 정보. - 상태 테이블
doc_migrations(신규, 스키마 마이그레이션 1건으로 생성):{corpusVersion PK, docsRevision, embeddingModel, chunkerVersion, chunkCount, embeddedCount, status: applied|failed|rolled_back, startedAt, finishedAt, error}.doc_embeddings에corpusVersion열 추가 — 청크는 버전 태그로 남기고 활성 버전만 검색. - 러너
packages/database/src/scripts/run-doc-migration.ts: 기존run-migration.ts와 같은 env 계약(MIGRATION_RUN=true|false프리뷰/실행,MIGRATION_MODE=up|down) +CORPUS_URL(기본${docsBaseUrl 루트}/_corpus/guide-corpus.json, 로컬은 파일 경로 허용).up= 코퍼스 fetch(ETag/corpusVersion이 활성 버전과 같으면 즉시 no-op) → 이전 활성 버전과 청크 diff → 변경·신규만 Voyage 임베딩 upsert(동일 hash 청크는 새 버전 태그만 부여) → 활성 버전 전환(단일 UPDATE, 원자적).down= 직전applied버전으로 활성 전환(청크가 남아 있으므로 재임베딩 없음). 보존 정책: 최근 N(=3) 버전 청크만 유지, 나머지 정리. - "스키마성" 변경은
chunkerVersion/embeddingModel상수 bump = 전량 재임베딩 강제.vector(N)차원 변경만은 스키마 마이그레이션 영역(테이블 재생성).
- 버전 키 =
- 실행 지점 두 곳, 러너는 하나 (둘 다 같은
run-doc-migration로직 — 하나는 CLI, 하나는 API 안의 job 서비스):- 문서 배포 후 트리거(주 경로): sites 워크플로의 Deploy Docs 가 S3 sync·CloudFront invalidation 을 마친 뒤 sysadm API
POST /internal/doc-migration/run을 호출({corpusUrl, docsRevision}; 인증은 GitHub OIDC 토큰 또는 환경별 시크릿, 조직 스코프 없음 — 플랫폼 공용 인덱스). sysadm 은doc_migrations에queued행을 만들고 백그라운드로 러너를 돌린다(응답 즉시, 결과는 상태 행). API 이미지 재빌드·재배포 없음. 실패 시 워크플로는 경고만(문서 배포 자체는 성공 유지) — 재시도는 sysadmin 「AI 모니터」의 「인덱스 다시 만들기」 버튼(같은 엔드포인트). - 백엔드 배포 시 Job(보조 경로):
fig-gitops에jobs/doc-migration/api를 추가해jobs/migration/api성공 후 실행(같은 이미지,run-doc-migration커맨드,CORPUS_URL= 그 환경 docs 루트). 목적은 ① 새 환경/조직 DB 초기 적재 ②chunkerVersion/embeddingModelbump(코드 변경) 시 전량 재임베딩 ③ 문서 트리거가 실패한 채 남은 경우의 자가 치유. 코퍼스가 이미 활성 버전과 같으면 fetch 후 no-op 이라 비용 없음. 스키마 Job 은 실패 시 롤아웃 차단, 문서 Job 은 실패해도 롤아웃을 막지 않고doc_migrations.status=failed로 남긴다(검색은 직전 활성 버전으로 계속 동작).
- 문서 배포 후 트리거(주 경로): sites 워크플로의 Deploy Docs 가 S3 sync·CloudFront invalidation 을 마친 뒤 sysadm API
- 동시성:
doc_migrations에 advisory lock(pg_try_advisory_lock)으로 트리거·Job 이 겹쳐도 한 번만 실행. 같은corpusVersion재요청은 no-op. - 로컬:
pnpm db:migrate:docs스크립트(db:migrate와 나란히,CORPUS_URL=docs/.vitepress/dist/_corpus/guide-corpus.json),MIGRATION_RUN=false프리뷰가 "청크 N건 변경·M건 신규·K건 삭제, 예상 임베딩 호출 수"를 출력. - 코드↔문서 버전 정합: 문서와 API 가 독립 배포되므로 "코퍼스가 설명하는 기능이 아직 이 환경 API 에 없는" 창이 생길 수 있다. 문서는 배포 확인 후
released로만 공개하는 기존 규칙(product-changesREADME 8)이 이 창을 막는 1차 장치이고,ai.guideIndexStatus가docsRevision과 APIbuildRevision의 브랜치·날짜 차이를 경고로만 표시한다. - 조직 스코프:
organizationId = NULL(플랫폼 공용) 만 v1. 조직별 문서(notice등)는 v2.
드리프트 감지·노출
ai.guideIndexStatus프로시저:{docsRevision(index) vs buildRevision(API), lastIngestAt, pendingFeatures[]}.- 위젯 헤더에 "가이드 기준 2026-09-28 배포" 표시, 불일치 시 sysadmin 「AI 모니터」 탭(
tools/system-admin/.*ai-monitor.html, 기존)에 경고 행 추가. - 코드→문서 갭 게이트(사람 루프 보강):
feat라벨 PR 이codePaths로 어느product-changes기록에도 안 잡히면 PR 코멘트 봇이 "문서 기록 없음 — 주간 문서 작업 대상" 을 남기고docs-pending라벨 부착(머지 차단은 아님, README 의 "기능 PR 에 문서 의무 없음" 원칙 유지). 이 라벨 목록이 G1 의 "문서 준비 중" 근거가 된다.
완료 기준: dev 백엔드 배포 후 doc_embeddings 에 전 코퍼스가 있고, 가이드 문서 한 줄 수정 PR → dev docs 배포(API 재배포 없음) → 해당 청크 1건만 재임베딩된 것이 doc_migrations 와 로그로 확인된다. pnpm check:guide-corpus 가 CI 에서 돈다.
G1. 가이드 AI 어시스턴트 (DOCS 모듈)
AiModule.DOCS실사용:prompts/guide.ts(안정 프롬프트 — 앱·화면 어휘, 답변 형식 규칙, "모르면 모른다") +tools/guide.tools.ts:searchDocs(query, {app?, page?, k=8})— pgvector cosine + tsvector 하이브리드(RRF), 현재 앱·탭 메타로 가중. 반환: 절 제목·발췌·절대 링크(config.ai.docsBaseUrl)·영상 링크·pending여부.getScreenInfo(app, tab?)— G2 레지스트리에서 현재 화면의 메뉴·버튼·하위탭·연결 가이드 절 반환.listRecentChanges(app?, sinceDays)—source='change'청크 ("최근 뭐 바뀌었어?").
- 답변 카드 스키마(structured output):
{answer, steps[], links[{title,url,kind:guide|video}], actions[{type:navigate|highlight, target}], confidence, pendingNotice?}— 프런트가 카드로 렌더. - 컨텍스트 주입 확장:
getContext()에tab · subTab · route · 열린 모달 id · 권한 요약(역할명)추가. 행 데이터·개인정보는 넣지 않는다. - 탑재: employee-app(하단 시트형,
more섹션 진입 + 전역 FAB) · team-manager(기존 도크 패턴). 위젯app값에 따라 안정 프롬프트 변형(직원용은 존댓말·짧게·admin 기능 언급 금지). - 모드 분리: 시트 화면에서는 기존 시트 어시스턴트가
searchDocs를 추가 tool 로 받는다(별도 위젯 아님).searchSheetGuide는searchDocs(page ∈ hr, sheet-templates, payroll-sheets)로 대체. - 완료 기준(dev): admin 「연차 촉진 어디서 해?」→ 절차 3줄 +
admin#s7-5링크 + 영상 + 「바로 가기」 카드. employee-app 「재직증명서 어떻게 받아?」→employee-app#s13. 문서 없는 기능 질문 → "문서 준비 중" 안내.
G2. 화면 레지스트리 & 바로가기(딥링크)
packages/core/src/guide/screen-registry.generated.ts— 생성 소스: adminVALID_TABS+하위 키, employee-appSection/ApprovalTab, team-manager 탭, hr-system 진입점(시트 목록·급여대장·템플릿 창) + 수기 보강 파일screen-registry.overrides.json(라벨·아이콘·필요 권한·가이드 절·product-changesfeatureId).pnpm check:screen-registry로 라우터와의 드리프트 검사.- 딥링크 규약:
hereby://<app>/<tab>[/<sub>]?focus=<guideId>→ 프런트navigateTo()가 앱 내 이동은router.navigateTab/navigate, 앱 간은 절대 URL(okbest.dev.hereby.me/hr-system/#…)로 새 탭. admin 의 임베드(#embed/sheets)는 기존 해시 그대로. - 위젯 액션 카드 「바로 가기」: 권한 없으면 비활성 + 사유. 이동 후 위젯은 열린 채 유지(대화 연속).
- 완료 기준: 레지스트리에 admin 15탭+하위 6·employee-app 5섹션+4탭·team-manager 전 탭 등록, 각 항목에 가이드 절 ≥1 연결(없으면 check 경고).
G3. 화면 내 위치 하이라이트(투어)
- 앵커 속성
data-guide-id="admin.settings.shifts.add-button"를 주요 버튼·메뉴·탭에 부착(레지스트리 id 와 동일 네임스페이스).pnpm check:guide-anchors— 레지스트리가 참조하는 id 가 HTML 에 있는지 검사(기존check:modals/icons스크립트 패턴). packages/components에GuideSpotlight: 대상 요소 bounding box 로 딤+링 하이라이트, 말풍선(1~3줄), [다음][닫기], 스크롤·탭 전환 포함(navigateTo후 요소 대기). 요소가 없으면(권한·숨김) 조용히 링크 카드로 폴백.- 투어 정의는 가이드 절에서 생성하지 않는다(문장→DOM 매핑은 불안정).
screen-registry.overrides.json의tours[](id, steps[{guideId, text}]) 를 수기로 작성하고 우선순위 상위 10개 흐름만(직원 등록·휴가 승인·근무 그룹·시트 반영·명세서 공개 …). AI 는 질문에 맞는 tour id 를 고르기만 한다. - employee-app 모바일: 하이라이트는 v1 제외(바로가기까지), v2 검토.
G4. 통합 검색 팔레트 (Cmd+K / 검색 아이콘)
- 클라이언트 전용(모델 호출 없음): 레지스트리(메뉴·설정·화면) + 코퍼스 제목 인덱스(경량 JSON, 빌드 시 생성) + 최근 이동·최근 질문. 한글 초성·부분 일치.
- 결과 유형: 「이동」(딥링크) · 「설정」(하위탭) · 「가이드」(절 링크) · 「AI 에게 묻기」(입력을 위젯으로 넘김 — 결과가 없거나 문장형 질문일 때 상단 노출).
- 위치: admin·hr-system·team-manager 헤더 검색 +
⌘K/Ctrl+K. employee-app 은more화면 검색창. - 완료 기준: "근무 유형" 입력 →
#settings/shifts이동 항목 +admin#s6-1가이드 항목이 100ms 내 표시.
G5. 품질 루프
- 미해결 로그:
confidence < 임계또는 👎 또는 "문서 준비 중" 답변을ai_guide_gaps(질문·앱·탭·검색 top-k·docsRevision)에 기록 → sysadmin 「가이드 갭」 뷰 → 주간 문서 작업의 입력(product-changespending기록 초안 생성까지 자동화 가능). - eval golden set
services/ai/evals/docs.json: 질문 → 기대docPath#anchor포함 여부(설계 §8-3).pnpm eval:ai --module docs. 인제스트 변경 PR 에서 리콜 회귀 확인. - 사용량: 기존
usageSummary에module=docs분리. 조직 월 한도 공유, 가이드 모듈 일 상한 별도(저비용이므로 넉넉히). - 기존 「문제 신고」(CS 리포트) 에
docsRevision·hits[]첨부.
5. 공통 기술 사항
- 임베딩: Voyage
voyage-31024d (설계 §9 확정, 테이블 차원 고정).VOYAGE_API_KEYenv·config 추가,providers/voyage.ts. 키 부재 시 인제스트는 skip+경고, 검색은 tsvector 전용으로 degrade(기능 자체는 살아 있게). - 검색 SQL: 설계 §7-3 raw SQL +
to_tsvector('simple', content)GIN 인덱스 추가 마이그레이션(한국어 형태소 없음 → 벡터 주, FTS 보조). - 청킹: h2/h3 절 단위, 1,400자 초과 절은 문단 경계로 분할(chunkIndex 증가), 제목을 각 청크 앞에 프리픽스.
- 모델 라우팅:
DOCS= 경량 모델 기본(설계 §1-3 후보), 조직 오버라이드 기존 경로. 시트 화면에서searchDocs호출 시엔 시트 모듈 모델 그대로. - 보안: 코퍼스는 플랫폼 공용 문서만(조직 데이터 없음). 프롬프트 인젝션 면에서 문서는 신뢰 입력이지만
product-changessummary 도 코드 리뷰를 거친 파일이므로 동일 취급. 딥링크는 레지스트리 화이트리스트 밖 URL 생성 불가. - QA(자동 QA 참고): dev 에서 ①
ai.guideIndexStatus의docsRevision이 배포 커밋과 일치 ② 대표 질문 10개(앱별 2~3)의 링크 앵커가 실제 docs.dev 페이지에 존재 ③ 「바로 가기」 후 해시·화면 일치 ④ 하이라이트 대상 요소 존재. 모두 mutation 없음 → 회귀 테스트로 매 회차 실행 가능.
6. 열린 질문 (결정 필요)
- 인제스트 트리거 — (결정) 코퍼스는 docs 사이트 배포물(
_corpus/guide-corpus.json), 문서 배포 후 sysadm 엔드포인트 호출이 주 경로, 백엔드 배포 시doc-migrationJob 이 보조 경로. 남은 것: 엔드포인트 인증 방식(GitHub OIDC vs 환경 시크릿). - 문서 PR 의 백엔드 재배포 — (결정) 없음. 문서 PR 은 docs 사이트 배포 + 인제스트 트리거만. 남은 것: 운영(release-sites)에서도 문서 배포 즉시 운영 인덱스를 갱신할지, 운영 릴리즈 시점에 맞출지.
- "문서 준비 중" 판정 소스 —
product-changes의pending만 볼지,docs-pendingPR 라벨(G0 게이트)까지 합칠지. 라벨은 GitHub → API 로 가져올 경로가 필요. - employee-app 위젯 UX — 전역 FAB vs
more메뉴 진입만. 직원에게 AI 노출 시 조직 설정(settings.ai.enabled)과 별도로 직원 노출 플래그를 둘지. - 투어 v1 범위 — 상위 10개 흐름 목록 확정 주체(PM 팀 콸/카나 가이드 기준?).
- team-manager·inventory 가이드 — 사이트 미공개(
UNPUBLISHED_GUIDES)인데 AI 코퍼스엔 넣을지(링크는 못 주고 절차만 답하게 됨). - 영문 문서 — v1 은
locale=ko만. EN 인제스트 시점. - Voyage 계약·키 관리(BYOK 조직은 임베딩도 자기 키?) — 검색 인덱스는 플랫폼 공용이므로 플랫폼 키 단일 권장. (임베딩을 API 로 가는 것 자체는 2026-09-28 확정 — 남은 것은
voyage-3유지 vsvoyage-4갱신과 차원)
7. 관련 리서치 취합 — 「docs 임베딩 검색 시스템 계획」(2026-09-28)과의 관계
같은 날 작성된 별도 계획(2026-09-28-docs-embedding-search-plan.md, 이하 D-plan)은 docs/ 전체(547 md/mdx · 6.97MB)를 GPT·Claude 가 공통 MCP search/fetch 로 검색하는 개발자·에이전트용 시스템이다. 이 기획(G0~G5)은 최종 사용자용 인앱 가이드다. 대상은 다르지만 문서 파이프라인의 절반이 겹치므로 아래처럼 나눈다.
8-1. 두 계획의 대상 비교
| 항목 | D-plan (docs 검색 MCP) | 가이드 AI (G0~G5) |
|---|---|---|
| 사용자 | 개발자·PM, GPT/Claude 에이전트 | 병원 관리자·직원 (인앱) |
| 코퍼스 | docs/ 전체 — 규칙·설계·계획·이력·검증 원장 포함 | docs/ko/guides + features 사용자 절 + FAQ + product-changes (released) — 공개 가능한 부분집합 |
| 클라이언트 | 외부 MCP (search/fetch, OpenAI 호환 스키마) | AiAssistant 위젯 → API tool searchDocs |
| 저장소 | 별도 PostgreSQL(+pgvector) | 제품 API DB doc_embeddings (조직별 K8s 배포, organizationId=NULL) |
| 임베딩 | 자체 호스팅 Qwen3-Embedding-4B(2,560d, halfvec) 기준선, voyage-4-large 와 비교 | 설계 §9 확정값 voyage-3 1024d (vector(1024) 테이블 고정) — 재검토 대상 |
| 재정렬 | Qwen3-Reranker-0.6B (GPU #1) | 없음 (v1) |
| 인프라 | RTX 3090 ×2 사내 서버 | GPU 없음 — API 서버는 외부 임베딩 API 호출만 |
| 접근 범위 | access_scope + 인증(내부 문서 포함) | 플랫폼 공용 문서만, 조직 인증은 기존 tRPC ctx |
| 상태 메타 | document_kind · status · canonical_source · verification_level | pending(문서 준비 중) / released |
| 색인 버전 | index_version + 활성 전환·ID 고정 fetch·보존 기간 | corpusVersion + doc_migrations 활성 전환·down·N=3 보존 |
8-2. 공유할 것 (한 벌만 만든다)
- 파서·청커·메타데이터 모듈 — D-plan 2단계(문서 색인)에서 만드는 파서를 G0 의
gen-guide-corpus가 그대로 import 한다. 가이드 코퍼스 = 전체 코퍼스에document_kind ∈ {guide, feature(사용자 절), faq, change} ∧ access_scope = public필터를 건 뷰. 청크 스키마를 D-plan §5 로 통일:document_id · chunk_id · parent_section_id · path · heading_path · anchor · source_url · source_commit · content_hash · processing_version · embedding_model_revision · document_kind · status · canonical_source · verification_level · access_scope. 이 기획의pending은status로,chunkerVersion은processing_version으로,corpusVersion은index_version으로 용어 통일. - 정본(canonical) 규칙 — 생성 가이드(
guides/*.md) vs fragments HTML 중 대표 본문 하나만 색인하고 앵커 연결은 보존(D-plan §5). G0 코퍼스 항목 중 "UNPUBLISHED_GUIDES제외" 도access_scope로 표현. - 색인 버전·전환 원칙 — 검증 후 활성 전환, 실패 시 이전 버전 유지, 삭제·이름 변경 경로 정리, 결과 ID 가 버전을 고정.
doc_migrations설계와 동일 원칙이므로 러너 로직(diff → 증분 임베딩 → 원자적 전환 → down)을 공용 패키지로 두고 저장소 어댑터만 분리. - 하이브리드 검색·평가 방법 — 벡터 + 키워드 후보 합집합 → RRF, 점수 단순 합산 금지. 평가 질문셋은 조정용/최종용 분리, 필수 근거 포함률·잘못된 과거 계획 선택률·p50/p95 를 같은 하네스(
services/ai/evals)로 측정. G5 의docs.jsongolden set 은 D-plan 1단계 질문셋의 사용자 질문 부분집합. - 임베딩 모델 결정은 한 번 — 두 계획이 서로 다른 모델을 쓰면 벡터 공간이 달라 색인·평가를 공유할 수 없다(D-plan §6.1). 아래 8-3 ①에서 정한다.
8-3. 충돌·결정 필요 (G0 착수 전)
- 임베딩 모델 — 설계 §9 는
voyage-31024d 확정, D-plan 은 Qwen 자체 호스팅을 기준선으로 두고voyage-4-large와 비교 중. 제품 API 서버에는 GPU 가 없고 조직별로 배포되므로, 제품 인덱스가 사내 GPU 임베딩 서비스에 런타임 의존하는 구조는 운영 리스크(가용성·네트워크 경로) 가 크다. 제안: 가이드 AI 는 API 임베딩(Voyage 4 계열) 고정, 개발 docs 검색은 Qwen/Voyage 비교 실험을 계속하되 최종적으로 같은 모델로 수렴시킨다. 수렴이 Qwen 이면 제품 쪽은 "코퍼스 임베딩을 docs 배포 산출물(_corpus/guide-corpus.json에 벡터 포함)"로 옮겨 API 서버가 임베딩을 계산하지 않게 하는 방안이 있다 — 단 질문 임베딩은 여전히 런타임에 필요하므로 완전 분리는 안 된다. → 결정(2026-09-28 사용자 확정): API 임베딩(Voyage)으로 간다. Qwen 자체 호스팅은 제품 경로에 두지 않으며, D-plan 의 Qwen 실험은 비용·품질 벤치마크 대조군으로만 유지. - 차원·테이블 —
vector(1024)고정 테이블에 Voyage 4 large 를 쓰려면 MRL 로 1024 출력(D-plan §6 "1,024·1,536 비교" 항목) 을 택하거나, 차원 변경 스키마 마이그레이션(테이블 재생성 + 전량 재임베딩)을 G0 에 포함.voyage-3 → voyage-4갱신 여부와 차원은 D-plan 1~3단계 결과로 결정하고, 그 전까지 G0 는embedding_model_revision을 설정값으로 두어 모델 교체가 전량 재색인 1회로 끝나게 설계한다. - 재정렬 — 가이드 코퍼스는 수백 청크 규모라 v1 은 재정렬 없이 hybrid top-8. D-plan 3단계에서 재정렬 효과가 확인되면 G1 v2 에 API 리랭커(Voyage rerank) 를 옵션으로. GPU 리랭커를 제품 경로에 넣지 않는다.
- 키워드 검색 — D-plan 이 한국어 조사·복합명사·코드 식별자 토큰화를 검증하는 결과를 G1
searchDocs의 tsvector 설정(simplevs 커스텀 사전)에 그대로 적용. - 분류 체계 소유 —
document_kind · status · verification_level의 판정 기준 확정은 D-plan 1단계 산출물. G0 는 이 분류를 그대로 쓰고 자체 분류를 만들지 않는다. "문서 준비 중" 판정(열린 질문 3)은status+product-changes.documentation.status두 소스를 D-plan 분류에서 하나로 정한다. - 런타임은 분리 — 코드(파서·청커·러너·평가)만 공유하고, MCP 서버·GPU·별도 DB 는 개발 docs 검색 전용. 제품 API 는 MCP 서버를 호출하지 않는다(멀티테넌시 불변식 §1-2).
8-4. 통합 로드맵
D-plan 1단계 평가 기준(질문셋·분류 기준) ─┐
D-plan 2단계 파서·청커·메타데이터(공용) ─┼─▶ G0 gen-guide-corpus = 공용 파서 + public 필터 뷰
임베딩 모델 결정(8-3 ①②) ─┘ └▶ G0 doc_migrations 러너 (공용 러너 + 제품 DB 어댑터)
D-plan 3단계 하이브리드·재정렬 비교 ──────────▶ G1 searchDocs 설정값(RRF·k·토큰화) 확정
D-plan 4~5단계 MCP·운영 (개발자용, 제품과 무관) G2~G5 진행- G0 를 D-plan 2단계 뒤에 두면 파서를 두 번 만들지 않는다. 단 D-plan 이 지연되면 G0 는 기존
gen-sheet-guide-index청커로 먼저 시작하고 파서 교체를processing_versionbump 1회로 흡수한다. - 문서 반영: D-plan 을
docs/internal/에 두고,design-ai-architecture.md§7·§9 의 "voyage-3 1024d 확정" 에 재검토 중 표시를 남긴다(두 문서가 서로 다른 확정값을 갖지 않게).
8. 검토 요청
- 에픽 G0~G5 구성과 순서(G0 → G1 → G2 → G4 → G3 → G5)에 동의하는지
- §6 열린 질문 중 G0 착수 전 결정 필요: 1(엔드포인트 인증 방식) · 2(운영 인덱스 갱신 시점) · 8(Voyage 키)
- §7 취합에 따른 결정:
임베딩 API vs 자체 호스팅(API 확정) ·voyage-3유지 vsvoyage-4갱신과 차원 1024 유지 여부 · G0 를 D-plan 2단계 뒤에 둘지 - 검토 완료 후 에픽별 티켓을 Hereby med QA List DB 에 등록 예정 (현재 미등록)