From 0342290a898dcfc7c03089e7988036d82daecc27 Mon Sep 17 00:00:00 2001 From: chan000518 Date: Sat, 4 Oct 2025 11:32:50 +0900 Subject: [PATCH 01/14] =?UTF-8?q?=E2=9C=A8=20LLM=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=ED=99=94=20=EB=B0=8F=20Gemini=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TASK.md | 211 +++++++++++++++++++++++--- package.json | 1 + src/config.ts | 5 +- src/controllers/ai.controller.ts | 4 +- src/llm/index.ts | 28 ++++ src/llm/model-registry.ts | 12 ++ src/llm/providers/gemini.ts | 75 +++++++++ src/llm/providers/openai-responses.ts | 158 +++++++++++++++++++ src/llm/types.ts | 33 ++++ src/services/qa.service.ts | 75 ++++----- src/types/ai.types.ts | 13 ++ 11 files changed, 555 insertions(+), 60 deletions(-) create mode 100644 src/llm/index.ts create mode 100644 src/llm/model-registry.ts create mode 100644 src/llm/providers/gemini.ts create mode 100644 src/llm/providers/openai-responses.ts create mode 100644 src/llm/types.ts diff --git a/TASK.md b/TASK.md index 803edc7..3bb0eca 100644 --- a/TASK.md +++ b/TASK.md @@ -1,23 +1,188 @@ -## 리팩토링 계획 - -### Phase 1: Repository 계층 도입 (데이터 로직 분리) - -1. **[Repo] `src/repositories` 디렉토리 생성**: 데이터베이스 쿼리 로직을 모아둘 디렉토리를 생성합니다. -2. **[Repo] `post.repository.ts` 생성 및 이전**: - * `blog_post`, `post_chunks`, `post_title_embeddings` 테이블 관련 쿼리를 이 파일로 옮깁니다. - * `qa.service.ts`의 `findPostById`, `findSimilarChunks` 로직을 이전합니다. - * `embedding.service.ts`의 `storeTitleEmbedding`, `storeContentEmbeddings` 로직을 이전합니다. -3. **[Repo] `persona.repository.ts` 생성 및 이전**: - * `persona` 테이블 관련 쿼리를 이 파일로 옮깁니다. - * `qa.service.ts`의 `getSpeechTonePrompt` 내부 DB 조회 로직을 `findPersonaById`와 같은 함수로 분리하여 이전합니다. -4. **[Service] 서비스 계층 수정**: - * `qa.service.ts`와 `embedding.service.ts`가 DB에 직접 접근하는 대신, 새로 만든 Repository의 함수를 호출하도록 코드를 수정합니다. - -### Phase 2: 프롬프트 관리 분리 - -5. **[Prompt] `src/prompts` 디렉토리 생성**: 프롬프트 템플릿을 관리할 디렉토리를 생성합니다. -6. **[Prompt] `qa.prompts.ts` 파일 생성**: - * `qa.service.ts`에 하드코딩된 시스템 프롬프트와 사용자 메시지 생성 로직을 이 파일로 옮깁니다. - * `createRagPrompt`, `createPostContextPrompt`와 같이 동적으로 프롬프트를 생성하는 함수를 만듭니다. -7. **[Service] `qa.service.ts` 수정**: - * `qa.prompts.ts`에서 프롬프트 생성 함수를 가져와(import) 사용하도록 수정합니다. \ No newline at end of file +## 작업 계획 + +작업 순서 +- 1) LLM 모듈화(퍼사드/프로바이더/모델 레지스트리) + GPT-5 mini 기본 적용 +- 2) Gemini 도입: 병행 사용(전용) + 대체 사용(퍼사드) +- 3) 토큰 카운트 및 비용 로깅 추가(양 프로바이더 공통) + +참고: 아래 문서의 섹션 순서와 무관하게 실제 구현 순서는 위의 "작업 순서"를 따릅니다. + + +### 1) LLM 모듈화(퍼사드/프로바이더/모델 레지스트리) + GPT-5 mini 기본 적용 + +목적: LLM 호출을 모듈화하여 옵션 기반으로 모델/프로바이더를 교체 가능하게 만들고, 기본 모델을 `gpt-5-mini`로 전환합니다. 토크나이저/가격표는 3단계에서 처리합니다. + +1. [구조] 파일/모듈 구성 + - 디렉토리: `src/llm/` + - `src/llm/types.ts` — 공통 인터페이스 정의 + - `GenerateRequest`: `{ provider?: 'openai'|'gemini', model?: string, messages?: OpenAIStyleMessages, contents?: GeminiStyleContents, stream?: boolean, tools?, options?: { temperature?, top_p?, max_output_tokens?, reasoning?, text? }, meta?: { userId?, categoryId?, postId? } }` + - `GenerateStream`: `onToken(text)`, `onToolCall(json)`, `onEnd()`, `onError(err)`(또는 AsyncIterable) + - `src/llm/modelRegistry.ts` — 모델 레지스트리/기본값 + - 논리 모델 키 → `{ provider, modelId, defaults, tokenizerKey?, pricingKey? }` + - 기본값: `defaultChat = { provider: 'openai', modelId: 'gpt-5-mini' }` + - `src/llm/providers/openaiResponses.ts` — OpenAI Responses API 구현 + - `src/llm/providers/gemini.ts` — @google/gemini 구현 + - `src/llm/index.ts` — 퍼사드: `generate(req: GenerateRequest): GenerateStream` 선택 라우팅 + - 기존 서비스(`qa.service.ts`)는 퍼사드만 사용하도록 변경 + +2. [기본 모델] GPT-5 mini 적용(Responses API) + - `src/config.ts`의 `CHAT_MODEL` 기본값을 `gpt-5-mini`로 변경 + - OpenAI 경로: `openai.responses.create/stream`로 마이그레이션(SSE 어댑터 포함) + - 기존 Chat Completions 경로는 임시 백업/옵션으로 유지 가능(필요 시) + +3. [옵션 기반 모델/프로바이더 선택] + - 요청 바디에 `llm?: { provider?: 'openai'|'gemini', model?: string, options?: {...} }` 허용 + - 미지정 시 레지스트리의 기본값 사용(`gpt-5-mini` on OpenAI) + - 향후 기능(Reasoning/Text 옵션, tool calls, timeout 등) 확장 용이 + +4. [검증/수용 기준] + - `/ai/ask` SSE 정상 동작(중단/지연 없음) + - 기존 프롬프트/툴 호출이 동일하게 동작(필요 시 어댑터) + - 로그/오류 처리 기존 수준 유지 + +### 2) Gemini 도입: 병행 사용(전용) + 대체 사용(퍼사드) + +목적: Gemini를 독립 엔드포인트로 직접 쓰는 경로와, 기존 GPT 경로의 대체 제공자로 모두 사용할 수 있게 합니다(퍼사드 경유). 이후 3단계에서 토큰/비용 로깅을 공통 적용합니다. + +1. [Config] Gemini 키/모델 설정 + - `.env` + - `GEMINI_API_KEY=...` + - `GEMINI_CHAT_MODEL=gemini-2.5-flash` (예: 변경 가능) + - `src/config.ts`에 항목 반영 및 기본값/검증 추가(Provider 고정 ENV는 사용하지 않음) + +2. [Provider] 퍼사드에 Gemini 구현 추가 + - 1단계에서 만든 LLM 퍼사드(`src/llm/index.ts`)에 Gemini 프로바이더를 추가 + - 구현 위치: `src/llm/providers/gemini.ts` (OpenAI 구현은 `src/llm/providers/openaiResponses.ts`) + - 퍼사드 인터페이스로 라우팅되어 기존 `qa.service.ts`는 퍼사드만 사용(교체 투명) + +3. [Gemini 호출] @google/genai SDK 적용 및 스트리밍 + - 의존성: `@google/genai` 추가 (설치 커맨드: `npm i @google/genai`) + - 클라이언트: `import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({});` (`GEMINI_API_KEY`는 환경변수에서 자동 주입) + - 비스트리밍(우선 적용): + - `ai.models.generateContent({ model: GEMINI_CHAT_MODEL, contents, config: { thinkingConfig: { thinkingBudget }}})` + - 기본값으로 `thinkingBudget=0`(생각 비활성화) 적용, `.env`에서 오버라이드 가능 + - 응답 텍스트를 한번에 수신한 뒤 SSE로 순차 chunk 분할하여 `answer` 이벤트로 전송(간단 구현) + - 스트리밍(선택 적용): + - SDK 제공 시 스트리밍 API 사용(예: `generateContentStream` 유사 기능)으로 델타를 받아 즉시 SSE로 전달 + - SDK에서 미지원일 경우, 비스트리밍으로 우선 릴리즈 후 스트리밍 전환 + - (옵션) Safety 설정, generationConfig(temperature/topP/maxOutputTokens) 파라미터는 설정값으로 노출 + +5. [토큰 카운팅] Gemini 대응 + - 사전 카운트(가능 시): SDK의 토큰 카운트 API(`tokens:count`/`countTokens`)가 제공되면 이를 사용해 프롬프트 토큰 계산 → 비용 선로깅 + - 네트워크 요청이므로 로깅 토글이 켜져 있을 때만 수행하도록 옵션화 + - 사후 카운트: 응답 텍스트 기준 동일 API로 출력 토큰 계산(또는 비가용 시 근사치) + - 폴백 전략: 카운트 API가 불가한 환경에서는 근사치 사용(문자수/4), 추후 정확도 개선 시 교체 + +6. [가격 정책] Gemini 추가 + - `src/config/pricing.ts`의 `PRICING_TABLE`에 Gemini 모델(`gemini-2.5-flash`, 임베딩 모델 등) 단가 추가 + - 동일한 `calcCost`, `formatCost` 로직 재사용 + +7. [생각(Thinking) 설정] 기본 비활성화 + - Gemini 2.5 Flash의 생각 기능은 응답 품질 대신 비용/지연이 증가하므로 기본 `thinkingBudget=0`으로 비활성화 + - `.env`에 `GEMINI_THINKING_BUDGET`를 두어 필요 시 활성화(정수값) + +8. [도구/함수 호출] 호환성 계획(선택) + - 현재 OpenAI `tool_calls`를 사용 중. Gemini는 `functionDeclarations`/`toolConfig` 형태로 유사 기능 제공 + - 1단계: Gemini 경로에서는 도구 호출 비활성화(빠른 도입) + - 2단계: 필요 시 `report_content_insufficient`를 Gemini `functionDeclarations`로 매핑하여 동일 동작 구현 + +9. [Wiring] 사용 패턴 + - 독립 사용(A): `POST /ai/gemini/ask`로 직접 호출(옵션: thinkingBudget 등) + - 대체 사용(B): 기존 `POST /ai/ask`에 `llm.provider?: 'openai'|'gemini'`, `llm.model?` 허용 → 퍼사드가 라우팅 + - 로깅 시 `provider` 필드를 포함(3단계에서 적용) + +10. [검증/수용 기준] + - OpenAI/Gemini 각각에서 동일한 SSE 응답 형식으로 동작 + - 요청 전/후 토큰·비용 로그가 두 프로바이더 모두에서 출력 + - 로깅 토글이 정상 작동, 스트리밍 성능 저하 없음 + +설정 확정 +- `GEMINI_CHAT_MODEL=gemini-2.5-flash` +- `GEMINI_THINKING_BUDGET=0` (기본값으로 비활성화) + +### 토큰 카운트 및 비용 로깅 추가 + +목적: LLM에 요청을 보내기 직전에 프롬프트(메시지) 토큰 수를 계산해 예상 입력 비용을 콘솔로 로깅하고, 스트리밍 응답 완료 후 실제 출력 토큰 수 기반 최종 비용을 추가 로깅합니다. 초기에는 `console.log`만 사용합니다. + +1. [Utils] 토크나이저 유틸 추가 + - 파일: `src/utils/tokenizer.ts` + - 내용: + - `getTokenizerForModel(model: string)` → 모델명에 따라 적절한 인코딩을 선택 + - `gpt-5*` → 자료 제공 전까지 임시로 `o200k_base` 사용(TBD, 전환 시 교체) + - `gpt-4o`, `gpt-4o-mini`, 기타 `o`계열 → `o200k_base` + - `countTextTokens(text: string, model: string): number` + - `countChatMessagesTokens(messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[], model: string): number` + - 메시지 `content`들을 토크나이즈하여 합산하고, 채팅 포맷 오버헤드(메시지당 소량, 모델별 상수)를 보정치로 가산 + - 주의: 보정치는 근사치이며, 정확한 정산은 응답 토큰 합산으로 후처리 + - 비고: 이미 프로젝트에 `@dqbd/tiktoken`이 포함되어 있으므로 이를 사용합니다. + +2. [Config] 가격 정책 맵 구조 설계 (임시 하드코딩 + ENV 오버라이드) + - 파일: `src/config/pricing.ts` + - 내용: + - `export type Pricing = { input_per_1k: number; output_per_1k: number; cached_input_per_1k?: number; currency: 'USD' | 'KRW' }` + - `PRICING_TABLE: Record`: 모델명 키에 따른 단가 설정 + - 선택: `LLM_PRICING_OVERRIDES`(JSON) 환경변수로 런타임 오버라이드 허용 + - 초기값은 사용자 제공 정책으로 채울 예정. 제공 전까지는 로깅에 `N/A` 표기 또는 0 처리. + + - 초기 PRICING_TABLE(제공 정책 반영, 단위: per 1K tokens, 통화: USD) + - `gpt-5`: { input_per_1k: 0.00125, cached_input_per_1k: 0.000125, output_per_1k: 0.01, currency: 'USD' } + - `gpt-5-mini`: { input_per_1k: 0.00025, cached_input_per_1k: 0.000025, output_per_1k: 0.002, currency: 'USD' } + - `gpt-5-nano`: { input_per_1k: 0.00005, cached_input_per_1k: 0.000005, output_per_1k: 0.0004, currency: 'USD' } + +3. [Utils] 비용 계산 유틸 추가 + - 파일: `src/utils/cost.ts` + - 내용: + - `getModelPricing(model: string): Pricing | null` + - `calcCost(tokens: number, per_1k: number): number` → 반올림 1~4자리(옵션) + - 화폐 표기 함수(선택): `formatCost(amount: number, currency: string)` + +4. [Facade] LLM 퍼사드에 비용 로깅 통합 + - 위치: `src/llm/index.ts` 퍼사드 내부에서 공통 로깅 수행 + - 기능 흐름(공통): + 1) 요청 전: 메시지/콘텐츠 토큰 카운트 → `promptTokens` + - OpenAI: `countChatMessagesTokens`(토크나이저) + - Gemini: `countTokens` API 가능 시 사용(불가 시 근사치) + 2) 단가 조회: `getModelPricing(model)` → `estInputCost` + 3) 선로깅: `{type:'llm.request', provider, model, promptTokens, estInputCost, corrId, userId, categoryId, postId}` + 4) 실제 호출: 등록된 프로바이더(OpenAI Responses 또는 Gemini)로 위임, 스트림은 그대로 중계 + 5) 스트림 종료 후: 출력 텍스트/함수인자 토큰 합산 → `completionTokens` + 6) 비용 계산: 입력/출력(+cached 입력이 있으면 분리) → `totalCost` + 7) 후로깅: `{type:'llm.response', provider, model, promptTokens, completionTokens, inputCost, outputCost, totalCost, durationMs, corrId, cachedInputTokens}` + - 주의: 기존 SSE 흐름(이벤트명/포맷) 불변 유지. 퍼사드는 원본 델타를 그대로 전달. + - 상관관계 ID(`corrId`)는 `uuid` 생성(또는 요청별 식별자 전달 시 사용). + +5. [Wiring] `qa.service.ts`에서 퍼사드 사용 + - 기존 직접 호출부를 LLM 퍼사드로 교체(`generate(req)`) + - 요청 바디의 `llm` 옵션을 퍼사드에 그대로 전달(provider/model/options) + - 출력 토큰 카운트/비용 로깅은 퍼사드 내부에서 처리 + +6. [옵션] 임베딩 호출 비용 로깅(확장) + - 파일: `src/services/embedding.service.ts` + - `createEmbeddings` 호출 직전 `input` 텍스트 전체 토큰 수 계산(`countTextTokens` 누적) → 입력 비용 로깅 + - 임베딩 모델 단가(`text-embedding-3-*`)도 `PRICING_TABLE`에 포함 + +7. [환경변수] 로깅 토글 및 라운딩 + - `.env` 키 추가(기본값은 off) + - `LLM_COST_LOG=true|false` (기본: true로 해도 무방) + - `LLM_COST_ROUND=2` (소수점 자리수, 선택) + - 로깅은 토글 꺼져 있으면 수행하지 않음 + +8. [로그 포맷] 예시(JSON 라인) + - 요청 전: `{ "type": "llm.request", "corrId": "...", "provider": "openai", "model": "gpt-5-mini", "promptTokens": 1234, "estInputCost": 0.00031, "userId": "...", "categoryId": 1, "postId": 42 }` + - 응답 후: `{ "type": "llm.response", "corrId": "...", "provider": "openai", "model": "gpt-5-mini", "promptTokens": 1234, "completionTokens": 456, "inputCost": 0.00031, "outputCost": 0.00091, "totalCost": 0.00122, "durationMs": 987, "cachedInputTokens": 0 }` + +9. [검증/수용 기준] + - `POST /ai/ask` 호출 시 콘솔에 요청 전/후 로그 각각 1회 출력 + - 모델/프롬프트/토큰 수/예상 비용/총 비용/시간(ms)이 포함되어야 함 + - 로깅 on/off 토글 동작, 라운딩 반영 확인 + - 기존 SSE 동작(끊김/지연) 변화 없음 + +10. [주의/한계] + - 채팅 포맷 오버헤드는 모델별로 상이하며 근사치 사용. 최종 비용은 출력 토큰 카운트까지 반영해 오차 최소화 + - 스트리밍 API는 서버에서 사용량 메타를 즉시 제공하지 않으므로(비스트리밍과 달리), 응답 텍스트 기반 자체 카운트 수행 + - 함수 호출(tool_calls) 토큰은 인자 길이에 비례하여 증가. 누적 텍스트/인자 기반으로 동일하게 카운트 + - Cached Input 과금: 제공 API에서 캐시 히트 토큰 정보를 명시적으로 제공하는 경우에만 `cachedInputTokens`로 분리 산정. 그렇지 않으면 일반 입력으로 계산(보수적) + +11. [다음 단계(선택)] + - `console.log` → 구조화 로거(Pino/Winston)로 교체, 샘플링·보존 기간 설정 + - DB 또는 시계열(예: ClickHouse/Prometheus) 적재로 사용자별 비용 대시보드 구성 diff --git a/package.json b/package.json index 712d202..2911813 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ }, "dependencies": { "@dqbd/tiktoken": "^1.0.13", + "@google/genai": "^0.2.0", "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", diff --git a/src/config.ts b/src/config.ts index 18993cc..1be73a1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,7 +12,10 @@ const configSchema = z.object({ TOKEN_AUDIENCE: z.string().default('bubblog'), ALGORITHM: z.string().default('HS256'), EMBED_MODEL: z.string().default('text-embedding-3-small'), - CHAT_MODEL: z.string().default('gpt-4o'), + CHAT_MODEL: z.string().default('gpt-5-mini'), + GEMINI_API_KEY: z.string().optional(), + GEMINI_CHAT_MODEL: z.string().default('gemini-2.5-flash'), + GEMINI_THINKING_BUDGET: z.string().optional(), }); const config = configSchema.parse(process.env); diff --git a/src/controllers/ai.controller.ts b/src/controllers/ai.controller.ts index e6ab029..1b9a593 100644 --- a/src/controllers/ai.controller.ts +++ b/src/controllers/ai.controller.ts @@ -49,13 +49,13 @@ export const askHandler = async ( next: NextFunction ) => { try { - const { question, user_id, category_id, speech_tone, post_id } = req.body; + const { question, user_id, category_id, speech_tone, post_id, llm } = req.body as any; res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); - const stream = await answerStream(question, user_id, category_id, speech_tone, post_id); + const stream = await answerStream(question, user_id, category_id, speech_tone, post_id, llm); stream.pipe(res); } catch (error) { diff --git a/src/llm/index.ts b/src/llm/index.ts new file mode 100644 index 0000000..9c39531 --- /dev/null +++ b/src/llm/index.ts @@ -0,0 +1,28 @@ +import { PassThrough } from 'stream'; +import { GenerateRequest } from './types'; +import { getDefaultChat } from './model-registry'; +import { generateOpenAIStream } from './providers/openai-responses'; +import { generateGeminiStream } from './providers/gemini'; + +export const generate = async (req: GenerateRequest): Promise => { + const merged = { ...req }; + if (!merged.provider || !merged.model) { + const def = getDefaultChat(); + merged.provider = merged.provider || def.provider; + merged.model = merged.model || def.modelId; + } + + if (merged.provider === 'openai') { + return generateOpenAIStream(merged); + } + + if (merged.provider === 'gemini') { + return generateGeminiStream(merged); + } + + const stream = new PassThrough(); + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ message: 'Unknown provider' })}\n\n`); + stream.end(); + return stream; +}; diff --git a/src/llm/model-registry.ts b/src/llm/model-registry.ts new file mode 100644 index 0000000..14cbdfe --- /dev/null +++ b/src/llm/model-registry.ts @@ -0,0 +1,12 @@ +import { ProviderName } from './types'; + +type ModelEntry = { + provider: ProviderName; + modelId: string; +}; + +// Minimal registry for now; can expand with tokenizer/pricing later. +const DEFAULT_CHAT: ModelEntry = { provider: 'openai', modelId: 'gpt-5-mini' }; + +export const getDefaultChat = (): ModelEntry => DEFAULT_CHAT; + diff --git a/src/llm/providers/gemini.ts b/src/llm/providers/gemini.ts new file mode 100644 index 0000000..a399317 --- /dev/null +++ b/src/llm/providers/gemini.ts @@ -0,0 +1,75 @@ +import { PassThrough } from 'stream'; +import config from '../../config'; +import { GenerateRequest } from '../types'; + +// Using @google/genai per project plan; keep types loose for compatibility +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { GoogleGenAI } = require('@google/genai'); + +const buildPromptFromMessages = (messages: { role: string; content: string }[]) => { + // Simple concatenation preserving roles + return messages + .map((m) => `[${m.role}]\n${m.content}`) + .join('\n\n'); +}; + +export const generateGeminiStream = async (req: GenerateRequest): Promise => { + const stream = new PassThrough(); + try { + const modelId = req.model || process.env.GEMINI_CHAT_MODEL || 'gemini-2.5-flash'; + const apiKey = (config as any).GEMINI_API_KEY || process.env.GEMINI_API_KEY; + if (!apiKey) { + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ message: 'Gemini API key not configured' })}\n\n`); + stream.end(); + return stream; + } + + const ai = new GoogleGenAI({ apiKey }); + + const text = buildPromptFromMessages(req.messages || []); + + const generationConfig: any = {}; + if (req.options?.temperature != null) generationConfig.temperature = req.options.temperature; + if (req.options?.top_p != null) generationConfig.topP = req.options.top_p; + if (req.options?.max_output_tokens != null) generationConfig.maxOutputTokens = req.options.max_output_tokens; + + const thinkingBudget = parseInt(process.env.GEMINI_THINKING_BUDGET || '0', 10) || 0; + const configBlock: any = thinkingBudget > 0 ? { thinkingConfig: { thinkingBudget } } : {}; + + // Non-streaming first, then chunk SSE + const result = await ai.models.generateContent({ + model: modelId, + contents: [ + { + role: 'user', + parts: [{ text }], + }, + ], + generationConfig, + config: configBlock, + }); + + // Try common text access paths + const outputText = (result?.response?.text && result.response.text()) || (result?.text && result.text()) || ''; + + const finalText = typeof outputText === 'string' ? outputText : ''; + + const chunkSize = 400; + for (let i = 0; i < finalText.length; i += chunkSize) { + const chunk = finalText.slice(i, i + chunkSize); + stream.write(`event: answer\n`); + stream.write(`data: ${JSON.stringify(chunk)}\n\n`); + } + stream.write(`event: end\n`); + stream.write(`data: [DONE]\n\n`); + stream.end(); + return stream; + } catch (err) { + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); + stream.end(); + return stream; + } +}; + diff --git a/src/llm/providers/openai-responses.ts b/src/llm/providers/openai-responses.ts new file mode 100644 index 0000000..1100db6 --- /dev/null +++ b/src/llm/providers/openai-responses.ts @@ -0,0 +1,158 @@ +import { PassThrough } from 'stream'; +import OpenAI from 'openai'; +import config from '../../config'; +import { GenerateRequest, OpenAIStyleMessage, OpenAIStyleTool } from '../types'; + +const openai = new OpenAI({ apiKey: config.OPENAI_API_KEY }); + +const toResponsesInput = (messages: OpenAIStyleMessage[] = []) => { + // Convert simple chat-style messages to Responses API input format + return messages.map((m) => ({ + role: m.role, + content: [{ type: 'text', text: m.content }], + })); +}; + +export const generateOpenAIStream = async (req: GenerateRequest): Promise => { + const stream = new PassThrough(); + const model = req.model || 'gpt-5-mini'; + const messages = req.messages || []; + const tools = (req.tools || []) as unknown as OpenAI.Responses.ResponseCreateParams['tools']; + + // For gpt-5-* prefer Responses API. For other models, fall back to Chat Completions streaming. + const isGpt5Family = /(^|\b)gpt-5/i.test(model); + + try { + if (isGpt5Family) { + // Prefer Responses API streaming for gpt-5 + try { + const responsesStream: any = await (openai as any).responses.stream({ + model, + input: toResponsesInput(messages) as any, + tools: tools as any, + temperature: req.options?.temperature, + top_p: req.options?.top_p, + max_output_tokens: req.options?.max_output_tokens, + }); + + responsesStream.on('response.output_text.delta', (delta: string) => { + if (delta) { + stream.write(`event: answer\n`); + stream.write(`data: ${JSON.stringify(delta)}\n\n`); + } + }); + + // Stream tool-call arguments as answer chunks to maintain SSE shape + responsesStream.on('response.tool_call.delta', (toolDelta: any) => { + const argsDelta = toolDelta?.arguments_delta || toolDelta?.arguments || ''; + if (argsDelta) { + stream.write(`event: answer\n`); + stream.write(`data: ${JSON.stringify(argsDelta)}\n\n`); + } + }); + + responsesStream.on('response.completed', () => { + stream.write(`event: end\n`); + stream.write(`data: [DONE]\n\n`); + stream.end(); + }); + + responsesStream.on('error', (e: any) => { + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); + stream.end(); + }); + + // Ensure the stream starts and we await its completion + await responsesStream.done(); + return stream; + } catch (e) { + // Fallback to non-streaming Responses if streaming path fails + try { + const response = await openai.responses.create({ + model, + input: toResponsesInput(messages) as any, + // Avoid tools in non-streaming mode to ensure text output + temperature: req.options?.temperature, + top_p: req.options?.top_p, + max_output_tokens: req.options?.max_output_tokens, + }); + const text = (response as any).output_text ?? ''; + const answerText = typeof text === 'string' ? text : ''; + const fallbackText = (() => { + try { + const outputs = (response as any).output || []; + if (Array.isArray(outputs) && outputs.length > 0) { + const parts = outputs + .flatMap((o: any) => o.content || []) + .filter((c: any) => c.type === 'output_text') + .map((c: any) => c.text) + .join(''); + return parts || ''; + } + } catch { + // ignore + } + return ''; + })(); + const finalText = answerText || fallbackText; + const chunkSize = 400; + for (let i = 0; i < finalText.length; i += chunkSize) { + const chunk = finalText.slice(i, i + chunkSize); + stream.write(`event: answer\n`); + stream.write(`data: ${JSON.stringify(chunk)}\n\n`); + } + stream.write(`event: end\n`); + stream.write(`data: [DONE]\n\n`); + stream.end(); + return stream; + } catch (e2) { + // fall through to chat completions streaming below + } + } + } + + // Chat Completions streaming as universal fallback + const chatStream = await openai.chat.completions.create({ + model, + messages: messages as any, + tools: (req.tools as OpenAI.Chat.Completions.ChatCompletionTool[]) || undefined, + tool_choice: req.tools && req.tools.length > 0 ? 'auto' : undefined, + stream: true, + temperature: req.options?.temperature, + top_p: req.options?.top_p, + max_tokens: req.options?.max_output_tokens as any, + }); + + for await (const chunk of chatStream) { + const content = chunk.choices[0]?.delta?.content || ''; + const toolCalls = chunk.choices[0]?.delta?.tool_calls; + + if (toolCalls) { + for (const toolCall of toolCalls) { + if (toolCall.function?.arguments) { + stream.write(`event: answer\n`); + stream.write(`data: ${JSON.stringify(toolCall.function.arguments)}\n\n`); + } + } + } else if (content) { + stream.write(`event: answer\n`); + stream.write(`data: ${JSON.stringify(content)}\n\n`); + } + + if (chunk.choices[0]?.finish_reason) { + stream.write(`event: end\n`); + stream.write(`data: [DONE]\n\n`); + stream.end(); + break; + } + } + + return stream; + } catch (err) { + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); + stream.end(); + return stream; + } +}; diff --git a/src/llm/types.ts b/src/llm/types.ts new file mode 100644 index 0000000..b17bc54 --- /dev/null +++ b/src/llm/types.ts @@ -0,0 +1,33 @@ +export type ProviderName = 'openai' | 'gemini'; + +export type OpenAIStyleMessage = { + role: 'system' | 'user' | 'assistant' | 'tool' | 'function'; + content: string; +}; + +export type OpenAIStyleTool = { + type: 'function'; + function: { + name: string; + description?: string; + parameters?: Record; + }; +}; + +export type GenerateRequest = { + provider?: ProviderName; + model?: string; + messages?: OpenAIStyleMessage[]; + tools?: OpenAIStyleTool[]; + options?: { + temperature?: number; + top_p?: number; + max_output_tokens?: number; + }; + meta?: { + userId?: string; + categoryId?: number; + postId?: number; + }; +}; + diff --git a/src/services/qa.service.ts b/src/services/qa.service.ts index 2361bbc..549a919 100644 --- a/src/services/qa.service.ts +++ b/src/services/qa.service.ts @@ -1,14 +1,10 @@ import { createEmbeddings } from './embedding.service'; import { PassThrough } from 'stream'; -import OpenAI from 'openai'; import config from '../config'; import * as postRepository from '../repositories/post.repository'; import * as personaRepository from '../repositories/persona.repository'; import * as qaPrompts from '../prompts/qa.prompts'; - -const openai = new OpenAI({ - apiKey: config.OPENAI_API_KEY, -}); +import { generate } from '../llm'; const preprocessContent = (content: string): string => { const plainText = content.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim(); @@ -27,20 +23,40 @@ const getSpeechTonePrompt = async (speechTone: number, userId: string): Promise< return "간결하고 명확한 말투로 답변해"; // Default } +type LlmOverride = { + provider?: 'openai' | 'gemini'; + model?: string; + options?: { temperature?: number; top_p?: number; max_output_tokens?: number }; +}; + export const answerStream = async ( question: string, userId: string, categoryId?: number, speechTone: number = -1, - postId?: number + postId?: number, + llm?: LlmOverride ): Promise => { const stream = new PassThrough(); - let messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = []; - let tools: OpenAI.Chat.Completions.ChatCompletionTool[] | undefined = undefined; + let messages: { role: 'system' | 'user' | 'assistant' | 'tool' | 'function'; content: string }[] = []; + let tools: + | { + type: 'function'; + function: { name: string; description?: string; parameters?: Record }; + }[] + | undefined = undefined; (async () => { const speechTonePrompt = await getSpeechTonePrompt(speechTone, userId); + const toSimpleMessages = ( + raw: any[] + ): { role: 'system' | 'user' | 'assistant' | 'tool' | 'function'; content: string }[] => { + return (raw || []).map((m: any) => ({ + role: m.role, + content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content), + })); + }; if (postId) { const post = await postRepository.findPostById(postId); @@ -61,7 +77,9 @@ export const answerStream = async ( stream.write(`event: exist_in_post_status\ndata: true\n\n`); stream.write(`event: context\ndata: ${JSON.stringify([{ postId: post.id, postTitle: post.title }])}\n\n`); - messages = qaPrompts.createPostContextPrompt(post, processedContent, question, speechTonePrompt); + messages = toSimpleMessages( + qaPrompts.createPostContextPrompt(post, processedContent, question, speechTonePrompt) + ); } else { const [questionEmbedding] = await createEmbeddings([question]); @@ -73,7 +91,9 @@ export const answerStream = async ( const context = similarChunks.map(chunk => ({ postId: chunk.postId, postTitle: chunk.postTitle })); stream.write(`event: context\ndata: ${JSON.stringify(context)}\n\n`); - messages = qaPrompts.createRagPrompt(question, similarChunks, speechTonePrompt); + messages = toSimpleMessages( + qaPrompts.createRagPrompt(question, similarChunks, speechTonePrompt) + ); tools = [ { type: "function", @@ -92,34 +112,21 @@ export const answerStream = async ( ]; } - const responseStream = await openai.chat.completions.create({ - model: config.CHAT_MODEL, + const llmStream = await generate({ + provider: llm?.provider || 'openai', + model: llm?.model || config.CHAT_MODEL, messages, tools, - tool_choice: tools ? 'auto' : undefined, - stream: true, + options: llm?.options, + meta: { userId, categoryId, postId }, }); - for await (const chunk of responseStream) { - const content = chunk.choices[0]?.delta?.content || ""; - const toolCalls = chunk.choices[0]?.delta?.tool_calls; - - if (toolCalls) { - for (const toolCall of toolCalls) { - if (toolCall.function?.arguments) { - stream.write(`event: answer\ndata: ${JSON.stringify(toolCall.function.arguments)}\n\n`); - } - } - } else if (content) { - stream.write(`event: answer\ndata: ${JSON.stringify(content)}\n\n`); - } - - if (chunk.choices[0]?.finish_reason) { - stream.write(`event: end\ndata: [DONE]\n\n`); - stream.end(); - break; - } - } + llmStream.on('data', (chunk) => { + stream.write(chunk); + }); + llmStream.on('end', () => { + stream.end(); + }); })().catch(err => { console.error('Stream process error:', err); diff --git a/src/types/ai.types.ts b/src/types/ai.types.ts index e596d1a..b9ed539 100644 --- a/src/types/ai.types.ts +++ b/src/types/ai.types.ts @@ -28,6 +28,19 @@ export const askSchema = z.object({ category_id: z.number().optional(), post_id: z.number().optional(), speech_tone: z.number().optional(), + llm: z + .object({ + provider: z.enum(['openai', 'gemini']).optional(), + model: z.string().optional(), + options: z + .object({ + temperature: z.number().optional(), + top_p: z.number().optional(), + max_output_tokens: z.number().optional(), + }) + .optional(), + }) + .optional(), }), }); From a3d6079c797c7eee1af582a070e1ad9bd909a67f Mon Sep 17 00:00:00 2001 From: chan000518 Date: Sat, 4 Oct 2025 11:35:22 +0900 Subject: [PATCH 02/14] =?UTF-8?q?=E2=9C=A8=20LLM=20=EB=B9=84=EC=9A=A9=20?= =?UTF-8?q?=EB=A1=9C=EA=B9=85=20=EB=B0=8F=20=EA=B0=80=EA=B2=A9=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config.ts | 2 + src/llm/index.ts | 137 ++++++++++++++++++++++++++++++++++++++--- src/utils/cost.ts | 40 ++++++++++++ src/utils/tokenizer.ts | 32 ++++++++++ 4 files changed, 201 insertions(+), 10 deletions(-) create mode 100644 src/utils/cost.ts create mode 100644 src/utils/tokenizer.ts diff --git a/src/config.ts b/src/config.ts index 1be73a1..ba81564 100644 --- a/src/config.ts +++ b/src/config.ts @@ -16,6 +16,8 @@ const configSchema = z.object({ GEMINI_API_KEY: z.string().optional(), GEMINI_CHAT_MODEL: z.string().default('gemini-2.5-flash'), GEMINI_THINKING_BUDGET: z.string().optional(), + LLM_COST_LOG: z.string().default('false'), + LLM_COST_ROUND: z.coerce.number().default(4), }); const config = configSchema.parse(process.env); diff --git a/src/llm/index.ts b/src/llm/index.ts index 9c39531..ba30ce4 100644 --- a/src/llm/index.ts +++ b/src/llm/index.ts @@ -3,6 +3,10 @@ import { GenerateRequest } from './types'; import { getDefaultChat } from './model-registry'; import { generateOpenAIStream } from './providers/openai-responses'; import { generateGeminiStream } from './providers/gemini'; +import { countChatMessagesTokens, countTextTokens } from '../utils/tokenizer'; +import { calcCost, getModelPricing } from '../utils/cost'; +import config from '../config'; +import { randomUUID } from 'crypto'; export const generate = async (req: GenerateRequest): Promise => { const merged = { ...req }; @@ -12,17 +16,130 @@ export const generate = async (req: GenerateRequest): Promise => { merged.model = merged.model || def.modelId; } - if (merged.provider === 'openai') { - return generateOpenAIStream(merged); - } + const doLog = (config.LLM_COST_LOG || '').toString().toLowerCase() === 'true'; + const round = config.LLM_COST_ROUND ?? 4; + const corrId = randomUUID(); + const model = merged.model as string; + const provider = merged.provider as string; - if (merged.provider === 'gemini') { - return generateGeminiStream(merged); + // Pre-call logging: prompt tokens + estimated input cost + const messages = merged.messages || []; + let promptTokens = 0; + try { + promptTokens = countChatMessagesTokens(messages as any, model); + } catch { + // ignore + } + const pricing = getModelPricing(model); + const estInputCost = pricing ? calcCost(promptTokens, pricing.input_per_1k) : 0; + if (doLog) { + const pre = { + type: 'llm.request', + corrId, + provider, + model, + promptTokens, + estInputCost, + userId: merged.meta?.userId, + categoryId: merged.meta?.categoryId, + postId: merged.meta?.postId, + }; + console.log(JSON.stringify(pre)); } - const stream = new PassThrough(); - stream.write(`event: error\n`); - stream.write(`data: ${JSON.stringify({ message: 'Unknown provider' })}\n\n`); - stream.end(); - return stream; + const startedAt = Date.now(); + + const providerStream = + merged.provider === 'openai' + ? await generateOpenAIStream(merged) + : merged.provider === 'gemini' + ? await generateGeminiStream(merged) + : (() => { + const s = new PassThrough(); + s.write(`event: error\n`); + s.write(`data: ${JSON.stringify({ message: 'Unknown provider' })}\n\n`); + s.end(); + return s; + })(); + + // Wrap provider stream to accumulate output tokens + const outer = new PassThrough(); + let buffer = ''; + let outputText = ''; + + const flushBuffer = () => { + // Split by double newline to get SSE events + const chunks = buffer.split('\n\n'); + // Keep last partial + buffer = chunks.pop() || ''; + for (const block of chunks) { + const lines = block.split('\n'); + let evt: string | null = null; + let dataLine: string | null = null; + for (const line of lines) { + if (line.startsWith('event:')) evt = line.slice(6).trim(); + if (line.startsWith('data:')) dataLine = line.slice(5).trim(); + } + if (evt === 'answer' && dataLine) { + try { + const parsed = JSON.parse(dataLine); + if (typeof parsed === 'string') outputText += parsed; + else outputText += JSON.stringify(parsed); + } catch { + outputText += dataLine; + } + } + outer.write(block + '\n\n'); + } + }; + + providerStream.on('data', (chunk) => { + const str = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk); + buffer += str; + flushBuffer(); + }); + providerStream.on('end', () => { + if (buffer.length > 0) { + outer.write(buffer); + buffer = ''; + } + + const completionTokens = (() => { + try { + return countTextTokens(outputText, model); + } catch { + return 0; + } + })(); + const durationMs = Date.now() - startedAt; + if (doLog) { + const inputCost = pricing ? calcCost(promptTokens, pricing.input_per_1k) : 0; + const outputCost = pricing ? calcCost(completionTokens, pricing.output_per_1k) : 0; + const totalCost = inputCost + outputCost; + const post = { + type: 'llm.response', + corrId, + provider, + model, + promptTokens, + completionTokens, + inputCost, + outputCost, + totalCost, + durationMs, + }; + console.log(JSON.stringify(post)); + } + outer.end(); + }); + providerStream.on('error', (e) => { + if (doLog) { + console.log( + JSON.stringify({ type: 'llm.error', corrId, provider, model, message: (e as any)?.message || 'error' }) + ); + } + outer.emit('error', e); + }); + + return outer; }; diff --git a/src/utils/cost.ts b/src/utils/cost.ts new file mode 100644 index 0000000..62334db --- /dev/null +++ b/src/utils/cost.ts @@ -0,0 +1,40 @@ +export type Pricing = { + input_per_1k: number; + output_per_1k: number; + cached_input_per_1k?: number; + currency: 'USD' | 'KRW' | string; +}; + +const PRICING_TABLE: Record = { + // OpenAI + 'gpt-5-mini': { input_per_1k: 0.00025, output_per_1k: 0.002, cached_input_per_1k: 0.000025, currency: 'USD' }, + 'gpt-5-nano': { input_per_1k: 0.00005, output_per_1k: 0.0004, cached_input_per_1k: 0.000005, currency: 'USD' }, + 'gpt-4o': { input_per_1k: 0.005, output_per_1k: 0.015, currency: 'USD' }, + 'gpt-4o-mini': { input_per_1k: 0.0005, output_per_1k: 0.0015, currency: 'USD' }, + // Embeddings + 'text-embedding-3-small': { input_per_1k: 0.00002, output_per_1k: 0, currency: 'USD' }, + // Gemini (example values — update per official pricing if needed) + 'gemini-2.5-flash': { input_per_1k: 0.0001, output_per_1k: 0.0004, currency: 'USD' }, +}; + +export const getModelPricing = (model: string): Pricing | null => { + if (!model) return null; + const key = model.toLowerCase(); + if (PRICING_TABLE[key]) return PRICING_TABLE[key]; + // naive aliasing for common variants + if (key.startsWith('gpt-4o')) return PRICING_TABLE['gpt-4o']; + if (key.startsWith('gpt-5-mini')) return PRICING_TABLE['gpt-5-mini']; + return null; +}; + +export const calcCost = (tokens: number, per_1k: number): number => { + if (!per_1k) return 0; + return (tokens / 1000) * per_1k; +}; + +export const formatCost = (amount: number, currency: string, round: number = 4): string => { + const factor = Math.pow(10, Math.max(0, round)); + const rounded = Math.round(amount * factor) / factor; + return `${rounded} ${currency}`; +}; + diff --git a/src/utils/tokenizer.ts b/src/utils/tokenizer.ts new file mode 100644 index 0000000..48f8fbf --- /dev/null +++ b/src/utils/tokenizer.ts @@ -0,0 +1,32 @@ +import { get_encoding } from '@dqbd/tiktoken'; + +const encodingForModel = (model: string): string => { + const lower = (model || '').toLowerCase(); + if (lower.includes('gpt-5') || lower.includes('gpt-4o') || lower.includes('o1') || lower.includes('o3')) { + return 'o200k_base'; + } + return 'cl100k_base'; +}; + +export const countTextTokens = (text: string, model: string): number => { + const encKey = encodingForModel(model); + const enc = get_encoding(encKey); + try { + const tokens = enc.encode(text || ''); + return tokens.length; + } finally { + // no explicit free in @dqbd/tiktoken browser build; safe to let GC handle + } +}; + +type SimpleMessage = { role: string; content: string }; + +export const countChatMessagesTokens = (messages: SimpleMessage[], model: string): number => { + // Approximate: sum content token counts + minimal role overhead + const overheadPerMsg = 3; // rough + const roleOverhead = 1; + return messages.reduce((sum, m) => { + return sum + countTextTokens(m.content || '', model) + overheadPerMsg + roleOverhead; + }, 0); +}; + From 77c033fcb1cad0961aedab78b662575895a6f81a Mon Sep 17 00:00:00 2001 From: chan000518 Date: Sun, 5 Oct 2025 10:33:47 +0900 Subject: [PATCH 03/14] =?UTF-8?q?=F0=9F=90=9B=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 219 ++++++++++++++++++++++++++++++++++++++++- src/utils/tokenizer.ts | 10 +- 2 files changed, 223 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65109c4..5814cd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@dqbd/tiktoken": "^1.0.13", + "@google/genai": "^0.2.0", "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", @@ -47,6 +48,18 @@ "resolved": "https://registry.npmjs.org/@dqbd/tiktoken/-/tiktoken-1.0.22.tgz", "integrity": "sha512-RYhO8xeHkMNX5Ixqf4M1Ve3siCYJY/dI0yLnlX4M4oIEDOvjMIQ+E+3OUpAaZcWTaMtQJzGcDAghYfllpx3i/w==" }, + "node_modules/@google/genai": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-0.2.0.tgz", + "integrity": "sha512-r7EiRHSqc6D1lDIMvM4OemjUwPpUbYb9jTxe1eLCiFbooHrmPc6U9z3n56E/iWzigkZmjRh4IC0CMzoB1aql9w==", + "dependencies": { + "google-auth-library": "^9.14.2", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -284,6 +297,14 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "engines": { + "node": ">= 14" + } + }, "node_modules/agentkeepalive": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", @@ -330,6 +351,33 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -535,7 +583,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, "dependencies": { "ms": "^2.1.3" }, @@ -747,6 +794,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -859,6 +911,34 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -906,6 +986,49 @@ "node": ">= 6" } }, + "node_modules/google-auth-library": { + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-auth-library/node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-auth-library/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -917,6 +1040,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/gtoken/node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/gtoken/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -977,6 +1131,18 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -1057,6 +1223,25 @@ "node": ">=0.12.0" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -1922,6 +2107,18 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -1958,6 +2155,26 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/src/utils/tokenizer.ts b/src/utils/tokenizer.ts index 48f8fbf..bc662f4 100644 --- a/src/utils/tokenizer.ts +++ b/src/utils/tokenizer.ts @@ -1,11 +1,11 @@ -import { get_encoding } from '@dqbd/tiktoken'; +import { get_encoding, type TiktokenEncoding } from '@dqbd/tiktoken'; -const encodingForModel = (model: string): string => { - const lower = (model || '').toLowerCase(); +const encodingForModel = (model?: string): TiktokenEncoding => { + const lower = (model ?? '').toLowerCase(); if (lower.includes('gpt-5') || lower.includes('gpt-4o') || lower.includes('o1') || lower.includes('o3')) { - return 'o200k_base'; + return 'o200k_base' as TiktokenEncoding; } - return 'cl100k_base'; + return 'cl100k_base' as TiktokenEncoding; }; export const countTextTokens = (text: string, model: string): number => { From 7ee29e4f4da8ff876814b6d8547d70b050452c18 Mon Sep 17 00:00:00 2001 From: chan000518 Date: Sun, 5 Oct 2025 14:00:48 +0900 Subject: [PATCH 04/14] =?UTF-8?q?=F0=9F=90=9B=20=EB=94=94=EB=B2=84?= =?UTF-8?q?=EA=B9=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config.ts | 1 + src/llm/index.ts | 17 +++ src/llm/providers/openai-responses.ts | 161 ++++++++++++++++++++------ src/llm/types.ts | 4 +- src/prompts/qa.prompts.ts | 17 ++- src/services/qa.service.ts | 32 +++++ 6 files changed, 191 insertions(+), 41 deletions(-) diff --git a/src/config.ts b/src/config.ts index ba81564..5bd402a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,6 +12,7 @@ const configSchema = z.object({ TOKEN_AUDIENCE: z.string().default('bubblog'), ALGORITHM: z.string().default('HS256'), EMBED_MODEL: z.string().default('text-embedding-3-small'), + // 기본 LLM 모델: GPT-5 계열 CHAT_MODEL: z.string().default('gpt-5-mini'), GEMINI_API_KEY: z.string().optional(), GEMINI_CHAT_MODEL: z.string().default('gemini-2.5-flash'), diff --git a/src/llm/index.ts b/src/llm/index.ts index ba30ce4..3c67eb4 100644 --- a/src/llm/index.ts +++ b/src/llm/index.ts @@ -67,6 +67,13 @@ export const generate = async (req: GenerateRequest): Promise => { let buffer = ''; let outputText = ''; + // Debug: start info + try { + console.log( + JSON.stringify({ type: 'debug.llm.start', provider, model, messages: (messages || []).length }) + ); + } catch {} + const flushBuffer = () => { // Split by double newline to get SSE events const chunks = buffer.split('\n\n'); @@ -130,6 +137,11 @@ export const generate = async (req: GenerateRequest): Promise => { }; console.log(JSON.stringify(post)); } + try { + console.log( + JSON.stringify({ type: 'debug.llm.end', provider, model, durationMs, outputChars: outputText.length }) + ); + } catch {} outer.end(); }); providerStream.on('error', (e) => { @@ -138,6 +150,11 @@ export const generate = async (req: GenerateRequest): Promise => { JSON.stringify({ type: 'llm.error', corrId, provider, model, message: (e as any)?.message || 'error' }) ); } + try { + console.error( + JSON.stringify({ type: 'debug.llm.error', provider, model, message: (e as any)?.message || 'error' }) + ); + } catch {} outer.emit('error', e); }); diff --git a/src/llm/providers/openai-responses.ts b/src/llm/providers/openai-responses.ts index 1100db6..430728c 100644 --- a/src/llm/providers/openai-responses.ts +++ b/src/llm/providers/openai-responses.ts @@ -7,38 +7,103 @@ const openai = new OpenAI({ apiKey: config.OPENAI_API_KEY }); const toResponsesInput = (messages: OpenAIStyleMessage[] = []) => { // Convert simple chat-style messages to Responses API input format + // Responses API expects 'input_text' as the content type (not 'text'). return messages.map((m) => ({ role: m.role, - content: [{ type: 'text', text: m.content }], + content: [{ type: 'input_text', text: m.content }], })); }; +const toResponsesTools = (tools: OpenAIStyleTool[] = []) => { + // Map Chat Completions style tool definitions to Responses API format + // Chat: { type: 'function', function: { name, description, parameters } } + // Responses: { type: 'function', name, description, parameters } + return tools + .filter((t) => t && (t as any).type === 'function' && (t as any).function?.name) + .map((t) => ({ + type: 'function', + name: t.function.name, + description: t.function.description, + parameters: t.function.parameters, + })); +}; + export const generateOpenAIStream = async (req: GenerateRequest): Promise => { const stream = new PassThrough(); + // Guard to avoid writing after stream end + let closed = false; + const safeWrite = (chunk: string) => { + if (!closed && !stream.writableEnded && !stream.destroyed) { + stream.write(chunk); + } + }; + const safeEnd = () => { + if (!closed && !stream.writableEnded && !stream.destroyed) { + closed = true; + stream.end(); + } else { + closed = true; + } + }; const model = req.model || 'gpt-5-mini'; const messages = req.messages || []; - const tools = (req.tools || []) as unknown as OpenAI.Responses.ResponseCreateParams['tools']; + const toolsChat = (req.tools || []) as OpenAIStyleTool[]; // For gpt-5-* prefer Responses API. For other models, fall back to Chat Completions streaming. const isGpt5Family = /(^|\b)gpt-5/i.test(model); + // Debug: basic call info + try { + console.log( + JSON.stringify({ + type: 'debug.openai.start', + model, + isGpt5Family, + hasTools: Array.isArray(req.tools) && req.tools.length > 0, + options: { + temperature: req.options?.temperature, + top_p: req.options?.top_p, + max_output_tokens: req.options?.max_output_tokens, + reasoning_effort: (req as any)?.options?.reasoning_effort, + text_verbosity: (req as any)?.options?.text_verbosity, + }, + }) + ); + } catch {} + try { if (isGpt5Family) { // Prefer Responses API streaming for gpt-5 try { - const responsesStream: any = await (openai as any).responses.stream({ + const respParams: any = { model, input: toResponsesInput(messages) as any, - tools: tools as any, - temperature: req.options?.temperature, - top_p: req.options?.top_p, + tools: toolsChat && toolsChat.length > 0 ? toResponsesTools(toolsChat) : undefined, max_output_tokens: req.options?.max_output_tokens, - }); + }; + // GPT-5 family: omit temperature/top_p; allow reasoning/text controls + if (req.options?.reasoning_effort) { + respParams.reasoning = { effort: req.options.reasoning_effort }; + } + if (req.options?.text_verbosity) { + respParams.text = { verbosity: req.options.text_verbosity }; + } + try { + console.log( + JSON.stringify({ type: 'debug.openai.path', path: 'responses.stream', paramsKeys: Object.keys(respParams) }) + ); + } catch {} + const responsesStream: any = await (openai as any).responses.stream(respParams); + let loggedFirstDelta = false; responsesStream.on('response.output_text.delta', (delta: string) => { if (delta) { - stream.write(`event: answer\n`); - stream.write(`data: ${JSON.stringify(delta)}\n\n`); + safeWrite(`event: answer\n`); + safeWrite(`data: ${JSON.stringify(delta)}\n\n`); + if (!loggedFirstDelta) { + try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: delta.length })); } catch {} + loggedFirstDelta = true; + } } }); @@ -46,21 +111,27 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { const argsDelta = toolDelta?.arguments_delta || toolDelta?.arguments || ''; if (argsDelta) { - stream.write(`event: answer\n`); - stream.write(`data: ${JSON.stringify(argsDelta)}\n\n`); + safeWrite(`event: answer\n`); + safeWrite(`data: ${JSON.stringify(argsDelta)}\n\n`); } }); responsesStream.on('response.completed', () => { - stream.write(`event: end\n`); - stream.write(`data: [DONE]\n\n`); - stream.end(); + safeWrite(`event: end\n`); + safeWrite(`data: [DONE]\n\n`); + safeEnd(); + try { console.log(JSON.stringify({ type: 'debug.openai.completed' })); } catch {} }); responsesStream.on('error', (e: any) => { - stream.write(`event: error\n`); - stream.write(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); - stream.end(); + safeWrite(`event: error\n`); + safeWrite(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); + safeEnd(); + try { + console.error( + JSON.stringify({ type: 'debug.openai.error', path: 'responses.stream', message: (e as any)?.message }) + ); + } catch {} }); // Ensure the stream starts and we await its completion @@ -69,14 +140,20 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { @@ -99,20 +176,26 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { - const systemPrompt = `너는 사용자의 블로그 글 컨텍스트만으로 답변한다. 컨텍스트에 없는 사실은 추정하지 말고 “문서에 없음”이라고 말한다. 말투는 speech_tone 지시에 따른다.`; + const systemPrompt = ` 당신은 블로그 운영자 AI입니다. 사용자의 블로그에 대한 질문에 답변합니다. + 블로그 운영자 AI는 사용자의 질문에 대해 블로그 본문 컨텍스트를 참고하여 답변합니다. + 모든 한국어 응답은 무슨일이 있어도 반드시 답변 말투 및 규칙을 따릅니다. + 또한 주어진 내용외의 내용을 지어내지 마십시오. + + [응답 규칙] + 1. 만약 제목과 본문을 활용해 답변할 수 있다면 답변 말투 및 규칙을 지켜 직접 답변하고, 마지막에 추가적인 내용에 대한 질문을 유도하는 문장을 추가합니다. + 2. 만약 질문이 욕설·비난·무관·부적절하거나 주어진 제목, 본문과 관련이 없다면 사과와 블로그 관련된 내용만 답변 가능하다는 내용을 답변 말투 및 규칙을 지켜 답합니다. + 3. 질문이 블로그 카테고리나 사용자 블로그에는 부합하지만 제공된 본문 컨텍스트의 내용이 매우 부족하거나 적절하지 않다고 판단되면 report_content_insufficient 함수를 호출하고 답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다. + `; const userMessage = ` +[instruction] +답변 말투: "${speechTonePrompt}" + [context] 제목: ${post.title} 작성일: ${post.created_at} @@ -18,9 +30,6 @@ ${processedContent} [user] ${question} - -[instruction] -답변 말투: "${speechTonePrompt}" `; return [ diff --git a/src/services/qa.service.ts b/src/services/qa.service.ts index 549a919..eef997f 100644 --- a/src/services/qa.service.ts +++ b/src/services/qa.service.ts @@ -38,6 +38,11 @@ export const answerStream = async ( llm?: LlmOverride ): Promise => { const stream = new PassThrough(); + try { + console.log( + JSON.stringify({ type: 'debug.qa.start', questionLen: question?.length || 0, userId, categoryId, postId, speechTone, llm }) + ); + } catch {} let messages: { role: 'system' | 'user' | 'assistant' | 'tool' | 'function'; content: string }[] = []; let tools: @@ -64,18 +69,25 @@ export const answerStream = async ( if (!post) { stream.write(`event: error\ndata: ${JSON.stringify({ code: 404, message: 'Post not found' })}\n\n`); stream.end(); + try { console.warn(JSON.stringify({ type: 'debug.qa.post', status: 'not_found', postId })); } catch {} return; } if (post.user_id !== userId) { stream.write(`event: error\ndata: ${JSON.stringify({ code: 403, message: 'Forbidden' })}\n\n`); stream.end(); + try { console.warn(JSON.stringify({ type: 'debug.qa.post', status: 'forbidden', postId })); } catch {} return; } const processedContent = preprocessContent(post.content); stream.write(`event: exist_in_post_status\ndata: true\n\n`); stream.write(`event: context\ndata: ${JSON.stringify([{ postId: post.id, postTitle: post.title }])}\n\n`); + try { + console.log( + JSON.stringify({ type: 'debug.qa.path', mode: 'post', postId: post.id, processedLen: processedContent.length }) + ); + } catch {} messages = toSimpleMessages( qaPrompts.createPostContextPrompt(post, processedContent, question, speechTonePrompt) @@ -90,6 +102,11 @@ export const answerStream = async ( const context = similarChunks.map(chunk => ({ postId: chunk.postId, postTitle: chunk.postTitle })); stream.write(`event: context\ndata: ${JSON.stringify(context)}\n\n`); + try { + console.log( + JSON.stringify({ type: 'debug.qa.path', mode: 'rag', similarChunks: similarChunks.length, contextPreview: context.slice(0, 3) }) + ); + } catch {} messages = toSimpleMessages( qaPrompts.createRagPrompt(question, similarChunks, speechTonePrompt) @@ -120,6 +137,18 @@ export const answerStream = async ( options: llm?.options, meta: { userId, categoryId, postId }, }); + try { + console.log( + JSON.stringify({ + type: 'debug.qa.call', + provider: llm?.provider || 'openai', + model: llm?.model || config.CHAT_MODEL, + messages: messages.length, + tools: (tools || []).length, + hasOptions: !!llm?.options, + }) + ); + } catch {} llmStream.on('data', (chunk) => { stream.write(chunk); @@ -127,6 +156,9 @@ export const answerStream = async ( llmStream.on('end', () => { stream.end(); }); + llmStream.on('error', (e) => { + try { console.error(JSON.stringify({ type: 'debug.qa.llmError', message: (e as any)?.message || 'error' })); } catch {} + }); })().catch(err => { console.error('Stream process error:', err); From cf88ceb0091b5b75db7ad6443a7bfb7940e03a3c Mon Sep 17 00:00:00 2001 From: chan000518 Date: Sun, 5 Oct 2025 14:50:30 +0900 Subject: [PATCH 05/14] =?UTF-8?q?=E2=9C=A8=20ask=20V2=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- REPORT-askv2.md | 92 +++++ TASK.md | 481 +++++++++++++++--------- src/app.ts | 2 + src/controllers/ai.v2.controller.ts | 29 ++ src/prompts/qa.v2.prompts.ts | 142 +++++++ src/repositories/post.repository.ts | 95 ++++- src/routes/ai.v2.routes.ts | 14 + src/services/qa.v2.service.ts | 208 ++++++++++ src/services/search-plan.service.ts | 102 +++++ src/services/semantic-search.service.ts | 36 ++ src/types/ai.v2.types.ts | 79 ++++ src/utils/time.ts | 82 ++++ 12 files changed, 1173 insertions(+), 189 deletions(-) create mode 100644 REPORT-askv2.md create mode 100644 src/controllers/ai.v2.controller.ts create mode 100644 src/prompts/qa.v2.prompts.ts create mode 100644 src/routes/ai.v2.routes.ts create mode 100644 src/services/qa.v2.service.ts create mode 100644 src/services/search-plan.service.ts create mode 100644 src/services/semantic-search.service.ts create mode 100644 src/types/ai.v2.types.ts create mode 100644 src/utils/time.ts diff --git a/REPORT-askv2.md b/REPORT-askv2.md new file mode 100644 index 0000000..b0d5e12 --- /dev/null +++ b/REPORT-askv2.md @@ -0,0 +1,92 @@ +# 보고서: /ai/v2/ask 구현 내역과 구조(한국어) + +## 1) 개요 +- 목적: v1의 고정형 RAG 흐름을 개선하기 위해, 사용자의 질문을 LLM이 “검색 계획(JSON)”으로 구조화 → 서버가 안전한 시맨틱 SQL 검색 수행 → v1과 동일한 방식으로 최종 답변을 SSE로 스트리밍하는 v2 파이프라인을 추가했습니다. +- 상태: v1은 수정하지 않고 유지. v2 엔드포인트 `POST /ai/v2/ask`(SSE) 신규 추가 및 전체 흐름 구현 완료. + +## 2) v1의 주요 문제점(한계) +- 고정 파라미터 검색: 임계치(0.2), LIMIT(5)가 고정되어 질문 의도(기간/정렬/가중치/갯수 등) 반영이 어려움. +- 시간/정렬 표현 미흡: “최근 글/9월 글/지난주” 등 자연어 시간 요구를 반영할 수 없음. +- 컨텍스트 제어 부족: LLM 입력 컨텍스트의 개수/범위를 질문 의도나 비용/토큰 예산에 맞춰 유연하게 조절하기 어려움. +- 관측성 부족: 어떤 기준/전략으로 검색되었는지(계획/파라미터)를 클라이언트에서 파악하기 어려움. +- 보안/안전 제약: 프롬프트/검색 로직이 단순해, 미래에 복잡한 동적 쿼리로 확장 시 안전한 경계(화이트리스트/스키마 강제)가 필요. + +## 3) v2의 도입/해결 방안과 가능해진 것 +- LLM 검색 계획(JSON) 도입 + - OpenAI Responses API + JSON Schema 강제 → LLM이 오직 스키마에 맞는 JSON만 출력. + - 계획 항목: `mode`(rag/post), `top_k`, `threshold`, `weights{chunk,title}`, `filters{user_id, category_ids?, post_id?, time?}`, `sort`, `limit`. +- 시간/정렬 의도 반영 + - 자연어 시간(최근/이번 달/지난주/9월/작년 등)을 `filters.time`에 구조화. + - 서버는 KST 기준 절대 기간으로 표준화(from/to) 후 안전 SQL에 반영. + - 최신순/오래된순 정렬(`sort`) 지원. +- 안전한 서버 표준화/실행 + - Zod로 계획 검증 + 범위 강제(top_k 1..10, limit 1..20, threshold 0..1, weights 합=1). + - SQL은 화이트리스트 템플릿 + 파라미터 바인딩으로만 구성(문자열 결합 금지). +- 관측성 강화 + - SSE 메타 이벤트(`search_plan`, `search_result`)를 추가해, 검색 계획과 결과 요약을 클라이언트에 투명하게 제공. +- 컨텍스트 최적화 + - 청크 검색 후보(top_k)를 넓게 가져온 뒤, 포스트 단위 중복 제거 + `limit`개까지만 컨텍스트/노출로 사용(토큰/비용 관리). +- 폴백 안전성 + - 계획 생성 실패 시 v1 RAG 경로로 자동 폴백하여 기능 연속성 보장. + +## 4) v2 구조(파일과 역할) +- 라우팅/컨트롤러 + - `src/routes/ai.v2.routes.ts`: `/ai/v2/ask` SSE 라우트. + - `src/controllers/ai.v2.controller.ts`: SSE 헤더 설정, 서비스 호출/파이프. + - `src/app.ts`: `/ai/v2` 마운트. +- 플래너 LLM & 타입 + - `src/types/ai.v2.types.ts`: v2 요청/검색 계획 Zod 스키마. + - `src/prompts/qa.v2.prompts.ts`: 검색 계획 프롬프트/JSON 스키마. + - `src/services/search-plan.service.ts`: Responses API 호출 → 계획 JSON 검증/정규화. +- 시간 표준화 + - `src/utils/time.ts`: KST 기준 상대/월/분기/연도 → 절대기간 변환. +- 시맨틱 서치 + - `src/services/semantic-search.service.ts`: 질문 임베딩 생성 → 동적 저장소 호출. + - `src/repositories/post.repository.ts`: `findSimilarChunksV2`(가중치/임계치/기간/정렬/topK 파라미터 반영). +- 오케스트레이션 + - `src/services/qa.v2.service.ts`: `search_plan`→`search_result` 발행, v1 프롬프트 재사용으로 최종 LLM 스트림 중계. + +## 5) v2 요청→응답 흐름 +1) 클라이언트: `POST /ai/v2/ask` (JWT 필요) +2) 컨트롤러: SSE 헤더 설정 → `answerStreamV2` 호출 +3) post 모드(post_id 존재): 소유자 검증 → 계획/결과 이벤트 발행 → 본문 컨텍스트로 메시지 구성 → 답변 스트림 +4) rag 모드: 플래너 LLM으로 계획 생성 → Zod 검증/시간 표준화 → `search_plan` 이벤트 발행 → 시맨틱 서치 실행 → `search_result`/`exist_in_post_status`/`context` 발행 → RAG 프롬프트 구성 → 답변 스트림 +5) 공통: `src/llm` 레이어를 통해 `answer` 청크 스트리밍, 종료 시 `end` 이벤트 + +SSE 이벤트 순서 +- `search_plan` → `search_result` → `exist_in_post_status` → `context` → `answer`* → `end` +- 오류 시: `error` + +## 6) 모델/설정 +- 기본 LLM: `openai/gpt-5-mini`(요청 `llm` 또는 `CHAT_MODEL`로 변경 가능) +- 임베딩: `text-embedding-3-small` +- Gemini: 응답 스트림은 지원(계획 LLM은 현재 OpenAI 사용) + +## 7) 보안/안전 +- 계획 출력은 JSON Schema로 제한, 서버에서 Zod 검증 및 값 범위 강제. +- SQL은 파라미터 바인딩/화이트리스트 템플릿만 사용. +- post 모드에서 소유권 체크. +- SSE에는 민감정보 제외(제목/ID 등만 노출). + +## 8) 현재 동작과 향후 확장 +- 현재 + - `top_k`: 청크 단위 후보 개수(리콜 폭)로 SQL LIMIT 적용(v1과 동일). + - `limit`: 현재는 미적용(v1과 동일 동작 유지). 컨텍스트는 청크 Top-K를 그대로 사용하며, 포스트 단위 중복 제거도 하지 않음. + - `sort`: 유사도 우선 + 최신순/오래된순 보조 정렬. +- 향후 + - `limit` 적용을 재도입하여 컨텍스트 길이/비용 최적화(옵션화 가능). + - 포스트별 상위 N청크 추출(윈도우 함수) 설계로 깊이/다양성 균형. + - `search_sql` 이벤트(템플릿 ID + 파라미터 프리뷰)로 관측성 강화. + - 계획 LLM의 프로바이더 확장(Gemini) 및 프롬프트 튜닝 고도화. + +## 9) 사용 예시 +- 요청 바디 예시 +``` +{ + "question": "9월 글 2개만 보여줘", + "user_id": "", + "speech_tone": -1, + "llm": { "provider": "openai", "model": "gpt-5-mini" } +} +``` +- 기대 SSE 순서: `search_plan` → `search_result` → `exist_in_post_status` → `context` → `answer*` → `end` diff --git a/TASK.md b/TASK.md index 3bb0eca..6016664 100644 --- a/TASK.md +++ b/TASK.md @@ -1,188 +1,293 @@ -## 작업 계획 - -작업 순서 -- 1) LLM 모듈화(퍼사드/프로바이더/모델 레지스트리) + GPT-5 mini 기본 적용 -- 2) Gemini 도입: 병행 사용(전용) + 대체 사용(퍼사드) -- 3) 토큰 카운트 및 비용 로깅 추가(양 프로바이더 공통) - -참고: 아래 문서의 섹션 순서와 무관하게 실제 구현 순서는 위의 "작업 순서"를 따릅니다. - - -### 1) LLM 모듈화(퍼사드/프로바이더/모델 레지스트리) + GPT-5 mini 기본 적용 - -목적: LLM 호출을 모듈화하여 옵션 기반으로 모델/프로바이더를 교체 가능하게 만들고, 기본 모델을 `gpt-5-mini`로 전환합니다. 토크나이저/가격표는 3단계에서 처리합니다. - -1. [구조] 파일/모듈 구성 - - 디렉토리: `src/llm/` - - `src/llm/types.ts` — 공통 인터페이스 정의 - - `GenerateRequest`: `{ provider?: 'openai'|'gemini', model?: string, messages?: OpenAIStyleMessages, contents?: GeminiStyleContents, stream?: boolean, tools?, options?: { temperature?, top_p?, max_output_tokens?, reasoning?, text? }, meta?: { userId?, categoryId?, postId? } }` - - `GenerateStream`: `onToken(text)`, `onToolCall(json)`, `onEnd()`, `onError(err)`(또는 AsyncIterable) - - `src/llm/modelRegistry.ts` — 모델 레지스트리/기본값 - - 논리 모델 키 → `{ provider, modelId, defaults, tokenizerKey?, pricingKey? }` - - 기본값: `defaultChat = { provider: 'openai', modelId: 'gpt-5-mini' }` - - `src/llm/providers/openaiResponses.ts` — OpenAI Responses API 구현 - - `src/llm/providers/gemini.ts` — @google/gemini 구현 - - `src/llm/index.ts` — 퍼사드: `generate(req: GenerateRequest): GenerateStream` 선택 라우팅 - - 기존 서비스(`qa.service.ts`)는 퍼사드만 사용하도록 변경 - -2. [기본 모델] GPT-5 mini 적용(Responses API) - - `src/config.ts`의 `CHAT_MODEL` 기본값을 `gpt-5-mini`로 변경 - - OpenAI 경로: `openai.responses.create/stream`로 마이그레이션(SSE 어댑터 포함) - - 기존 Chat Completions 경로는 임시 백업/옵션으로 유지 가능(필요 시) - -3. [옵션 기반 모델/프로바이더 선택] - - 요청 바디에 `llm?: { provider?: 'openai'|'gemini', model?: string, options?: {...} }` 허용 - - 미지정 시 레지스트리의 기본값 사용(`gpt-5-mini` on OpenAI) - - 향후 기능(Reasoning/Text 옵션, tool calls, timeout 등) 확장 용이 - -4. [검증/수용 기준] - - `/ai/ask` SSE 정상 동작(중단/지연 없음) - - 기존 프롬프트/툴 호출이 동일하게 동작(필요 시 어댑터) - - 로그/오류 처리 기존 수준 유지 - -### 2) Gemini 도입: 병행 사용(전용) + 대체 사용(퍼사드) - -목적: Gemini를 독립 엔드포인트로 직접 쓰는 경로와, 기존 GPT 경로의 대체 제공자로 모두 사용할 수 있게 합니다(퍼사드 경유). 이후 3단계에서 토큰/비용 로깅을 공통 적용합니다. - -1. [Config] Gemini 키/모델 설정 - - `.env` - - `GEMINI_API_KEY=...` - - `GEMINI_CHAT_MODEL=gemini-2.5-flash` (예: 변경 가능) - - `src/config.ts`에 항목 반영 및 기본값/검증 추가(Provider 고정 ENV는 사용하지 않음) - -2. [Provider] 퍼사드에 Gemini 구현 추가 - - 1단계에서 만든 LLM 퍼사드(`src/llm/index.ts`)에 Gemini 프로바이더를 추가 - - 구현 위치: `src/llm/providers/gemini.ts` (OpenAI 구현은 `src/llm/providers/openaiResponses.ts`) - - 퍼사드 인터페이스로 라우팅되어 기존 `qa.service.ts`는 퍼사드만 사용(교체 투명) - -3. [Gemini 호출] @google/genai SDK 적용 및 스트리밍 - - 의존성: `@google/genai` 추가 (설치 커맨드: `npm i @google/genai`) - - 클라이언트: `import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({});` (`GEMINI_API_KEY`는 환경변수에서 자동 주입) - - 비스트리밍(우선 적용): - - `ai.models.generateContent({ model: GEMINI_CHAT_MODEL, contents, config: { thinkingConfig: { thinkingBudget }}})` - - 기본값으로 `thinkingBudget=0`(생각 비활성화) 적용, `.env`에서 오버라이드 가능 - - 응답 텍스트를 한번에 수신한 뒤 SSE로 순차 chunk 분할하여 `answer` 이벤트로 전송(간단 구현) - - 스트리밍(선택 적용): - - SDK 제공 시 스트리밍 API 사용(예: `generateContentStream` 유사 기능)으로 델타를 받아 즉시 SSE로 전달 - - SDK에서 미지원일 경우, 비스트리밍으로 우선 릴리즈 후 스트리밍 전환 - - (옵션) Safety 설정, generationConfig(temperature/topP/maxOutputTokens) 파라미터는 설정값으로 노출 - -5. [토큰 카운팅] Gemini 대응 - - 사전 카운트(가능 시): SDK의 토큰 카운트 API(`tokens:count`/`countTokens`)가 제공되면 이를 사용해 프롬프트 토큰 계산 → 비용 선로깅 - - 네트워크 요청이므로 로깅 토글이 켜져 있을 때만 수행하도록 옵션화 - - 사후 카운트: 응답 텍스트 기준 동일 API로 출력 토큰 계산(또는 비가용 시 근사치) - - 폴백 전략: 카운트 API가 불가한 환경에서는 근사치 사용(문자수/4), 추후 정확도 개선 시 교체 - -6. [가격 정책] Gemini 추가 - - `src/config/pricing.ts`의 `PRICING_TABLE`에 Gemini 모델(`gemini-2.5-flash`, 임베딩 모델 등) 단가 추가 - - 동일한 `calcCost`, `formatCost` 로직 재사용 - -7. [생각(Thinking) 설정] 기본 비활성화 - - Gemini 2.5 Flash의 생각 기능은 응답 품질 대신 비용/지연이 증가하므로 기본 `thinkingBudget=0`으로 비활성화 - - `.env`에 `GEMINI_THINKING_BUDGET`를 두어 필요 시 활성화(정수값) - -8. [도구/함수 호출] 호환성 계획(선택) - - 현재 OpenAI `tool_calls`를 사용 중. Gemini는 `functionDeclarations`/`toolConfig` 형태로 유사 기능 제공 - - 1단계: Gemini 경로에서는 도구 호출 비활성화(빠른 도입) - - 2단계: 필요 시 `report_content_insufficient`를 Gemini `functionDeclarations`로 매핑하여 동일 동작 구현 - -9. [Wiring] 사용 패턴 - - 독립 사용(A): `POST /ai/gemini/ask`로 직접 호출(옵션: thinkingBudget 등) - - 대체 사용(B): 기존 `POST /ai/ask`에 `llm.provider?: 'openai'|'gemini'`, `llm.model?` 허용 → 퍼사드가 라우팅 - - 로깅 시 `provider` 필드를 포함(3단계에서 적용) - -10. [검증/수용 기준] - - OpenAI/Gemini 각각에서 동일한 SSE 응답 형식으로 동작 - - 요청 전/후 토큰·비용 로그가 두 프로바이더 모두에서 출력 - - 로깅 토글이 정상 작동, 스트리밍 성능 저하 없음 - -설정 확정 -- `GEMINI_CHAT_MODEL=gemini-2.5-flash` -- `GEMINI_THINKING_BUDGET=0` (기본값으로 비활성화) - -### 토큰 카운트 및 비용 로깅 추가 - -목적: LLM에 요청을 보내기 직전에 프롬프트(메시지) 토큰 수를 계산해 예상 입력 비용을 콘솔로 로깅하고, 스트리밍 응답 완료 후 실제 출력 토큰 수 기반 최종 비용을 추가 로깅합니다. 초기에는 `console.log`만 사용합니다. - -1. [Utils] 토크나이저 유틸 추가 - - 파일: `src/utils/tokenizer.ts` - - 내용: - - `getTokenizerForModel(model: string)` → 모델명에 따라 적절한 인코딩을 선택 - - `gpt-5*` → 자료 제공 전까지 임시로 `o200k_base` 사용(TBD, 전환 시 교체) - - `gpt-4o`, `gpt-4o-mini`, 기타 `o`계열 → `o200k_base` - - `countTextTokens(text: string, model: string): number` - - `countChatMessagesTokens(messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[], model: string): number` - - 메시지 `content`들을 토크나이즈하여 합산하고, 채팅 포맷 오버헤드(메시지당 소량, 모델별 상수)를 보정치로 가산 - - 주의: 보정치는 근사치이며, 정확한 정산은 응답 토큰 합산으로 후처리 - - 비고: 이미 프로젝트에 `@dqbd/tiktoken`이 포함되어 있으므로 이를 사용합니다. - -2. [Config] 가격 정책 맵 구조 설계 (임시 하드코딩 + ENV 오버라이드) - - 파일: `src/config/pricing.ts` - - 내용: - - `export type Pricing = { input_per_1k: number; output_per_1k: number; cached_input_per_1k?: number; currency: 'USD' | 'KRW' }` - - `PRICING_TABLE: Record`: 모델명 키에 따른 단가 설정 - - 선택: `LLM_PRICING_OVERRIDES`(JSON) 환경변수로 런타임 오버라이드 허용 - - 초기값은 사용자 제공 정책으로 채울 예정. 제공 전까지는 로깅에 `N/A` 표기 또는 0 처리. - - - 초기 PRICING_TABLE(제공 정책 반영, 단위: per 1K tokens, 통화: USD) - - `gpt-5`: { input_per_1k: 0.00125, cached_input_per_1k: 0.000125, output_per_1k: 0.01, currency: 'USD' } - - `gpt-5-mini`: { input_per_1k: 0.00025, cached_input_per_1k: 0.000025, output_per_1k: 0.002, currency: 'USD' } - - `gpt-5-nano`: { input_per_1k: 0.00005, cached_input_per_1k: 0.000005, output_per_1k: 0.0004, currency: 'USD' } - -3. [Utils] 비용 계산 유틸 추가 - - 파일: `src/utils/cost.ts` - - 내용: - - `getModelPricing(model: string): Pricing | null` - - `calcCost(tokens: number, per_1k: number): number` → 반올림 1~4자리(옵션) - - 화폐 표기 함수(선택): `formatCost(amount: number, currency: string)` - -4. [Facade] LLM 퍼사드에 비용 로깅 통합 - - 위치: `src/llm/index.ts` 퍼사드 내부에서 공통 로깅 수행 - - 기능 흐름(공통): - 1) 요청 전: 메시지/콘텐츠 토큰 카운트 → `promptTokens` - - OpenAI: `countChatMessagesTokens`(토크나이저) - - Gemini: `countTokens` API 가능 시 사용(불가 시 근사치) - 2) 단가 조회: `getModelPricing(model)` → `estInputCost` - 3) 선로깅: `{type:'llm.request', provider, model, promptTokens, estInputCost, corrId, userId, categoryId, postId}` - 4) 실제 호출: 등록된 프로바이더(OpenAI Responses 또는 Gemini)로 위임, 스트림은 그대로 중계 - 5) 스트림 종료 후: 출력 텍스트/함수인자 토큰 합산 → `completionTokens` - 6) 비용 계산: 입력/출력(+cached 입력이 있으면 분리) → `totalCost` - 7) 후로깅: `{type:'llm.response', provider, model, promptTokens, completionTokens, inputCost, outputCost, totalCost, durationMs, corrId, cachedInputTokens}` - - 주의: 기존 SSE 흐름(이벤트명/포맷) 불변 유지. 퍼사드는 원본 델타를 그대로 전달. - - 상관관계 ID(`corrId`)는 `uuid` 생성(또는 요청별 식별자 전달 시 사용). - -5. [Wiring] `qa.service.ts`에서 퍼사드 사용 - - 기존 직접 호출부를 LLM 퍼사드로 교체(`generate(req)`) - - 요청 바디의 `llm` 옵션을 퍼사드에 그대로 전달(provider/model/options) - - 출력 토큰 카운트/비용 로깅은 퍼사드 내부에서 처리 - -6. [옵션] 임베딩 호출 비용 로깅(확장) - - 파일: `src/services/embedding.service.ts` - - `createEmbeddings` 호출 직전 `input` 텍스트 전체 토큰 수 계산(`countTextTokens` 누적) → 입력 비용 로깅 - - 임베딩 모델 단가(`text-embedding-3-*`)도 `PRICING_TABLE`에 포함 - -7. [환경변수] 로깅 토글 및 라운딩 - - `.env` 키 추가(기본값은 off) - - `LLM_COST_LOG=true|false` (기본: true로 해도 무방) - - `LLM_COST_ROUND=2` (소수점 자리수, 선택) - - 로깅은 토글 꺼져 있으면 수행하지 않음 - -8. [로그 포맷] 예시(JSON 라인) - - 요청 전: `{ "type": "llm.request", "corrId": "...", "provider": "openai", "model": "gpt-5-mini", "promptTokens": 1234, "estInputCost": 0.00031, "userId": "...", "categoryId": 1, "postId": 42 }` - - 응답 후: `{ "type": "llm.response", "corrId": "...", "provider": "openai", "model": "gpt-5-mini", "promptTokens": 1234, "completionTokens": 456, "inputCost": 0.00031, "outputCost": 0.00091, "totalCost": 0.00122, "durationMs": 987, "cachedInputTokens": 0 }` - -9. [검증/수용 기준] - - `POST /ai/ask` 호출 시 콘솔에 요청 전/후 로그 각각 1회 출력 - - 모델/프롬프트/토큰 수/예상 비용/총 비용/시간(ms)이 포함되어야 함 - - 로깅 on/off 토글 동작, 라운딩 반영 확인 - - 기존 SSE 동작(끊김/지연) 변화 없음 - -10. [주의/한계] - - 채팅 포맷 오버헤드는 모델별로 상이하며 근사치 사용. 최종 비용은 출력 토큰 카운트까지 반영해 오차 최소화 - - 스트리밍 API는 서버에서 사용량 메타를 즉시 제공하지 않으므로(비스트리밍과 달리), 응답 텍스트 기반 자체 카운트 수행 - - 함수 호출(tool_calls) 토큰은 인자 길이에 비례하여 증가. 누적 텍스트/인자 기반으로 동일하게 카운트 - - Cached Input 과금: 제공 API에서 캐시 히트 토큰 정보를 명시적으로 제공하는 경우에만 `cachedInputTokens`로 분리 산정. 그렇지 않으면 일반 입력으로 계산(보수적) - -11. [다음 단계(선택)] - - `console.log` → 구조화 로거(Pino/Winston)로 교체, 샘플링·보존 기간 설정 - - DB 또는 시계열(예: ClickHouse/Prometheus) 적재로 사용자별 비용 대시보드 구성 +# v2 설계 및 작업 계획 (LLM 주도 SQL 기반 시맨틱 서치 → 응답 스트리밍) + +## 목표 +- v1 API/흐름은 그대로 유지. +- v2에서 질의를 LLM이 “검색 계획(계획 JSON)”으로 변환 → 서버가 안전하게 실행하여 컨텍스트 확보 → 확보한 컨텍스트와 함께 LLM에 넘겨 최종 답변을 SSE로 스트리밍. + +## 적합성 평가 (요약) +- 장점 + - LLM이 질문 의도를 기반으로 동적 필터/가중치/Top-K/Threshold를 튜닝한 “검색 계획”을 생산하여 검색 적합도를 끌어올릴 수 있음. + - DB 스키마/비즈니스 제약을 반영해 검색 전략을 바꾸기 쉬움(프롬프트/제약 업데이트로 최적화 가능). +- 리스크 및 보완 + - “LLM이 직접 SQL 문자열”은 주입/스키마 일탈 위험. 안전하게 “계획(JSON)”을 생성하게 하고, 서버가 화이트리스트 템플릿/파라미터 바인딩으로 SQL을 구성하는 방식 권장. + - 벡터 연산 상 LLM은 임베딩을 생성할 수 없으므로, 서버가 질문 임베딩을 계산하여 파라미터로 주입해야 함. + - 실패/부적합 시 v1 RAG 경로로 폴백 필요. + +결론: “LLM → 검색 계획(JSON) → 서버가 안전 SQL 구성/실행 → 결과 컨텍스트로 최종 LLM”의 변형 설계가 적합하며 안전/유지보수에도 유리. + +## v2 전체 흐름 +1) 클라이언트가 `POST /ai/v2/ask`로 질문 전송(SSE 응답). +2) 서버가 LLM에 “검색 계획” 생성을 요청(계획 JSON; SQL 문자열 생성은 비권장, 옵션으로 지원). +3) 서버가 계획(JSON)을 검증/정규화 후 파라미터 바인딩으로 안전 SQL 실행(벡터 임베딩은 서버가 생성). +4) 검색 결과(문맥) 메타 이벤트 송신(`search_plan`, `search_result`). +5) 기존 v1과 동일한 형식의 최종 LLM 호출을 수행하고 `answer`를 스트리밍. +6) 종료 시 `end: [DONE]` 송신. + +## API 설계 +- Route: `POST /ai/v2/ask` (SSE) +- Auth: 기존 `authMiddleware` 재사용 +- Request Body (제안) + - `question: string` + - `user_id: string` + - `category_id?: number` + - `post_id?: number` (지정 시 해당 글 컨텍스트 중심) + - `speech_tone?: number` + - `llm?: { provider?: 'openai'|'gemini', model?: string, options?: { temperature?: number, top_p?: number, max_output_tokens?: number } }` +- SSE 이벤트(순서 권장) + - `event: search_plan` / `data: { ...계획JSON }` + - `event: search_sql` / `data: { templateId, paramsPreview }` (SQL 템플릿 경로 선택 시, 민감정보 제외 프리뷰) + - `event: search_result` / `data: [{ postId, postTitle }]` + - `event: exist_in_post_status` / `data: true|false` (v1과 동일) + - `event: context` / `data: [{ postId, postTitle }]` (v1과 동일) + - `event: answer` (여러 번) + - `event: end` / `data: [DONE]` + - `event: error` (오류 시) + +## LLM “검색 계획” 출력 스키마(권장) +```json +{ + "mode": "rag", // "rag" | "post" + "top_k": 5, // 1~20 범위 권장 + "threshold": 0.2, // 0.0~1.0, 유사도 하한 + "weights": { "chunk": 0.7, "title": 0.3 }, + "filters": { + "user_id": "", + "category_ids": [7], // 필요 시 + "post_id": 123, // mode=post 시 + "time": { // 시간/날짜 필터(선택) + "type": "relative", // "relative" | "absolute" | "month" | "year" | "quarter" + "unit": "day", // relative: "day" | "week" | "month" | "year" + "value": 30 // relative: 정수(양수) + // absolute: { from: ISO8601, to: ISO8601 } + // month: { month: 1..12, year?: number } + // year: { year: number } + // quarter: { quarter: 1..4, year?: number } + } + }, + "sort": "created_at_desc", // "created_at_desc" | "created_at_asc" + "limit": 5 // 결과 행 상한(서버 상한 적용) +} +``` +- 서버에서 Zod로 검증 후 기본값/상한선 적용(top_k max 10 등), 불일치 시 안전 폴백값 적용. +- SQL 템플릿은 서버가 선택/생성하며, 파라미터는 모두 바인딩 처리. + +### 시간/날짜 필터 처리 규칙 +- 서버 표준화 단계에서만 절대 기간으로 변환(Asia/Seoul 기준 권장): + - relative: 현재 시각 기준으로 from/to 계산(예: 최근 30일) + - month: 연도 미지정 시 현재 연도 사용(예: “9월” → 올해 9월 1일 00:00:00 ~ 9월 말 23:59:59) + - quarter/year: 분기·연도 경계 계산 +- 검증 실패·모호 값: 날짜 필터 제외 혹은 기본 30일 적용 후 로그 남기고 폴백 +- 모든 상수값은 서버에서 범위 강제(limit<=20, top_k<=10, threshold 0..1, weights 합=1) + +## SQL 실행(안전 구성) +- 벡터 임베딩: 서버가 `createEmbeddings([question])`로 생성. +- 화이트리스트 템플릿(예시) + - 공통: 사용자/카테고리/소유권 필터를 CTE에서 먼저 적용. + - 스코어링: `(w_chunk * (1 - (pc.embedding <=> $embed))) + (w_title * (1 - (pte.embedding <=> $embed))) AS score` + - 임계치: `WHERE (1 - (pc.embedding <=> $embed)) > $threshold` + - 날짜 필터: `AND bp.created_at BETWEEN $from AND $to` (표준화된 절대 기간 사용) + - 정렬/상한: `ORDER BY score DESC` + 옵션 정렬(`created_at_desc|asc`) 병합, `LIMIT $limit` +- 모든 동적 값은 파라미터로 바인딩하고, 가중치/상한 등은 서버에서 범위 제한. + +## 최종 LLM 호출(응답 생성) +- v1의 `generate` 재사용(프로바이더/모델 동일 정책). +- 프롬프트: v1의 `qa.prompts`를 재사용하되, v2에서는 `search_result` 컨텍스트를 그대로 투입. +- v1과 동일한 `report_content_insufficient` 툴 전략 유지(필요 시). + +## 디렉터리/컴포넌트 추가 계획 +- `src/routes/ai.v2.routes.ts` — v2 라우터(`POST /ask`). +- `src/controllers/ai.v2.controller.ts` — SSE 헤더 설정, 서비스 호출/파이프. +- `src/services/search-plan.service.ts` — LLM에 검색 계획 요청 및 스키마 검증. +- `src/services/semantic-search.service.ts` — 계획(JSON)→SQL 템플릿 매핑 및 안전 실행. +- `src/services/qa.v2.service.ts` — 전체 orchestrator: 계획 생성→검색→컨텍스트 이벤트→최종 LLM 스트림. +- `src/prompts/qa.v2.prompts.ts` — 검색 계획 LLM 프롬프트(스키마/제약 포함). +- `src/types/ai.v2.types.ts` — 요청/계획/응답 타입/Zod 스키마. +- `src/routes/ai.routes.ts`는 그대로, `app.ts`에 `/ai/v2` 라우트 추가. + +## 프롬프트 가이드(검색 계획용, 요지) +- 역할: “블로그 시맨틱 검색 플래너”. +- 입력: 질문, 사용자 메타(user_id/category_id/post_id), 스키마/제약 요약, 기본값. +- 출력: 상기 계획 JSON 스키마만 생성(그 외 텍스트 금지). +- 제약: 값 범위(Top-K, threshold, weights 합=1), 허용된 필드만. +- 실패 시: 기본값으로 귀결되는 최소 계획을 출력하도록 유도. +- 시간/날짜 처리 지침: + - 시스템 메시지에 현재 날짜/시간과 타임존(예: Asia/Seoul)을 제공 + - “최근/이번 달/지난주/9월/작년 9월” 등 자연어 시간을 위 스키마의 time 필드로 구조화 + - 연도 미지정 시 현재 연도 가정, 모호하면 relative 30일로 유도 + +## 예시 +- “최근 글 보여줘” + - LLM 계획(JSON): `{ "mode": "rag", "top_k": 5, "threshold": 0.2, "weights": { "chunk": 0.7, "title": 0.3 }, "filters": { "user_id": "", "time": { "type": "relative", "unit": "day", "value": 30 } }, "sort": "created_at_desc", "limit": 5 }` + - 서버 표준화: `time → absolute { from: <30일 전 00:00+09:00>, to: <지금+09:00> }`, `limit=5` + +- “9월 글 2개” + - LLM 계획(JSON): `{ "mode": "rag", "top_k": 5, "threshold": 0.2, "weights": { "chunk": 0.7, "title": 0.3 }, "filters": { "user_id": "", "time": { "type": "month", "month": 9 } }, "sort": "created_at_desc", "limit": 2 }` + - 서버 표준화: `time → absolute { from: YYYY-09-01T00:00:00+09:00, to: YYYY-09-30T23:59:59+09:00 } (연도 미지정 시 올해)`, `limit=2` + +## 폴백 전략 +- 계획 JSON 검증 실패/LLM 오류 → v1 RAG 경로로 폴백. +- 검색 결과 0건 → v1과 동일하게 `exist_in_post_status=false` 전송 후, 부족 안내 규칙에 맞춰 답변 유도. + +## 텔레메트리/비용 +- `llm.request/llm.response` 로그 기존 그대로 사용. +- v2 전용 디버그 이벤트: `debug.plan.start`, `debug.plan.json`, `debug.plan.sql`, `debug.plan.result` 등. + +## 마이그레이션/DB +- 추가 테이블 불필요(기존 `post_chunks`, `post_title_embeddings` 재사용). +- 필요 시 뷰/인덱스 최적화 검토: `post_chunks(post_id, embedding)`, `post_title_embeddings(post_id, embedding)`. + +## 보안/안전장치 +- LLM은 “계획 JSON”만 생성(기본). SQL은 서버가 템플릿/파라미터 바인딩으로 생성. +- 만약 SQL 문자열 모드가 필요하면: 템플릿 ID+파라미터만 허용하거나, 정규식/AST로 화이트리스트 검증 후 실행. +- SSE에 민감 값(user_id/token 등) 노출 금지. + +## 단계별 작업(체크리스트) +1) 스켈레톤 + - [ ] 라우터/컨트롤러 v2 추가(`/ai/v2/ask`) + - [ ] SSE 헤더/에러 핸들링 공통화 +2) 검색 계획 + - [ ] `search-plan.service` + `qa.v2.prompts` + Zod 스키마 + - [ ] 계획 실패 시 v1 경로 폴백 +3) 검색 실행 + - [ ] 임베딩 생성(질문) + - [ ] 템플릿 기반 안전 SQL 실행 + 파라미터 바인딩 + - [ ] `search_plan`, `search_result` SSE 송신 +4) 최종 응답 스트림 + - [ ] v1 `generate` 재사용하여 LLM 스트림 + - [ ] v1과 동일한 `answer`/`end`/`error` 이벤트 유지 +5) 관측성/테스트 + - [ ] 디버그/비용 로그 연결 + - [ ] 단위 테스트: 계획 검증/템플릿 빌더/리포지토리 + - [ ] 통합 테스트: SSE 이벤트 순서/형식 + +## 수용 기준(AC) +- `/ai/v2/ask`가 SSE로 동작하고, `search_plan`→`search_result`→`answer` 순으로 이벤트가 수신된다. +- 계획 JSON이 범위를 벗어나거나 실패해도 서버는 안전 폴백으로 정상 응답을 스트리밍한다. +- SQL은 파라미터 바인딩으로만 구성되며, 화이트리스트 템플릿을 벗어난 질의가 실행되지 않는다. +- v1과 동일한 최종 응답 품질을 유지하거나 개선한다. + +## 검색 계획 LLM 프롬프트(초안) + +목표: LLM이 “검색 계획 JSON”만 출력하도록 강제하여 서버가 안전하게 SQL 템플릿을 선택·실행할 수 있도록 한다. 자연어 시간(최근/이번 달/지난주/9월/작년 9월 등)을 구조화하고, 정렬/상한/가중치/임계치 값 제약을 지키도록 한다. + +입력 변수(서버가 주입) +- now_utc, now_kst: 현재 시간(ISO8601) +- timezone: 문자열(예: Asia/Seoul) +- user_id: 요청자의 사용자 ID +- category_id?: 선택, 존재 시 조상 기준 필터 +- post_id?: 선택, 존재 시 mode=post 우선 +- defaults: { top_k: 5, threshold: 0.2, weights: { chunk: 0.7, title: 0.3 }, sort: created_at_desc, limit: 5 } +- question: 사용자 질문 원문 + +출력 형식(반드시 엄수) +- 오직 하나의 JSON 객체만 출력. 추가 텍스트/주석/마크다운/설명 금지. +- 키/값은 스키마 내 필드만 사용. 불필요 필드 생성 금지. + +스키마(재확인) +{ + "mode": "rag" | "post", + "top_k": number, // 1..10 + "threshold": number, // 0..1 + "weights": { "chunk": number, "title": number }, // 0..1, 합=1 + "filters": { + "user_id": string, + "category_ids"?: number[], // 제공 시 우선 적용(카테고리 조상 ID) + "post_id"?: number, // mode=post 시 필수 + "time"?: { // 하나만 선택 + "type": "relative" | "absolute" | "month" | "year" | "quarter", + // relative + "unit"?: "day" | "week" | "month" | "year", + "value"?: number, + // absolute + "from"?: string, // ISO8601 + "to"?: string, // ISO8601 + // month + "month"?: number, // 1..12, year 없으면 현재 연도 가정 + "year"?: number, + // quarter + "quarter"?: number // 1..4, year 없으면 현재 연도 가정 + } + }, + "sort": "created_at_desc" | "created_at_asc", + "limit": number // 1..20 +} + +규칙(핵심) +- post_id가 존재하면 mode="post"를 사용하고 filters.post_id를 설정. 그렇지 않으면 mode="rag". +- category_id가 있으면 filters.category_ids에 포함(단일 ID여도 배열 사용 허용). +- 가중치 합은 1이 되도록 조정(기본 chunk 0.7, title 0.3). 범위를 넘을 경우 기본값 사용. +- top_k는 1..10, limit는 1..20, threshold는 0..1 범위로 제한. 미지정 시 기본값 사용. +- 시간 표현 해석: + - “최근/요즘/최근 N개” → relative(단, “N개”는 limit=N으로 반영; 기간은 기본 30일 유지) + - “최근 N일/주/달/년” → relative + { unit, value } + - “이번 달/이번 주/올해/올해 9월” → month/year/quarter로 구조화 + - “9월”처럼 연도 미지정 → 현재 연도 가정 + - “지난주/지난달/작년” → relative 또는 해당 단위 기간으로 구조화 + - 모호하거나 충돌 시 time 생략(서버 기본 30일 적용 예상) +- 정렬: “최근/최신/새로운” 등은 created_at_desc. “오래된”은 created_at_asc. +- 질문에 “N개”가 있으면 limit=N 반영(상한 20). +- JSON 이외 어떤 텍스트도 출력하지 말 것. + +시스템 프롬프트 템플릿 +""" +You are a Search Plan Generator for a Korean blogging platform. +Your task is to read the user question and output ONLY a JSON object that defines a safe search plan. + +Context: +- now_utc: {now_utc} +- now_kst: {now_kst} +- timezone: {timezone} +- user_id: {user_id} +- category_id: {category_id} +- post_id: {post_id} +- defaults: {"top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"sort":"created_at_desc","limit":5} + +Rules: +1) Output ONLY a single JSON object matching the schema below. No extra text. +2) Respect bounds: top_k 1..10, limit 1..20, threshold 0..1, weights in [0,1] and sum to 1. +3) If post_id exists, use mode="post" and include filters.post_id; else mode="rag". +4) If category_id exists, include it in filters.category_ids. +5) Interpret Korean temporal phrases into filters.time using the provided timezone. + - “최근/최신/요즘”: prefer sort=created_at_desc. If a concrete period is given (e.g., 최근 30일), use relative. + - “이번 달/이번 주/올해/올해 9월”: use month/year/quarter forms. + - Month without year (e.g., “9월”): assume current year. + - “지난주/지난달/작년”: use the respective period. + - If ambiguous, omit time (server applies defaults). +6) If the question asks for N items (e.g., “N개”), set limit=N within bounds. +7) Keep the weights to defaults unless a clear need implies otherwise. + +Schema: +{SCHEMA_JSON} + +Question (Korean): +{question} + +Respond with ONLY the JSON object. No markdown, no explanation. +""" + +Few-shot 예시 +- Q: "최근 글 보여줘" + 출력: + {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","time":{"type":"relative","unit":"day","value":30}},"sort":"created_at_desc","limit":5} + +- Q: "9월 글 2개" + 출력: + {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","time":{"type":"month","month":9}},"sort":"created_at_desc","limit":2} + +- Q: "카테고리 7의 최신 글 3개" + 출력: + {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","category_ids":[7]},"sort":"created_at_desc","limit":3} + +- Q: "지난주에 쓴 포스트 중 추천해줘" + 출력: + {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","time":{"type":"relative","unit":"week","value":1}},"sort":"created_at_desc","limit":5} + +- Q: "이 포스트(123) 기준으로 답해줘" + 출력: + {"mode":"post","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","post_id":123},"sort":"created_at_desc","limit":5} + +검증 포인트(서버 측) +- JSON 파싱 실패 → v1 폴백 +- 값 범위 초과 → 기본값/상한으로 교정 +- time 표준화(절대 from/to 변환), 타임존 적용 +- category_ids/post_id 소유권 확인 diff --git a/src/app.ts b/src/app.ts index 6968488..dfd79c4 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,6 +1,7 @@ import express, { Express, Request, Response, NextFunction } from 'express'; import cors from 'cors'; import aiRouter from './routes/ai.routes'; +import aiV2Router from './routes/ai.v2.routes'; const app: Express = express(); @@ -21,6 +22,7 @@ app.get('/', (request: Request, response: Response) => { }); app.use('/ai', aiRouter); +app.use('/ai/v2', aiV2Router); // Central Error Handler app.use((err: Error, req: Request, res: Response, next: NextFunction) => { diff --git a/src/controllers/ai.v2.controller.ts b/src/controllers/ai.v2.controller.ts new file mode 100644 index 0000000..ed1f579 --- /dev/null +++ b/src/controllers/ai.v2.controller.ts @@ -0,0 +1,29 @@ +import { Request, Response, NextFunction } from 'express'; +import { AskV2Request } from '../types/ai.v2.types'; +import { answerStreamV2 } from '../services/qa.v2.service'; + +export const askV2Handler = async ( + req: Request<{}, {}, AskV2Request>, + res: Response, + next: NextFunction +) => { + try { + const { question, user_id, category_id, speech_tone, post_id, llm } = req.body as any; + res.setHeader('Content-Type', 'text/event-stream'); + res.setHeader('Cache-Control', 'no-cache'); + res.setHeader('Connection', 'keep-alive'); + + const stream = await answerStreamV2( + question, + user_id, + category_id, + speech_tone, + post_id, + llm + ); + stream.pipe(res); + } catch (error) { + next(error); + } +}; + diff --git a/src/prompts/qa.v2.prompts.ts b/src/prompts/qa.v2.prompts.ts new file mode 100644 index 0000000..da03657 --- /dev/null +++ b/src/prompts/qa.v2.prompts.ts @@ -0,0 +1,142 @@ +// Search Plan prompt templates for v2 + +import { SearchPlan } from '../types/ai.v2.types'; + +export const getSearchPlanSchemaJson = (): Record => ({ + type: 'object', + additionalProperties: false, + properties: { + mode: { enum: ['rag', 'post'] }, + top_k: { type: 'integer', minimum: 1, maximum: 10 }, + threshold: { type: 'number', minimum: 0, maximum: 1 }, + weights: { + type: 'object', + additionalProperties: false, + properties: { + chunk: { type: 'number', minimum: 0, maximum: 1 }, + title: { type: 'number', minimum: 0, maximum: 1 }, + }, + required: ['chunk', 'title'], + }, + filters: { + type: 'object', + additionalProperties: false, + properties: { + user_id: { type: 'string' }, + category_ids: { type: 'array', items: { type: 'integer' } }, + post_id: { type: 'integer' }, + time: { + oneOf: [ + { + type: 'object', + additionalProperties: false, + properties: { + type: { const: 'relative' }, + unit: { enum: ['day', 'week', 'month', 'year'] }, + value: { type: 'integer', minimum: 1 }, + }, + required: ['type', 'unit', 'value'], + }, + { + type: 'object', + additionalProperties: false, + properties: { + type: { const: 'absolute' }, + from: { type: 'string' }, + to: { type: 'string' }, + }, + required: ['type', 'from', 'to'], + }, + { + type: 'object', + additionalProperties: false, + properties: { + type: { const: 'month' }, + month: { type: 'integer', minimum: 1, maximum: 12 }, + year: { type: 'integer' }, + }, + required: ['type', 'month'], + }, + { + type: 'object', + additionalProperties: false, + properties: { + type: { const: 'year' }, + year: { type: 'integer' }, + }, + required: ['type', 'year'], + }, + { + type: 'object', + additionalProperties: false, + properties: { + type: { const: 'quarter' }, + quarter: { type: 'integer', minimum: 1, maximum: 4 }, + year: { type: 'integer' }, + }, + required: ['type', 'quarter'], + }, + ], + }, + }, + required: ['user_id'], + }, + sort: { enum: ['created_at_desc', 'created_at_asc'] }, + limit: { type: 'integer', minimum: 1, maximum: 20 }, + }, + required: ['mode', 'top_k', 'threshold', 'weights', 'filters', 'sort', 'limit'], +}); + +export const buildSearchPlanPrompt = (params: { + now_utc: string; + now_kst: string; + timezone: string; + user_id: string; + category_id?: number; + post_id?: number; + defaults?: Partial; + question: string; +}): string => { + const defaults = JSON.stringify( + params.defaults || { + top_k: 5, + threshold: 0.2, + weights: { chunk: 0.7, title: 0.3 }, + sort: 'created_at_desc', + limit: 5, + mode: 'rag', + filters: { user_id: params.user_id }, + }, + ); + + const schemaHint = JSON.stringify(getSearchPlanSchemaJson()); + + return [ + 'You are a Search Plan Generator for a Korean blogging platform.', + 'Your task is to read the user question and output ONLY a JSON object that defines a safe search plan.', + '', + `now_utc: ${params.now_utc}`, + `now_kst: ${params.now_kst}`, + `timezone: ${params.timezone}`, + `user_id: ${params.user_id}`, + `category_id: ${params.category_id ?? ''}`, + `post_id: ${params.post_id ?? ''}`, + `defaults: ${defaults}`, + '', + 'Rules:', + '1) Output ONLY a single JSON object matching the schema. No extra text.', + '2) Respect bounds: top_k 1..10, limit 1..20, threshold 0..1, weights in [0,1] and sum to 1.', + '3) If post_id exists, use mode="post" and include filters.post_id; else mode="rag".', + '4) If category_id exists, include it in filters.category_ids.', + '5) Interpret Korean temporal phrases into filters.time using the provided timezone. Month without year assumes current year.', + '6) If the question asks for N items (e.g., “N개”), set limit=N within bounds.', + '7) Keep weights to defaults unless a clear need implies otherwise.', + '', + `Schema: ${schemaHint}`, + '', + `Question (Korean):\n${params.question}`, + '', + 'Respond with ONLY the JSON object. No markdown, no explanation.', + ].join('\n'); +}; + diff --git a/src/repositories/post.repository.ts b/src/repositories/post.repository.ts index 545dc57..6af3af3 100644 --- a/src/repositories/post.repository.ts +++ b/src/repositories/post.repository.ts @@ -131,4 +131,97 @@ export const storeContentEmbeddings = async ( await pool.query('ROLLBACK'); throw error; } -}; \ No newline at end of file +}; + +// ========= READ QUERIES (V2 dynamic) ========= +export const findSimilarChunksV2 = async (params: { + userId: string; + embedding: number[]; + categoryId?: number; + from?: string; // ISO UTC + to?: string; // ISO UTC + threshold?: number; // 0..1 + topK?: number; // default 5, max 10 + weights?: { chunk: number; title: number }; + sort?: 'created_at_desc' | 'created_at_asc'; +}): Promise => { + const pool = getDb(); + const wChunk = Math.max(0, Math.min(1, params.weights?.chunk ?? 0.7)); + const wTitle = Math.max(0, Math.min(1, params.weights?.title ?? 0.3)); + const thr = params.threshold != null ? Math.max(0, Math.min(1, params.threshold)) : 0.2; + const limit = Math.min(10, Math.max(1, params.topK ?? 5)); + + const parts: string[] = []; + const values: any[] = []; + + // $1: userId, $2: embedding + values.push(params.userId); + values.push(pgvector.toSql(params.embedding)); + + const hasCategory = typeof params.categoryId === 'number'; + const hasTime = !!(params.from && params.to); + + if (hasCategory) { + const catParam = values.length + 1; // next index + parts.push(` + WITH category_ids AS ( + SELECT DISTINCT cc.descendant_id + FROM category_closure cc + WHERE cc.ancestor_id = $${catParam} + ), + filtered_posts AS ( + SELECT bp.id AS post_id, bp.title AS post_title, bp.created_at + FROM blog_post bp + WHERE bp.user_id = $1 AND bp.category_id IN (SELECT descendant_id FROM category_ids) + )`); + values.push(params.categoryId); + } else { + parts.push(` + WITH filtered_posts AS ( + SELECT id AS post_id, title AS post_title, created_at + FROM blog_post + WHERE user_id = $1 + )`); + } + + // base select and threshold + const thrParam = values.length + 1; + parts.push(` + SELECT + fp.post_id, + fp.post_title, + pc.content AS post_chunk, + (${wChunk} * (1.0 - (pc.embedding <=> $2))) + (${wTitle} * (1.0 - (pte.embedding <=> $2))) AS similarity_score, + fp.created_at + FROM filtered_posts fp + JOIN post_chunks pc ON pc.post_id = fp.post_id + JOIN post_title_embeddings pte ON pte.post_id = fp.post_id + WHERE (1.0 - (pc.embedding <=> $2)) > $${thrParam} + `); + values.push(thr); + + if (hasTime) { + const fromParam = values.length + 1; + const toParam = values.length + 2; + parts.push(` AND fp.created_at BETWEEN $${fromParam} AND $${toParam}`); + values.push(params.from, params.to); + } + + let orderBy = 'similarity_score DESC'; + if (params.sort === 'created_at_desc') orderBy = 'similarity_score DESC, fp.created_at DESC'; + if (params.sort === 'created_at_asc') orderBy = 'similarity_score DESC, fp.created_at ASC'; + + const limitParam = values.length + 1; + parts.push(` ORDER BY ${orderBy} LIMIT $${limitParam}`); + values.push(limit); + + const sql = parts.join('\n'); + + const { rows } = await pool.query(sql, values); + return rows.map((row) => ({ + postId: row.post_id, + postTitle: row.post_title, + postChunk: row.post_chunk, + similarityScore: row.similarity_score, + })); +}; diff --git a/src/routes/ai.v2.routes.ts b/src/routes/ai.v2.routes.ts new file mode 100644 index 0000000..2558023 --- /dev/null +++ b/src/routes/ai.v2.routes.ts @@ -0,0 +1,14 @@ +import { Router } from 'express'; +import { askV2Handler } from '../controllers/ai.v2.controller'; +import { authMiddleware } from '../middlewares/auth.middleware'; + +const aiV2Router = Router(); + +aiV2Router.get('/health', (req, res) => { + res.status(200).json({ status: 'ok', v: 'v2' }); +}); + +aiV2Router.post('/ask', authMiddleware, askV2Handler); + +export default aiV2Router; + diff --git a/src/services/qa.v2.service.ts b/src/services/qa.v2.service.ts new file mode 100644 index 0000000..ef2db41 --- /dev/null +++ b/src/services/qa.v2.service.ts @@ -0,0 +1,208 @@ +import { PassThrough } from 'stream'; +import { generate } from '../llm'; +import config from '../config'; +import * as qaPrompts from '../prompts/qa.prompts'; +import * as postRepository from '../repositories/post.repository'; +import * as personaRepository from '../repositories/persona.repository'; +import { generateSearchPlan } from './search-plan.service'; +import { runSemanticSearch } from './semantic-search.service'; + +const preprocessContent = (content: string): string => { + const plainText = content.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim(); + return plainText.length > 40000 ? plainText.substring(0, 40000) : plainText; +}; + +const getSpeechTonePrompt = async (speechTone: number, userId: string): Promise => { + if (speechTone === -1) return '간결하고 명확한 말투로 답변해'; + if (speechTone === -2) + return '아래의 블로그 본문 컨텍스트를 참고하여 본문의 말투를 파악해 최대한 비슷한 말투로 답변해'; + + const persona = await personaRepository.findPersonaById(speechTone, userId); + if (persona) return `${persona.name}: ${persona.description}`; + return '간결하고 명확한 말투로 답변해'; +}; + +type LlmOverride = { + provider?: 'openai' | 'gemini'; + model?: string; + options?: { temperature?: number; top_p?: number; max_output_tokens?: number }; +}; + +export const answerStreamV2 = async ( + question: string, + userId: string, + categoryId?: number, + speechTone: number = -1, + postId?: number, + llm?: LlmOverride +): Promise => { + const stream = new PassThrough(); + + (async () => { + const speechTonePrompt = await getSpeechTonePrompt(speechTone, userId); + + let messages: { role: 'system' | 'user' | 'assistant' | 'tool' | 'function'; content: string }[] = []; + let tools: + | { + type: 'function'; + function: { name: string; description?: string; parameters?: Record }; + }[] + | undefined = undefined; + + const toSimpleMessages = ( + raw: any[] + ): { role: 'system' | 'user' | 'assistant' | 'tool' | 'function'; content: string }[] => { + return (raw || []).map((m: any) => ({ + role: m.role, + content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content), + })); + }; + + if (postId) { + // Post-centric path (same as v1 with added v2 pre-events) + const post = await postRepository.findPostById(postId); + if (!post || post.user_id !== userId) { + const code = !post ? 404 : 403; + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ code, message: !post ? 'Post not found' : 'Forbidden' })}\n\n`); + stream.end(); + return; + } + // Emit plan event for transparency + stream.write(`event: search_plan\n`); + stream.write( + `data: ${JSON.stringify({ mode: 'post', filters: { post_id: postId, user_id: userId } })}\n\n` + ); + + const processed = preprocessContent(post.content); + const ctx = [{ postId: post.id, postTitle: post.title }]; + stream.write(`event: search_result\n`); + stream.write(`data: ${JSON.stringify(ctx)}\n\n`); + stream.write(`event: exist_in_post_status\n`); + stream.write(`data: true\n\n`); + stream.write(`event: context\n`); + stream.write(`data: ${JSON.stringify(ctx)}\n\n`); + + messages = toSimpleMessages( + qaPrompts.createPostContextPrompt(post, processed, question, speechTonePrompt) + ); + } else { + // Plan generation + const planPair = await generateSearchPlan(question, { user_id: userId, category_id: categoryId }); + if (!planPair) { + // Fallback to v1 RAG silently + const [questionEmbedding] = await (await import('./embedding.service')).createEmbeddings([ + question, + ]); + const similarChunks = await postRepository.findSimilarChunks(userId, questionEmbedding, categoryId); + const context = similarChunks.map((c) => ({ postId: c.postId, postTitle: c.postTitle })); + stream.write(`event: search_plan\n`); + stream.write(`data: ${JSON.stringify({ mode: 'rag', fallback: true })}\n\n`); + stream.write(`event: search_result\n`); + stream.write(`data: ${JSON.stringify(context)}\n\n`); + stream.write(`event: exist_in_post_status\n`); + stream.write(`data: ${JSON.stringify(similarChunks.length > 0)}\n\n`); + stream.write(`event: context\n`); + stream.write(`data: ${JSON.stringify(context)}\n\n`); + + messages = toSimpleMessages( + qaPrompts.createRagPrompt(question, similarChunks, speechTonePrompt) + ); + tools = [ + { + type: 'function', + function: { + name: 'report_content_insufficient', + description: '카테고리는 맞지만 본문 컨텍스트가 부족할 때 호출', + parameters: { + type: 'object', + properties: { + text: { + type: 'string', + description: + '답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다.', + }, + }, + required: ['text'], + }, + }, + }, + ]; + } else { + const plan = planPair.normalized; + stream.write(`event: search_plan\n`); + stream.write(`data: ${JSON.stringify(plan)}\n\n`); + + // Execute semantic search per plan + const rows = await runSemanticSearch(question, userId, plan); + // v1과 동일하게: 청크 Top-K를 그대로 사용(포스트 단위 dedupe/limit 미적용) + const context = rows.map((r) => ({ postId: r.postId, postTitle: r.postTitle })); + stream.write(`event: search_result\n`); + stream.write(`data: ${JSON.stringify(context)}\n\n`); + stream.write(`event: exist_in_post_status\n`); + stream.write(`data: ${JSON.stringify(rows.length > 0)}\n\n`); + stream.write(`event: context\n`); + stream.write(`data: ${JSON.stringify(context)}\n\n`); + + messages = toSimpleMessages( + qaPrompts.createRagPrompt( + question, + rows.map((r) => ({ + postId: r.postId, + postTitle: r.postTitle, + postChunk: r.postChunk, + similarityScore: r.similarityScore, + })) as any, + speechTonePrompt + ) + ); + tools = [ + { + type: 'function', + function: { + name: 'report_content_insufficient', + description: '카테고리는 맞지만 본문 컨텍스트가 부족할 때 호출', + parameters: { + type: 'object', + properties: { + text: { + type: 'string', + description: + '답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다.', + }, + }, + required: ['text'], + }, + }, + }, + ]; + } + } + + const llmStream = await generate({ + provider: llm?.provider || 'openai', + model: llm?.model || config.CHAT_MODEL, + messages, + tools, + options: llm?.options, + meta: { userId, categoryId, postId }, + }); + + llmStream.on('data', (chunk) => stream.write(chunk)); + llmStream.on('end', () => stream.end()); + llmStream.on('error', () => { + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); + stream.end(); + }); + })().catch((err) => { + try { + console.error('v2 Stream process error:', err); + } catch {} + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); + stream.end(); + }); + + return stream; +}; diff --git a/src/services/search-plan.service.ts b/src/services/search-plan.service.ts new file mode 100644 index 0000000..f2861da --- /dev/null +++ b/src/services/search-plan.service.ts @@ -0,0 +1,102 @@ +import OpenAI from 'openai'; +import config from '../config'; +import { buildSearchPlanPrompt, getSearchPlanSchemaJson } from '../prompts/qa.v2.prompts'; +import { planSchema, type SearchPlan } from '../types/ai.v2.types'; +import { nowUtc, toAbsoluteRangeKst } from '../utils/time'; + +const openai = new OpenAI({ apiKey: config.OPENAI_API_KEY }); + +export type PlanContext = { + user_id: string; + category_id?: number; + post_id?: number; + timezone?: string; // default Asia/Seoul +}; + +export const generateSearchPlan = async ( + question: string, + ctx: PlanContext +): Promise<{ plan: SearchPlan; normalized: SearchPlan } | null> => { + const timezone = ctx.timezone || 'Asia/Seoul'; + const now = nowUtc(); + const nowUtcIso = now.toISOString(); + const nowKstIso = new Date(now.getTime() + 9 * 3600 * 1000).toISOString(); + + const prompt = buildSearchPlanPrompt({ + now_utc: nowUtcIso, + now_kst: nowKstIso, + timezone, + user_id: ctx.user_id, + category_id: ctx.category_id, + post_id: ctx.post_id, + question, + }); + + const schema = getSearchPlanSchemaJson(); + + try { + const response: any = await (openai as any).responses.create({ + model: config.CHAT_MODEL || 'gpt-5-mini', + input: [{ role: 'user', content: [{ type: 'input_text', text: prompt }] }], + response_format: { type: 'json_schema', json_schema: { name: 'SearchPlan', schema, strict: true } }, + max_output_tokens: 600, + }); + + const text = (response as any)?.output_text || ''; + const raw = text && text.trim().startsWith('{') ? text : (() => { + // Fallback: try to extract JSON from response.output + try { + const outputs = (response as any).output || []; + const parts = outputs + .flatMap((o: any) => o.content || []) + .filter((c: any) => typeof c?.text === 'string') + .map((c: any) => c.text) + .join(''); + return parts; + } catch { + return ''; + } + })(); + const parsed = JSON.parse(raw); + const plan = planSchema.parse(parsed); + + // Normalize weights sum to 1 + const sum = (plan.weights?.chunk ?? 0) + (plan.weights?.title ?? 0); + const weights = sum > 0 ? { chunk: plan.weights.chunk / sum, title: plan.weights.title / sum } : { chunk: 0.7, title: 0.3 }; + + // Normalize time range to absolute if provided + let normPlan: SearchPlan = { ...plan, weights }; + if (plan.filters?.time) { + const abs = toAbsoluteRangeKst(plan.filters.time as any, now); + if (abs) { + normPlan = { + ...normPlan, + filters: { ...normPlan.filters, time: { type: 'absolute', from: abs.from, to: abs.to } as any }, + }; + } else { + // drop invalid time + const { time, ...rest } = normPlan.filters || ({} as any); + normPlan = { ...normPlan, filters: rest as any }; + } + } + + // Enforce bounds just in case + normPlan.top_k = Math.min(10, Math.max(1, normPlan.top_k || 5)); + normPlan.limit = Math.min(20, Math.max(1, normPlan.limit || 5)); + normPlan.threshold = Math.min(1, Math.max(0, normPlan.threshold ?? 0.2)); + if (!normPlan.mode) normPlan.mode = (ctx.post_id ? 'post' : 'rag') as any; + if (ctx.category_id && !normPlan.filters.category_ids) normPlan.filters.category_ids = [ctx.category_id]; + if (ctx.post_id) { + normPlan.mode = 'post'; + normPlan.filters.post_id = ctx.post_id; + } + + return { plan, normalized: normPlan }; + } catch (e) { + try { + console.error(JSON.stringify({ type: 'debug.plan.error', message: (e as any)?.message || 'error' })); + } catch {} + return null; + } +}; + diff --git a/src/services/semantic-search.service.ts b/src/services/semantic-search.service.ts new file mode 100644 index 0000000..05561ac --- /dev/null +++ b/src/services/semantic-search.service.ts @@ -0,0 +1,36 @@ +import { createEmbeddings } from './embedding.service'; +import * as postRepository from '../repositories/post.repository'; +import { SearchPlan } from '../types/ai.v2.types'; + +export type SemanticSearchResult = { + postId: string; + postTitle: string; + postChunk: string; + similarityScore: number; +}[]; + +export const runSemanticSearch = async ( + question: string, + userId: string, + plan: SearchPlan +): Promise => { + const [embedding] = await createEmbeddings([question]); + + const from = (plan.filters as any)?.time?.type === 'absolute' ? (plan.filters as any).time.from : undefined; + const to = (plan.filters as any)?.time?.type === 'absolute' ? (plan.filters as any).time.to : undefined; + + const rows = await postRepository.findSimilarChunksV2({ + userId, + embedding, + categoryId: (plan.filters as any)?.category_ids?.[0], + from, + to, + threshold: plan.threshold, + topK: plan.top_k, + weights: plan.weights, + sort: plan.sort, + }); + + return rows; +}; + diff --git a/src/types/ai.v2.types.ts b/src/types/ai.v2.types.ts new file mode 100644 index 0000000..f10debb --- /dev/null +++ b/src/types/ai.v2.types.ts @@ -0,0 +1,79 @@ +import { z } from 'zod'; + +// ===== Plan JSON Schema (Zod) ===== + +export const timeFilterSchema = z.discriminatedUnion('type', [ + z.object({ + type: z.literal('relative'), + unit: z.enum(['day', 'week', 'month', 'year']), + value: z.number().int().positive(), + }), + z.object({ + type: z.literal('absolute'), + from: z.string(), // ISO8601 + to: z.string(), // ISO8601 + }), + z.object({ + type: z.literal('month'), + month: z.number().int().min(1).max(12), + year: z.number().int().optional(), + }), + z.object({ + type: z.literal('year'), + year: z.number().int(), + }), + z.object({ + type: z.literal('quarter'), + quarter: z.number().int().min(1).max(4), + year: z.number().int().optional(), + }), +]); + +export const planSchema = z.object({ + mode: z.enum(['rag', 'post']).default('rag'), + top_k: z.number().int().min(1).max(10).default(5), + threshold: z.number().min(0).max(1).default(0.2), + weights: z + .object({ chunk: z.number().min(0).max(1), title: z.number().min(0).max(1) }) + .default({ chunk: 0.7, title: 0.3 }), + filters: z + .object({ + user_id: z.string(), + category_ids: z.array(z.number().int()).optional(), + post_id: z.number().int().optional(), + time: timeFilterSchema.optional(), + }) + .default({ user_id: '' }), + sort: z.enum(['created_at_desc', 'created_at_asc']).default('created_at_desc'), + limit: z.number().int().min(1).max(20).default(5), +}); + +export type SearchPlan = z.infer; + +// ===== API: /ai/v2/ask ===== + +export const askV2Schema = z.object({ + body: z.object({ + question: z.string(), + user_id: z.string(), + category_id: z.number().optional(), + post_id: z.number().optional(), + speech_tone: z.number().optional(), + llm: z + .object({ + provider: z.enum(['openai', 'gemini']).optional(), + model: z.string().optional(), + options: z + .object({ + temperature: z.number().optional(), + top_p: z.number().optional(), + max_output_tokens: z.number().optional(), + }) + .optional(), + }) + .optional(), + }), +}); + +export type AskV2Request = z.infer['body']; + diff --git a/src/utils/time.ts b/src/utils/time.ts new file mode 100644 index 0000000..406a16e --- /dev/null +++ b/src/utils/time.ts @@ -0,0 +1,82 @@ +// Minimal KST time utilities and range normalization + +const KST_OFFSET_MINUTES = 9 * 60; // UTC+9 + +const toDate = (isoOrDate: string | Date): Date => (isoOrDate instanceof Date ? isoOrDate : new Date(isoOrDate)); + +export const nowUtc = (): Date => new Date(); + +export const toKst = (d: Date): Date => { + // Convert UTC date to KST by adding offset + return new Date(d.getTime() + KST_OFFSET_MINUTES * 60 * 1000); +}; + +export const fromKstToUtc = (d: Date): Date => { + return new Date(d.getTime() - KST_OFFSET_MINUTES * 60 * 1000); +}; + +const startOfDay = (d: Date): Date => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0); +const endOfDay = (d: Date): Date => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999); + +export const startOfMonth = (year: number, monthIndex0: number): Date => new Date(year, monthIndex0, 1, 0, 0, 0, 0); +export const endOfMonth = (year: number, monthIndex0: number): Date => new Date(year, monthIndex0 + 1, 0, 23, 59, 59, 999); + +export const startOfQuarter = (year: number, quarter: number): Date => { + const m0 = (quarter - 1) * 3; // 0-based month index + return new Date(year, m0, 1, 0, 0, 0, 0); +}; +export const endOfQuarter = (year: number, quarter: number): Date => { + const m0 = quarter * 3 - 1; // end month index + return new Date(year, m0 + 1, 0, 23, 59, 59, 999); +}; + +export type AbsoluteRange = { from: string; to: string }; + +export const toAbsoluteRangeKst = (input: { type: string; [k: string]: any }, base: Date = nowUtc()): AbsoluteRange | null => { + try { + const baseKst = toKst(base); + const year = baseKst.getFullYear(); + if (input.type === 'relative') { + const unit = String(input.unit); + const value = Math.max(1, parseInt(String(input.value || '1'), 10)); + const toK = endOfDay(baseKst); + const fromK = new Date(toK.getTime()); + if (unit === 'day') fromK.setDate(fromK.getDate() - value + 1); + else if (unit === 'week') fromK.setDate(fromK.getDate() - value * 7 + 1); + else if (unit === 'month') fromK.setMonth(fromK.getMonth() - value); + else if (unit === 'year') fromK.setFullYear(fromK.getFullYear() - value); + const fromUtc = fromKstToUtc(startOfDay(fromK)); + const toUtc = fromKstToUtc(toK); + return { from: fromUtc.toISOString(), to: toUtc.toISOString() }; + } + if (input.type === 'absolute') { + const from = new Date(input.from); + const to = new Date(input.to); + return { from: from.toISOString(), to: to.toISOString() }; + } + if (input.type === 'month') { + const m = Math.max(1, Math.min(12, parseInt(String(input.month), 10))); + const y = input.year ? parseInt(String(input.year), 10) : year; + const fromK = startOfMonth(y, m - 1); + const toK = endOfMonth(y, m - 1); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + if (input.type === 'year') { + const y = parseInt(String(input.year), 10); + const fromK = startOfMonth(y, 0); + const toK = endOfMonth(y, 11); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + if (input.type === 'quarter') { + const q = Math.max(1, Math.min(4, parseInt(String(input.quarter), 10))); + const y = input.year ? parseInt(String(input.year), 10) : year; + const fromK = startOfQuarter(y, q); + const toK = endOfQuarter(y, q); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + } catch { + // ignore + } + return null; +}; + From f7e09a6a0c5c8011f218d5aa6b662cf54f91dfb6 Mon Sep 17 00:00:00 2001 From: chan000518 Date: Sun, 5 Oct 2025 15:09:54 +0900 Subject: [PATCH 06/14] =?UTF-8?q?=F0=9F=93=9D=20askV2=20=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reports/REPORT-askv2.md | 7 +++++-- docs/structureDiagram/askV1-structure.png | Bin 0 -> 149241 bytes docs/structureDiagram/askV2-structure.png | Bin 0 -> 131020 bytes 3 files changed, 5 insertions(+), 2 deletions(-) rename REPORT-askv2.md => docs/reports/REPORT-askv2.md (97%) create mode 100644 docs/structureDiagram/askV1-structure.png create mode 100644 docs/structureDiagram/askV2-structure.png diff --git a/REPORT-askv2.md b/docs/reports/REPORT-askv2.md similarity index 97% rename from REPORT-askv2.md rename to docs/reports/REPORT-askv2.md index b0d5e12..6bc5641 100644 --- a/REPORT-askv2.md +++ b/docs/reports/REPORT-askv2.md @@ -1,4 +1,4 @@ -# 보고서: /ai/v2/ask 구현 내역과 구조(한국어) +# 보고서: /ai/v2/ask 구현 내역과 구조 ## 1) 개요 - 목적: v1의 고정형 RAG 흐름을 개선하기 위해, 사용자의 질문을 LLM이 “검색 계획(JSON)”으로 구조화 → 서버가 안전한 시맨틱 SQL 검색 수행 → v1과 동일한 방식으로 최종 답변을 SSE로 스트리밍하는 v2 파이프라인을 추가했습니다. @@ -11,6 +11,8 @@ - 관측성 부족: 어떤 기준/전략으로 검색되었는지(계획/파라미터)를 클라이언트에서 파악하기 어려움. - 보안/안전 제약: 프롬프트/검색 로직이 단순해, 미래에 복잡한 동적 쿼리로 확장 시 안전한 경계(화이트리스트/스키마 강제)가 필요. +![alt text](../structureDiagram/askV1-structure.png) + ## 3) v2의 도입/해결 방안과 가능해진 것 - LLM 검색 계획(JSON) 도입 - OpenAI Responses API + JSON Schema 강제 → LLM이 오직 스키마에 맞는 JSON만 출력. @@ -28,7 +30,7 @@ - 청크 검색 후보(top_k)를 넓게 가져온 뒤, 포스트 단위 중복 제거 + `limit`개까지만 컨텍스트/노출로 사용(토큰/비용 관리). - 폴백 안전성 - 계획 생성 실패 시 v1 RAG 경로로 자동 폴백하여 기능 연속성 보장. - +![alt text](../structureDiagram/askV2-structure.png) ## 4) v2 구조(파일과 역할) - 라우팅/컨트롤러 - `src/routes/ai.v2.routes.ts`: `/ai/v2/ask` SSE 라우트. @@ -90,3 +92,4 @@ SSE 이벤트 순서 } ``` - 기대 SSE 순서: `search_plan` → `search_result` → `exist_in_post_status` → `context` → `answer*` → `end` + diff --git a/docs/structureDiagram/askV1-structure.png b/docs/structureDiagram/askV1-structure.png new file mode 100644 index 0000000000000000000000000000000000000000..c621efceb772f131ede94d422a97415d0fe96f26 GIT binary patch literal 149241 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ÐT!5Y4&Np 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 H`uTqVFVW3S literal 0 HcmV?d00001 diff --git a/docs/structureDiagram/askV2-structure.png b/docs/structureDiagram/askV2-structure.png new file mode 100644 index 0000000000000000000000000000000000000000..daad8e90225f770d53b6aadc6ef7a86cfbc3d290 GIT binary patch literal 131020 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

+h(-<4_r1 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 Date: Sun, 5 Oct 2025 16:04:11 +0900 Subject: [PATCH 07/14] =?UTF-8?q?=F0=9F=90=9B=20ask=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=20=EC=97=90=EB=9F=AC=20=EB=B0=8F=20sse=20?= =?UTF-8?q?=EB=8D=B8=ED=83=80=20=EB=8B=A8=EC=9C=84=20=EC=A0=84=EB=8B=AC=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/ai.controller.ts | 40 +++++++++- src/llm/providers/openai-responses.ts | 103 +++++++++++++++++++------- src/services/qa.service.ts | 11 +++ 3 files changed, 125 insertions(+), 29 deletions(-) diff --git a/src/controllers/ai.controller.ts b/src/controllers/ai.controller.ts index 1b9a593..d276f23 100644 --- a/src/controllers/ai.controller.ts +++ b/src/controllers/ai.controller.ts @@ -51,12 +51,46 @@ export const askHandler = async ( try { const { question, user_id, category_id, speech_tone, post_id, llm } = req.body as any; - res.setHeader('Content-Type', 'text/event-stream'); - res.setHeader('Cache-Control', 'no-cache'); + // SSE headers and anti-buffering hints + res.setHeader('Content-Type', 'text/event-stream; charset=utf-8'); + res.setHeader('Cache-Control', 'no-cache, no-transform'); res.setHeader('Connection', 'keep-alive'); + // Nginx buffering off + res.setHeader('X-Accel-Buffering', 'no'); + // Flush headers early so clients start processing immediately + (res as any).flushHeaders?.(); + // Reduce Nagle’s algorithm buffering on the socket for faster flush + (res.socket as any)?.setNoDelay?.(true); + // Prime the SSE stream to break proxy buffering thresholds + res.write(':ok\n\n'); const stream = await answerStream(question, user_id, category_id, speech_tone, post_id, llm); - stream.pipe(res); + // Manually bridge to ensure flushing of SSE deltas + stream.on('data', (chunk) => { + const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)); + res.write(buf); + const canFlush = typeof (res as any).flush === 'function'; + // try to flush if supported by runtime/middleware + (res as any).flush?.(); + try { + console.log( + JSON.stringify({ type: 'debug.sse.write', at: Date.now(), bytes: buf.length, flushed: canFlush }) + ); + } catch {} + }); + stream.on('end', () => { + res.end(); + }); + stream.on('error', () => { + res.end(); + }); + + // Cleanup if client disconnects + req.on('close', () => { + try { + stream.destroy(); + } catch {} + }); } catch (error) { next(error); diff --git a/src/llm/providers/openai-responses.ts b/src/llm/providers/openai-responses.ts index 430728c..3a2e86b 100644 --- a/src/llm/providers/openai-responses.ts +++ b/src/llm/providers/openai-responses.ts @@ -84,9 +84,15 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { - if (delta) { + responsesStream.on('response.output_text.delta', (ev: any) => { + const text = typeof ev === 'string' ? ev : ev?.delta ?? ''; + if (text) { safeWrite(`event: answer\n`); - safeWrite(`data: ${JSON.stringify(delta)}\n\n`); + safeWrite(`data: ${JSON.stringify(text)}\n\n`); + try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: String(text).length, at: Date.now() })); } catch {} if (!loggedFirstDelta) { - try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: delta.length })); } catch {} + try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: String(text).length })); } catch {} loggedFirstDelta = true; } } }); // Stream tool-call arguments as answer chunks to maintain SSE shape - responsesStream.on('response.tool_call.delta', (toolDelta: any) => { - const argsDelta = toolDelta?.arguments_delta || toolDelta?.arguments || ''; + responsesStream.on('response.tool_call.delta', (ev: any) => { + const argsDelta = ev?.arguments_delta || ev?.arguments || ev?.delta || ''; if (argsDelta) { safeWrite(`event: answer\n`); safeWrite(`data: ${JSON.stringify(argsDelta)}\n\n`); } }); + // Catch-all messages to ensure we don't miss alternative text events + responsesStream.on('message', (msg: any) => { + try { + const m = typeof msg === 'string' ? JSON.parse(msg) : msg; + if (!m) return; + // Prefer explicit output_text delta + if (m.type === 'response.output_text.delta' && m.delta) { + safeWrite(`event: answer\n`); + safeWrite(`data: ${JSON.stringify(m.delta)}\n\n`); + } + // Some SDKs may emit full output_text chunk at once + else if (m.type === 'response.output_text' && typeof m.text === 'string') { + safeWrite(`event: answer\n`); + safeWrite(`data: ${JSON.stringify(m.text)}\n\n`); + } + // Generic delta fallback + else if (m.type === 'response.delta' && typeof m.delta === 'string') { + safeWrite(`event: answer\n`); + safeWrite(`data: ${JSON.stringify(m.delta)}\n\n`); + } + // Log for visibility + console.log( + JSON.stringify({ type: 'debug.openai.msg', mtype: m.type, keys: Object.keys(m || {}) }) + ); + } catch (e) { + try { console.log(JSON.stringify({ type: 'debug.openai.msg_parse_error' })); } catch {} + } + }); + responsesStream.on('response.completed', () => { safeWrite(`event: end\n`); safeWrite(`data: [DONE]\n\n`); @@ -134,8 +171,12 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { + try { + await responsesStream.done(); + } catch {} + })(); return stream; } catch (e) { // Fallback to non-streaming Responses if streaming path fails @@ -147,6 +188,7 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { + try { + for await (const chunk of chatStream) { + const content = chunk.choices[0]?.delta?.content || ''; + const toolCalls = chunk.choices[0]?.delta?.tool_calls; - if (toolCalls) { - for (const toolCall of toolCalls) { - if (toolCall.function?.arguments) { + if (toolCalls) { + for (const toolCall of toolCalls) { + if (toolCall.function?.arguments) { + safeWrite(`event: answer\n`); + safeWrite(`data: ${JSON.stringify(toolCall.function.arguments)}\n\n`); + } + } + } else if (content) { safeWrite(`event: answer\n`); - safeWrite(`data: ${JSON.stringify(toolCall.function.arguments)}\n\n`); + safeWrite(`data: ${JSON.stringify(content)}\n\n`); } - } - } else if (content) { - safeWrite(`event: answer\n`); - safeWrite(`data: ${JSON.stringify(content)}\n\n`); - } - if (chunk.choices[0]?.finish_reason) { - safeWrite(`event: end\n`); - safeWrite(`data: [DONE]\n\n`); + if (chunk.choices[0]?.finish_reason) { + safeWrite(`event: end\n`); + safeWrite(`data: [DONE]\n\n`); + safeEnd(); + try { console.log(JSON.stringify({ type: 'debug.openai.completed', path: 'chat.completions.stream' })); } catch {} + break; + } + } + } catch (e) { + safeWrite(`event: error\n`); + safeWrite(`data: ${JSON.stringify({ message: 'Internal server error' })}\n\n`); safeEnd(); - try { console.log(JSON.stringify({ type: 'debug.openai.completed', path: 'chat.completions.stream' })); } catch {} - break; } - } + })(); return stream; } catch (err) { diff --git a/src/services/qa.service.ts b/src/services/qa.service.ts index eef997f..0d8ffe0 100644 --- a/src/services/qa.service.ts +++ b/src/services/qa.service.ts @@ -151,6 +151,17 @@ export const answerStream = async ( } catch {} llmStream.on('data', (chunk) => { + try { + const str = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk); + console.log( + JSON.stringify({ + type: 'debug.qa.chunk', + at: Date.now(), + bytes: Buffer.byteLength(str, 'utf8'), + preview: str.slice(0, 40).replace(/\n/g, '\\n'), + }) + ); + } catch {} stream.write(chunk); }); llmStream.on('end', () => { From 1a073c36efa83890b671c5e12b38a47b0751b463 Mon Sep 17 00:00:00 2001 From: chan000518 Date: Tue, 7 Oct 2025 16:21:35 +0900 Subject: [PATCH 08/14] =?UTF-8?q?=E2=9C=A8=20askV2=20=ED=95=98=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=A6=AC=EB=93=9C=20=EC=84=9C=EC=B9=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TASK.md | 352 +++++--------------------- docs/api.md | 148 +++++++++++ docs/migrations/2025-01-pgtrgm.sql | 9 + docs/migrations/README.md | 27 ++ package.json | 3 +- readme.md | 42 +++ src/prompts/qa.v2.prompts.ts | 17 +- src/repositories/post.repository.ts | 118 +++++++++ src/services/hybrid-search.service.ts | 104 ++++++++ src/services/qa.v2.service.ts | 31 ++- src/services/search-plan.service.ts | 39 ++- src/types/ai.v2.types.ts | 11 +- 12 files changed, 606 insertions(+), 295 deletions(-) create mode 100644 docs/api.md create mode 100644 docs/migrations/2025-01-pgtrgm.sql create mode 100644 docs/migrations/README.md create mode 100644 src/services/hybrid-search.service.ts diff --git a/TASK.md b/TASK.md index 6016664..4104ee2 100644 --- a/TASK.md +++ b/TASK.md @@ -1,293 +1,71 @@ -# v2 설계 및 작업 계획 (LLM 주도 SQL 기반 시맨틱 서치 → 응답 스트리밍) +## 하이브리드 서치 확장(질문 재작성 + 키워드) -## 목표 -- v1 API/흐름은 그대로 유지. -- v2에서 질의를 LLM이 “검색 계획(계획 JSON)”으로 변환 → 서버가 안전하게 실행하여 컨텍스트 확보 → 확보한 컨텍스트와 함께 LLM에 넘겨 최종 답변을 SSE로 스트리밍. +목표 +- 리콜 향상: 질문을 LLM이 재작성(rewrites)하고, 핵심 키워드를 생성하여 벡터+텍스트 양쪽에서 검색. +- 정밀/비용 제어: 재작성/키워드 개수를 제한하고, 융합 가중치로 결과를 안정적으로 선별. -## 적합성 평가 (요약) -- 장점 - - LLM이 질문 의도를 기반으로 동적 필터/가중치/Top-K/Threshold를 튜닝한 “검색 계획”을 생산하여 검색 적합도를 끌어올릴 수 있음. - - DB 스키마/비즈니스 제약을 반영해 검색 전략을 바꾸기 쉬움(프롬프트/제약 업데이트로 최적화 가능). -- 리스크 및 보완 - - “LLM이 직접 SQL 문자열”은 주입/스키마 일탈 위험. 안전하게 “계획(JSON)”을 생성하게 하고, 서버가 화이트리스트 템플릿/파라미터 바인딩으로 SQL을 구성하는 방식 권장. - - 벡터 연산 상 LLM은 임베딩을 생성할 수 없으므로, 서버가 질문 임베딩을 계산하여 파라미터로 주입해야 함. - - 실패/부적합 시 v1 RAG 경로로 폴백 필요. - -결론: “LLM → 검색 계획(JSON) → 서버가 안전 SQL 구성/실행 → 결과 컨텍스트로 최종 LLM”의 변형 설계가 적합하며 안전/유지보수에도 유리. - -## v2 전체 흐름 -1) 클라이언트가 `POST /ai/v2/ask`로 질문 전송(SSE 응답). -2) 서버가 LLM에 “검색 계획” 생성을 요청(계획 JSON; SQL 문자열 생성은 비권장, 옵션으로 지원). -3) 서버가 계획(JSON)을 검증/정규화 후 파라미터 바인딩으로 안전 SQL 실행(벡터 임베딩은 서버가 생성). -4) 검색 결과(문맥) 메타 이벤트 송신(`search_plan`, `search_result`). -5) 기존 v1과 동일한 형식의 최종 LLM 호출을 수행하고 `answer`를 스트리밍. -6) 종료 시 `end: [DONE]` 송신. - -## API 설계 -- Route: `POST /ai/v2/ask` (SSE) -- Auth: 기존 `authMiddleware` 재사용 -- Request Body (제안) - - `question: string` - - `user_id: string` - - `category_id?: number` - - `post_id?: number` (지정 시 해당 글 컨텍스트 중심) - - `speech_tone?: number` - - `llm?: { provider?: 'openai'|'gemini', model?: string, options?: { temperature?: number, top_p?: number, max_output_tokens?: number } }` -- SSE 이벤트(순서 권장) - - `event: search_plan` / `data: { ...계획JSON }` - - `event: search_sql` / `data: { templateId, paramsPreview }` (SQL 템플릿 경로 선택 시, 민감정보 제외 프리뷰) - - `event: search_result` / `data: [{ postId, postTitle }]` - - `event: exist_in_post_status` / `data: true|false` (v1과 동일) - - `event: context` / `data: [{ postId, postTitle }]` (v1과 동일) - - `event: answer` (여러 번) - - `event: end` / `data: [DONE]` - - `event: error` (오류 시) - -## LLM “검색 계획” 출력 스키마(권장) +Plan JSON 확장(초안) ```json { - "mode": "rag", // "rag" | "post" - "top_k": 5, // 1~20 범위 권장 - "threshold": 0.2, // 0.0~1.0, 유사도 하한 - "weights": { "chunk": 0.7, "title": 0.3 }, - "filters": { - "user_id": "", - "category_ids": [7], // 필요 시 - "post_id": 123, // mode=post 시 - "time": { // 시간/날짜 필터(선택) - "type": "relative", // "relative" | "absolute" | "month" | "year" | "quarter" - "unit": "day", // relative: "day" | "week" | "month" | "year" - "value": 30 // relative: 정수(양수) - // absolute: { from: ISO8601, to: ISO8601 } - // month: { month: 1..12, year?: number } - // year: { year: number } - // quarter: { quarter: 1..4, year?: number } - } - }, - "sort": "created_at_desc", // "created_at_desc" | "created_at_asc" - "limit": 5 // 결과 행 상한(서버 상한 적용) + "rewrites": ["..."], + "keywords": ["..."], + "hybrid": { "enabled": true, "alpha": 0.7, "max_rewrites": 4, "max_keywords": 8 } } ``` -- 서버에서 Zod로 검증 후 기본값/상한선 적용(top_k max 10 등), 불일치 시 안전 폴백값 적용. -- SQL 템플릿은 서버가 선택/생성하며, 파라미터는 모두 바인딩 처리. - -### 시간/날짜 필터 처리 규칙 -- 서버 표준화 단계에서만 절대 기간으로 변환(Asia/Seoul 기준 권장): - - relative: 현재 시각 기준으로 from/to 계산(예: 최근 30일) - - month: 연도 미지정 시 현재 연도 사용(예: “9월” → 올해 9월 1일 00:00:00 ~ 9월 말 23:59:59) - - quarter/year: 분기·연도 경계 계산 -- 검증 실패·모호 값: 날짜 필터 제외 혹은 기본 30일 적용 후 로그 남기고 폴백 -- 모든 상수값은 서버에서 범위 강제(limit<=20, top_k<=10, threshold 0..1, weights 합=1) - -## SQL 실행(안전 구성) -- 벡터 임베딩: 서버가 `createEmbeddings([question])`로 생성. -- 화이트리스트 템플릿(예시) - - 공통: 사용자/카테고리/소유권 필터를 CTE에서 먼저 적용. - - 스코어링: `(w_chunk * (1 - (pc.embedding <=> $embed))) + (w_title * (1 - (pte.embedding <=> $embed))) AS score` - - 임계치: `WHERE (1 - (pc.embedding <=> $embed)) > $threshold` - - 날짜 필터: `AND bp.created_at BETWEEN $from AND $to` (표준화된 절대 기간 사용) - - 정렬/상한: `ORDER BY score DESC` + 옵션 정렬(`created_at_desc|asc`) 병합, `LIMIT $limit` -- 모든 동적 값은 파라미터로 바인딩하고, 가중치/상한 등은 서버에서 범위 제한. - -## 최종 LLM 호출(응답 생성) -- v1의 `generate` 재사용(프로바이더/모델 동일 정책). -- 프롬프트: v1의 `qa.prompts`를 재사용하되, v2에서는 `search_result` 컨텍스트를 그대로 투입. -- v1과 동일한 `report_content_insufficient` 툴 전략 유지(필요 시). - -## 디렉터리/컴포넌트 추가 계획 -- `src/routes/ai.v2.routes.ts` — v2 라우터(`POST /ask`). -- `src/controllers/ai.v2.controller.ts` — SSE 헤더 설정, 서비스 호출/파이프. -- `src/services/search-plan.service.ts` — LLM에 검색 계획 요청 및 스키마 검증. -- `src/services/semantic-search.service.ts` — 계획(JSON)→SQL 템플릿 매핑 및 안전 실행. -- `src/services/qa.v2.service.ts` — 전체 orchestrator: 계획 생성→검색→컨텍스트 이벤트→최종 LLM 스트림. -- `src/prompts/qa.v2.prompts.ts` — 검색 계획 LLM 프롬프트(스키마/제약 포함). -- `src/types/ai.v2.types.ts` — 요청/계획/응답 타입/Zod 스키마. -- `src/routes/ai.routes.ts`는 그대로, `app.ts`에 `/ai/v2` 라우트 추가. - -## 프롬프트 가이드(검색 계획용, 요지) -- 역할: “블로그 시맨틱 검색 플래너”. -- 입력: 질문, 사용자 메타(user_id/category_id/post_id), 스키마/제약 요약, 기본값. -- 출력: 상기 계획 JSON 스키마만 생성(그 외 텍스트 금지). -- 제약: 값 범위(Top-K, threshold, weights 합=1), 허용된 필드만. -- 실패 시: 기본값으로 귀결되는 최소 계획을 출력하도록 유도. -- 시간/날짜 처리 지침: - - 시스템 메시지에 현재 날짜/시간과 타임존(예: Asia/Seoul)을 제공 - - “최근/이번 달/지난주/9월/작년 9월” 등 자연어 시간을 위 스키마의 time 필드로 구조화 - - 연도 미지정 시 현재 연도 가정, 모호하면 relative 30일로 유도 - -## 예시 -- “최근 글 보여줘” - - LLM 계획(JSON): `{ "mode": "rag", "top_k": 5, "threshold": 0.2, "weights": { "chunk": 0.7, "title": 0.3 }, "filters": { "user_id": "", "time": { "type": "relative", "unit": "day", "value": 30 } }, "sort": "created_at_desc", "limit": 5 }` - - 서버 표준화: `time → absolute { from: <30일 전 00:00+09:00>, to: <지금+09:00> }`, `limit=5` - -- “9월 글 2개” - - LLM 계획(JSON): `{ "mode": "rag", "top_k": 5, "threshold": 0.2, "weights": { "chunk": 0.7, "title": 0.3 }, "filters": { "user_id": "", "time": { "type": "month", "month": 9 } }, "sort": "created_at_desc", "limit": 2 }` - - 서버 표준화: `time → absolute { from: YYYY-09-01T00:00:00+09:00, to: YYYY-09-30T23:59:59+09:00 } (연도 미지정 시 올해)`, `limit=2` - -## 폴백 전략 -- 계획 JSON 검증 실패/LLM 오류 → v1 RAG 경로로 폴백. -- 검색 결과 0건 → v1과 동일하게 `exist_in_post_status=false` 전송 후, 부족 안내 규칙에 맞춰 답변 유도. - -## 텔레메트리/비용 -- `llm.request/llm.response` 로그 기존 그대로 사용. -- v2 전용 디버그 이벤트: `debug.plan.start`, `debug.plan.json`, `debug.plan.sql`, `debug.plan.result` 등. - -## 마이그레이션/DB -- 추가 테이블 불필요(기존 `post_chunks`, `post_title_embeddings` 재사용). -- 필요 시 뷰/인덱스 최적화 검토: `post_chunks(post_id, embedding)`, `post_title_embeddings(post_id, embedding)`. - -## 보안/안전장치 -- LLM은 “계획 JSON”만 생성(기본). SQL은 서버가 템플릿/파라미터 바인딩으로 생성. -- 만약 SQL 문자열 모드가 필요하면: 템플릿 ID+파라미터만 허용하거나, 정규식/AST로 화이트리스트 검증 후 실행. -- SSE에 민감 값(user_id/token 등) 노출 금지. - -## 단계별 작업(체크리스트) -1) 스켈레톤 - - [ ] 라우터/컨트롤러 v2 추가(`/ai/v2/ask`) - - [ ] SSE 헤더/에러 핸들링 공통화 -2) 검색 계획 - - [ ] `search-plan.service` + `qa.v2.prompts` + Zod 스키마 - - [ ] 계획 실패 시 v1 경로 폴백 -3) 검색 실행 - - [ ] 임베딩 생성(질문) - - [ ] 템플릿 기반 안전 SQL 실행 + 파라미터 바인딩 - - [ ] `search_plan`, `search_result` SSE 송신 -4) 최종 응답 스트림 - - [ ] v1 `generate` 재사용하여 LLM 스트림 - - [ ] v1과 동일한 `answer`/`end`/`error` 이벤트 유지 -5) 관측성/테스트 - - [ ] 디버그/비용 로그 연결 - - [ ] 단위 테스트: 계획 검증/템플릿 빌더/리포지토리 - - [ ] 통합 테스트: SSE 이벤트 순서/형식 - -## 수용 기준(AC) -- `/ai/v2/ask`가 SSE로 동작하고, `search_plan`→`search_result`→`answer` 순으로 이벤트가 수신된다. -- 계획 JSON이 범위를 벗어나거나 실패해도 서버는 안전 폴백으로 정상 응답을 스트리밍한다. -- SQL은 파라미터 바인딩으로만 구성되며, 화이트리스트 템플릿을 벗어난 질의가 실행되지 않는다. -- v1과 동일한 최종 응답 품질을 유지하거나 개선한다. - -## 검색 계획 LLM 프롬프트(초안) - -목표: LLM이 “검색 계획 JSON”만 출력하도록 강제하여 서버가 안전하게 SQL 템플릿을 선택·실행할 수 있도록 한다. 자연어 시간(최근/이번 달/지난주/9월/작년 9월 등)을 구조화하고, 정렬/상한/가중치/임계치 값 제약을 지키도록 한다. - -입력 변수(서버가 주입) -- now_utc, now_kst: 현재 시간(ISO8601) -- timezone: 문자열(예: Asia/Seoul) -- user_id: 요청자의 사용자 ID -- category_id?: 선택, 존재 시 조상 기준 필터 -- post_id?: 선택, 존재 시 mode=post 우선 -- defaults: { top_k: 5, threshold: 0.2, weights: { chunk: 0.7, title: 0.3 }, sort: created_at_desc, limit: 5 } -- question: 사용자 질문 원문 - -출력 형식(반드시 엄수) -- 오직 하나의 JSON 객체만 출력. 추가 텍스트/주석/마크다운/설명 금지. -- 키/값은 스키마 내 필드만 사용. 불필요 필드 생성 금지. - -스키마(재확인) -{ - "mode": "rag" | "post", - "top_k": number, // 1..10 - "threshold": number, // 0..1 - "weights": { "chunk": number, "title": number }, // 0..1, 합=1 - "filters": { - "user_id": string, - "category_ids"?: number[], // 제공 시 우선 적용(카테고리 조상 ID) - "post_id"?: number, // mode=post 시 필수 - "time"?: { // 하나만 선택 - "type": "relative" | "absolute" | "month" | "year" | "quarter", - // relative - "unit"?: "day" | "week" | "month" | "year", - "value"?: number, - // absolute - "from"?: string, // ISO8601 - "to"?: string, // ISO8601 - // month - "month"?: number, // 1..12, year 없으면 현재 연도 가정 - "year"?: number, - // quarter - "quarter"?: number // 1..4, year 없으면 현재 연도 가정 - } - }, - "sort": "created_at_desc" | "created_at_asc", - "limit": number // 1..20 -} - -규칙(핵심) -- post_id가 존재하면 mode="post"를 사용하고 filters.post_id를 설정. 그렇지 않으면 mode="rag". -- category_id가 있으면 filters.category_ids에 포함(단일 ID여도 배열 사용 허용). -- 가중치 합은 1이 되도록 조정(기본 chunk 0.7, title 0.3). 범위를 넘을 경우 기본값 사용. -- top_k는 1..10, limit는 1..20, threshold는 0..1 범위로 제한. 미지정 시 기본값 사용. -- 시간 표현 해석: - - “최근/요즘/최근 N개” → relative(단, “N개”는 limit=N으로 반영; 기간은 기본 30일 유지) - - “최근 N일/주/달/년” → relative + { unit, value } - - “이번 달/이번 주/올해/올해 9월” → month/year/quarter로 구조화 - - “9월”처럼 연도 미지정 → 현재 연도 가정 - - “지난주/지난달/작년” → relative 또는 해당 단위 기간으로 구조화 - - 모호하거나 충돌 시 time 생략(서버 기본 30일 적용 예상) -- 정렬: “최근/최신/새로운” 등은 created_at_desc. “오래된”은 created_at_asc. -- 질문에 “N개”가 있으면 limit=N 반영(상한 20). -- JSON 이외 어떤 텍스트도 출력하지 말 것. - -시스템 프롬프트 템플릿 -""" -You are a Search Plan Generator for a Korean blogging platform. -Your task is to read the user question and output ONLY a JSON object that defines a safe search plan. - -Context: -- now_utc: {now_utc} -- now_kst: {now_kst} -- timezone: {timezone} -- user_id: {user_id} -- category_id: {category_id} -- post_id: {post_id} -- defaults: {"top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"sort":"created_at_desc","limit":5} - -Rules: -1) Output ONLY a single JSON object matching the schema below. No extra text. -2) Respect bounds: top_k 1..10, limit 1..20, threshold 0..1, weights in [0,1] and sum to 1. -3) If post_id exists, use mode="post" and include filters.post_id; else mode="rag". -4) If category_id exists, include it in filters.category_ids. -5) Interpret Korean temporal phrases into filters.time using the provided timezone. - - “최근/최신/요즘”: prefer sort=created_at_desc. If a concrete period is given (e.g., 최근 30일), use relative. - - “이번 달/이번 주/올해/올해 9월”: use month/year/quarter forms. - - Month without year (e.g., “9월”): assume current year. - - “지난주/지난달/작년”: use the respective period. - - If ambiguous, omit time (server applies defaults). -6) If the question asks for N items (e.g., “N개”), set limit=N within bounds. -7) Keep the weights to defaults unless a clear need implies otherwise. - -Schema: -{SCHEMA_JSON} - -Question (Korean): -{question} - -Respond with ONLY the JSON object. No markdown, no explanation. -""" - -Few-shot 예시 -- Q: "최근 글 보여줘" - 출력: - {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","time":{"type":"relative","unit":"day","value":30}},"sort":"created_at_desc","limit":5} - -- Q: "9월 글 2개" - 출력: - {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","time":{"type":"month","month":9}},"sort":"created_at_desc","limit":2} - -- Q: "카테고리 7의 최신 글 3개" - 출력: - {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","category_ids":[7]},"sort":"created_at_desc","limit":3} - -- Q: "지난주에 쓴 포스트 중 추천해줘" - 출력: - {"mode":"rag","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","time":{"type":"relative","unit":"week","value":1}},"sort":"created_at_desc","limit":5} - -- Q: "이 포스트(123) 기준으로 답해줘" - 출력: - {"mode":"post","top_k":5,"threshold":0.2,"weights":{"chunk":0.7,"title":0.3},"filters":{"user_id":"{user_id}","post_id":123},"sort":"created_at_desc","limit":5} - -검증 포인트(서버 측) -- JSON 파싱 실패 → v1 폴백 -- 값 범위 초과 → 기본값/상한으로 교정 -- time 표준화(절대 from/to 변환), 타임존 적용 -- category_ids/post_id 소유권 확인 +- 기존 필드(`top_k`, `threshold`, `weights`, `filters.time`, `sort`, `limit`)와 공존. +- 서버에서 상한 강제(rewrites<=4, keywords<=8), 품질이 낮거나 중복인 항목 제거. + +프롬프트 가이드(확장) +- 역할: ‘검색 계획 + 재작성/키워드 생성’ +- 출력: 기존 계획 JSON + `rewrites[]`, `keywords[]`, `hybrid{}` +- 규칙: + - 불용/범용 단어(예: "글", "포스트", "블로그") 지양 + - 과도한 시기/주제 확장 금지(사용자 블로그 컨텍스트 벗어나지 않기) + - 중복/동의어 반복 최소화(문장 유사도 과다 시 제거) + +하이브리드 검색 파이프라인 +1) 멀티 벡터 검색: 원 질문 + rewrites 각각 임베딩 → pgvector Top-K 검색(합집합) +2) 텍스트 검색: keywords로 `post_chunks.content`/`blog_post.title` 텍스트 매칭 → Top-K 추출 +3) 랭킹 융합: 점수 정규화 후 `score = α·vec + (1-α)·text` 또는 RRF로 병합 → 상위 N 청크 선택 +4) 컨텍스트 구성: v1과 동일 프롬프트로 최종 LLM 호출 + +저장소/인덱스(제안) +- PostgreSQL 확장: `pg_trgm`(간단/범용) 또는 `tsvector`(정교) +- 1차안(pg_trgm) + - DDL: + - `CREATE EXTENSION IF NOT EXISTS pg_trgm;` + - `CREATE INDEX IF NOT EXISTS idx_pc_content_trgm ON post_chunks USING gin (content gin_trgm_ops);` + - `CREATE INDEX IF NOT EXISTS idx_bp_title_trgm ON blog_post USING gin (title gin_trgm_ops);` + - 질의: `similarity(content, $q) > $min OR content ILIKE ANY($patterns)` 등으로 text_score 계산 + +SSE 확장(선택) +- `event: rewrite` / `data: ["..."]` +- `event: keywords` / `data: ["..."]` +- `event: hybrid_result` / `data: [{ postId, postTitle }]` + +보안/안전 +- 재작성/키워드 출력 스키마 강제(JSON), 길이/개수 상한 +- 금칙어/민감어 필터(선택), 카테고리/기간 필터는 서버가 최종 결정 + +세부 구현 계획(하이브리드 서치) +1) 스키마/프롬프트 + - [ ] `src/types/ai.v2.types.ts`: Plan 스키마에 `rewrites[]`, `keywords[]`, `hybrid{enabled,alpha,max_rewrites,max_keywords}` 추가 + - [ ] `src/prompts/qa.v2.prompts.ts`: 프롬프트/JSON Schema에 확장 필드 반영 + few-shot 보강 +2) 플래너 서비스 + - [ ] `search-plan.service.ts`: 확장 필드 파싱/검증, 중복/불용어 필터링, 상한 강제 +3) 텍스트 검색 저장소 + - [ ] `post.repository.ts`: `textSearchChunksV2({ userId, query, keywords[], from?, to?, topK })` + - [ ] (옵션) DDL 문서화: pg_trgm 인덱스 생성 스크립트 추가 +4) 하이브리드 서비스 + - [ ] `hybrid-search.service.ts` 구현: 멀티 임베딩, 텍스트 검색, 정규화, α 융합/RRF, 상위 N 반환 +5) 오케스트레이션/이벤트 + - [ ] `qa.v2.service.ts`: plan.hybrid.enabled 시 하이브리드 경로 분기, (선택) `rewrite`/`keywords`/`hybrid_result` 송신 +6) 테스트/튜닝 + - [ ] 통합 테스트: 재작성/키워드 포함 질의에서 리콜↑ 확인 + - [ ] 가중치 α, Top-K 상수, 불용어/중복 필터 기준 튜닝 + - [ ] 0건/오류 폴백(v1 RAG) 검증 + +권장 단계적 도입 +- Phase 1: 스키마/프롬프트/하이브리드 파이프라인 구현(기본 α=0.7, rewrites<=3, keywords<=6) +- Phase 2: SSE 관측성 이벤트 추가, 품질 튜닝 +- Phase 3: 인덱스/성능 최적화, 불용어 사전/NER 보정 diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..4ed3103 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,148 @@ +# Bubblog AI API 문서 (v1 ~ v2) + +본 문서는 `/ai` (v1)와 `/ai/v2` (v2) 엔드포인트를 정리합니다. 서버는 Express 기반이며, `POST /ask` 류는 Server‑Sent Events(SSE)로 답변을 스트리밍합니다. + +## 기본 정보 +- Base Path + - v1: `/ai` + - v2: `/ai/v2` +- 인증 + - `POST /ask` 엔드포인트는 `Authorization: Bearer ` 필요 + - 임베딩 생성 엔드포인트는 인증 없이 사용 가능 +- 본문 형식: `application/json` +- SSE 수신: `Content-Type: text/event-stream` + - 이벤트명은 `event:` 라인으로, 데이터는 `data:` 라인으로 전송됩니다. + - 일반 텍스트 콘텐츠는 `event: answer`로 분할 전송되며, 종료 시 `event: end` + `data: [DONE]`가 송신됩니다. + +## v1 엔드포인트 (`/ai`) + +### GET `/ai/health` +- 인증: 불필요 +- 응답(200): `{ "status": "ok" }` + +### POST `/ai/embeddings/title` +- 인증: 불필요 +- 요청 Body + - `post_id`(number, required) + - `title`(string, required) +- 동작: 제목 임베딩 생성 후 저장 +- 응답(200): `{ "ok": true }` + +### POST `/ai/embeddings/content` +- 인증: 불필요 +- 요청 Body + - `post_id`(number, required) + - `content`(string, required) +- 동작: 본문을 약 512 토큰 단위로 중첩(50) 청킹 → 임베딩 생성/저장 +- 응답(200): `{ "post_id": number, "chunk_count": number, "success": true }` + +### POST `/ai/ask` (SSE) +- 인증: 필요 (`Authorization: Bearer `) +- 요청 Body + - `question`(string, required) + - `user_id`(string, required) + - `category_id`(number, optional) + - `post_id`(number, optional) — 지정 시 해당 글 컨텍스트에 국한하여 답변 + - `speech_tone`(number, optional) + - `-1`: 간결하고 명확한 말투(기본) + - `-2`: 해당 글의 말투를 최대한 모사 + - 양의 정수: 페르소나 ID(해당 유저의 등록된 페르소나 참조) + - `llm`(object, optional) + - `provider`: `openai` | `gemini` + - `model`: string (미지정 시 서버 기본값 사용) + - `options`: `{ temperature?, top_p?, max_output_tokens? }` +- SSE 이벤트(주요) + - `exist_in_post_status`: `true|false` — 관련 컨텍스트 존재 여부 + - `context`: `[ { postId, postTitle }, ... ]` — 검색/선택된 컨텍스트 요약 + - `answer`: 모델의 부분 응답 텍스트(여러 번 전송) + - `end`: 종료 시 `data: [DONE]` + - `error`: `{ code?, message }` — 예: `post_id`가 없거나 권한 없음(403), 없음(404) +- 예시(curl) + ```bash + curl -N \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -X POST http://localhost:3000/ai/ask \ + -d '{ + "question": "카테고리 A 관련 요약 해줘", + "user_id": "u_123", + "category_id": 1, + "speech_tone": -1 + }' + ``` + +## v2 엔드포인트 (`/ai/v2`) + +### GET `/ai/v2/health` +- 인증: 불필요 +- 응답(200): `{ "status": "ok", "v": "v2" }` + +### POST `/ai/v2/ask` (SSE) +- 인증: 필요 (`Authorization: Bearer `) +- 요청 Body (v1과 동일 스키마) + - `question`(string, required) + - `user_id`(string, required) + - `category_id`(number, optional) + - `post_id`(number, optional) + - `speech_tone`(number, optional) + - `llm`(object, optional) +- v2의 추가/변경 사항 + - 검색 계획 수립과 결과를 사전 이벤트로 투명하게 송신합니다. + - `post_id` 지정 시에도 동일한 형태의 사전 이벤트를 간략히 제공합니다. +- SSE 이벤트 순서(일반적인 흐름) + 1) `search_plan`: 검색 계획 정보 + - 예시 데이터(정규화된 계획): + ```json + { + "mode": "rag" | "post", + "top_k": 5, + "threshold": 0.2, + "weights": { "chunk": 0.7, "title": 0.3 }, + "filters": { "user_id": "u_123", "category_ids": [1], "post_id": 10?, "time": {...}? }, + "sort": "created_at_desc", + "limit": 5 + } + ``` + - `time` 필터는 `relative|absolute|month|year|quarter` 타입을 지원하며, 값은 ISO8601 또는 숫자 조합입니다. + 2) (하이브리드 사용 시) `rewrite`: `["재작성 질의", ...]` + 3) (하이브리드 사용 시) `keywords`: `["핵심 키워드", ...]` + 4) (하이브리드 사용 시) `hybrid_result`: `[ { postId, postTitle }, ... ]` — 융합 기준 상위 결과 요약 + 5) `search_result`: `[ { postId, postTitle }, ... ]` — 최종 컨텍스트 요약 + 6) `exist_in_post_status`: `true|false` + 7) `context`: `[ { postId, postTitle }, ... ]` — 모델 프롬프트에 사용되는 컨텍스트 요약 + 8) `answer` 스트리밍(여러 번) + 9) `end` with `data: [DONE]` + - 오류 시 `error`: `{ code?, message }` + +- 예시(curl) + ```bash + curl -N \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -X POST http://localhost:3000/ai/v2/ask \ + -d '{ + "question": "최근 한 달 블로그에서 프로젝트 X 관련 내용 요약", + "user_id": "u_123", + "category_id": 3, + "llm": { "provider": "openai", "options": { "temperature": 0.2 } } + }' + ``` + +## 참고 사항 +- `post_id`가 지정된 요청에서 해당 글이 존재하지 않거나, 글의 `user_id`가 요청 `user_id`와 다르면 SSE로 `error` 이벤트가 송신되고 스트림이 종료됩니다. +- v1/v2 모두 모델 응답 텍스트는 `answer` 이벤트로 분할 전송됩니다. 클라이언트는 누적하여 최종 답변을 구성해야 합니다. +- EventSource(브라우저) 사용 예시 + ```js + const es = new EventSource('/ai/v2/ask', { withCredentials: true }); // 헤더 인증이 필요한 경우 fetch/XHR 권장 + es.addEventListener('search_plan', (e) => console.log('plan', e.data)); + es.addEventListener('search_result', (e) => console.log('result', e.data)); + es.addEventListener('context', (e) => console.log('ctx', e.data)); + es.addEventListener('answer', (e) => renderAppend(JSON.parse(e.data))); + es.addEventListener('end', () => es.close()); + es.addEventListener('error', (e) => es.close()); + ``` + +## 요약 +- v1 `/ai/ask`: 컨텍스트 존재 여부와 요약(`exist_in_post_status`, `context`) 후 답변 스트리밍 +- v2 `/ai/v2/ask`: 위 흐름에 더해 검색 계획(`search_plan`)과 검색 결과 요약(`search_result`)을 추가로 제공 +- 임베딩 API(v1): 게시물 제목/본문 임베딩 생성 및 저장 diff --git a/docs/migrations/2025-01-pgtrgm.sql b/docs/migrations/2025-01-pgtrgm.sql new file mode 100644 index 0000000..168a891 --- /dev/null +++ b/docs/migrations/2025-01-pgtrgm.sql @@ -0,0 +1,9 @@ +-- Enable pg_trgm and add GIN indexes for text search on content and title +CREATE EXTENSION IF NOT EXISTS pg_trgm; + +CREATE INDEX IF NOT EXISTS idx_pc_content_trgm + ON post_chunks USING gin (content gin_trgm_ops); + +CREATE INDEX IF NOT EXISTS idx_bp_title_trgm + ON blog_post USING gin (title gin_trgm_ops); + diff --git a/docs/migrations/README.md b/docs/migrations/README.md new file mode 100644 index 0000000..3f4de87 --- /dev/null +++ b/docs/migrations/README.md @@ -0,0 +1,27 @@ +# Migrations Guide + +This folder contains SQL scripts for optional indexes/extensions used by the AI services. + +## Apply pg_trgm for text search + +File: `2025-01-pgtrgm.sql` + +Purpose: +- Enable `pg_trgm` extension and add GIN indexes on `post_chunks.content` and `blog_post.title` to accelerate partial/fuzzy text search used in hybrid search. + +Run (with `DATABASE_URL`): + +```bash +psql "$DATABASE_URL" -f docs/migrations/2025-01-pgtrgm.sql +``` + +Or inside `psql`: + +```sql +\i docs/migrations/2025-01-pgtrgm.sql +``` + +Notes: +- Indexes increase disk usage and write overhead; create only on columns used for text search. +- The extension must be installed once per database. + diff --git a/package.json b/package.json index 2911813..f4594d4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/server.ts", "build": "tsc", "start": "node dist/server.js", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "db:migrate:pgtrgm": "psql \"$DATABASE_URL\" -f docs/migrations/2025-01-pgtrgm.sql" }, "keywords": [], "author": "", diff --git a/readme.md b/readme.md index a656468..fa301f2 100644 --- a/readme.md +++ b/readme.md @@ -87,3 +87,45 @@ CREATE INDEX idx_post_title_embeddings_embedding ## 4. AI 서버 작동 ### `.env` 파일 작성 (루트 디렉토리 `BUBBLOG_AI`에 위치) + +--- + +## 5. 텍스트 검색 인덱스 (pg_trgm) + +하이브리드 검색의 키워드/부분일치 성능 향상을 위해 `pg_trgm` 확장 및 GIN 인덱스를 추가합니다. + +### 5.1 확장 및 인덱스 생성 스크립트 + +프로젝트에 제공된 스크립트를 사용하세요: + +`docs/migrations/2025-01-pgtrgm.sql` + +내용: + +```sql +CREATE EXTENSION IF NOT EXISTS pg_trgm; +CREATE INDEX IF NOT EXISTS idx_pc_content_trgm ON post_chunks USING gin (content gin_trgm_ops); +CREATE INDEX IF NOT EXISTS idx_bp_title_trgm ON blog_post USING gin (title gin_trgm_ops); +``` + +### 5.2 적용 방법 + +- 환경변수 `DATABASE_URL`이 설정된 경우: + +```bash +psql "$DATABASE_URL" -f docs/migrations/2025-01-pgtrgm.sql +``` + +- 또는 npm 스크립트 사용: + +```bash +npm run db:migrate:pgtrgm +``` + +- 또는 수동 실행(PostgreSQL 쉘 접속 후): + +```sql +\i docs/migrations/2025-01-pgtrgm.sql +``` + +주의: 인덱스는 쓰기 비용과 디스크 사용량을 증가시킵니다. 텍스트 검색에 사용하는 컬럼(`post_chunks.content`, `blog_post.title`)에만 생성하세요. diff --git a/src/prompts/qa.v2.prompts.ts b/src/prompts/qa.v2.prompts.ts index da03657..48ef58c 100644 --- a/src/prompts/qa.v2.prompts.ts +++ b/src/prompts/qa.v2.prompts.ts @@ -18,6 +18,19 @@ export const getSearchPlanSchemaJson = (): Record => ({ }, required: ['chunk', 'title'], }, + rewrites: { type: 'array', items: { type: 'string' } }, + keywords: { type: 'array', items: { type: 'string' } }, + hybrid: { + type: 'object', + additionalProperties: false, + properties: { + enabled: { type: 'boolean' }, + alpha: { type: 'number', minimum: 0, maximum: 1 }, + max_rewrites: { type: 'integer', minimum: 0, maximum: 4 }, + max_keywords: { type: 'integer', minimum: 0, maximum: 8 }, + }, + required: ['enabled', 'alpha', 'max_rewrites', 'max_keywords'], + }, filters: { type: 'object', additionalProperties: false, @@ -131,6 +144,9 @@ export const buildSearchPlanPrompt = (params: { '5) Interpret Korean temporal phrases into filters.time using the provided timezone. Month without year assumes current year.', '6) If the question asks for N items (e.g., “N개”), set limit=N within bounds.', '7) Keep weights to defaults unless a clear need implies otherwise.', + '8) When helpful for recall, set hybrid.enabled=true and generate concise rewrites (<= max_rewrites) and focused keywords (<= max_keywords).', + '9) Avoid stop/common words (예: "글", "포스트", "블로그", "소개", "정리"). Keep within the user context; avoid over-broad topics or time spans.', + '10) Remove near-duplicates: if rewrites/keywords are synonymous or highly similar, include only one.', '', `Schema: ${schemaHint}`, '', @@ -139,4 +155,3 @@ export const buildSearchPlanPrompt = (params: { 'Respond with ONLY the JSON object. No markdown, no explanation.', ].join('\n'); }; - diff --git a/src/repositories/post.repository.ts b/src/repositories/post.repository.ts index 6af3af3..1fdec4c 100644 --- a/src/repositories/post.repository.ts +++ b/src/repositories/post.repository.ts @@ -18,6 +18,13 @@ export interface SimilarChunk { similarityScore: number; } +export interface TextSearchHit { + postId: string; + postTitle: string; + postChunk: string; + textScore: number; +} + // ========= READ QUERIES ========= export const findPostById = async (postId: number): Promise => { const pool = getDb(); @@ -225,3 +232,114 @@ export const findSimilarChunksV2 = async (params: { similarityScore: row.similarity_score, })); }; + +export const textSearchChunksV2 = async (params: { + userId: string; + query?: string; + keywords?: string[]; + categoryId?: number; + from?: string; + to?: string; + topK?: number; + sort?: 'created_at_desc' | 'created_at_asc'; +}): Promise => { + const pool = getDb(); + const limit = Math.min(10, Math.max(1, params.topK ?? 5)); + + const values: any[] = []; + values.push(params.userId); + + const hasCategory = typeof params.categoryId === 'number'; + const hasTime = !!(params.from && params.to); + const hasQuery = !!params.query && params.query.trim().length > 0; + const keywords = (params.keywords || []).filter((k) => typeof k === 'string' && k.trim().length > 0); + + const withParts: string[] = []; + if (hasCategory) { + const catParam = values.length + 1; + withParts.push(` + category_ids AS ( + SELECT DISTINCT cc.descendant_id FROM category_closure cc WHERE cc.ancestor_id = $${catParam} + ), + filtered_posts AS ( + SELECT bp.id AS post_id, bp.title AS post_title, bp.created_at + FROM blog_post bp + WHERE bp.user_id = $1 AND bp.category_id IN (SELECT descendant_id FROM category_ids) + )`); + values.push(params.categoryId); + } else { + withParts.push(` + filtered_posts AS ( + SELECT id AS post_id, title AS post_title, created_at + FROM blog_post + WHERE user_id = $1 + )`); + } + + let base = ` + SELECT + fp.post_id, + fp.post_title, + pc.content AS post_chunk, + 0::float8 AS content_sim, + 0::float8 AS title_sim, + fp.created_at + FROM filtered_posts fp + JOIN post_chunks pc ON pc.post_id = fp.post_id + `; + if (hasQuery) { + const qParam = values.length + 1; + base = ` + SELECT + fp.post_id, + fp.post_title, + pc.content AS post_chunk, + COALESCE(similarity(pc.content, $${qParam}), 0) AS content_sim, + COALESCE(similarity(fp.post_title, $${qParam}), 0) AS title_sim, + fp.created_at + FROM filtered_posts fp + JOIN post_chunks pc ON pc.post_id = fp.post_id + `; + values.push(params.query); + } + + const whereParts: string[] = []; + if (hasTime) { + const fromParam = values.length + 1; + const toParam = values.length + 2; + whereParts.push(`fp.created_at BETWEEN $${fromParam} AND $${toParam}`); + values.push(params.from, params.to); + } + + const likePatterns: string[] = []; + for (const k of keywords) { + likePatterns.push(`%${k}%`); + } + if (likePatterns.length > 0) { + const arrParam = values.length + 1; + whereParts.push(`(pc.content ILIKE ANY($${arrParam}) OR fp.post_title ILIKE ANY($${arrParam}))`); + values.push(likePatterns); + } + + const whereSql = whereParts.length > 0 ? `WHERE ${whereParts.join(' AND ')}` : ''; + + let orderBy = 'content_sim DESC'; + if (params.sort === 'created_at_desc') orderBy = 'content_sim DESC, fp.created_at DESC'; + if (params.sort === 'created_at_asc') orderBy = 'content_sim DESC, fp.created_at ASC'; + + const limitParam = values.length + 1; + const sql = `${withParts.length > 0 ? 'WITH ' + withParts.join(',\n') : ''} +${base} +${whereSql} +ORDER BY ${orderBy} +LIMIT $${limitParam}`; + values.push(limit); + + const { rows } = await pool.query(sql, values); + return rows.map((row) => ({ + postId: row.post_id, + postTitle: row.post_title, + postChunk: row.post_chunk, + textScore: Math.max(Number(row.content_sim) || 0, Number(row.title_sim) || 0), + })); +}; diff --git a/src/services/hybrid-search.service.ts b/src/services/hybrid-search.service.ts new file mode 100644 index 0000000..592e723 --- /dev/null +++ b/src/services/hybrid-search.service.ts @@ -0,0 +1,104 @@ +import { createEmbeddings } from './embedding.service'; +import * as postRepository from '../repositories/post.repository'; +import { SearchPlan } from '../types/ai.v2.types'; + +export type HybridSearchResult = { + postId: string; + postTitle: string; + postChunk: string; + similarityScore: number; +}[]; + +type Candidate = { + postId: string; + postTitle: string; + postChunk: string; + vecScore?: number; + textScore?: number; +}; + +export const runHybridSearch = async ( + question: string, + userId: string, + plan: SearchPlan +): Promise => { + const queries = [question, ...((plan.rewrites as string[]) || [])]; + const alpha = Math.max(0, Math.min(1, (plan.hybrid as any)?.alpha ?? 0.7)); + + const from = (plan.filters as any)?.time?.type === 'absolute' ? (plan.filters as any).time.from : undefined; + const to = (plan.filters as any)?.time?.type === 'absolute' ? (plan.filters as any).time.to : undefined; + const categoryId = (plan.filters as any)?.category_ids?.[0]; + + const embeddings = await createEmbeddings(queries); + + const byKey = new Map(); + + for (let i = 0; i < embeddings.length; i++) { + const emb = embeddings[i]; + const rows = await postRepository.findSimilarChunksV2({ + userId, + embedding: emb, + categoryId, + from, + to, + threshold: plan.threshold, + topK: plan.top_k, + weights: plan.weights, + sort: plan.sort, + }); + for (const r of rows) { + const key = `${r.postId}:${r.postChunk}`; + const prev = byKey.get(key); + const curVec = Number(r.similarityScore) || 0; + if (!prev) { + byKey.set(key, { postId: r.postId, postTitle: r.postTitle, postChunk: r.postChunk, vecScore: curVec }); + } else { + prev.vecScore = Math.max(prev.vecScore || 0, curVec); + } + } + } + + const textRows = await postRepository.textSearchChunksV2({ + userId, + query: question, + keywords: (plan.keywords as string[]) || [], + categoryId, + from, + to, + topK: plan.top_k, + sort: plan.sort, + }); + for (const r of textRows) { + const key = `${r.postId}:${r.postChunk}`; + const prev = byKey.get(key); + const curText = Number(r.textScore) || 0; + if (!prev) { + byKey.set(key, { postId: r.postId, postTitle: r.postTitle, postChunk: r.postChunk, textScore: curText }); + } else { + prev.textScore = Math.max(prev.textScore || 0, curText); + } + } + + const list = Array.from(byKey.values()); + const vecVals = list.map((c) => c.vecScore || 0); + const textVals = list.map((c) => c.textScore || 0); + const vMin = Math.min(...vecVals, 0); + const vMax = Math.max(...vecVals, 0); + const tMin = Math.min(...textVals, 0); + const tMax = Math.max(...textVals, 0); + + const norm = (v: number, lo: number, hi: number) => (hi > lo ? (v - lo) / (hi - lo) : 0); + + const fused = list + .map((c) => { + const v = norm(c.vecScore || 0, vMin, vMax); + const t = norm(c.textScore || 0, tMin, tMax); + const score = alpha * v + (1 - alpha) * t; + return { postId: c.postId, postTitle: c.postTitle, postChunk: c.postChunk, similarityScore: score }; + }) + .sort((a, b) => b.similarityScore - a.similarityScore) + .slice(0, Math.min(10, Math.max(1, plan.top_k || 5))); + + return fused; +}; + diff --git a/src/services/qa.v2.service.ts b/src/services/qa.v2.service.ts index ef2db41..fd5b459 100644 --- a/src/services/qa.v2.service.ts +++ b/src/services/qa.v2.service.ts @@ -129,13 +129,36 @@ export const answerStreamV2 = async ( }, ]; } else { - const plan = planPair.normalized; + const plan: any = planPair.normalized; stream.write(`event: search_plan\n`); stream.write(`data: ${JSON.stringify(plan)}\n\n`); - // Execute semantic search per plan - const rows = await runSemanticSearch(question, userId, plan); - // v1과 동일하게: 청크 Top-K를 그대로 사용(포스트 단위 dedupe/limit 미적용) + let rows: { postId: string; postTitle: string; postChunk: string; similarityScore: number }[] = []; + if (plan.hybrid?.enabled) { + if (Array.isArray(plan.rewrites) && plan.rewrites.length > 0) { + stream.write(`event: rewrite\n`); + stream.write(`data: ${JSON.stringify(plan.rewrites)}\n\n`); + } + if (Array.isArray(plan.keywords) && plan.keywords.length > 0) { + stream.write(`event: keywords\n`); + stream.write(`data: ${JSON.stringify(plan.keywords)}\n\n`); + } + rows = await (await import('./hybrid-search.service')).runHybridSearch( + question, + userId, + plan + ); + const hybridContext = rows.map((r) => ({ postId: r.postId, postTitle: r.postTitle })); + stream.write(`event: hybrid_result\n`); + stream.write(`data: ${JSON.stringify(hybridContext)}\n\n`); + + if (!rows.length) { + rows = await runSemanticSearch(question, userId, plan); + } + } else { + rows = await runSemanticSearch(question, userId, plan); + } + const context = rows.map((r) => ({ postId: r.postId, postTitle: r.postTitle })); stream.write(`event: search_result\n`); stream.write(`data: ${JSON.stringify(context)}\n\n`); diff --git a/src/services/search-plan.service.ts b/src/services/search-plan.service.ts index f2861da..c26ac5a 100644 --- a/src/services/search-plan.service.ts +++ b/src/services/search-plan.service.ts @@ -66,6 +66,34 @@ export const generateSearchPlan = async ( // Normalize time range to absolute if provided let normPlan: SearchPlan = { ...plan, weights }; + + const clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n)); + + const stopwords = new Set([ + '글', + '포스트', + '블로그', + '소개', + '정리', + '내용', + '최신', + '최근', + '정보', + ]); + + const cleanList = (arr: string[] | undefined, max: number) => { + const uniq = new Set(); + for (const s of arr || []) { + const t = String(s || '').trim(); + if (!t) continue; + if (t.length < 2) continue; + if (stopwords.has(t)) continue; + const key = t.toLowerCase(); + if (uniq.has(key)) continue; + uniq.add(key); + } + return Array.from(uniq).slice(0, max); + }; if (plan.filters?.time) { const abs = toAbsoluteRangeKst(plan.filters.time as any, now); if (abs) { @@ -84,6 +112,16 @@ export const generateSearchPlan = async ( normPlan.top_k = Math.min(10, Math.max(1, normPlan.top_k || 5)); normPlan.limit = Math.min(20, Math.max(1, normPlan.limit || 5)); normPlan.threshold = Math.min(1, Math.max(0, normPlan.threshold ?? 0.2)); + const maxRewrites = clamp(plan.hybrid?.max_rewrites ?? 3, 0, 4); + const maxKeywords = clamp(plan.hybrid?.max_keywords ?? 6, 0, 8); + normPlan.hybrid = { + enabled: !!plan.hybrid?.enabled, + alpha: clamp(plan.hybrid?.alpha ?? 0.7, 0, 1), + max_rewrites: maxRewrites, + max_keywords: maxKeywords, + } as any; + normPlan.rewrites = cleanList(plan.rewrites, maxRewrites) as any; + normPlan.keywords = cleanList(plan.keywords, maxKeywords) as any; if (!normPlan.mode) normPlan.mode = (ctx.post_id ? 'post' : 'rag') as any; if (ctx.category_id && !normPlan.filters.category_ids) normPlan.filters.category_ids = [ctx.category_id]; if (ctx.post_id) { @@ -99,4 +137,3 @@ export const generateSearchPlan = async ( return null; } }; - diff --git a/src/types/ai.v2.types.ts b/src/types/ai.v2.types.ts index f10debb..1027ba4 100644 --- a/src/types/ai.v2.types.ts +++ b/src/types/ai.v2.types.ts @@ -36,6 +36,16 @@ export const planSchema = z.object({ weights: z .object({ chunk: z.number().min(0).max(1), title: z.number().min(0).max(1) }) .default({ chunk: 0.7, title: 0.3 }), + rewrites: z.array(z.string()).default([]), + keywords: z.array(z.string()).default([]), + hybrid: z + .object({ + enabled: z.boolean().default(false), + alpha: z.number().min(0).max(1).default(0.7), + max_rewrites: z.number().int().min(0).max(4).default(3), + max_keywords: z.number().int().min(0).max(8).default(6), + }) + .default({ enabled: false, alpha: 0.7, max_rewrites: 3, max_keywords: 6 }), filters: z .object({ user_id: z.string(), @@ -76,4 +86,3 @@ export const askV2Schema = z.object({ }); export type AskV2Request = z.infer['body']; - From 4915fee496f7ff76b2fcf6b6cf73694fa64cc81f Mon Sep 17 00:00:00 2001 From: chan000518 Date: Wed, 8 Oct 2025 16:15:52 +0900 Subject: [PATCH 09/14] =?UTF-8?q?=F0=9F=90=9B=20=EA=B8=80=20=EC=86=8C?= =?UTF-8?q?=EC=9C=A0=EA=B6=8C=20=EB=B0=8F=20=EC=9E=84=ED=8F=AC=ED=8A=B8=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api.md | 3 +- docs/reports/REPORT-askv2.md | 185 ++++++++++++++++------------ src/prompts/qa.v2.prompts.ts | 8 +- src/repositories/post.repository.ts | 3 +- src/services/qa.service.ts | 14 ++- src/services/qa.v2.service.ts | 19 +-- 6 files changed, 137 insertions(+), 95 deletions(-) diff --git a/docs/api.md b/docs/api.md index 4ed3103..a61eb38 100644 --- a/docs/api.md +++ b/docs/api.md @@ -129,7 +129,8 @@ ``` ## 참고 사항 -- `post_id`가 지정된 요청에서 해당 글이 존재하지 않거나, 글의 `user_id`가 요청 `user_id`와 다르면 SSE로 `error` 이벤트가 송신되고 스트림이 종료됩니다. +- `post_id`가 지정된 요청에서 해당 글이 존재하지 않으면 SSE로 `error` 이벤트(404)가 송신되고 스트림이 종료됩니다. +- `post.is_public`이 `false`인 글은 요청 `user_id`가 글 소유자와 다르면 `error` 이벤트(403)로 차단됩니다. `post.is_public`이 `true`면 누구나 접근 가능합니다. - v1/v2 모두 모델 응답 텍스트는 `answer` 이벤트로 분할 전송됩니다. 클라이언트는 누적하여 최종 답변을 구성해야 합니다. - EventSource(브라우저) 사용 예시 ```js diff --git a/docs/reports/REPORT-askv2.md b/docs/reports/REPORT-askv2.md index 6bc5641..ea77fc2 100644 --- a/docs/reports/REPORT-askv2.md +++ b/docs/reports/REPORT-askv2.md @@ -1,95 +1,124 @@ -# 보고서: /ai/v2/ask 구현 내역과 구조 +# 보고서: /ai/v2/ask — 동작 방식, 하이브리드 서치, 검색 계획 ## 1) 개요 -- 목적: v1의 고정형 RAG 흐름을 개선하기 위해, 사용자의 질문을 LLM이 “검색 계획(JSON)”으로 구조화 → 서버가 안전한 시맨틱 SQL 검색 수행 → v1과 동일한 방식으로 최종 답변을 SSE로 스트리밍하는 v2 파이프라인을 추가했습니다. -- 상태: v1은 수정하지 않고 유지. v2 엔드포인트 `POST /ai/v2/ask`(SSE) 신규 추가 및 전체 흐름 구현 완료. +- 목표: v1의 고정형 RAG 한계를 보완. “검색 계획(JSON)”을 LLM이 생성 → 서버가 안전하게 표준화/검증 → 시맨틱/하이브리드 검색 수행 → 최종 답변을 SSE로 스트리밍. +- 상태: `POST /ai/v2/ask`(SSE) 운영 중. v1은 유지하며, v2에서 계획 기반 검색·관측성을 추가. -## 2) v1의 주요 문제점(한계) -- 고정 파라미터 검색: 임계치(0.2), LIMIT(5)가 고정되어 질문 의도(기간/정렬/가중치/갯수 등) 반영이 어려움. -- 시간/정렬 표현 미흡: “최근 글/9월 글/지난주” 등 자연어 시간 요구를 반영할 수 없음. -- 컨텍스트 제어 부족: LLM 입력 컨텍스트의 개수/범위를 질문 의도나 비용/토큰 예산에 맞춰 유연하게 조절하기 어려움. -- 관측성 부족: 어떤 기준/전략으로 검색되었는지(계획/파라미터)를 클라이언트에서 파악하기 어려움. -- 보안/안전 제약: 프롬프트/검색 로직이 단순해, 미래에 복잡한 동적 쿼리로 확장 시 안전한 경계(화이트리스트/스키마 강제)가 필요. +## 2) v1의 한계와 v2가 해결한 점 +- 고정 파라미터 문제 → 동적 계획 + - v1: 임계치(0.2), LIMIT(5), 가중치(0.7/0.3) 고정. + - v2: `top_k`, `threshold`, `weights`, `sort`, `limit`을 계획으로 동적 제어(서버가 범위 강제). +- 시간/정렬 의도 미흡 → 자연어 시간 해석 + - v1: “최근/지난주/9월/작년” 반영 불가. + - v2: `filters.time`에 상대/월/분기/연도 표현 → `KST 절대범위(from/to)`로 변환해 쿼리에 반영. +- 컨텍스트 제어/비용 → 토큰 예산 컨트롤 + - v1: 컨텍스트 폭 조절 한계. + - v2: `top_k`(리콜 폭), `limit`(노출 개수; 현재 미적용)로 조절 가능. 향후 dedupe/limit 적용 예정. +- 관측성 부족 → SSE 메타 이벤트 확장 + - v1: 검색 근거 불투명. + - v2: `search_plan`, `rewrite`, `keywords`, `hybrid_result`, `search_result` 등으로 의사결정 가시화. +- 검색 방식 단일 → 하이브리드 도입 + - v1: 임베딩 기반 RAG만. + - v2: 벡터+텍스트 하이브리드 융합으로 재현율/정확도 개선. ![alt text](../structureDiagram/askV1-structure.png) -## 3) v2의 도입/해결 방안과 가능해진 것 -- LLM 검색 계획(JSON) 도입 - - OpenAI Responses API + JSON Schema 강제 → LLM이 오직 스키마에 맞는 JSON만 출력. - - 계획 항목: `mode`(rag/post), `top_k`, `threshold`, `weights{chunk,title}`, `filters{user_id, category_ids?, post_id?, time?}`, `sort`, `limit`. -- 시간/정렬 의도 반영 - - 자연어 시간(최근/이번 달/지난주/9월/작년 등)을 `filters.time`에 구조화. - - 서버는 KST 기준 절대 기간으로 표준화(from/to) 후 안전 SQL에 반영. - - 최신순/오래된순 정렬(`sort`) 지원. -- 안전한 서버 표준화/실행 - - Zod로 계획 검증 + 범위 강제(top_k 1..10, limit 1..20, threshold 0..1, weights 합=1). - - SQL은 화이트리스트 템플릿 + 파라미터 바인딩으로만 구성(문자열 결합 금지). -- 관측성 강화 - - SSE 메타 이벤트(`search_plan`, `search_result`)를 추가해, 검색 계획과 결과 요약을 클라이언트에 투명하게 제공. -- 컨텍스트 최적화 - - 청크 검색 후보(top_k)를 넓게 가져온 뒤, 포스트 단위 중복 제거 + `limit`개까지만 컨텍스트/노출로 사용(토큰/비용 관리). -- 폴백 안전성 - - 계획 생성 실패 시 v1 RAG 경로로 자동 폴백하여 기능 연속성 보장. -![alt text](../structureDiagram/askV2-structure.png) -## 4) v2 구조(파일과 역할) -- 라우팅/컨트롤러 - - `src/routes/ai.v2.routes.ts`: `/ai/v2/ask` SSE 라우트. - - `src/controllers/ai.v2.controller.ts`: SSE 헤더 설정, 서비스 호출/파이프. - - `src/app.ts`: `/ai/v2` 마운트. -- 플래너 LLM & 타입 - - `src/types/ai.v2.types.ts`: v2 요청/검색 계획 Zod 스키마. - - `src/prompts/qa.v2.prompts.ts`: 검색 계획 프롬프트/JSON 스키마. - - `src/services/search-plan.service.ts`: Responses API 호출 → 계획 JSON 검증/정규화. -- 시간 표준화 - - `src/utils/time.ts`: KST 기준 상대/월/분기/연도 → 절대기간 변환. -- 시맨틱 서치 - - `src/services/semantic-search.service.ts`: 질문 임베딩 생성 → 동적 저장소 호출. - - `src/repositories/post.repository.ts`: `findSimilarChunksV2`(가중치/임계치/기간/정렬/topK 파라미터 반영). -- 오케스트레이션 - - `src/services/qa.v2.service.ts`: `search_plan`→`search_result` 발행, v1 프롬프트 재사용으로 최종 LLM 스트림 중계. +## 3) 검색 계획(Planner)과 안전 표준화 +- 스키마(`src/types/ai.v2.types.ts`) + - `mode`: `rag|post` + - `top_k`(1..10), `threshold`(0..1), `weights`(`chunk`,`title`) + - `filters`: `{ user_id, category_ids?, post_id?, time? }` + - `sort`: `created_at_desc|created_at_asc`, `limit`(1..20) + - `hybrid`: `{ enabled, alpha, max_rewrites, max_keywords }`, `rewrites`: string[], `keywords`: string[] +- 프롬프트 규칙 강화(`src/prompts/qa.v2.prompts.ts`) + - 서버 제공 필터(`user_id`, `category_id`, `post_id`)는 고정(FIXED)이며 변경 금지. + - 플래너는 `top_k`, `threshold`, `filters.time`, `sort`, `limit`, `hybrid`, `rewrites`, `keywords`만 결정. +- 생성/정규화(`src/services/search-plan.service.ts`) + - OpenAI Responses API(JSON Schema strict) → Zod 파싱/검증. + - 값 범위 강제, 가중치 합 1로 정규화, 불용어/중복 제거로 `rewrites`/`keywords` 정제. + - 시간 필터를 `KST 절대범위`로 변환(`src/utils/time.ts`). + - 카테고리/포스트 ID는 서버가 최종 주입(정합성 보장). 실패 시 v1 RAG 폴백. + +## 4) 검색 엔진: 시맨틱 + 하이브리드 +- 시맨틱(`src/services/semantic-search.service.ts` → `findSimilarChunksV2`) + - 입력: 질문 임베딩, `threshold/top_k/weights/sort`, 카테고리/시간 필터. + - 점수: `w_chunk*(1 - chunk_dist) + w_title*(1 - title_dist)`. + - SQL: 파라미터 바인딩/화이트리스트 템플릿. +- 하이브리드(`src/services/hybrid-search.service.ts`) + - 입력: 원 질문 + `rewrites`(재작성), `keywords`(키워드), `alpha`. + - 벡터 경로: 각 query 임베딩 → 시맨틱 검색 → 동일 청크는 최대 vecScore로 병합. + - 텍스트 경로: ILIKE/텍스트 유사도 기반 `textSearchChunksV2` → 최대 textScore로 병합. + - 정규화/융합: min-max 정규화 후 `score = alpha*vec + (1-alpha)*text`로 랭킹 → 상위 `top_k` 반환. + - SSE: `rewrite`, `keywords`, `hybrid_result` 이벤트로 중간 산출물/요약 제공. +- 폴백: 하이브리드 결과가 비어있으면 시맨틱 경로로 재시도. -## 5) v2 요청→응답 흐름 -1) 클라이언트: `POST /ai/v2/ask` (JWT 필요) -2) 컨트롤러: SSE 헤더 설정 → `answerStreamV2` 호출 -3) post 모드(post_id 존재): 소유자 검증 → 계획/결과 이벤트 발행 → 본문 컨텍스트로 메시지 구성 → 답변 스트림 -4) rag 모드: 플래너 LLM으로 계획 생성 → Zod 검증/시간 표준화 → `search_plan` 이벤트 발행 → 시맨틱 서치 실행 → `search_result`/`exist_in_post_status`/`context` 발행 → RAG 프롬프트 구성 → 답변 스트림 -5) 공통: `src/llm` 레이어를 통해 `answer` 청크 스트리밍, 종료 시 `end` 이벤트 +![alt text](../structureDiagram/askV2-structure.png) -SSE 이벤트 순서 -- `search_plan` → `search_result` → `exist_in_post_status` → `context` → `answer`* → `end` -- 오류 시: `error` +## 5) 파이프라인(SSE 이벤트)과 모드 +- 컨트롤러/오케스트레이터 + - `src/controllers/ai.v2.controller.ts`: SSE 헤더 설정, 서비스 파이프. + - `src/services/qa.v2.service.ts`: 계획 생성→검색→LLM 호출까지 오케스트레이션. +- post 모드(post_id 존재) + - 접근 정책: `post.is_public=false`면 소유자만(403), `true`면 공개. 미존재 404. + - 이벤트: `search_plan`(합성) → `search_result` → `exist_in_post_status:true` → `context` → `answer`* → `end`. + - 컨텍스트: 단일 글 본문(가공) 사용. RAG/하이브리드 미사용. +- rag/하이브리드 모드 + - 일반 흐름: + 1) `search_plan`(정규화된 계획) + 2) `rewrite`(선택) + 3) `keywords`(선택) + 4) `hybrid_result`(선택) + 5) `search_result` + 6) `exist_in_post_status` + 7) `context` + 8) `answer`* → `end` + - 오류 시: `error` 송신. -## 6) 모델/설정 -- 기본 LLM: `openai/gpt-5-mini`(요청 `llm` 또는 `CHAT_MODEL`로 변경 가능) -- 임베딩: `text-embedding-3-small` -- Gemini: 응답 스트림은 지원(계획 LLM은 현재 OpenAI 사용) +## 6) LLM/비용/프로바이더 +- 기본 모델: `openai/gpt-5-mini`(환경변수로 변경 가능), 임베딩: `text-embedding-3-small`. +- OpenAI: GPT‑5 Responses API 스트리밍 우선, 실패 시 논스트림/Chat Completions 폴백. 툴콜 인자도 `answer` 청크로 송신. +- Gemini: 현재 논스트림 결과를 SSE 청크로 전송. +- 비용 로깅: 프롬프트/완료 토큰, 추정 비용 로깅(`src/llm/index.ts`). -## 7) 보안/안전 -- 계획 출력은 JSON Schema로 제한, 서버에서 Zod 검증 및 값 범위 강제. -- SQL은 파라미터 바인딩/화이트리스트 템플릿만 사용. -- post 모드에서 소유권 체크. -- SSE에는 민감정보 제외(제목/ID 등만 노출). +## 7) 보안·정합성 +- JSON Schema + Zod 검증 + 범위 강제. +- 서버가 `user_id/category_id/post_id` 필터를 최종 강제(LLM 변조 무력화). +- SQL 파라미터 바인딩/템플릿 화이트리스트. +- SSE 데이터 최소화(제목/ID/요약만). +- post 모드 접근 제어: `is_public` 조건 기반. -## 8) 현재 동작과 향후 확장 +## 8) 현재 동작과 한계(향후 과제) - 현재 - - `top_k`: 청크 단위 후보 개수(리콜 폭)로 SQL LIMIT 적용(v1과 동일). - - `limit`: 현재는 미적용(v1과 동일 동작 유지). 컨텍스트는 청크 Top-K를 그대로 사용하며, 포스트 단위 중복 제거도 하지 않음. - - `sort`: 유사도 우선 + 최신순/오래된순 보조 정렬. + - `top_k`로 리콜 폭 제어, 시맨틱/하이브리드 모두 적용. + - `limit`은 계획에 있으나 컨텍스트 축약에는 아직 미적용(Top‑K 청크를 그대로 사용). + - 청크 기준 컨텍스트로 포스트 중복 가능. + - 카테고리 배열은 첫 항목만 반영. - 향후 - - `limit` 적용을 재도입하여 컨텍스트 길이/비용 최적화(옵션화 가능). - - 포스트별 상위 N청크 추출(윈도우 함수) 설계로 깊이/다양성 균형. - - `search_sql` 이벤트(템플릿 ID + 파라미터 프리뷰)로 관측성 강화. - - 계획 LLM의 프로바이더 확장(Gemini) 및 프롬프트 튜닝 고도화. + - 포스트 단위 dedupe + `limit` 적용(윈도우 함수 등)으로 비용/다양성 균형. + - 다중 카테고리 필터 완전 반영. + - `search_sql`/`search_debug` 이벤트로 쿼리/파라미터 노출. + - 텍스트 경로 고도화(순위 함수/전처리/키워드 확장), 모델 프로바이더 다양화. -## 9) 사용 예시 -- 요청 바디 예시 -``` +## 9) 파일 맵(핵심) +- 라우트/컨트롤러: `src/routes/ai.v2.routes.ts`, `src/controllers/ai.v2.controller.ts`, `src/app.ts` +- 플래너/타입/프롬프트: `src/services/search-plan.service.ts`, `src/types/ai.v2.types.ts`, `src/prompts/qa.v2.prompts.ts` +- 시간 유틸: `src/utils/time.ts` +- 검색: `src/services/semantic-search.service.ts`, `src/services/hybrid-search.service.ts`, `src/repositories/post.repository.ts` +- 오케스트레이션: `src/services/qa.v2.service.ts` +- LLM: `src/llm/*` + +## 10) 예시 +- 요청 +```json { - "question": "9월 글 2개만 보여줘", - "user_id": "", - "speech_tone": -1, - "llm": { "provider": "openai", "model": "gpt-5-mini" } + "question": "지난달 프로젝트 X 관련 핵심만 3개 보여줘", + "user_id": "u_123", + "category_id": 3, + "llm": { "provider": "openai", "options": { "temperature": 0.2 } } } ``` -- 기대 SSE 순서: `search_plan` → `search_result` → `exist_in_post_status` → `context` → `answer*` → `end` - +- 이벤트 예시 + - `search_plan`(rag, time=지난달, top_k/threshold/weights/sort/limit/hybrid 포함) + - `rewrite`/`keywords`(선택) + - `hybrid_result`(선택) + - `search_result` → `exist_in_post_status` → `context` → `answer`* → `end` diff --git a/src/prompts/qa.v2.prompts.ts b/src/prompts/qa.v2.prompts.ts index 48ef58c..ef6c0f9 100644 --- a/src/prompts/qa.v2.prompts.ts +++ b/src/prompts/qa.v2.prompts.ts @@ -139,8 +139,12 @@ export const buildSearchPlanPrompt = (params: { 'Rules:', '1) Output ONLY a single JSON object matching the schema. No extra text.', '2) Respect bounds: top_k 1..10, limit 1..20, threshold 0..1, weights in [0,1] and sum to 1.', - '3) If post_id exists, use mode="post" and include filters.post_id; else mode="rag".', - '4) If category_id exists, include it in filters.category_ids.', + '3) Server-provided filters are FIXED constraints. Do NOT change or omit them:', + ' - Always keep filters.user_id as provided (unchanged).', + ' - If category_id exists, include ONLY that id in filters.category_ids (no additions/removals).', + ' - If post_id exists, include exactly that as filters.post_id (no substitutions).', + ' - Your job is to decide top_k, threshold, filters.time, sort, and limit only; do NOT invent other filters.', + '4) Mode must follow constraints: if post_id exists, use mode="post"; otherwise use mode="rag".', '5) Interpret Korean temporal phrases into filters.time using the provided timezone. Month without year assumes current year.', '6) If the question asks for N items (e.g., “N개”), set limit=N within bounds.', '7) Keep weights to defaults unless a clear need implies otherwise.', diff --git a/src/repositories/post.repository.ts b/src/repositories/post.repository.ts index 1fdec4c..eade868 100644 --- a/src/repositories/post.repository.ts +++ b/src/repositories/post.repository.ts @@ -9,6 +9,7 @@ export interface Post { tags: string[]; created_at: string; user_id: string; + is_public:boolean; } export interface SimilarChunk { @@ -29,7 +30,7 @@ export interface TextSearchHit { export const findPostById = async (postId: number): Promise => { const pool = getDb(); const { rows } = await pool.query( - 'SELECT id, title, content, tags, created_at, user_id FROM blog_post WHERE id = $1', + 'SELECT id, title, content, tags, created_at, user_id, is_public FROM blog_post WHERE id = $1', [postId] ); return rows.length > 0 ? rows[0] : null; diff --git a/src/services/qa.service.ts b/src/services/qa.service.ts index 0d8ffe0..e0b308f 100644 --- a/src/services/qa.service.ts +++ b/src/services/qa.service.ts @@ -72,12 +72,14 @@ export const answerStream = async ( try { console.warn(JSON.stringify({ type: 'debug.qa.post', status: 'not_found', postId })); } catch {} return; } - - if (post.user_id !== userId) { - stream.write(`event: error\ndata: ${JSON.stringify({ code: 403, message: 'Forbidden' })}\n\n`); - stream.end(); - try { console.warn(JSON.stringify({ type: 'debug.qa.post', status: 'forbidden', postId })); } catch {} - return; + + // Enforce conditional ownership: if post is not public, require owner + if (!post.is_public && post.user_id !== userId) { + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ code: 403, message: 'Forbidden' })}\n\n`); + stream.end(); + try { console.warn(JSON.stringify({ type: 'debug.qa.post', status: 'forbidden', postId })); } catch {} + return; } const processedContent = preprocessContent(post.content); diff --git a/src/services/qa.v2.service.ts b/src/services/qa.v2.service.ts index fd5b459..9027c36 100644 --- a/src/services/qa.v2.service.ts +++ b/src/services/qa.v2.service.ts @@ -6,6 +6,8 @@ import * as postRepository from '../repositories/post.repository'; import * as personaRepository from '../repositories/persona.repository'; import { generateSearchPlan } from './search-plan.service'; import { runSemanticSearch } from './semantic-search.service'; +import { runHybridSearch } from './hybrid-search.service'; +import { createEmbeddings } from './embedding.service'; const preprocessContent = (content: string): string => { const plainText = content.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim(); @@ -61,10 +63,15 @@ export const answerStreamV2 = async ( if (postId) { // Post-centric path (same as v1 with added v2 pre-events) const post = await postRepository.findPostById(postId); - if (!post || post.user_id !== userId) { - const code = !post ? 404 : 403; + if (!post) { stream.write(`event: error\n`); - stream.write(`data: ${JSON.stringify({ code, message: !post ? 'Post not found' : 'Forbidden' })}\n\n`); + stream.write(`data: ${JSON.stringify({ code: 404, message: 'Post not found' })}\n\n`); + stream.end(); + return; + } + if (!post.is_public && post.user_id !== userId) { + stream.write(`event: error\n`); + stream.write(`data: ${JSON.stringify({ code: 403, message: 'Forbidden' })}\n\n`); stream.end(); return; } @@ -91,9 +98,7 @@ export const answerStreamV2 = async ( const planPair = await generateSearchPlan(question, { user_id: userId, category_id: categoryId }); if (!planPair) { // Fallback to v1 RAG silently - const [questionEmbedding] = await (await import('./embedding.service')).createEmbeddings([ - question, - ]); + const [questionEmbedding] = await createEmbeddings([question]); const similarChunks = await postRepository.findSimilarChunks(userId, questionEmbedding, categoryId); const context = similarChunks.map((c) => ({ postId: c.postId, postTitle: c.postTitle })); stream.write(`event: search_plan\n`); @@ -143,7 +148,7 @@ export const answerStreamV2 = async ( stream.write(`event: keywords\n`); stream.write(`data: ${JSON.stringify(plan.keywords)}\n\n`); } - rows = await (await import('./hybrid-search.service')).runHybridSearch( + rows = await runHybridSearch( question, userId, plan From 0b616dacf1e6da54d8c4dfcc8a11a23aa669ed28 Mon Sep 17 00:00:00 2001 From: chan000518 Date: Wed, 8 Oct 2025 16:17:06 +0900 Subject: [PATCH 10/14] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20=ED=95=98=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=A6=AC=EB=93=9C=20=EA=B2=80=EC=83=89=20=EA=B3=84?= =?UTF-8?q?=ED=9A=8D=20=EC=8B=9C=20=EC=95=8C=ED=8C=8C=EA=B0=92=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0=20=EB=9D=BC=EB=B2=A8=EC=9D=84=20=ED=86=B5=ED=95=B4=20?= =?UTF-8?q?=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api.md | 56 +++++++++++++++++++---------- src/prompts/qa.v2.prompts.ts | 9 +++-- src/services/search-plan.service.ts | 9 ++++- src/types/ai.v2.types.ts | 6 ++-- 4 files changed, 55 insertions(+), 25 deletions(-) diff --git a/docs/api.md b/docs/api.md index a61eb38..fcce131 100644 --- a/docs/api.md +++ b/docs/api.md @@ -79,40 +79,58 @@ ### POST `/ai/v2/ask` (SSE) - 인증: 필요 (`Authorization: Bearer `) -- 요청 Body (v1과 동일 스키마) +- 요청 Body - `question`(string, required) - `user_id`(string, required) - `category_id`(number, optional) - `post_id`(number, optional) - `speech_tone`(number, optional) + - `-1`: 기본 말투(간결/명확) + - `-2`: 해당 글(post 모드) 말투 모사 + - 양수: 페르소나 ID(해당 유저의 등록 페르소나) - `llm`(object, optional) -- v2의 추가/변경 사항 - - 검색 계획 수립과 결과를 사전 이벤트로 투명하게 송신합니다. - - `post_id` 지정 시에도 동일한 형태의 사전 이벤트를 간략히 제공합니다. + - `provider`: `openai` | `gemini` + - `model`: string (미지정 시 서버 기본값 사용) + - `options`: `{ temperature?: number, top_p?: number, max_output_tokens?: number }` +- 동작 개요 + - 서버가 질문을 토대로 “검색 계획(JSON)”을 생성·검증·정규화한 뒤, 계획에 따라 시맨틱/하이브리드 검색을 수행하고 결과를 SSE로 스트리밍합니다. + - `post_id`가 있으면 post 모드(단일 글 컨텍스트)로 처리하며, 간략한 `search_plan`/`search_result` 이벤트 후 본문 기반 답변을 스트리밍합니다. +- 하이브리드 검색(벡터+텍스트) + - 계획에 `hybrid.enabled: true`인 경우 활성화됩니다. + - `rewrites`(재작성 질의)와 `keywords`(핵심 키워드)를 생성하여 벡터/텍스트 두 경로로 후보를 수집하고, `alpha` 가중으로 점수를 융합해 상위 `top_k`를 선택합니다. + - SSE로 `rewrite`, `keywords`, `hybrid_result` 이벤트가 순차 송신됩니다. 하이브리드 결과가 없으면 시맨틱 검색으로 폴백합니다. - SSE 이벤트 순서(일반적인 흐름) - 1) `search_plan`: 검색 계획 정보 - - 예시 데이터(정규화된 계획): + 1) `search_plan`: 정규화된 검색 계획(JSON) + - 예시 데이터(정규화): ```json { - "mode": "rag" | "post", + "mode": "rag", "top_k": 5, "threshold": 0.2, "weights": { "chunk": 0.7, "title": 0.3 }, - "filters": { "user_id": "u_123", "category_ids": [1], "post_id": 10?, "time": {...}? }, + "filters": { + "user_id": "u_123", + "category_ids": [3], + "time": { "type": "absolute", "from": "2025-09-01T00:00:00.000Z", "to": "2025-09-30T23:59:59.999Z" } + }, "sort": "created_at_desc", - "limit": 5 + "limit": 5, + "hybrid": { "enabled": true, "alpha": 0.7, "max_rewrites": 3, "max_keywords": 6 }, + "rewrites": ["프로젝트 X 요약", "프로젝트 X 핵심"], + "keywords": ["프로젝트 X", "핵심", "요약"] } ``` - - `time` 필터는 `relative|absolute|month|year|quarter` 타입을 지원하며, 값은 ISO8601 또는 숫자 조합입니다. - 2) (하이브리드 사용 시) `rewrite`: `["재작성 질의", ...]` - 3) (하이브리드 사용 시) `keywords`: `["핵심 키워드", ...]` - 4) (하이브리드 사용 시) `hybrid_result`: `[ { postId, postTitle }, ... ]` — 융합 기준 상위 결과 요약 - 5) `search_result`: `[ { postId, postTitle }, ... ]` — 최종 컨텍스트 요약 + - 비고: 카테고리는 단일 값만 지원하며 서버는 첫 번째 항목만 사용합니다. + - post 모드에서는 간략한 형태(`{ mode: "post", filters: { post_id, user_id } }`)가 송신될 수 있습니다. + 2) (하이브리드 사용 시) `rewrite`: `string[]` + 3) (하이브리드 사용 시) `keywords`: `string[]` + 4) (하이브리드 사용 시) `hybrid_result`: `[ { postId, postTitle }, ... ]` + 5) `search_result`: `[ { postId, postTitle }, ... ]` — 최종 컨텍스트 요약(하이브리드 또는 시맨틱) 6) `exist_in_post_status`: `true|false` - 7) `context`: `[ { postId, postTitle }, ... ]` — 모델 프롬프트에 사용되는 컨텍스트 요약 - 8) `answer` 스트리밍(여러 번) - 9) `end` with `data: [DONE]` - - 오류 시 `error`: `{ code?, message }` + 7) `context`: `[ { postId, postTitle }, ... ]` + 8) `answer` — 모델 부분 응답(여러 번) + 9) `end` — `data: [DONE]` + - 오류 시 `error`: `{ code?: number, message: string }` - 예시(curl) ```bash @@ -124,7 +142,7 @@ "question": "최근 한 달 블로그에서 프로젝트 X 관련 내용 요약", "user_id": "u_123", "category_id": 3, - "llm": { "provider": "openai", "options": { "temperature": 0.2 } } + "llm": { "provider": "openai", "model": "gpt-5-mini", "options": { "temperature": 0.2, "top_p": 0.9, "max_output_tokens": 800 } } }' ``` diff --git a/src/prompts/qa.v2.prompts.ts b/src/prompts/qa.v2.prompts.ts index ef6c0f9..ad82feb 100644 --- a/src/prompts/qa.v2.prompts.ts +++ b/src/prompts/qa.v2.prompts.ts @@ -25,11 +25,11 @@ export const getSearchPlanSchemaJson = (): Record => ({ additionalProperties: false, properties: { enabled: { type: 'boolean' }, - alpha: { type: 'number', minimum: 0, maximum: 1 }, + retrieval_bias: { enum: ['lexical', 'balanced', 'semantic'] }, max_rewrites: { type: 'integer', minimum: 0, maximum: 4 }, max_keywords: { type: 'integer', minimum: 0, maximum: 8 }, }, - required: ['enabled', 'alpha', 'max_rewrites', 'max_keywords'], + required: ['enabled', 'retrieval_bias', 'max_rewrites', 'max_keywords'], }, filters: { type: 'object', @@ -148,7 +148,10 @@ export const buildSearchPlanPrompt = (params: { '5) Interpret Korean temporal phrases into filters.time using the provided timezone. Month without year assumes current year.', '6) If the question asks for N items (e.g., “N개”), set limit=N within bounds.', '7) Keep weights to defaults unless a clear need implies otherwise.', - '8) When helpful for recall, set hybrid.enabled=true and generate concise rewrites (<= max_rewrites) and focused keywords (<= max_keywords).', + '8) When helpful for recall, set hybrid.enabled=true and choose hybrid.retrieval_bias ∈ {lexical, balanced, semantic}. Then generate concise rewrites (<= max_rewrites) and focused keywords (<= max_keywords).', + ' - lexical: keyword/정확 매칭이 중요할 때 (숫자, 버전, 고유명사 등).', + ' - balanced: 일반 질의.', + ' - semantic: 개념/요약/의도 중심일 때.', '9) Avoid stop/common words (예: "글", "포스트", "블로그", "소개", "정리"). Keep within the user context; avoid over-broad topics or time spans.', '10) Remove near-duplicates: if rewrites/keywords are synonymous or highly similar, include only one.', '', diff --git a/src/services/search-plan.service.ts b/src/services/search-plan.service.ts index c26ac5a..ee9a1fe 100644 --- a/src/services/search-plan.service.ts +++ b/src/services/search-plan.service.ts @@ -114,9 +114,16 @@ export const generateSearchPlan = async ( normPlan.threshold = Math.min(1, Math.max(0, normPlan.threshold ?? 0.2)); const maxRewrites = clamp(plan.hybrid?.max_rewrites ?? 3, 0, 4); const maxKeywords = clamp(plan.hybrid?.max_keywords ?? 6, 0, 8); + + // Map retrieval_bias -> alpha (fallback to provided alpha or default) + const bias = (plan.hybrid as any)?.retrieval_bias || 'balanced'; + const biasAlpha = bias === 'lexical' ? 0.3 : bias === 'semantic' ? 0.75 : 0.5; + const alpha = clamp(((plan.hybrid as any)?.alpha ?? biasAlpha) as number, 0, 1); + normPlan.hybrid = { enabled: !!plan.hybrid?.enabled, - alpha: clamp(plan.hybrid?.alpha ?? 0.7, 0, 1), + retrieval_bias: bias, + alpha, max_rewrites: maxRewrites, max_keywords: maxKeywords, } as any; diff --git a/src/types/ai.v2.types.ts b/src/types/ai.v2.types.ts index 1027ba4..c944b54 100644 --- a/src/types/ai.v2.types.ts +++ b/src/types/ai.v2.types.ts @@ -41,11 +41,13 @@ export const planSchema = z.object({ hybrid: z .object({ enabled: z.boolean().default(false), - alpha: z.number().min(0).max(1).default(0.7), + // LLM outputs retrieval_bias label; server maps to alpha + retrieval_bias: z.enum(['lexical', 'balanced', 'semantic']).default('balanced'), + alpha: z.number().min(0).max(1).optional(), max_rewrites: z.number().int().min(0).max(4).default(3), max_keywords: z.number().int().min(0).max(8).default(6), }) - .default({ enabled: false, alpha: 0.7, max_rewrites: 3, max_keywords: 6 }), + .default({ enabled: false, retrieval_bias: 'balanced', max_rewrites: 3, max_keywords: 6 }), filters: z .object({ user_id: z.string(), From aaaf4c483707f6eba99e47ddb8aeac13a893bf4a Mon Sep 17 00:00:00 2001 From: chan000518 Date: Wed, 8 Oct 2025 16:31:23 +0900 Subject: [PATCH 11/14] =?UTF-8?q?=F0=9F=93=9D=20v2=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=B5=9C=EC=8B=A0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api.md | 10 +- docs/reports/REPORT-askv2.md | 142 ++++++++++++---------- docs/structureDiagram/askV1-structure.png | Bin 149241 -> 131020 bytes docs/structureDiagram/askV2-structure.png | Bin 131020 -> 149241 bytes 4 files changed, 83 insertions(+), 69 deletions(-) diff --git a/docs/api.md b/docs/api.md index fcce131..7b08af3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -97,7 +97,9 @@ - `post_id`가 있으면 post 모드(단일 글 컨텍스트)로 처리하며, 간략한 `search_plan`/`search_result` 이벤트 후 본문 기반 답변을 스트리밍합니다. - 하이브리드 검색(벡터+텍스트) - 계획에 `hybrid.enabled: true`인 경우 활성화됩니다. - - `rewrites`(재작성 질의)와 `keywords`(핵심 키워드)를 생성하여 벡터/텍스트 두 경로로 후보를 수집하고, `alpha` 가중으로 점수를 융합해 상위 `top_k`를 선택합니다. + - `rewrites`(재작성 질의)와 `keywords`(핵심 키워드)를 생성하여 벡터/텍스트 두 경로로 후보를 수집하고, `hybrid.retrieval_bias` 라벨을 서버가 `alpha` 값으로 매핑해 점수를 융합하여 상위 `top_k`를 선택합니다. + - 매핑(기본): `lexical → 0.3`, `balanced → 0.5`, `semantic → 0.75` + - 정규화/결합식: `score = alpha*vec + (1-alpha)*text` (min-max 정규화 후) - SSE로 `rewrite`, `keywords`, `hybrid_result` 이벤트가 순차 송신됩니다. 하이브리드 결과가 없으면 시맨틱 검색으로 폴백합니다. - SSE 이벤트 순서(일반적인 흐름) 1) `search_plan`: 정규화된 검색 계획(JSON) @@ -115,12 +117,14 @@ }, "sort": "created_at_desc", "limit": 5, - "hybrid": { "enabled": true, "alpha": 0.7, "max_rewrites": 3, "max_keywords": 6 }, + "hybrid": { "enabled": true, "retrieval_bias": "balanced", "alpha": 0.5, "max_rewrites": 3, "max_keywords": 6 }, "rewrites": ["프로젝트 X 요약", "프로젝트 X 핵심"], "keywords": ["프로젝트 X", "핵심", "요약"] } ``` - - 비고: 카테고리는 단일 값만 지원하며 서버는 첫 번째 항목만 사용합니다. + - 비고: + - `hybrid.retrieval_bias`는 LLM이 결정하는 라벨이며, 서버는 이를 `alpha`로 변환해 사용합니다. + - 카테고리는 단일 값만 지원하며 서버는 첫 번째 항목만 사용합니다. - post 모드에서는 간략한 형태(`{ mode: "post", filters: { post_id, user_id } }`)가 송신될 수 있습니다. 2) (하이브리드 사용 시) `rewrite`: `string[]` 3) (하이브리드 사용 시) `keywords`: `string[]` diff --git a/docs/reports/REPORT-askv2.md b/docs/reports/REPORT-askv2.md index ea77fc2..c9d4229 100644 --- a/docs/reports/REPORT-askv2.md +++ b/docs/reports/REPORT-askv2.md @@ -1,103 +1,113 @@ -# 보고서: /ai/v2/ask — 동작 방식, 하이브리드 서치, 검색 계획 +# 보고서: /ai/v2/ask — 구조, 동작, 하이브리드 검색 계획 ## 1) 개요 - 목표: v1의 고정형 RAG 한계를 보완. “검색 계획(JSON)”을 LLM이 생성 → 서버가 안전하게 표준화/검증 → 시맨틱/하이브리드 검색 수행 → 최종 답변을 SSE로 스트리밍. -- 상태: `POST /ai/v2/ask`(SSE) 운영 중. v1은 유지하며, v2에서 계획 기반 검색·관측성을 추가. +- 상태: `POST /ai/v2/ask`(SSE) 운영 중. v1은 유지하며, v2에서 계획 기반 검색과 관측성을 강화. -## 2) v1의 한계와 v2가 해결한 점 -- 고정 파라미터 문제 → 동적 계획 - - v1: 임계치(0.2), LIMIT(5), 가중치(0.7/0.3) 고정. - - v2: `top_k`, `threshold`, `weights`, `sort`, `limit`을 계획으로 동적 제어(서버가 범위 강제). -- 시간/정렬 의도 미흡 → 자연어 시간 해석 - - v1: “최근/지난주/9월/작년” 반영 불가. - - v2: `filters.time`에 상대/월/분기/연도 표현 → `KST 절대범위(from/to)`로 변환해 쿼리에 반영. -- 컨텍스트 제어/비용 → 토큰 예산 컨트롤 - - v1: 컨텍스트 폭 조절 한계. - - v2: `top_k`(리콜 폭), `limit`(노출 개수; 현재 미적용)로 조절 가능. 향후 dedupe/limit 적용 예정. -- 관측성 부족 → SSE 메타 이벤트 확장 - - v1: 검색 근거 불투명. - - v2: `search_plan`, `rewrite`, `keywords`, `hybrid_result`, `search_result` 등으로 의사결정 가시화. -- 검색 방식 단일 → 하이브리드 도입 +## 2) v1의 한계와 v2 도입 효과 +- 고정 파라미터 → 동적 계획 + - v1: 임계치(0.2), LIMIT(5), 가중치(0.7/0.3) 등 고정. + - v2: `top_k`, `threshold`, `weights`, `sort`, `limit`을 질문/맥락에 맞게 동적 제어(서버가 범위 강제). +- 시간/정렬 의도 미반영 → 자연어 시간 해석 + - v1: “최근/지난주/9월/작년” 같은 시간 의도 반영 불가. + - v2: `filters.time`(상대/월/분기/연도)을 받아 `KST 절대범위(from/to)`로 변환해 쿼리에 반영. +- 리콜/정밀도 균형 한계 → 하이브리드 - v1: 임베딩 기반 RAG만. - - v2: 벡터+텍스트 하이브리드 융합으로 재현율/정확도 개선. + - v2: 벡터+텍스트 하이브리드 융합으로 재현율 향상 및 키워드 민감 질의 대응. +- 관측성 부족 → SSE 메타 이벤트 + - v1: 검색/선택 근거가 불투명. + - v2: `search_plan`, `rewrite`, `keywords`, `hybrid_result`, `search_result` 등으로 의사결정 가시화. +- 안전성/정합성 + - v1: 클라이언트 입력 이탈 감지 어려움. + - v2: JSON Schema(strict) + Zod 검증 + 필터 강제 주입으로 안전한 실행계획만 수행. +- 비용/토큰 관리 + - v1: 고정 상수로 세밀한 제어 어려움. + - v2: `top_k`/향후 `limit`/dedupe로 토큰 예산을 상황별 최적화 가능. -![alt text](../structureDiagram/askV1-structure.png) +![v1 구조](../structureDiagram/askV1-structure.png) ## 3) 검색 계획(Planner)과 안전 표준화 -- 스키마(`src/types/ai.v2.types.ts`) - - `mode`: `rag|post` - - `top_k`(1..10), `threshold`(0..1), `weights`(`chunk`,`title`) +- 타입/스키마(`src/types/ai.v2.types.ts`) + - `mode`: `rag | post` + - `top_k`(1..10), `threshold`(0..1), `weights`(`chunk`,`title`; 합 1로 정규화) - `filters`: `{ user_id, category_ids?, post_id?, time? }` - - `sort`: `created_at_desc|created_at_asc`, `limit`(1..20) - - `hybrid`: `{ enabled, alpha, max_rewrites, max_keywords }`, `rewrites`: string[], `keywords`: string[] -- 프롬프트 규칙 강화(`src/prompts/qa.v2.prompts.ts`) + - `sort`: `created_at_desc | created_at_asc`, `limit`(1..20) + - `hybrid`: `{ enabled, retrieval_bias, alpha?, max_rewrites, max_keywords }` + - `rewrites`: string[], `keywords`: string[] +- 프롬프트 규칙(`src/prompts/qa.v2.prompts.ts`) - 서버 제공 필터(`user_id`, `category_id`, `post_id`)는 고정(FIXED)이며 변경 금지. - 플래너는 `top_k`, `threshold`, `filters.time`, `sort`, `limit`, `hybrid`, `rewrites`, `keywords`만 결정. + - 하이브리드 시 `hybrid.retrieval_bias ∈ {lexical, balanced, semantic}` 라벨을 결정. - 생성/정규화(`src/services/search-plan.service.ts`) - - OpenAI Responses API(JSON Schema strict) → Zod 파싱/검증. - - 값 범위 강제, 가중치 합 1로 정규화, 불용어/중복 제거로 `rewrites`/`keywords` 정제. + - OpenAI Responses(JSON Schema strict) → Zod 파싱/검증. + - 값 범위 강제, `weights` 합 1로 정규화. + - 불용어/중복 제거로 `rewrites`/`keywords` 정제. - 시간 필터를 `KST 절대범위`로 변환(`src/utils/time.ts`). - - 카테고리/포스트 ID는 서버가 최종 주입(정합성 보장). 실패 시 v1 RAG 폴백. + - `retrieval_bias → alpha` 매핑(서버): `lexical→0.3`, `balanced→0.5`, `semantic→0.75`(필요 시 서버가 `alpha`를 직접 클램프/주입). + - `user_id/category_id/post_id`는 서버가 최종 주입(정합성 보장). 실패 시 v1 RAG 폴백. ## 4) 검색 엔진: 시맨틱 + 하이브리드 - 시맨틱(`src/services/semantic-search.service.ts` → `findSimilarChunksV2`) - 입력: 질문 임베딩, `threshold/top_k/weights/sort`, 카테고리/시간 필터. - 점수: `w_chunk*(1 - chunk_dist) + w_title*(1 - title_dist)`. - - SQL: 파라미터 바인딩/화이트리스트 템플릿. + - 저장소: `postRepository.findSimilarChunksV2(...)` 호출, 파라미터 바인딩 기반 안전 쿼리. - 하이브리드(`src/services/hybrid-search.service.ts`) - - 입력: 원 질문 + `rewrites`(재작성), `keywords`(키워드), `alpha`. - - 벡터 경로: 각 query 임베딩 → 시맨틱 검색 → 동일 청크는 최대 vecScore로 병합. - - 텍스트 경로: ILIKE/텍스트 유사도 기반 `textSearchChunksV2` → 최대 textScore로 병합. - - 정규화/융합: min-max 정규화 후 `score = alpha*vec + (1-alpha)*text`로 랭킹 → 상위 `top_k` 반환. - - SSE: `rewrite`, `keywords`, `hybrid_result` 이벤트로 중간 산출물/요약 제공. -- 폴백: 하이브리드 결과가 비어있으면 시맨틱 경로로 재시도. + - 입력: 원 질문 + `rewrites`(재작성), `keywords`(키워드), `alpha`(서버 매핑). + - 벡터 경로: 각 query 임베딩 → 시맨틱 후보 수집 → 동일 청크는 최대 vecScore로 병합. + - 텍스트 경로: `textSearchChunksV2`(키워드/질의 기반 텍스트 검색) → 동일 청크는 최대 textScore로 병합. + - 정규화/융합: min-max 정규화 후 `score = alpha*vec + (1-alpha)*text`로 결합 → 상위 `top_k`를 반환. + - 폴백: 하이브리드 결과 비었을 때 시맨틱 경로로 재시도. + - SSE 메타: `rewrite`, `keywords`, `hybrid_result`로 중간 산출물/요약을 별도 송신. -![alt text](../structureDiagram/askV2-structure.png) +![v2 구조](../structureDiagram/askV2-structure.png) ## 5) 파이프라인(SSE 이벤트)과 모드 -- 컨트롤러/오케스트레이터 - - `src/controllers/ai.v2.controller.ts`: SSE 헤더 설정, 서비스 파이프. - - `src/services/qa.v2.service.ts`: 계획 생성→검색→LLM 호출까지 오케스트레이션. -- post 모드(post_id 존재) - - 접근 정책: `post.is_public=false`면 소유자만(403), `true`면 공개. 미존재 404. - - 이벤트: `search_plan`(합성) → `search_result` → `exist_in_post_status:true` → `context` → `answer`* → `end`. - - 컨텍스트: 단일 글 본문(가공) 사용. RAG/하이브리드 미사용. +- 컨트롤/오케스트레이션 + - `src/controllers/ai.v2.controller.ts`: SSE 헤더, 스트림 라우팅. + - `src/services/qa.v2.service.ts`: 계획 생성 → 검색 실행(하이브리드/시맨틱) → LLM 호출까지 오케스트레이션. +- post 모드(`post_id` 존재) + - 접근 정책: `post.is_public=false`면 소유자만(403), 미존재 시 404. + - 이벤트: `search_plan`(간략) → `search_result` → `exist_in_post_status:true` → `context` → `answer`* → `end`. + - 컨텍스트: 해당 글 본문만 사용(전처리 후). 하이브리드 미사용. - rag/하이브리드 모드 - - 일반 흐름: - 1) `search_plan`(정규화된 계획) - 2) `rewrite`(선택) - 3) `keywords`(선택) - 4) `hybrid_result`(선택) - 5) `search_result` - 6) `exist_in_post_status` - 7) `context` - 8) `answer`* → `end` + - 이벤트 순서(일반): + 1) `search_plan`: 정규화된 계획(JSON). `hybrid.enabled`가 true면 `retrieval_bias`와 서버 계산 `alpha`가 함께 포함. + 2) `rewrite`(선택): 계획의 재작성 질의 목록. + 3) `keywords`(선택): 계획의 핵심 키워드 목록. + 4) `hybrid_result`(선택): 하이브리드 후보 요약. + 5) `search_result`: 최종 컨텍스트 요약. + 6) `exist_in_post_status`: `true | false`. + 7) `context`: `[ { postId, postTitle }, ... ]`. + 8) `answer`*: 모델 부분 응답. + 9) `end`: 종료 시그널(`[DONE]`). - 오류 시: `error` 송신. ## 6) LLM/비용/프로바이더 - 기본 모델: `openai/gpt-5-mini`(환경변수로 변경 가능), 임베딩: `text-embedding-3-small`. -- OpenAI: GPT‑5 Responses API 스트리밍 우선, 실패 시 논스트림/Chat Completions 폴백. 툴콜 인자도 `answer` 청크로 송신. -- Gemini: 현재 논스트림 결과를 SSE 청크로 전송. -- 비용 로깅: 프롬프트/완료 토큰, 추정 비용 로깅(`src/llm/index.ts`). +- OpenAI: Responses API 스트리밍 우선, 실패 시 논스트림/Chat Completions 폴백. +- Gemini: 현재 논스트림 결과를 SSE 청크로 분할 전송. +- 비용 로깅: 프롬프트/완료 토큰 및 추정 비용 로깅(`src/llm/*`). +- 툴콜: 컨텍스트 부족 시 `report_content_insufficient` 툴을 통해 안내 문구 유도. ## 7) 보안·정합성 -- JSON Schema + Zod 검증 + 범위 강제. -- 서버가 `user_id/category_id/post_id` 필터를 최종 강제(LLM 변조 무력화). -- SQL 파라미터 바인딩/템플릿 화이트리스트. -- SSE 데이터 최소화(제목/ID/요약만). -- post 모드 접근 제어: `is_public` 조건 기반. +- 생성 계획 방어선: JSON Schema(strict) + Zod 검증 + 서버 측 범위 강제. +- 필터 주입: `user_id/category_id/post_id`는 서버가 최종 주입하여 일탈 방지. +- SQL 안전성: 파라미터 바인딩/화이트리스트 템플릿. +- 데이터 최소화: SSE에는 ID/제목 위주 요약만 전송. +- 접근 제어: post 모드에서 `is_public`/소유자 검사. ## 8) 현재 동작과 한계(향후 과제) - 현재 - `top_k`로 리콜 폭 제어, 시맨틱/하이브리드 모두 적용. - - `limit`은 계획에 있으나 컨텍스트 축약에는 아직 미적용(Top‑K 청크를 그대로 사용). - - 청크 기준 컨텍스트로 포스트 중복 가능. + - `limit`은 계획에는 존재하나 컨텍스트 축약에는 미적용(향후 포스트 단위 dedupe와 함께 적용 예정). + - 청크 단위 랭킹 → 동일 포스트 다수 노출 가능. - 카테고리 배열은 첫 항목만 반영. - 향후 - - 포스트 단위 dedupe + `limit` 적용(윈도우 함수 등)으로 비용/다양성 균형. - - 다중 카테고리 필터 완전 반영. - - `search_sql`/`search_debug` 이벤트로 쿼리/파라미터 노출. - - 텍스트 경로 고도화(순위 함수/전처리/키워드 확장), 모델 프로바이더 다양화. + - 포스트 단위 dedupe + `limit` 적용으로 다양성/비용 균형. + - `retrieval_bias → alpha` 매핑의 AB 테스트/텔레메트리 튜닝(예: {0.25,0.5,0.8}). + - 점수 정규화 고도화(z-score/quantile) 및 RRF 옵션 도입 검토. + - 텍스트 경로 향상(전처리/순위 함수/키워드 확장) 및 프로바이더 다변화. + - SSE `search_sql`/`search_debug`로 투명성 강화. ## 9) 파일 맵(핵심) - 라우트/컨트롤러: `src/routes/ai.v2.routes.ts`, `src/controllers/ai.v2.controller.ts`, `src/app.ts` @@ -118,7 +128,7 @@ } ``` - 이벤트 예시 - - `search_plan`(rag, time=지난달, top_k/threshold/weights/sort/limit/hybrid 포함) + - `search_plan`(rag, time=지난달, top_k/threshold/weights/sort/limit/hybrid 포함; hybrid.retrieval_bias와 서버 주입 alpha 함께 표기) - `rewrite`/`keywords`(선택) - `hybrid_result`(선택) - `search_result` → `exist_in_post_status` → `context` → `answer`* → `end` diff --git a/docs/structureDiagram/askV1-structure.png b/docs/structureDiagram/askV1-structure.png index c621efceb772f131ede94d422a97415d0fe96f26..daad8e90225f770d53b6aadc6ef7a86cfbc3d290 100644 GIT binary patch literal 131020 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

+h(-<4_r1 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ÐT!5Y4&Np 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
9J)p-Fr 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 H`uTqVFVW3S diff --git a/docs/structureDiagram/askV2-structure.png b/docs/structureDiagram/askV2-structure.png index daad8e90225f770d53b6aadc6ef7a86cfbc3d290..c621efceb772f131ede94d422a97415d0fe96f26 100644 GIT binary patch literal 149241 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ÐT!5Y4&Np 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
9J)p-Fr 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 H`uTqVFVW3S literal 131020 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

+h(-<4_r1 z_h3&tiRW~6igg=X6wjLRpBgAMlg*dnm^?x!=SdsVM$Jl!+xVNl<#?0>G%IN>4oiUx ze@UOY5B}8HTzg26P}}YkrRw>HGSA+*s=kW#Xcqe!dez|Sbq~9J$J1wbaiJLCR*-zV zx50`I`{?9!3Qb!HQRD>5i9$2fsq6&Lq~Ub~plh$FwLc=pNCVhv;%2SvMOiNbk3C@; z>y+txSV7zjV(JMX8((ZAqzifHw|dC#?Y`TET$pBD6!gy>ChAAkcyGWt0M+MJB-Z|k z@>(i2-dX36z%4B|;}l3CrTAye2|EA$Gc8V9)gXROdV%HGUy*CzJ|bM=>AEKtzVFMD zfy>r`j!Bt;B6L-50%a~fBU?Y-EW>=()kRU0Az;u{1p`5< zOOWr7WA2pkIeUQ4>0e#A+6xN7o ztG!a=)@FvTC9m`SDVbPlK`0QxmGil`?fW7TOs<>a<{OqGowA$t-P^HGV?AUFvtP1v z9pZ3pi9Hcx=pjK8x63YfHyd(Y7%E#BDYxJJ_M+||M~Y~h_{t}!ke@7*>5}+w?Y(te z)LYj!KFU##a+G5L0s=M-D%}{ANO!9UNY~IXfGw#~(j{FYJ(Nl*DKQM)IYW2zTi@}% z@ALfL|K2~}=X3Kpb5xX>{oQ-*wXSuoYws1DIkA>GT70l&xU>;>@C52m-kiuCl255E z==f@qg4lmptY@CB`ejAV>t)}mEM3!FjA5!2z^EWwA+-l)YKdq#Ff`ZtH?zM-gXihf zx<%vs(suOxyPh{aHa`~_q1~QS%$5gT`{QA2#Zny|?7zvHwV^UWgWm3sPSMeD&)4pcx4k|K@Bc}P?^w=`JX*5ko0w6u>- zaiG-@<$)`KpCN(CKDL6GGsKER9f9e?*r-hD)+Lk-9_&YM67ZEDo&NGoOEJ;%*y^tW zUjN%JA$&v9Xp9Y_12%y-lWz2bU+!B|DlR$U`%zg|-G9RZGQ%|8wdwfpVBk=5L#9suaoAw?;dFL#w;frg1Ct4>&oV!w6{1Gp4NqNd?U$g2Rz8|hw zAgB9dI!q%Mb1AoU3eR&+;5bUcuCSn><{GvB*`e~~GX0F{B_`i^?wDU(+&M+DQUNGEBHQ}r z)c)&UPea62nIZ)4xdDr);&BmG*YS6kug(a)Vo-;7oD``%g|bLpCIwozs2q6yk(?SI<>l@Y3NZDn1`^dcM{xlPS@r+Zzj-FRtoKi%qTcX2R<9 zvFmLee74FVu^Hb4>P}A%rhH83yxfB;K9mF6h)9yI# zp#0*>kzRtc17@gh>-8wz0ovN99fdmA6=YMvjrfnmEPWM~Gt%_xr`4r3>n^+dz!>{&P1_OV$X1j@L zWb1XL+lbh;K+)$qunQ7xYkjFUE!$cUBwsh^R#-BEI6hT)0SI z3NMnSG!ivyPlqxr9Ydkn2OU#PTVnyq zoN=F{%v-43sTn4taB0Nz@>QNuGEtxK5W*;Y}CN6(F)l+@lCLJ zplu=3KW|K`z9OH|A6!%V6DWsTBgijNcsl;JV5=p>akzra5y{S8+>04X3KEG}Y4WjI ziE@6o`m4PD@$~7`bLeJB&xFMUmTR8n$nIdla~{#2f-Z!0cus-Tix!7a=e~1c_M;$J z3{Euj7H}L^OHu2sS;u z)=`zqy&kVlzxAyfEUASU2k6_5s8|_nBLa@@UmM*L0GW?i(%)*kr#U~gyZh&DMYJ{yv+#PzzqzVa5qvn_${n3WDE zF1M>E&wn<|*r_4~dedZN_vo9=4BmY5t14iNAXP@EVMkhes-v0zoBGtbS3dqP3@vhJ+jZWkrkX9eST#q zZl!5`PI%O}F_r3){FGxW*Mc7)y313gWE8aLUNd53M#v874@UA@jD0)Cz&RbMC{mdQ zeQUs0YMc5@3(fY+@P;%bOmn}(Q4k=25F3&&=_9ail6Pb0HG^MoR4+ynt*Hb+G^f(d z%^*K+cbujzNjm5-(_!rMxc$u*7a)sIRL*A??`92K97c^lwyJ&wmv%}Hu1tA3diXP} zeEWWckcfD`7{v4a;yfi-AYv}1HpMG!v>h}S7-6-OUDRUjx|i|Mw&f*~D+so(!@7#u zbxHfaJ26dw>rc))w_=N#Ee@<(7L3|d<@~XaWWV2Fg7Jokbp@w;=1FesQh!*57+o$|j0>!T* zNMdm108>A()T8Ki4TL|e4>JOZNbKOx-L>{uD`&~G(w*n;ymxPP4iNJk(U8^lR=n`$ zK=e@kZao#1V-OZQag&(SBRN0@1xJxGOJf6vyRR->V2bhZ@cI9Jpl0}keRG5baBanN zWC!Jo-Mo}jVIsxDSE="MKzem1<%P#ulYz8D5GmD^X)C9aP)SnYF;JA91{>xa}m z2#)-dBF?p;LvKEOFc56kJE({TgGMwTf!l75m-}%u;nm?}Ieb@kZhhqShO7~7&LP;D#lHh3P{mrzBnRUMGd?RTGWE`Zi*p4nDX_KFFk^(`E zKfj=0))(4+vCfw{8z6|RoN*InxnZg0JhKTxnJBiP3pDdM6OJEnnf8mYSf5Um2=IV zk7-Y%@VdCYjsQf|czU{-g@FU)PNQ$GygDZ!kDoxo*DT@~)jT}g1@jz>jysJ!5cS^n z8b>dK1ilkeZ)!udeEE8BShOiuDf;p1?3R}zb>%SK+0p%-$y#uH>n;Iveage~NS zrs=MCJJLO92eWE6#^xoO^$< zJ?b*E??or&d!KEUPLpe>NzDHF#+O-3nH~MNlAE;K@k@WmKu_>W@kN)A*6$BYCY!HT zS#WgO-dV?3uPGb&4m9qvu5I0qc|i$-Yj|Q_43McXq;jEvuDp7 za<`5&a51Y{E95A|KEN-HF`;+6kJF1|R9?P})s5X^({v<$l2r^)wY7bx*?L4tOoSKi zUfwf%-r-0uT-Y`-r@J>})Yhg<>q=a6b8XO7SnJI*3Syw$2r+P(QHI1iH6N03y|fQ! z@B~XAzKx@H`Qn^H;YXSf;dW&pqB(h3^6l<+hFQl^>_+Tyq#>qe3p)#oGIULb4zLAw z)qJ_pGb~hoRSf5yUt6CS`Z~>w^5~q^Ug6!?JEDNsX5XjX7}odNGOdR0?7LfrGu>_H zQr$SWx217uG`a2zWwkRR@L91MUDRGik26_CM4FQOjy0Z{1PO)rmuJWbl&`Uf8VD$Sw)MW|Wf# za%)x>YR~k01=ea@Aa$p5zt<9%r7iEdM%%*cV(TCHtXAjfo`|qqzN}|dH<%;lnajGeFifW8 zWYt?DzcI8?BIoDd9L3*G?>w*?6xWepM0c_@p=vO0?`_8(lfRe7`}d)^%DWb+fN)SE z$u+ns8dv4!NSvC(Q{E(_kP`ryQ4-qUo`Z5(BBCSyw!Y_L8@ghDGT$6yX9QU=i+aYr zr?Vx{L!Gdg(_TCX}_`L15oYONBuy}v){wb!3FX07>HbjqfK zmDPSaN0^~)*;rgqABdx2mLpq7q@>gS{s=n<)o>yVbc+%Z$jFcnY>wuY1Ooyqtleu* zwjSu+ZcW;l*}1mDW4U<|u2iF?KkiMjvv5aVK_N$OElB*P)DrG7*R%uK;lrz=A@xu4 zwPVEUt&54sCw@t`h|Yln8JkQPOisn^OTuuAxNHMIGRG)GO*^k!@OK_knO(BbVB53+ zy~RW;I;nxn&>xtVF*pq^f-R1%b(L@B5?68uJBBZL8W$ctPfzY0)K`*#Cgr3AZ+H_rLyUlUs_0!gQPo3p4bHs|E6ZzuXscgeHo15nyXFD}wa-L>}WpjqrKE5e* z#@qhMQgI`XQ`1>!+K5iC)R-f57k}0%EHBESRa%M%~yJx-!?G)o{)NgN~lHIw`*rYw76~; z4`QAx#EE4BS8ERKc6&cR%5<9VW`m~D=o<1fh8!BQvhpFFiElYe3nDnNX<=>emFmW) zsGkm1-Zk%JZkuLagyz{R?_;Ax1}3iE^Q$%FDqnq?&LF-~6FgSn*r<^FDH@IK8nJ!) zebdx&eDUUh^MOpngB;QOC@&}cKs9=5pxPgVB;I(*doRlLc2>5V2{_@N0J8?J|2bOM z)2BzU8M;jRxa{Ch4hv8FN{w>Y=Ld2t+$jk7iesz9L9+Xb;zn9^UnQalS3A`Pu!WAw z1HIVkL>=>PX1Gl6{VU@;Jt|sSX=FP=yX!-9hxWGnyvn2lFF@O*w_&+DU%j|&-&T+O z3RW!7qL}1lSC4xeT$k~vx}C!r+5=BdXvY1Lzq_DrZ5=BoI_NRxNiS%x*DA8}XHX67 zU{1flK>O15*9)4TXYG7Q=I%j{=&j@XkN;J`l3rWdXSmPI&#%a&qQH9XnmP*$ljG%y zPsp@4HL)8%dBVcRtxFT34cd0~_Z4t?3TQ3QPUW?=vvaU-PF}#u&ZG7y z^bREzRpRH*N-tl(X1RX-{>{8L-?!Nr-Q5|5p(P<3Z8<@V6v(+*dO*vl&`$x5TdO0j&%%il8cK&uxQ=um{iw^jGJM;tX_YX|OIX z>l}-cltYjIu&Y>I9?LKgZQ&?|{adSYjrGp$+diBe+nif=p`ef3+TJ~U0{}j1Q;4*~ zU!Fd9E=}k-uR2pgN}IBh0wtv&dfoC>yJAe++p|oeAM90F>QxeZ`;M!FFg z!%g>FzL80zXOf#m-qB9rB5_sIK08cd+hI9n(kJmJ?;a~*!3kRR7X2dU63uX5h!}1^ zV7zL!Q#3%pyO+dzY~Q}-JU840^4<7d?uZ8&y2V9&HiIMR>;Z#M>AB@e^>Hp=$$mCa z{|}2oEk=F+erIBeI^$xM#MY4`4UNsJ8XAFLzSu*rs68kDY%_Ezz-yWYnq*XTR&1|T>5MU8J5HwW z8^mD-LLx%5Q{y}e)jTIFt0bT((f%owL9N5&WPb?Ua~tAp)n||>m@j5mx)19@Xm*a( zT$v2$|Cq7+2tYJy(U={u8|rInmiC@s+v&gT7EyA%o9D`nkz#YAJ#*_S8*=l# zx6d+(UJU*@{tA6yIUPV28u32aOw}|jqjj+27#-EI9hW%H%lTU$rmcCsn%<5EjX zv=En8xno_*5Vz^wTU1sffBX>YAjQ}(GawKpz`@L{^iyB>>Buu1z4`Z1QK`Z)57P=-9KKw{C(iv z8Ri2xGUK=t!%s_JZ8bV- zHUTV>|I@1H@5%5*kQVBz^aT;ydvlx?X6V1pU*%^~Wc1vOfOckN$*FO6xFQ5ZB+2!PU!eRW=+1E=2C^ANDL-)IC{Y7jIo+=gq2_Gydw6 z#Fo0?Wj(T^>oLfQ<6Gz>{z(HJL2akETE;j^-M%?a3(&bD%E*tONlIZCjC+MF&4g} z3|%)ch@mim62*f~&r>S5b98rvE}Y`f#Y#1Xm)(8x#JD+n?+XKF(aduXM`2Bjf;6Bff0FpTl)ST|J`^zr-l~$k zzHMZj=sxJIO~c`eAfw1uDGRbA3)0y`2%h{#jY;^g5Y$>-o%`dy-Ea zKfb=XCH1JqxGy7=*m*IpqV49s%ENehXu;6dZRdO*xvf_12IAPf$%~BY8RmKlTVX#* zfVcDyRJy*k6Qy2iUvl|!HRb8kId9%HAn*U?jjg15fSToO>9t4*$X|5G`~&@Nv5Hqo zuxVy>Yz%SWDTZ>@oSXvdTQZ`wqya#DrsaFE+D$WWaw~#o{MEj>vn!h@&$?`}=qW-F zcibkbwcn=Uu5_p|u~-zb`Mp(px$+V_GoWA*r)C za~Z~l8~tDcmox`Jm(`?RM{^gB*TpwXOD+Q*T&Ubjur4>dX!8Kl1A|(`>`NXFaTw&# zbePi6lO1Jll;g!(D%WI`n)30i`*=xU|s;UYuVE&>__M}i7 zpfbq3SuYOvXEvLJ;!M;bOT2UE86_=k*1LDZ;(KB|?DsBR`liQtD*S@zheRl}oBa&R zEO@-7Q#|-}S#x)Hm&c>V5$oRB{6&kML9|g7`Xi=nh)1V55AG}FK5*4_DjS$H?Vgha z*v!fSfCGM_Gg0!azTL!xId1#$wd-B)d-RHI*5O%_sR6AzOe)}h=ra8B*?V1q!6?7K zYvI)!Unp+%E5G%D>Keh0@N1@jv_6?5itS>&2Ro75w4|ZqzzJ090*s^sayOdN+@+s( zR$Kv4>QY<3QrW3!foW?Mx9R%XscIlxtdVW*w%sG$S?+ozH)e(fCW_Xs@uB1NFCB_N z&-=novrFCDkUQ#BVe-3jhuCFLoH(Thp%P5^9^wTu+SEmyVEt}r6cX~bZ3q7vfXnhU za<_Yau>%&xM{CDDZOKxE?w)Cgsmj^AJ5F~?!GXkACTtwP{nS^IpF+8Oo7b-*5OXn$ zy{^}TW${D543p~nA7hGzZbg4SruJ4^}4>bsrhFIL0#NpVUP^# zTI0wdPJ#08Oi-m$f9rcg=v4x&8pO8e2-wYbHux1~Q=SWryL2TbV-MWMhQ=o+X8;ba zHYZ+#g#s%Ka9h8x@j5WubKQgz8JPDMQYsHv;91}N`3yzzEge_aEe7#Sqtqf&ww0~h zH)cvx`*;bjztNw?AX+w^Og;1q@)*~Nes`&pnh)cf*-Q_4E7S6%Wgb0Aprt3f5e=uc ze(2`nfn%7-JKk#1I2j`)y&W@Pjd%77CzjPVf|(^Uh~{<{K6lFmpPiH>7=YYM7tg-J zjpSaiP5yvfcDn8n-euK)lA6COx>R+om)IIYd>JW@cy1)}Hb)&`bqW=hr?rnC=fxEp z@&_TOj2mKM5QJ)1ZXUaKE!fjMLM;cup`qE38>qz@R3mBDHldNR+&(z2>?VSKLnMD6 zatJXhl8DkNvYc0we|&iXyBacbC8y)H12q96Nb$P7Oj`QRe3g1kZh2F-rzbRFJIUkF zbuL?{RDnxm1M4*3Ph97&^RKvTlHW7u2?=@+oWbE)jAVeMNE-?F#Y54VtE=2n_1j(m zaTA)881aaE_#Aa?Ci1qZC*i#$$qgHyBw4eBAQhdi`a-j7?ezIgd4MKT5OiWaO(J!- zYirbS`Wt_###L(O%`QbjpjGR03P&vJS0h(N@)ha8vgC#2a6Z*~1*`scNar^>GkGPd ztt&O|<}769R_)%-ABv8gb`6!RB+Q?DBts$$4;57&A7uh^_UuU`)wE`h6M~G z5m+AcuBISIKtSQ{1(uF^M=549TQm(gy}ZKATHryE07P(8XF@i**zUsw*chd1qV@h2 z)$%h9Vd=S*neehe``ceCwK!I>OE?ReF3Lp~g68%rF-2?-YX&9)4iLY+oyiyy5n+Wc z5SNt|OqXVGlUfnm)dTPuU*lHk$aamCqPJ;9kaYW8;HS}e(dy_N^5e(5*6!{QGbQua z24}-@YZ-yij+xxcD<6Bc7~i*0nPyWNm5GFMAdzOo268Iz$Vc%mO56dY%D`jQB@rZs zsnWm))q)CW;~);oA1 z7~4F(ryunh@L`73fBzlN`Ew2j=yrDfa<*>SZSnoj_vON~x|YTOeFj5<3wYnaD6<4!PCgh#+mX(IWBk>KkXbi*lHBFX)o|W(4K;3 zfqM0;w+0HDmD<^d2m`5^5P&lv6My=XBD26_OR=})Q52GJ4ow;Im*kpvzTv;ff+Pt* z;q~fwsQ~s%KM-+?Tb~_Fy(XU1^?^~-tT8O+)!^eVY`4CAXvj(>V}CSRur z9T2u#av$2@X##l0uUPgL=ob$zdk;qK`ND+@_|}bclX^nPV}u)eexF8;b{L-^?KjlJ zcTCp9sqjh9DxmaLB^Iy-?zcc&8-{Crg=*U@G!F};A_O|tj*!& zoyzo~sNebFnneNNEU2lB7GBWhTj=b*sW=^)9$fB}!cX!wC1gW|fKI$ywRh)k?JciR zrJB!|5U;CeoFgRMGuA}l?oFdWRo>&&xOQIr`l{09UFC}H<5JRJ4R1s|Fz+mhZMzBC z#F2-2S{N^nw#@_o_Ce8|!Y6?3w(JV|YZv`8T}mfCH%oJ9IvbOw&XYXrS9Jsr zp}tOm%ujitb*nQylFo)!>r%M+E$%No#EPJpjG6BA-@eED5aD{4@<5Fc0_cF8NlKQ} zAOb~VKH=;5rEiWw&|#Uoqchz>7+Oxaee%+-fl>y_Hi2Y@@EJg1J#5H4tFAR2!8l#L zaZgG^GIL^|O&DS2<&gQ_cC)o86EG{e^6rXf8R+J^Dl4BMduuq3#H}K4 zgff=6eIrqmHJS75%v1OxL=T0 z3fYZ*y47OBdWBn##*|xKNoiW;06Eusflk*lO!y3u2gl zZ@F0+)KPOq%Qg^_DdY36!j}=`?;$*9Wm(dzHwZ8aY~1_Hi7#PDpU1s@Xq^xaG8u|1kk26H01oi;lWEoxI1{ z80{);AWc`N4+mtnE2OZ^J;7>Z?+#J)jg1+heJUopPgpi4#S}JPUU?=}#hE7rmgJO_8Spg?EiGGfLK_#1jZN6V zieW1Ni@v+Aa}`)TxW)ofBH;cSA1{Ri=+5HHymR+CCGDB4UqJr7I?Be*t_DWw8<>+g zJ=2c4B1+hUDM14`Q{Ts2!KM$7TwKwByvJGBOW2D1|Nfp;I-ZSj?jpR zIkc5Ifra8KYaGIqNYs8+v<2H%%IGi&Fq<}HO7q3o$xPkEaPLCq`HG+E#98^O&c zyh2nSA91wtMRS}ue!nmQ{V1mo#zEw@BwIa-*s6D{pd+E6Qny@>Ei4z;8^;H;VE;9?wzg(_vSFK=EGrgw|7zY@bVy1H zp)qZFGF@tF*l~=Jz0>GyeVTrmTtMI-j9rP6s^MXx9$Q0rsfUPtOpx-buT0|;6NvYp zUTLMWz%{IaJKz)gAT4m=)LuCzA7fCZt!m(=8W7c~xiF~j=or-E`{qx6ArJ_AcffJ{ zP$1c&qxB{xch@6#s_<3YT2K{&LAG!-e2Q!9;ih>t;Vf_gE;Gqz*#wb4<9f%JEtc+Y0bZ)bg)&ML7fnj-IXD z^vHvVo0HxVrv|}Ns@^BaZcUyBoKaM8hz-e!>>43XBt+JXsbj67(T14+a%i#ndd$wN zKA>!~kyHy~~!l5Ct}QcHGiP^^NB3a;zM%kxF4`|xFg&pB+xr)_lz)=R^{ zz~{s=c}RGi*F0~o1n{chy_CVU>4jr6jHFf3yTy2JhDynq#StT{)3BA>WRG+Rpf~B( zJ6mVYotswCch!2adL0RFO8a@F%4f*4XLp)Crmj>hZC{AJxz7)`;wMoy;t9RCE6}ZJ zBPVk8eoo6EMx=AUK{n~iX2I<2g#r7O^Hzi9)pHfiCiw*Z5}AJ$s3Li7K7IVi3>D{a zH(*nLzOCng^YRu8v1CY1i*NUfBps$F19B&YxIG)wetv?o=)ve8j%C{?ir1yKCQR44 zh3>rkitMxoaZ({8BF~D*89*bd{Q494i06is6*)3Zij1(UI7 zn{df!JMEzXXwjNx-&>d39LQ2!zVjEIVg(f-(e*1?zSAEjvoi0^@`>cLh>v=ue??XZ zJ)H)lQunLU&wywCIbs{K9Sz*IsO`a7xIL&}3-RJ80}?NJLl1(NNu{tNSH+@RgnMW3 z&nF+iO?adH0C^xK!bbkufooT;$N}5<2Fa@OC;Q*EY=vExcC zcdrB&nvE5yYyi2|d9Cz0QV7WIyIP7q8&KQ{g==054b>qi2!w^@w2JFyA=b6CLC>mg z__{jb*u2*roJCFg?dMqQ`=p}*n@l8(bXV}gDbeL$+}oBT#SG$&Lqk~rGbE)omC+B> zkzXD>P)Fj^^hf5GFJDFL#^)idQG@wO0q4CP!zY|SxYTYxN&u%F5@(29G7$4XG`X`= z^}eW`N_u)Kdh}kT0))%%rLzsqOS4H?NQnZZ`W^oK*V(`gCz-<2squhAI#2(NsoB%Z zhstx$DBVphM^6^1ZX!f?u;G-Hq@?-g8zRCtA)YctF(w_R9owG^rL>Jf(c5wC9*s;> z@K)f{NhIdOj{x1_pvlI*;fblKo-bKt#c`Eyc16>#ovrR^v^;2obm z1A2XT%3|_hejpKcypYTA8xX7}Tj@Gm5W8Y}pSv986f)>BbwoW! z?`Jl0QAmUEzoKG}zCJL!5EXeb2cCeUlE${8t6vArM5Lx*^%h_ZkN6EU`xeTTffcfT zU=lsqOg9ry9NPh*U^-9Q@E62jJ%YpL;!V-L@l3bnnPUUde^1Chx}6~BXp$fIfB2O1 zlL>Z;WsV8g#l)oObDyRnshx_-Szwv_yUKXrdW}-XhR*ba*oqI=V#?-BrUEOr*Q1i5 zA>!LWdU?A>?Y`oLwjZY{p0@O-i=2SVXof|=Z7eO_^v$KpG{-$g@TNI#Os&kx5tpUj z%t78QF!gfEH=20y6Dg%iLZ{hyC8+RQ(Qhdrr85QBVHf1n~CF=;@YC6^+cKQ>P~@K5uk z=k73;$Rmy%#MP@f>LEa4*=iNVRs+e$$Kr6~Q*~u59N;&5fQCKCz>vbKe)*jCwL8GE zswdxnk#SFwnU7Bgml3C%_|`wm65V;?5peuEkbH%kNAcTyn#mPcowqS4=*e<>vdav( zcN!@8chw`d8I=GdTIFMNiU&Qv-90`+g!+~+p2hn9v~QM*_IvfqYS)&F@vNbgTYdFcE`K+MOGpC!hngaIhmx^%@&sbch5;)# zzk*x!R|_|0<{v3HlbD3`%gk|Z0O4eS4ikO%SEcpFyeB74Jz&(%x#fRG^h}6%yk?{4 zLPJ7I`ja#lo`~L{JBtS`i)~1-wootUfcO?k``x zDiOQ}@v{}KDQhwj-`a}sa$ghPFz0KWonjKt2V}Zzdgu_kH1KU1SneZ74%YMHFCIDC^W;{9Kf|$TsNRmXUol9^kTS2M3uf!Q)9mHA zV3&M~K_mkz!DHyT?~2qj`^T(TBv?1G>TLKjHR`jvxPPlf{uP(X2_1@+UF&o1dKo8A zooeq029P|yZmpocuEoBOkf((H3425VGB=PvG{XR%=jnE51ntHzeFhmgdgpOF-{fSW zL#us~QT*X8>m_^2bLWKg`A6E?D7TmNkh%|M)A}XC^{EX^#c`RW*Byb%8${Um%~bK; z-YDRQ2B3~pP+v=@c7`)!qUb`?)_B93~O+UjAY7Rk@RR))+%=gnw zn$5ST$7sy^=Ffx^#A7#-8~FziZ`QKyx@VGVp`+KX26d%=GBc0Yusjt0Wz{p-U~sR1 zQjeVpwb68>$Qp|Eivp-SEN9Q#E{E17<^;(r+g^>&&^kI!t zJ9zp3q969TTA3=}M}^etI~)-)j6|gGCDA>9YZ@^rP*|x0@joqKooBis=6UPDBHVm$ zcUN!Qd8+DBi`Qg2i9O>cU7)iV3F7!~$=KsT0ZubfjT3L1O>l@xU{KUr#l)mYwa^f= zRDtZ0geR3os~>ftXmc&e$VDG;uR+9e(QhI|34|erUZT@#0X>#oKsUQye@8*+ERE@~ zxz}B46olQFo=vz%S?$g}Wj5D)GIDiXfY)5Fby|RvjhVUgxlx=7$N=QlfC@y&s3_Gv z3J0DIL%YLwJ_eXyAmOA7%iee3L zZJs`mc(1o0&S+SS6wY&hG&aJ);+^OmIfGD41jtJlmgJI8RXTZ*&-(~6$W|w0DD2~F-=K#sP}OjDW%z7!#{_* zhCbL3l?PTv6gv8Z5>Tv;~nd4@uK0%xrv|SF+c%yL%W& zY-Kr&Ua}1phuzHe?y9rrpLUeIp10Q(cYf4jTN^vDvkE3+0mu#nnt-EDld@z@wT$uI zGNz99c4VTGW6&7R5zZz?7@VyXlnV#|YCLyN>DvYXBM$08gq#)m*yOysxpzO+f|f6f z=ySE?Z;)vf+J58LDH*1d{Qy_#HtXQfZIXp*NmAti3DWL|B5i(|zubQTwX<`;yaOCR ze3-q8>lM^1fev)!yP^uAfq8D6g0PcpAn*RS+sTG`08 zL60zV^n4y$j)+N$S^lee3bJs>tLKKCWp-kA54@ETy~Fd@tGq(5I!H2+^0!kk5vbfW zSpouPbXknC*(KSK~3ctph@`3qxh+#mCuNepJ|Xr>PM6iO;T$pBis19m=} ze=6hCry8=i9vxW`D**O~)#SCb-oR>%B;11!`+9KId2V|3R>f8MNC8O@yEDj))1_1{ z2d>ZeETHvU2Y)iisP2PMkdFSF639V$9k+v_b|d0;>fioL`?vox8~I+Qu`%D18?oRq z?!!|#1uP|Du2{?#%b6~D7E(ltt6(dreRkkxky6|Y7V<*uT38+^@YW!N&4GMkCICNG zq6P?8-C9BQ=3k|iRiJEA&BZ(u+kA?B{5ZpHmwj?Jh7^hNcLPqr+pz`$-=wc|!gZ#W zAJIo3`0SX<)+^Yg=!Jm;<=eLtItnY?oYy2Sqr8yd*IQ~@+IDmJIcMpo2w;1ESS0V5DL)^85VIeLw6X zm+Hn(lxhXXVx+2H2Xs|>zK+g0nX4yD!VKvs)V$Ns-W8y}QPyoh!x20tjJHR2LKX1y z-Fea=s_Yz}Vo(MU&mg18H$Fa2m|-%+F|AbDm)3(6$JQv(*A(<#j<9{!7N0AI???y1 zDj*6TsUVtkZ`6XA?;Fxo;+K$nK!?@&DXLnMvE}6+10Eeun?0Okqt1p}AqjkCg-zGI z{*GQo70eLSqOBF65`x;zze&;0=~r90v4SwGDG3|q?KLdm`8t|^`WK^r(yqSW_8Ru4dMy$ownvE@=(+g8!b0u=3{1kT zGech=WZVWB3{Wsp)6Xf<$d&g}gd4vdRc{%EgoHd@%ZNkX&T%Ij(KsCscdym-!`%() zAFD%C>cY-vh;peCJ0OUHoDl9-eS*GP{O4Z7Yrv2B zUO^Z#eF1d|xi#_Jp{&Y^*F?g6jALW=UA1CsD}E-P7NE=`MJ*~3o+~1vCz-JJ>&ga1 zFDwh9${&tS;6K&5?HIMX=gbBQH&ESarj%#TsG4SUP|kJcdO7P4RwhHvOBd|c0)<7y zL3#=uWU6qq?}pco=CW{!=Y0PBH~*(y+gs-o!T9AQ$XVKg>(7|7M`Qnc<7ONRZZk`_OS8p5d znIK_OBX?gLa(n9;t6LGPo!k`ZcEQ`$Gq0;OGBtSRT`UXg#9UH=n|**_&aSNe+6n%b zE^?rI>dbf6Jju{6Jrc@BLqBDB)3nviWtSOoa@yL-?)ixGAZ^T}Gve`OAivJsnDWpe z82n4S@(!pTJ}WM0?r7x*MGg=yxJ6W`2!X9(wv7EM_e|2mIJL7ORu->WcND#x_ZsFa zUSs1Da>mw8BR7FiDnR9b5VIjU;4xOwTj?33>z0z7OdKc{?<}+NVg}*?hzvxb0{0M9D`X{$$U=}l_TRE*40;-@)fy>wY zg6Khj|AG^BsiACL<^#R*2*K61bX8Va{fgrnE(Vu06)IL{SsN{iB#Uc=7)vyw8?pC6 z%1aMFzOEli0x;q!vLIKyioojjYnh1JOjbq7HlCJ0BUMVCkZCvOhHx(#>VBc1jMi-_ zQ%Y5c=?a{4FR<#fw(7&mL5i;e$X>d|d?4jzih@^zX-+k)yTleXXr_xzD?gPjxM&ga zHcl1`P>7!cY~nPxs}917i?YDE!GmXPZj$IwDDFU|@0>cXiVt6urH@8WmPXHEt1mrS z$bULy;A9g);{f{M-386T(t{Y-BV#04^KmHK+Rx+j&N67n3&z39F~wnI2Her>o7$Te zx4-!yd_0IpWj-jR#I{2rqtJ85+G?ms+TCekr5i4&N7A_a=56@4l;2eO zzJ~I*tmCvC6kERDfO=x2fLRvc4g{%|R(Qe8!=b8AaFfX1{!O@WAB2~+HTTlZ(Ub_q zi$+sQ*53pD@I4I+Z#b@UL<_WAI>tM58xWd7t<=!Ur34Jo3Cw{y90|GusX7aQmSh;< z+p}h%E>k7g{)m?nFSa2rO#G8WF%^hfwSZae08zN(t+fz^SdnBX zxv_#0K0>>v;b)8TqXd0W5K~f8rUQur1BcT?M|!iWDtgsG=()7i<{K0wT6|7}L#ohR zgRLWoZuyVjdJ}JwL6rannqK2}JaV(!uc5JVV_F-j!6`&{!sm&)1@c4q8L*oQz>eia zm1D?}t5s|hcK4cLUy368AK9BEMlt;X(M?@ibbWJg*Lz6%4^W4~o)=qjxoAkL$_!iW zc0vFOISv~7WH>|CEPNy896f#VhDlWxsEQ+Af^nlZUu2d!cj1Scl!00G4^+8cTc?4u z$W`nL(Y*eJbip#}=ok|hl+l{fK$QgLQS5aQJ{`dCQuQny>{Nar+o`DBcM9aR>gk^r zfOqs({m!P@uG%W{sgzMc6T&Y1!?VazfO>7ZQ8FKwr%IPJ2LBL+szEN9l%O#JEyuvH z7#8bpS|MgsB(^=w4eLxppV@Q+L}N~Cl(dcuf2wCPSfDS!55=o-Dwt`?PLjC?s+}d;Z)%kVH~%lKm#k)zVec>H^E|BK2*?7X36tSK680 zAyt3t0SGIR%Da4ZjEKwAF-`zA*_DR5=z$ z*AUGkDIr8$Bx;!J_kpPbh%N!;b8aW;Fxg=od$NWem0FM^aFh*Lqj_>m;9Uv0)XW@0 zmn>)xrRtHKM1=KHLJEV&CT9Qxw+aYi+BSx=0r_V_Y0wJIQ~VUX3KngaJDw?&0TRF8 zKZDvOCxsxz&sywA2ti(mmIO4MNYYT?hHGtTU}YS77~Zlc%4OB_AiUTndpw8!95uBS zQW!veCBjBQN+3vH1zJQzSMN({Q8+Ti0dBY$xO*w-@{4dd#oSI-6+w$oan-naQymIv z$m7}`ChhjA7cXC?!8t5KUv3mA`Jh;ozzdp0z-|S`jS4ZM!N^G+#0vxDgrq=;L)QRe zBbNp!>ZY}f4M5e!4BWu<`3a2}AzsjJ1E?1U)lhGNRRR<;Wj;WCtU(uHazY3a+q6g3_pTK_O^oC%4IoLTJZMNmONCAh$oIifVGg=Ss_P-F za?b6n#Um@aw?jdM!t*P!ThN6dU8hhBC!6LvuNgy&2vE+PB?8?+7uKk$-?nuNc_kSk zGll|E50U&saK{{c1gRfVL>`y%RS8TbxZKYOWE4*5JZlEP?k=S3uo&QNdPf7AO@OC; zbRzRy2CF(N8*sIDz(M=@f$X6Gl8f}TjQ8`~YzX2at%_^|)Z%G&sB)6N zte@m*oug(nLc%b7Dc#3NArR@GuLfFVuKxM*Uin8;L;7y?>;FhYNPiv{`OlmG{;4UF z{NbN>5THOt{m<7|R}$>`=Nm1gs=m+lW*Qd{(Y!@Kz;b@`k9NTJ%nD6eY#oiPPyB2bYP z*~uNGy!`v?5~6D)eR===Z_`If{Er^vq#iq@fABY{ffMPsf0BC1kbe8$w}ol=?N2H&;cV)kzij=#S&X;)Suj z*FpKFzwHdQc=&hIE98&=%l!45>e)l6jd@7$%H4NN*8QWbjOfA}jV=55NDbTIe9+G& zmuS&L!*Ruy3i^i(LRYp#6jD1%^f>cVf6q?;6McMM4pA%2c>SEW;qQicq`&!ZxPxi< ze|8cCnix=DhYHynyB9W$w8MH-No%_K+^Ww+(Yx$(Un#}m67j}Kxs!_oy Date: Wed, 8 Oct 2025 18:37:38 +0900 Subject: [PATCH 12/14] =?UTF-8?q?=F0=9F=90=9B=20gpt=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EC=8A=A4=ED=82=A4=EB=A7=88=20?= =?UTF-8?q?=EB=B3=80=ED=99=94=20=EB=B0=8F=20=ED=95=84=ED=84=B0(=ED=83=80?= =?UTF-8?q?=EC=9E=84)=20=EA=B5=AC=EC=B2=B4=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/llm/providers/openai-responses.ts | 12 +- src/prompts/qa.v2.prompts.ts | 89 ++------- src/services/qa.v2.service.ts | 26 +++ src/services/search-plan.service.ts | 277 +++++++++++++++++++++++--- src/types/ai.v2.types.ts | 72 ++++--- src/utils/time.ts | 131 +++++++++++- 6 files changed, 480 insertions(+), 127 deletions(-) diff --git a/src/llm/providers/openai-responses.ts b/src/llm/providers/openai-responses.ts index 3a2e86b..d45d2db 100644 --- a/src/llm/providers/openai-responses.ts +++ b/src/llm/providers/openai-responses.ts @@ -101,17 +101,17 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { const text = typeof ev === 'string' ? ev : ev?.delta ?? ''; if (text) { safeWrite(`event: answer\n`); safeWrite(`data: ${JSON.stringify(text)}\n\n`); - try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: String(text).length, at: Date.now() })); } catch {} - if (!loggedFirstDelta) { - try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: String(text).length })); } catch {} - loggedFirstDelta = true; - } + // try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: String(text).length, at: Date.now() })); } catch {} + // if (!loggedFirstDelta) { + // try { console.log(JSON.stringify({ type: 'debug.openai.delta', len: String(text).length })); } catch {} + // loggedFirstDelta = true; + // } } }); diff --git a/src/prompts/qa.v2.prompts.ts b/src/prompts/qa.v2.prompts.ts index ad82feb..a752324 100644 --- a/src/prompts/qa.v2.prompts.ts +++ b/src/prompts/qa.v2.prompts.ts @@ -31,73 +31,28 @@ export const getSearchPlanSchemaJson = (): Record => ({ }, required: ['enabled', 'retrieval_bias', 'max_rewrites', 'max_keywords'], }, + // Only time is allowed under filters. Responses JSON Schema requires closed objects + // with explicit required fields at each level. We constrain time to label-form only. filters: { type: 'object', additionalProperties: false, properties: { - user_id: { type: 'string' }, - category_ids: { type: 'array', items: { type: 'integer' } }, - post_id: { type: 'integer' }, time: { - oneOf: [ - { - type: 'object', - additionalProperties: false, - properties: { - type: { const: 'relative' }, - unit: { enum: ['day', 'week', 'month', 'year'] }, - value: { type: 'integer', minimum: 1 }, - }, - required: ['type', 'unit', 'value'], - }, - { - type: 'object', - additionalProperties: false, - properties: { - type: { const: 'absolute' }, - from: { type: 'string' }, - to: { type: 'string' }, - }, - required: ['type', 'from', 'to'], - }, - { - type: 'object', - additionalProperties: false, - properties: { - type: { const: 'month' }, - month: { type: 'integer', minimum: 1, maximum: 12 }, - year: { type: 'integer' }, - }, - required: ['type', 'month'], - }, - { - type: 'object', - additionalProperties: false, - properties: { - type: { const: 'year' }, - year: { type: 'integer' }, - }, - required: ['type', 'year'], - }, - { - type: 'object', - additionalProperties: false, - properties: { - type: { const: 'quarter' }, - quarter: { type: 'integer', minimum: 1, maximum: 4 }, - year: { type: 'integer' }, - }, - required: ['type', 'quarter'], - }, - ], + type: 'object', + additionalProperties: false, + properties: { + type: { type: 'string', enum: ['label'] }, + label: { type: 'string', minLength: 1 }, + }, + required: ['type', 'label'], }, }, - required: ['user_id'], + required: ['time'], }, sort: { enum: ['created_at_desc', 'created_at_asc'] }, limit: { type: 'integer', minimum: 1, maximum: 20 }, }, - required: ['mode', 'top_k', 'threshold', 'weights', 'filters', 'sort', 'limit'], + required: ['mode', 'top_k', 'threshold', 'weights', 'rewrites', 'keywords', 'hybrid', 'filters', 'sort', 'limit'], }); export const buildSearchPlanPrompt = (params: { @@ -117,8 +72,6 @@ export const buildSearchPlanPrompt = (params: { weights: { chunk: 0.7, title: 0.3 }, sort: 'created_at_desc', limit: 5, - mode: 'rag', - filters: { user_id: params.user_id }, }, ); @@ -134,20 +87,20 @@ export const buildSearchPlanPrompt = (params: { `user_id: ${params.user_id}`, `category_id: ${params.category_id ?? ''}`, `post_id: ${params.post_id ?? ''}`, - `defaults: ${defaults}`, '', 'Rules:', '1) Output ONLY a single JSON object matching the schema. No extra text.', - '2) Respect bounds: top_k 1..10, limit 1..20, threshold 0..1, weights in [0,1] and sum to 1.', - '3) Server-provided filters are FIXED constraints. Do NOT change or omit them:', - ' - Always keep filters.user_id as provided (unchanged).', - ' - If category_id exists, include ONLY that id in filters.category_ids (no additions/removals).', - ' - If post_id exists, include exactly that as filters.post_id (no substitutions).', - ' - Your job is to decide top_k, threshold, filters.time, sort, and limit only; do NOT invent other filters.', + '2) Respect bounds: top_k 1..10, limit 1..20, threshold 0..1, weights in [0,1]. The server normalizes their sum.', + '3) Do NOT output any filters other than filters.time. The server injects user_id/category_id/post_id.', + ' - Your job: decide top_k, threshold, sort, limit; and optionally rewrites/keywords/hybrid only.', '4) Mode must follow constraints: if post_id exists, use mode="post"; otherwise use mode="rag".', - '5) Interpret Korean temporal phrases into filters.time using the provided timezone. Month without year assumes current year.', - '6) If the question asks for N items (e.g., “N개”), set limit=N within bounds.', - '7) Keep weights to defaults unless a clear need implies otherwise.', + '5) Time MUST be provided via a label only: filters.time = { "type": "label", "label": "..." }', + ' - Allowed labels (examples): "all_time"(no filter), "today", "yesterday", "last_7_days", "last_14_days", "last_30_days", "this_month", "last_month",', + ' or structured: "2006_to_now", "2019-2022", "2024-Q3", "Q3-2024", "2024-09", "2024".', + ' - For queries like "최근 글", prefer a short window label such as "last_7_days" or "last_30_days" (choose appropriately).', + '6) Do NOT include any temporal words or ranges inside rewrites/keywords. Temporal intent must live ONLY in filters.time.', + '7) If the question asks for N items (e.g., “N개”), set limit=N within bounds.', + '8) Keep weights to defaults unless a clear need implies otherwise.', '8) When helpful for recall, set hybrid.enabled=true and choose hybrid.retrieval_bias ∈ {lexical, balanced, semantic}. Then generate concise rewrites (<= max_rewrites) and focused keywords (<= max_keywords).', ' - lexical: keyword/정확 매칭이 중요할 때 (숫자, 버전, 고유명사 등).', ' - balanced: 일반 질의.', diff --git a/src/services/qa.v2.service.ts b/src/services/qa.v2.service.ts index 9027c36..294195e 100644 --- a/src/services/qa.v2.service.ts +++ b/src/services/qa.v2.service.ts @@ -137,6 +137,32 @@ export const answerStreamV2 = async ( const plan: any = planPair.normalized; stream.write(`event: search_plan\n`); stream.write(`data: ${JSON.stringify(plan)}\n\n`); + // Console debug for emitted search plan + try { + console.log( + JSON.stringify( + { + type: 'debug.sse.search_plan', + userId, + categoryId, + plan_summary: { + mode: plan.mode, + top_k: plan.top_k, + threshold: plan.threshold, + weights: plan.weights, + sort: plan.sort, + limit: plan.limit, + hybrid: plan.hybrid, + time: plan?.filters?.time || null, + rewrites_len: Array.isArray(plan.rewrites) ? plan.rewrites.length : 0, + keywords_len: Array.isArray(plan.keywords) ? plan.keywords.length : 0, + }, + }, + null, + 0, + ), + ); + } catch {} let rows: { postId: string; postTitle: string; postChunk: string; similarityScore: number }[] = []; if (plan.hybrid?.enabled) { diff --git a/src/services/search-plan.service.ts b/src/services/search-plan.service.ts index ee9a1fe..22fa98a 100644 --- a/src/services/search-plan.service.ts +++ b/src/services/search-plan.service.ts @@ -32,32 +32,228 @@ export const generateSearchPlan = async ( question, }); - const schema = getSearchPlanSchemaJson(); try { + // Debug prompt before request + try { + console.log( + JSON.stringify( + { + type: 'debug.plan.prompt', + model: config.CHAT_MODEL || 'gpt-5-mini', + prompt_len: prompt.length, + head: prompt.slice(0, 600), + tail: prompt.slice(Math.max(0, prompt.length - 600)), + }, + null, + 0, + ), + ); + } catch {} + const response: any = await (openai as any).responses.create({ model: config.CHAT_MODEL || 'gpt-5-mini', - input: [{ role: 'user', content: [{ type: 'input_text', text: prompt }] }], - response_format: { type: 'json_schema', json_schema: { name: 'SearchPlan', schema, strict: true } }, - max_output_tokens: 600, + input: prompt, + text: { format: { type: 'json_schema', name: 'SearchPlan', schema: getSearchPlanSchemaJson()} }, + max_output_tokens: 1500, }); - const text = (response as any)?.output_text || ''; - const raw = text && text.trim().startsWith('{') ? text : (() => { - // Fallback: try to extract JSON from response.output + // Debug peek: log response shapes before JSON extraction + try { + const outputs = (response as any)?.output || []; + const outputSummary = outputs.map((o: any) => ({ + role: o?.role, + content: (o?.content || []).map((c: any) => ({ + type: c?.type, + hasText: typeof c?.text === 'string', + textLen: typeof c?.text === 'string' ? (c.text as string).length : undefined, + hasJson: !!c?.json, + })), + })); + const outputText = (response as any)?.output_text; + console.log( + JSON.stringify( + { type: 'debug.plan.response.peek', has_output_text: !!outputText, output_text_len: typeof outputText === 'string' ? outputText.length : undefined, output_summary: outputSummary }, + null, + 0, + ), + ); + } catch {} + + // Extract structured JSON if available, otherwise parse text + let parsed: any = null; + try { + const outputs = (response as any)?.output || []; + for (const o of outputs) { + for (const c of (o?.content || [])) { + if (c && (c.type === 'json' || c.type === 'output_json') && c.json) { + parsed = c.json; + break; + } + } + if (parsed) break; + } + } catch {} + // Also check output_text for JSON string if using Responses API response_format + if (!parsed && typeof (response as any)?.output_text === 'string') { + const s = ((response as any).output_text as string).trim(); + if (s.startsWith('{')) { + try { parsed = JSON.parse(s); } catch {} + } + } + if (!parsed) { + const texts: string[] = []; + const ot = (response as any)?.output_text; + if (typeof ot === 'string') texts.push(ot); + try { + const outputs = (response as any)?.output || []; + for (const o of outputs) { + for (const c of (o?.content || [])) { + const t = typeof c?.text === 'string' ? c.text : undefined; + if (t) texts.push(t); + } + } + } catch {} + const raw = texts.join('').trim(); + // Debug: log raw text before JSON.parse + try { + console.log( + JSON.stringify( + { type: 'debug.plan.raw_text', len: raw.length, head: raw.slice(0, 200) }, + null, + 0, + ), + ); + } catch {} + if (!raw) { + // Graceful fallback: unable to parse structured output + return null; + } + + // Robust extraction of first balanced JSON object + const tryParse = (s: string): any | null => { + try { return JSON.parse(s); } catch { return null; } + }; + let candidate = tryParse(raw); + if (!candidate) { + const start = raw.indexOf('{'); + if (start >= 0) { + let depth = 0; + let inStr = false; + let esc = false; + for (let i = start; i < raw.length; i++) { + const ch = raw[i]; + if (inStr) { + if (esc) esc = false; + else if (ch === '\\') esc = true; + else if (ch === '"') inStr = false; + } else { + if (ch === '"') inStr = true; + else if (ch === '{') depth++; + else if (ch === '}') { + depth--; + if (depth === 0) { + const sub = raw.slice(start, i + 1); + candidate = tryParse(sub); + if (candidate) break; + } + } + } + } + if (!candidate) { + const last = raw.lastIndexOf('}'); + if (last > start) candidate = tryParse(raw.slice(start, last + 1)); + } + } + } + if (!candidate) { + try { + console.warn(JSON.stringify({ type: 'debug.plan.parse_fail', note: 'could not extract JSON from raw' })); + } catch {} + return null; + } + parsed = candidate; + } + + // If still no parsed plan at this point, try a fallback call without text.format + if (!parsed) { try { - const outputs = (response as any).output || []; - const parts = outputs - .flatMap((o: any) => o.content || []) - .filter((c: any) => typeof c?.text === 'string') - .map((c: any) => c.text) - .join(''); - return parts; + const response2: any = await (openai as any).responses.create({ + model: config.CHAT_MODEL || 'gpt-5-mini', + input: prompt, + max_output_tokens: 700, + }); + // Debug peek for fallback + try { + const outputs = (response2 as any)?.output || []; + const outputSummary = outputs.map((o: any) => ({ + role: o?.role, + content: (o?.content || []).map((c: any) => ({ type: c?.type, hasText: typeof c?.text === 'string', textLen: typeof c?.text === 'string' ? (c.text as string).length : undefined })) + })); + const outputText = (response2 as any)?.output_text; + console.log(JSON.stringify({ type: 'debug.plan.fallback.peek', has_output_text: !!outputText, output_text_len: typeof outputText === 'string' ? outputText.length : undefined, output_summary: outputSummary })); + } catch {} + + // Parse fallback response + let parsed2: any = null; + try { + const outputs = (response2 as any)?.output || []; + for (const o of outputs) { + for (const c of (o?.content || [])) { + const t = typeof c?.text === 'string' ? c.text : undefined; + if (t) { + const s = t.trim(); + if (s.startsWith('{')) { try { parsed2 = JSON.parse(s); } catch {} } + if (parsed2) break; + } + } + if (parsed2) break; + } + } catch {} + if (!parsed2) { + const ot = (response2 as any)?.output_text; + if (typeof ot === 'string') { + const s = ot.trim(); + try { parsed2 = JSON.parse(s); } catch {} + } + } + if (!parsed2) { + console.warn(JSON.stringify({ type: 'debug.plan.fallback.parse_fail' })); + // proceed to chat completions fallback + } + if (parsed2) parsed = parsed2; } catch { - return ''; + // continue to chat completions fallback } - })(); - const parsed = JSON.parse(raw); + } + + // Final fallback: Chat Completions with JSON object mode + if (!parsed) { + try { + const sys = 'You output ONLY a single JSON object matching the SearchPlan shape. No extra text.'; + const userMsg = prompt; + const cc: any = await (openai as any).chat.completions.create({ + model: config.CHAT_MODEL || 'gpt-5-mini', + messages: [ + { role: 'system', content: sys }, + { role: 'user', content: userMsg }, + ], + response_format: { type: 'json_object' }, + max_tokens: 700, + }); + // Debug + try { + console.log(JSON.stringify({ type: 'debug.plan.cc.peek', choices: (cc as any)?.choices?.length || 0 })); + } catch {} + const content = (cc as any)?.choices?.[0]?.message?.content || ''; + if (typeof content === 'string' && content.trim().startsWith('{')) { + parsed = JSON.parse(content); + } + } catch (e) { + try { console.warn(JSON.stringify({ type: 'debug.plan.cc.error', message: (e as any)?.message || 'error' })); } catch {} + return null; + } + } const plan = planSchema.parse(parsed); // Normalize weights sum to 1 @@ -94,8 +290,8 @@ export const generateSearchPlan = async ( } return Array.from(uniq).slice(0, max); }; - if (plan.filters?.time) { - const abs = toAbsoluteRangeKst(plan.filters.time as any, now); + if ((plan as any)?.filters?.time) { + const abs = toAbsoluteRangeKst(plan.filters?.time as any, now); if (abs) { normPlan = { ...normPlan, @@ -130,11 +326,44 @@ export const generateSearchPlan = async ( normPlan.rewrites = cleanList(plan.rewrites, maxRewrites) as any; normPlan.keywords = cleanList(plan.keywords, maxKeywords) as any; if (!normPlan.mode) normPlan.mode = (ctx.post_id ? 'post' : 'rag') as any; - if (ctx.category_id && !normPlan.filters.category_ids) normPlan.filters.category_ids = [ctx.category_id]; - if (ctx.post_id) { - normPlan.mode = 'post'; - normPlan.filters.post_id = ctx.post_id; - } + + // Note: Only filters.time is kept here to satisfy the SearchPlan schema. + // user_id/category_ids/post_id will be injected later by the query layer. + + // Console debug: final parsed + normalized plan + try { + const timeInfo = (normPlan as any)?.filters?.time; + console.log( + JSON.stringify( + { + type: 'debug.plan.final', + ctx: { user_id: ctx.user_id, category_id: ctx.category_id, post_id: ctx.post_id }, + summary: { + mode: normPlan.mode, + top_k: normPlan.top_k, + threshold: normPlan.threshold, + weights: normPlan.weights, + sort: normPlan.sort, + limit: normPlan.limit, + hybrid: { + enabled: !!normPlan.hybrid?.enabled, + retrieval_bias: normPlan.hybrid?.retrieval_bias, + alpha: normPlan.hybrid?.alpha, + max_rewrites: normPlan.hybrid?.max_rewrites, + max_keywords: normPlan.hybrid?.max_keywords, + }, + time: timeInfo ? { type: timeInfo.type, from: timeInfo.from, to: timeInfo.to } : null, + rewrites_len: (normPlan.rewrites || []).length, + keywords_len: (normPlan.keywords || []).length, + }, + plan, + normalized: normPlan, + }, + null, + 0, + ), + ); + } catch {} return { plan, normalized: normPlan }; } catch (e) { diff --git a/src/types/ai.v2.types.ts b/src/types/ai.v2.types.ts index c944b54..6e3353b 100644 --- a/src/types/ai.v2.types.ts +++ b/src/types/ai.v2.types.ts @@ -2,31 +2,49 @@ import { z } from 'zod'; // ===== Plan JSON Schema (Zod) ===== +// Time filter schema: support multiple shapes to reduce LLM fragility export const timeFilterSchema = z.discriminatedUnion('type', [ - z.object({ - type: z.literal('relative'), - unit: z.enum(['day', 'week', 'month', 'year']), - value: z.number().int().positive(), - }), - z.object({ - type: z.literal('absolute'), - from: z.string(), // ISO8601 - to: z.string(), // ISO8601 - }), - z.object({ - type: z.literal('month'), - month: z.number().int().min(1).max(12), - year: z.number().int().optional(), - }), - z.object({ - type: z.literal('year'), - year: z.number().int(), - }), - z.object({ - type: z.literal('quarter'), - quarter: z.number().int().min(1).max(4), - year: z.number().int().optional(), - }), + // Absolute ISO range + z + .object({ type: z.literal('absolute'), from: z.string(), to: z.string() }) + .strict(), + // Relative window: N units up to today (KST) + z + .object({ + type: z.literal('relative'), + unit: z.enum(['day', 'week', 'month', 'year']), + value: z.number().int().min(1).max(365), + }) + .strict(), + // Month of a year (default year=now) + z + .object({ type: z.literal('month'), year: z.number().int().optional(), month: z.number().int().min(1).max(12) }) + .strict(), + // Quarter of a year (default year=now) + z + .object({ type: z.literal('quarter'), year: z.number().int().optional(), quarter: z.number().int().min(1).max(4) }) + .strict(), + // Single year + z.object({ type: z.literal('year'), year: z.number().int() }).strict(), + // Named presets (limited set) + z + .object({ + type: z.literal('named'), + preset: z.enum([ + 'all_time', + 'all', + 'today', + 'yesterday', + 'last_7_days', + 'last_14_days', + 'last_30_days', + 'this_month', + 'last_month', + ]), + }) + .strict(), + // Free-form label, e.g., "2006_to_now", "2024-Q3", "2019-2022", "2024-09" + z.object({ type: z.literal('label'), label: z.string().min(1) }).strict(), ]); export const planSchema = z.object({ @@ -50,12 +68,10 @@ export const planSchema = z.object({ .default({ enabled: false, retrieval_bias: 'balanced', max_rewrites: 3, max_keywords: 6 }), filters: z .object({ - user_id: z.string(), - category_ids: z.array(z.number().int()).optional(), - post_id: z.number().int().optional(), time: timeFilterSchema.optional(), }) - .default({ user_id: '' }), + .strict() + .optional(), sort: z.enum(['created_at_desc', 'created_at_asc']).default('created_at_desc'), limit: z.number().int().min(1).max(20).default(5), }); diff --git a/src/utils/time.ts b/src/utils/time.ts index 406a16e..b950068 100644 --- a/src/utils/time.ts +++ b/src/utils/time.ts @@ -36,6 +36,44 @@ export const toAbsoluteRangeKst = (input: { type: string; [k: string]: any }, ba try { const baseKst = toKst(base); const year = baseKst.getFullYear(); + // Named presets + if (input.type === 'named') { + const p = String(input.preset || '').toLowerCase(); + const endK = endOfDay(baseKst); + const beginOfTodayK = startOfDay(baseKst); + const endUtc = fromKstToUtc(endK).toISOString(); + const todayStartUtc = fromKstToUtc(beginOfTodayK).toISOString(); + if (p === 'all' || p === 'all_time') return null; // no time filter + if (p === 'today') return { from: todayStartUtc, to: endUtc }; + if (p === 'yesterday') { + const yK = new Date(beginOfTodayK.getTime()); + yK.setDate(yK.getDate() - 1); + return { from: fromKstToUtc(startOfDay(yK)).toISOString(), to: fromKstToUtc(endOfDay(yK)).toISOString() }; + } + const daysBack = (n: number) => { + const toK = endK; + const fromK = new Date(toK.getTime()); + fromK.setDate(fromK.getDate() - (n - 1)); + return { from: fromKstToUtc(startOfDay(fromK)).toISOString(), to: fromKstToUtc(toK).toISOString() }; + }; + if (p === 'last_7_days') return daysBack(7); + if (p === 'last_14_days') return daysBack(14); + if (p === 'last_30_days') return daysBack(30); + if (p === 'this_month') { + const fromK = startOfMonth(year, baseKst.getMonth()); + const toK = endOfMonth(year, baseKst.getMonth()); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + if (p === 'last_month') { + const m = baseKst.getMonth(); + const yAdj = m === 0 ? year - 1 : year; + const mAdj = m === 0 ? 11 : m - 1; + const fromK = startOfMonth(yAdj, mAdj); + const toK = endOfMonth(yAdj, mAdj); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + return null; // unknown named: drop filter + } if (input.type === 'relative') { const unit = String(input.unit); const value = Math.max(1, parseInt(String(input.value || '1'), 10)); @@ -74,9 +112,100 @@ export const toAbsoluteRangeKst = (input: { type: string; [k: string]: any }, ba const toK = endOfQuarter(y, q); return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; } + if (input.type === 'label') { + const raw = String(input.label || '').trim(); + if (!raw) return null; + const s = raw.replace(/\s+/g, '').toLowerCase(); + const endK = endOfDay(baseKst); + // Support common named tokens expressed as labels + const startTodayK = startOfDay(baseKst); + const toUtcStr = fromKstToUtc(endK).toISOString(); + const fromTodayUtcStr = fromKstToUtc(startTodayK).toISOString(); + const daysBack = (n: number) => { + const toK = endK; + const fromK = new Date(toK.getTime()); + fromK.setDate(fromK.getDate() - (n - 1)); + return { from: fromKstToUtc(startOfDay(fromK)).toISOString(), to: fromKstToUtc(toK).toISOString() }; + }; + if (s === 'all' || s === 'all_time') return null; // drop filter + if (s === 'today') return { from: fromTodayUtcStr, to: toUtcStr }; + if (s === 'yesterday') { + const yK = new Date(startTodayK.getTime()); + yK.setDate(yK.getDate() - 1); + return { from: fromKstToUtc(startOfDay(yK)).toISOString(), to: fromKstToUtc(endOfDay(yK)).toISOString() }; + } + if (s === 'last_7_days') return daysBack(7); + if (s === 'last_14_days') return daysBack(14); + if (s === 'last_30_days') return daysBack(30); + if (s === 'this_month') { + const fromK = startOfMonth(year, baseKst.getMonth()); + const toK = endOfMonth(year, baseKst.getMonth()); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + if (s === 'last_month') { + const m = baseKst.getMonth(); + const yAdj = m === 0 ? year - 1 : year; + const mAdj = m === 0 ? 11 : m - 1; + const fromK = startOfMonth(yAdj, mAdj); + const toK = endOfMonth(yAdj, mAdj); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + // 1) YYYY_to_now / YYYY-to-now + let m = s.match(/^(\d{4})(?:_|-|to)+now$/); + if (m) { + const y = parseInt(m[1], 10); + const fromK = startOfMonth(y, 0); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(endK).toISOString() }; + } + // 2) YYYY-YYYY / YYYY..YYYY / YYYY_to_YYYY + m = s.match(/^(\d{4})(?:\.|_|-|to){1,2}(\d{4})$/); + if (m) { + const y1 = parseInt(m[1], 10); + const y2 = parseInt(m[2], 10); + const a = Math.min(y1, y2); + const b = Math.max(y1, y2); + const fromK = startOfMonth(a, 0); + const toK = endOfMonth(b, 11); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + // 3) YYYY-Qn or Qn-YYYY + m = s.match(/^(\d{4})(?:-|_)q([1-4])$/); + if (m) { + const y = parseInt(m[1], 10); + const q = parseInt(m[2], 10); + const fromK = startOfQuarter(y, q); + const toK = endOfQuarter(y, q); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + m = s.match(/^q([1-4])(?:-|_)?(\d{4})$/); + if (m) { + const q = parseInt(m[1], 10); + const y = parseInt(m[2], 10); + const fromK = startOfQuarter(y, q); + const toK = endOfQuarter(y, q); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + // 4) YYYY-MM + m = s.match(/^(\d{4})(?:-|_)?(\d{1,2})$/); + if (m) { + const y = parseInt(m[1], 10); + const month = Math.max(1, Math.min(12, parseInt(m[2], 10))); + const fromK = startOfMonth(y, month - 1); + const toK = endOfMonth(y, month - 1); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + // 5) YYYY + m = s.match(/^(\d{4})$/); + if (m) { + const y = parseInt(m[1], 10); + const fromK = startOfMonth(y, 0); + const toK = endOfMonth(y, 11); + return { from: fromKstToUtc(fromK).toISOString(), to: fromKstToUtc(toK).toISOString() }; + } + return null; // unrecognized label + } } catch { // ignore } return null; }; - From 45fad46852b271ba4ce1d21167e87e494d7ce1ef Mon Sep 17 00:00:00 2001 From: chan000518 Date: Thu, 9 Oct 2025 00:36:56 +0900 Subject: [PATCH 13/14] =?UTF-8?q?=F0=9F=90=9B=20=EB=A7=90=ED=88=AC=20?= =?UTF-8?q?=EB=B0=8F=20=ED=8E=91=EC=85=98=20=EC=BD=9C=EB=A7=81=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api.md | 16 +++--- src/llm/providers/openai-responses.ts | 42 +++++++++++---- src/prompts/qa.prompts.ts | 17 ++++--- src/services/qa.v2.service.ts | 73 +++++++++++++++------------ src/services/search-plan.service.ts | 5 +- 5 files changed, 94 insertions(+), 59 deletions(-) diff --git a/docs/api.md b/docs/api.md index 7b08af3..2e55bef 100644 --- a/docs/api.md +++ b/docs/api.md @@ -93,14 +93,14 @@ - `model`: string (미지정 시 서버 기본값 사용) - `options`: `{ temperature?: number, top_p?: number, max_output_tokens?: number }` - 동작 개요 - - 서버가 질문을 토대로 “검색 계획(JSON)”을 생성·검증·정규화한 뒤, 계획에 따라 시맨틱/하이브리드 검색을 수행하고 결과를 SSE로 스트리밍합니다. + - 서버가 질문을 토대로 “검색 계획(JSON)”을 생성·검증·정규화한 뒤, 계획에 따라 시맨틱 또는 하이브리드 검색을 수행하고 결과를 SSE로 스트리밍합니다. - `post_id`가 있으면 post 모드(단일 글 컨텍스트)로 처리하며, 간략한 `search_plan`/`search_result` 이벤트 후 본문 기반 답변을 스트리밍합니다. - 하이브리드 검색(벡터+텍스트) - 계획에 `hybrid.enabled: true`인 경우 활성화됩니다. - `rewrites`(재작성 질의)와 `keywords`(핵심 키워드)를 생성하여 벡터/텍스트 두 경로로 후보를 수집하고, `hybrid.retrieval_bias` 라벨을 서버가 `alpha` 값으로 매핑해 점수를 융합하여 상위 `top_k`를 선택합니다. - 매핑(기본): `lexical → 0.3`, `balanced → 0.5`, `semantic → 0.75` - - 정규화/결합식: `score = alpha*vec + (1-alpha)*text` (min-max 정규화 후) - - SSE로 `rewrite`, `keywords`, `hybrid_result` 이벤트가 순차 송신됩니다. 하이브리드 결과가 없으면 시맨틱 검색으로 폴백합니다. + - 결합식: `score = alpha*vec + (1-alpha)*text` (각 경로 점수 min-max 정규화 후) + - SSE로 `rewrite`, `keywords`, `hybrid_result` 이벤트가 필요한 경우에만 송신됩니다. 하이브리드 결과가 없으면 시맨틱 검색으로 폴백합니다. - SSE 이벤트 순서(일반적인 흐름) 1) `search_plan`: 정규화된 검색 계획(JSON) - 예시 데이터(정규화): @@ -111,8 +111,6 @@ "threshold": 0.2, "weights": { "chunk": 0.7, "title": 0.3 }, "filters": { - "user_id": "u_123", - "category_ids": [3], "time": { "type": "absolute", "from": "2025-09-01T00:00:00.000Z", "to": "2025-09-30T23:59:59.999Z" } }, "sort": "created_at_desc", @@ -123,9 +121,9 @@ } ``` - 비고: - - `hybrid.retrieval_bias`는 LLM이 결정하는 라벨이며, 서버는 이를 `alpha`로 변환해 사용합니다. - - 카테고리는 단일 값만 지원하며 서버는 첫 번째 항목만 사용합니다. - - post 모드에서는 간략한 형태(`{ mode: "post", filters: { post_id, user_id } }`)가 송신될 수 있습니다. + - `filters.time`만 포함됩니다. `user_id`/`category_id`/`post_id` 등은 서버가 검색 시 내부적으로 적용합니다. + - `hybrid.retrieval_bias`는 LLM 라벨이며 서버가 `alpha`로 변환해 사용합니다. + - post 모드에서는 간략한 형태 예: `{ "mode": "post", "filters": { "post_id": 123, "user_id": "u_123" } }`. 2) (하이브리드 사용 시) `rewrite`: `string[]` 3) (하이브리드 사용 시) `keywords`: `string[]` 4) (하이브리드 사용 시) `hybrid_result`: `[ { postId, postTitle }, ... ]` @@ -135,6 +133,8 @@ 8) `answer` — 모델 부분 응답(여러 번) 9) `end` — `data: [DONE]` - 오류 시 `error`: `{ code?: number, message: string }` +- 폴백 동작 + - 플래너 실패 시 `search_plan`으로 `{ "mode": "rag", "fallback": true }`가 송신되며, v1 스타일 RAG로 컨텍스트를 구성합니다. - 예시(curl) ```bash diff --git a/src/llm/providers/openai-responses.ts b/src/llm/providers/openai-responses.ts index d45d2db..65cc1ec 100644 --- a/src/llm/providers/openai-responses.ts +++ b/src/llm/providers/openai-responses.ts @@ -123,6 +123,14 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise { + const args = ev?.arguments || ev?.arguments_delta || ''; + if (args) { + safeWrite(`event: answer\n`); + safeWrite(`data: ${JSON.stringify(args)}\n\n`); + } + }); // Catch-all messages to ensure we don't miss alternative text events responsesStream.on('message', (msg: any) => { @@ -238,17 +246,31 @@ export const generateOpenAIStream = async (req: GenerateRequest): Promise 0 ? 'auto' : undefined, - stream: true, - temperature: req.options?.temperature, - top_p: req.options?.top_p, - max_tokens: req.options?.max_output_tokens as any, - }); + let chatStream: any; + // temperature/top_p are not supported on reasoning models (e.g., GPT-5 family) + if (!isGpt5Family) { + chatStream = await openai.chat.completions.create({ + model, + messages: messages as any, + tools: (req.tools as OpenAI.Chat.Completions.ChatCompletionTool[]) || undefined, + tool_choice: req.tools && req.tools.length > 0 ? 'auto' : undefined, + stream: true, + temperature: req.options?.temperature, + top_p: req.options?.top_p, + max_tokens: req.options?.max_output_tokens as any, + }); + } else { + chatStream = await openai.chat.completions.create({ + model, + messages: messages as any, + tools: (req.tools as OpenAI.Chat.Completions.ChatCompletionTool[]) || undefined, + tool_choice: req.tools && req.tools.length > 0 ? 'auto' : undefined, + stream: true, + max_tokens: req.options?.max_output_tokens as any, + }); + } + // Iterate asynchronously; return stream immediately to allow real-time consumption (async () => { try { diff --git a/src/prompts/qa.prompts.ts b/src/prompts/qa.prompts.ts index 8f93f75..599e46d 100644 --- a/src/prompts/qa.prompts.ts +++ b/src/prompts/qa.prompts.ts @@ -12,15 +12,16 @@ export const createPostContextPrompt = ( 모든 한국어 응답은 무슨일이 있어도 반드시 답변 말투 및 규칙을 따릅니다. 또한 주어진 내용외의 내용을 지어내지 마십시오. + [말투 지침] + ${speechTonePrompt} + - 위 말투/지시문을 출력에 절대 노출하지 말고(예: "말투", "규칙" 등 언급 금지), 실제 답변 내용에만 반영하십시오. + [응답 규칙] 1. 만약 제목과 본문을 활용해 답변할 수 있다면 답변 말투 및 규칙을 지켜 직접 답변하고, 마지막에 추가적인 내용에 대한 질문을 유도하는 문장을 추가합니다. 2. 만약 질문이 욕설·비난·무관·부적절하거나 주어진 제목, 본문과 관련이 없다면 사과와 블로그 관련된 내용만 답변 가능하다는 내용을 답변 말투 및 규칙을 지켜 답합니다. - 3. 질문이 블로그 카테고리나 사용자 블로그에는 부합하지만 제공된 본문 컨텍스트의 내용이 매우 부족하거나 적절하지 않다고 판단되면 report_content_insufficient 함수를 호출하고 답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다. + 3. 질문이 블로그 카테고리나 사용자 블로그에는 부합하지만 제공된 본문 컨텍스트의 내용이 매우 부족하거나 적절하지 않다고 판단되면, 함수명이나 함수 호출을 절대 언급하지 말고(예: "report_content_insufficient" 같은 문자열이나 괄호 "()" 출력 금지), 답변 말투 및 규칙을 지켜 자연스럽게 다음을 수행합니다: (a) 현재로서는 본문 컨텍스트가 부족함을 간단히 안내하고, (b) 질문과 직접 관련된 정보를 구체적으로 요청합니다(예: 게시일, 최근 글 목록, 최신 포스트의 제목과 날짜 등). 서버가 내부 함수를 제공하는 경우에도 사용자가 보는 답변에는 함수명/호출을 절대 노출하지 않습니다. `; const userMessage = ` -[instruction] -답변 말투: "${speechTonePrompt}" - [context] 제목: ${post.title} 작성일: ${post.created_at} @@ -49,14 +50,16 @@ export const createRagPrompt = ( 모든 한국어 응답은 무슨일이 있어도 반드시 답변 말투 및 규칙을 따릅니다. 또한 주어진 내용외의 내용을 지어내지 마십시오. + [말투 지침] + ${speechTonePrompt} + - 위 말투/지시문을 출력에 절대 노출하지 말고(예: "말투", "규칙" 등 언급 금지), 실제 답변 내용에만 반영하십시오. + [응답 규칙] 1. 만약 제목과 본문을 활용해 답변할 수 있다면 답변 말투 및 규칙을 지켜 직접 답변하고, 마지막에 추가적인 내용에 대한 질문을 유도하는 문장을 추가합니다. 2. 만약 질문이 욕설·비난·무관·부적절하거나 주어진 제목, 본문과 관련이 없다면 사과와 블로그 관련된 내용만 답변 가능하다는 내용을 답변 말투 및 규칙을 지켜 답합니다. - 3. 질문이 블로그 카테고리나 사용자 블로그에는 부합하지만 제공된 본문 컨텍스트의 내용이 매우 부족하거나 적절하지 않다고 판단되면 report_content_insufficient 함수를 호출하고 답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다. + 3. 질문이 블로그 카테고리나 사용자 블로그에는 부합하지만 제공된 본문 컨텍스트의 내용이 매우 부족하거나 적절하지 않다고 판단되면, 함수명이나 함수 호출을 절대 언급하지 말고(예: "report_content_insufficient" 같은 문자열이나 괄호 "()" 출력 금지), 답변 말투 및 규칙을 지켜 자연스럽게 다음을 수행합니다: (a) 현재로서는 본문 컨텍스트가 부족함을 간단히 안내하고, (b) 질문과 직접 관련된 정보를 구체적으로 요청합니다(예: 게시일, 최근 글 목록, 최신 포스트의 제목과 날짜 등). 서버가 내부 함수를 제공하는 경우에도 사용자가 보는 답변에는 함수명/호출을 절대 노출하지 않습니다. `; const userMessage = ` - 답변 말투 및 규칙: "${speechTonePrompt}" - 반드시 말투 및 규칙에 따라 대답하세요! 아래의 질문과 블로그 본문 컨텍스트를 참고하여 답변하세요. 사용자의 질문: ${question} 가장 근접한 블로그 본문 컨텍스트: diff --git a/src/services/qa.v2.service.ts b/src/services/qa.v2.service.ts index 294195e..8a8e651 100644 --- a/src/services/qa.v2.service.ts +++ b/src/services/qa.v2.service.ts @@ -113,26 +113,30 @@ export const answerStreamV2 = async ( messages = toSimpleMessages( qaPrompts.createRagPrompt(question, similarChunks, speechTonePrompt) ); - tools = [ - { - type: 'function', - function: { - name: 'report_content_insufficient', - description: '카테고리는 맞지만 본문 컨텍스트가 부족할 때 호출', - parameters: { - type: 'object', - properties: { - text: { - type: 'string', - description: - '답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다.', + if (similarChunks.length === 0) { + tools = undefined; + } else { + tools = [ + { + type: 'function', + function: { + name: 'report_content_insufficient', + description: '카테고리는 맞지만 본문 컨텍스트가 부족할 때 호출', + parameters: { + type: 'object', + properties: { + text: { + type: 'string', + description: + '답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다.', + }, }, + required: ['text'], }, - required: ['text'], }, }, - }, - ]; + ]; + } } else { const plan: any = planPair.normalized; stream.write(`event: search_plan\n`); @@ -210,26 +214,31 @@ export const answerStreamV2 = async ( speechTonePrompt ) ); - tools = [ - { - type: 'function', - function: { - name: 'report_content_insufficient', - description: '카테고리는 맞지만 본문 컨텍스트가 부족할 때 호출', - parameters: { - type: 'object', - properties: { - text: { - type: 'string', - description: - '답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다.', + // If no context was found, avoid tool-calls to force direct natural-language guidance + if (rows.length === 0) { + tools = undefined; + } else { + tools = [ + { + type: 'function', + function: { + name: 'report_content_insufficient', + description: '카테고리는 맞지만 본문 컨텍스트가 부족할 때 호출', + parameters: { + type: 'object', + properties: { + text: { + type: 'string', + description: + '답변 말투 및 규칙을 지켜 해당 내용이 아직 부족하다는 안내를 합니다. 그 후 본문 컨텍스트를 참고해 질문과 관련된 답변할 수 있는 내용을 언급하고 해당 내용에 대한 질문을 직접적으로 유도합니다.', + }, }, + required: ['text'], }, - required: ['text'], }, }, - }, - ]; + ]; + } } } diff --git a/src/services/search-plan.service.ts b/src/services/search-plan.service.ts index 22fa98a..507a1c4 100644 --- a/src/services/search-plan.service.ts +++ b/src/services/search-plan.service.ts @@ -40,7 +40,7 @@ export const generateSearchPlan = async ( JSON.stringify( { type: 'debug.plan.prompt', - model: config.CHAT_MODEL || 'gpt-5-mini', + model: 'gpt-5-mini', prompt_len: prompt.length, head: prompt.slice(0, 600), tail: prompt.slice(Math.max(0, prompt.length - 600)), @@ -52,9 +52,10 @@ export const generateSearchPlan = async ( } catch {} const response: any = await (openai as any).responses.create({ - model: config.CHAT_MODEL || 'gpt-5-mini', + model: 'gpt-5-mini', input: prompt, text: { format: { type: 'json_schema', name: 'SearchPlan', schema: getSearchPlanSchemaJson()} }, + reasoning: { effort: 'minimal' }, max_output_tokens: 1500, }); From 3bfb8ea234aac5a694a1ca242147a7e862042959 Mon Sep 17 00:00:00 2001 From: chan000518 Date: Thu, 9 Oct 2025 00:37:16 +0900 Subject: [PATCH 14/14] =?UTF-8?q?=F0=9F=90=9B=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=A1=B0=ED=9A=8C=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/repositories/post.repository.ts | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/repositories/post.repository.ts b/src/repositories/post.repository.ts index eade868..ffc17c0 100644 --- a/src/repositories/post.repository.ts +++ b/src/repositories/post.repository.ts @@ -29,11 +29,26 @@ export interface TextSearchHit { // ========= READ QUERIES ========= export const findPostById = async (postId: number): Promise => { const pool = getDb(); - const { rows } = await pool.query( - 'SELECT id, title, content, tags, created_at, user_id, is_public FROM blog_post WHERE id = $1', + // Some databases may not have a `tags` column on blog_post. + // Select existing columns and populate `tags` as an empty array fallback. + const { rows } = await pool.query( + 'SELECT id, title, content, created_at, user_id, is_public FROM blog_post WHERE id = $1', [postId] ); - return rows.length > 0 ? rows[0] : null; + if (rows.length === 0) return null; + + const row = rows[0] as any; + const post: Post = { + id: row.id, + title: row.title, + content: row.content, + // Fallback: DB has no tags column; keep empty list so prompts render gracefully + tags: Array.isArray(row.tags) ? row.tags : [], + created_at: row.created_at, + user_id: row.user_id, + is_public: row.is_public, + }; + return post; }; export const findSimilarChunks = async (