Skip to content

유저 가이드 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-starteddocs/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 공용 위젯 — admin dashboard.html · hr-system dashboard.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.ts searchSheetGuide 하나 — 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.DOCS enum · 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. 앱 네비게이션 (바로가기·투어의 기반) ​

앱라우팅딥링크 가능성
adminrouter.ts 해시 라우터 — VALID_TABS 15개(employees teams organization wards roles settings leaves leave offsite esign payroll scheduler embed documents attendance parameters) + 하위 키 `#settings/<orgmyinfo
hr-system시트 워크북 (월·시트 slug·폴더)중간 — 시트 id/slug 기반 진입은 있으나 열 설정 등 모달은 상태 기반
employee-approuter.ts 경로 라우터 — `Section: shiftsmessenger
team-managerrouter store navigate('/<tab>'), tabFromPath()높음

2. 격차 (이번 기획이 채우는 것) ​

  1. [최우선] 문서 → 벡터 인덱스 자동 동기화 없음. doc_embeddings 는 빈 테이블. 배포와 인덱스가 연결돼 있지 않아 기능이 나가도 AI 는 옛 문서(또는 무지)로 답한다.
  2. 코드 변경 → 문서 갱신은 주간 사람 루프 — "문서가 아직 안 따라온 기능"을 AI 가 모르고 자신 있게 틀리게 답할 위험. product-changes 의 pending 상태를 답변에 쓰는 장치 없음.
  3. 가이드 검색 tool 이 시트 62절뿐. admin·employee-app·team-manager 가이드·FAQ·기능 문서는 검색 불가.
  4. 위젯이 admin·hr-system 에만. employee-app(모바일)·team-manager 미탑재.
  5. "어디 있어?"에 위치로 답하는 수단 없음 — 화면 레지스트리(탭·하위탭·버튼 ↔ 가이드 절) 부재, 딥링크 카드·하이라이트 없음.
  6. 메뉴·설정·문서 통합 검색(Cmd+K) 없음.
  7. 미해결 질문(답 못 한 것)을 문서 백로그로 되돌리는 루프 없음.

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.md
  • video-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/docs prebuild) 에 붙여 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, TypeORM migrations 테이블, 타임스탬프 파일)과 별도 버전 체계로 관리한다. 문서 마이그레이션은 파일 단위가 아니라 코퍼스 버전 단위다.
    • 버전 키 = 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 서비스):
    1. 문서 배포 후 트리거(주 경로): 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 모니터」의 「인덱스 다시 만들기」 버튼(같은 엔드포인트).
    2. 백엔드 배포 시 Job(보조 경로): fig-gitops 에 jobs/doc-migration/api 를 추가해 jobs/migration/api 성공 후 실행(같은 이미지, run-doc-migration 커맨드, CORPUS_URL = 그 환경 docs 루트). 목적은 ① 새 환경/조직 DB 초기 적재 ② chunkerVersion/embeddingModel bump(코드 변경) 시 전량 재임베딩 ③ 문서 트리거가 실패한 채 남은 경우의 자가 치유. 코퍼스가 이미 활성 버전과 같으면 fetch 후 no-op 이라 비용 없음. 스키마 Job 은 실패 시 롤아웃 차단, 문서 Job 은 실패해도 롤아웃을 막지 않고 doc_migrations.status=failed 로 남긴다(검색은 직전 활성 버전으로 계속 동작).
  • 동시성: 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-changes README 8)이 이 창을 막는 1차 장치이고, ai.guideIndexStatus 가 docsRevision 과 API buildRevision 의 브랜치·날짜 차이를 경고로만 표시한다.
  • 조직 스코프: 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 — 생성 소스: admin VALID_TABS+하위 키, employee-app Section/ApprovalTab, team-manager 탭, hr-system 진입점(시트 목록·급여대장·템플릿 창) + 수기 보강 파일 screen-registry.overrides.json(라벨·아이콘·필요 권한·가이드 절·product-changes featureId). 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-changes pending 기록 초안 생성까지 자동화 가능).
  • 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-3 1024d (설계 §9 확정, 테이블 차원 고정). VOYAGE_API_KEY env·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-changes summary 도 코드 리뷰를 거친 파일이므로 동일 취급. 딥링크는 레지스트리 화이트리스트 밖 URL 생성 불가.
  • QA(자동 QA 참고): dev 에서 ① ai.guideIndexStatus 의 docsRevision 이 배포 커밋과 일치 ② 대표 질문 10개(앱별 2~3)의 링크 앵커가 실제 docs.dev 페이지에 존재 ③ 「바로 가기」 후 해시·화면 일치 ④ 하이라이트 대상 요소 존재. 모두 mutation 없음 → 회귀 테스트로 매 회차 실행 가능.

6. 열린 질문 (결정 필요) ​

  1. 인제스트 트리거 — (결정) 코퍼스는 docs 사이트 배포물(_corpus/guide-corpus.json), 문서 배포 후 sysadm 엔드포인트 호출이 주 경로, 백엔드 배포 시 doc-migration Job 이 보조 경로. 남은 것: 엔드포인트 인증 방식(GitHub OIDC vs 환경 시크릿).
  2. 문서 PR 의 백엔드 재배포 — (결정) 없음. 문서 PR 은 docs 사이트 배포 + 인제스트 트리거만. 남은 것: 운영(release-sites)에서도 문서 배포 즉시 운영 인덱스를 갱신할지, 운영 릴리즈 시점에 맞출지.
  3. "문서 준비 중" 판정 소스 — product-changes 의 pending 만 볼지, docs-pending PR 라벨(G0 게이트)까지 합칠지. 라벨은 GitHub → API 로 가져올 경로가 필요.
  4. employee-app 위젯 UX — 전역 FAB vs more 메뉴 진입만. 직원에게 AI 노출 시 조직 설정(settings.ai.enabled)과 별도로 직원 노출 플래그를 둘지.
  5. 투어 v1 범위 — 상위 10개 흐름 목록 확정 주체(PM 팀 콸/카나 가이드 기준?).
  6. team-manager·inventory 가이드 — 사이트 미공개(UNPUBLISHED_GUIDES)인데 AI 코퍼스엔 넣을지(링크는 못 주고 절차만 답하게 됨).
  7. 영문 문서 — v1 은 locale=ko 만. EN 인제스트 시점.
  8. Voyage 계약·키 관리(BYOK 조직은 임베딩도 자기 키?) — 검색 인덱스는 플랫폼 공용이므로 플랫폼 키 단일 권장. (임베딩을 API 로 가는 것 자체는 2026-09-28 확정 — 남은 것은 voyage-3 유지 vs voyage-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_levelpending(문서 준비 중) / released
색인 버전index_version + 활성 전환·ID 고정 fetch·보존 기간corpusVersion + doc_migrations 활성 전환·down·N=3 보존

8-2. 공유할 것 (한 벌만 만든다) ​

  1. 파서·청커·메타데이터 모듈 — 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 으로 용어 통일.
  2. 정본(canonical) 규칙 — 생성 가이드(guides/*.md) vs fragments HTML 중 대표 본문 하나만 색인하고 앵커 연결은 보존(D-plan §5). G0 코퍼스 항목 중 "UNPUBLISHED_GUIDES 제외" 도 access_scope 로 표현.
  3. 색인 버전·전환 원칙 — 검증 후 활성 전환, 실패 시 이전 버전 유지, 삭제·이름 변경 경로 정리, 결과 ID 가 버전을 고정. doc_migrations 설계와 동일 원칙이므로 러너 로직(diff → 증분 임베딩 → 원자적 전환 → down)을 공용 패키지로 두고 저장소 어댑터만 분리.
  4. 하이브리드 검색·평가 방법 — 벡터 + 키워드 후보 합집합 → RRF, 점수 단순 합산 금지. 평가 질문셋은 조정용/최종용 분리, 필수 근거 포함률·잘못된 과거 계획 선택률·p50/p95 를 같은 하네스(services/ai/evals)로 측정. G5 의 docs.json golden set 은 D-plan 1단계 질문셋의 사용자 질문 부분집합.
  5. 임베딩 모델 결정은 한 번 — 두 계획이 서로 다른 모델을 쓰면 벡터 공간이 달라 색인·평가를 공유할 수 없다(D-plan §6.1). 아래 8-3 ①에서 정한다.

8-3. 충돌·결정 필요 (G0 착수 전) ​

  1. 임베딩 모델 — 설계 §9 는 voyage-3 1024d 확정, 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 실험은 비용·품질 벤치마크 대조군으로만 유지.
  2. 차원·테이블 — 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회로 끝나게 설계한다.
  3. 재정렬 — 가이드 코퍼스는 수백 청크 규모라 v1 은 재정렬 없이 hybrid top-8. D-plan 3단계에서 재정렬 효과가 확인되면 G1 v2 에 API 리랭커(Voyage rerank) 를 옵션으로. GPU 리랭커를 제품 경로에 넣지 않는다.
  4. 키워드 검색 — D-plan 이 한국어 조사·복합명사·코드 식별자 토큰화를 검증하는 결과를 G1 searchDocs 의 tsvector 설정(simple vs 커스텀 사전)에 그대로 적용.
  5. 분류 체계 소유 — document_kind · status · verification_level 의 판정 기준 확정은 D-plan 1단계 산출물. G0 는 이 분류를 그대로 쓰고 자체 분류를 만들지 않는다. "문서 준비 중" 판정(열린 질문 3)은 status + product-changes.documentation.status 두 소스를 D-plan 분류에서 하나로 정한다.
  6. 런타임은 분리 — 코드(파서·청커·러너·평가)만 공유하고, 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_version bump 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 유지 vs voyage-4 갱신과 차원 1024 유지 여부 · G0 를 D-plan 2단계 뒤에 둘지
  • 검토 완료 후 에픽별 티켓을 Hereby med QA List DB 에 등록 예정 (현재 미등록)