[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,91 +2,250 @@
|
||||
id: wiki-2026-0508-search-optimization
|
||||
title: Search Optimization
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-SEOP-001]
|
||||
aliases: [Search Tuning, Retrieval Optimization, Hybrid Search]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
tags: [auto-reinforced, Search-Optimization, algorithms, pathfinding, Heuristic-Search, Efficiency]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [search, retrieval, bm25, vector, hybrid, rag]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-04-20
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: unspecified
|
||||
framework: unspecified
|
||||
language: Python
|
||||
framework: Elasticsearch + pgvector
|
||||
---
|
||||
|
||||
# [[Search-Optimization|Search-Optimization]]
|
||||
# Search Optimization
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
> "최단 경로를 향한 끝없는 탐색: 수없이 많은 선택지의 숲([[State|State]] Space)에서, 목표 지점까지의 비용을 최소화하기 위해 휴리스틱(Heuristic)이라는 나침반을 들고 가장 유망한 방향으로 발을 들이는 영리한 길 찾기."
|
||||
## 매 한 줄
|
||||
> **"매 search 의 quality 는 매 lexical(BM25) + semantic(vector) hybrid + reranker 의 stack — 매 single signal 의 X"**. 매 origin 은 1970s tf-idf, 1994 BM25 (Robertson); 매 modern state 는 BM25F + dense vector (ColBERT/E5/Cohere v3.5) + cross-encoder rerank, 매 RAG 의 retrieval layer.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
탐색 최적화(Search-Optimization)는 문제의 해답을 찾기 위해 가능한 모든 상태를 효율적으로 조사하는 기법입니다. (Grail-Search적 관점 포함)
|
||||
## 매 핵심
|
||||
|
||||
1. **주요 알고리즘**:
|
||||
* **Uninformed Search**: 정보 없이 다 뒤지는 방식 (BFS, DFS). ([[Brute-force|Brute-force]]와 연결)
|
||||
* **Informed Search (Heuristic)**: 목표까지 남은 거리를 '추정'해서 탐색 (A* Algorithm).
|
||||
* **Local Search**: 현재보다 나은 주변으로만 이동 (Hill Climbing, Simulated Annealing).
|
||||
2. **왜 중요한가?**:
|
||||
* 게임 AI의 경로 찾기, 물류 배송 최적화, 퍼즐 풀이, 그리고 신경망의 가중치를 찾는 과정([[Gradient-Descent|Gradient-Descent]]) 자체가 거대한 탐색 최적화 문제임.
|
||||
### 매 search stack (매 2026 modern)
|
||||
- **Lexical**: BM25 (Elasticsearch, OpenSearch, Tantivy) — 매 exact term, rare token, code.
|
||||
- **Dense vector**: bi-encoder (E5-large, Cohere embed-v3.5, OpenAI 3-large) — 매 semantic match.
|
||||
- **Sparse-learned**: SPLADE — 매 lexical + learned weight.
|
||||
- **Hybrid fusion**: RRF (Reciprocal Rank Fusion) or weighted score sum.
|
||||
- **Reranker**: cross-encoder (Cohere rerank-3.5, BGE-reranker-v2) — 매 top-50 → top-10.
|
||||
- **Query understanding**: LLM rewrite, HyDE, multi-query expansion.
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- **과거 데이터와의 충돌**: 과거에는 '완전 탐색 정책'으로 정답을 보장하려 했으나, 현대 정책은 정답보다 '충분히 좋은 해 정책(Satisficing)'을 제한된 시간 내에 찾는 효율성 정책을 우선시함(RL Update). ([[Bounded-Rationality|Bounded-Rationality]]와 연결)
|
||||
- **정책 변화(RL Update)**: 거대 모델의 추론 정책에서, 수많은 답변 후보 중 가장 논리적인 경로를 탐색하는 'MCTS(Monte Carlo Tree Search)' 기반의 사고 흐름 탐색 정책이 새로운 성능 향상의 돌파구가 됨.
|
||||
### 매 응용
|
||||
1. Site search (e-commerce, docs).
|
||||
2. RAG retrieval.
|
||||
3. Code search (GitHub).
|
||||
4. Internal knowledge search.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- [[Brute-force|Brute-force]], [[Optimization|Optimization]], [[Heuristics|Heuristics]], [[Combinatorial-Optimization|Combinatorial-Optimization]], [[Gradient-Descent|Gradient-Descent]]
|
||||
- **Modern Tech/Tools**: A* Search, MCTS, Beam Search (in NLP), AlphaGo's search engine.
|
||||
---
|
||||
## 💻 패턴
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
|
||||
## 💻 코드 패턴 (Code Patterns)
|
||||
|
||||
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
|
||||
|
||||
```text
|
||||
# TODO
|
||||
### 매 BM25 (Elasticsearch 9, 매 tuned)
|
||||
```json
|
||||
PUT /products
|
||||
{
|
||||
"settings": {
|
||||
"similarity": {
|
||||
"default": {
|
||||
"type": "BM25",
|
||||
"k1": 1.2,
|
||||
"b": 0.75
|
||||
}
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"title": { "type": "text", "boost": 3.0 },
|
||||
"description": { "type": "text" },
|
||||
"tags": { "type": "keyword" },
|
||||
"embedding": { "type": "dense_vector", "dims": 1024, "similarity": "cosine" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### 매 hybrid query (RRF, ES 9 native)
|
||||
```json
|
||||
GET /products/_search
|
||||
{
|
||||
"retriever": {
|
||||
"rrf": {
|
||||
"retrievers": [
|
||||
{ "standard": {
|
||||
"query": { "multi_match": {
|
||||
"query": "wireless earbuds noise cancel",
|
||||
"fields": ["title^3", "description"]
|
||||
}}
|
||||
}},
|
||||
{ "knn": {
|
||||
"field": "embedding",
|
||||
"query_vector_builder": {
|
||||
"text_embedding": {
|
||||
"model_id": "cohere-embed-v3-5",
|
||||
"model_text": "wireless earbuds noise cancel"
|
||||
}
|
||||
},
|
||||
"k": 50, "num_candidates": 200
|
||||
}}
|
||||
],
|
||||
"rank_window_size": 100,
|
||||
"rank_constant": 60
|
||||
}
|
||||
},
|
||||
"size": 10
|
||||
}
|
||||
```
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### 매 BM25 tuning (매 corpus 별 k1/b)
|
||||
```python
|
||||
# 매 short corpus (titles): k1=1.2, b=0.5 (매 length penalty 약하게)
|
||||
# 매 long docs (articles): k1=1.5, b=0.75 (매 default)
|
||||
# 매 code search: k1=2.0, b=0.0 (매 length 무관)
|
||||
# 매 grid search 매 NDCG@10 으로 tune
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
from rank_bm25 import BM25Okapi
|
||||
import numpy as np
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
def grid_search(corpus, queries, judgments):
|
||||
best = (None, -1)
|
||||
for k1 in [0.8, 1.0, 1.2, 1.5, 2.0]:
|
||||
for b in [0.0, 0.25, 0.5, 0.75, 1.0]:
|
||||
bm25 = BM25Okapi(corpus, k1=k1, b=b)
|
||||
ndcg = evaluate(bm25, queries, judgments)
|
||||
if ndcg > best[1]:
|
||||
best = ((k1, b), ndcg)
|
||||
return best
|
||||
```
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
### 매 cross-encoder rerank (Cohere v3.5)
|
||||
```python
|
||||
import cohere
|
||||
co = cohere.ClientV2()
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
# 매 stage 1: hybrid retrieve top 50
|
||||
candidates = hybrid_search(query, k=50)
|
||||
|
||||
# 매 stage 2: rerank to top 10
|
||||
resp = co.rerank(
|
||||
model="rerank-v3.5",
|
||||
query=query,
|
||||
documents=[c.text for c in candidates],
|
||||
top_n=10,
|
||||
)
|
||||
top10 = [candidates[r.index] for r in resp.results]
|
||||
```
|
||||
|
||||
### 매 HyDE (Hypothetical Document Embedding)
|
||||
```python
|
||||
import anthropic
|
||||
client = anthropic.Anthropic()
|
||||
|
||||
def hyde_query(question: str) -> str:
|
||||
"""매 question 을 hypothetical answer 로 변환 → 매 그것 을 embed."""
|
||||
msg = client.messages.create(
|
||||
model="claude-haiku-4-5",
|
||||
max_tokens=256,
|
||||
messages=[{"role": "user", "content":
|
||||
f"Write a 3-sentence hypothetical answer to: {question}"}],
|
||||
)
|
||||
return msg.content[0].text
|
||||
|
||||
# 매 query embedding 의 quality 향상 — 매 query-doc length asymmetry 완화
|
||||
hypothetical = hyde_query("how does pgvector handle 1024-dim embeddings?")
|
||||
emb = embed(hypothetical)
|
||||
results = vector_search(emb)
|
||||
```
|
||||
|
||||
### 매 multi-query expansion (매 LLM)
|
||||
```python
|
||||
def expand_query(q: str) -> list[str]:
|
||||
msg = client.messages.create(
|
||||
model="claude-haiku-4-5",
|
||||
max_tokens=256,
|
||||
messages=[{"role": "user", "content":
|
||||
f"Generate 3 alternative phrasings for search:\n{q}\n"
|
||||
"Return one per line."}],
|
||||
)
|
||||
return [q] + msg.content[0].text.splitlines()
|
||||
|
||||
# 매 매 phrasing 으로 search → RRF merge
|
||||
queries = expand_query("how to ship a model fast")
|
||||
all_hits = [search(q) for q in queries]
|
||||
final = rrf_merge(all_hits)
|
||||
```
|
||||
|
||||
### 매 pgvector hybrid (Postgres 17)
|
||||
```sql
|
||||
-- 매 BM25 (pg_search ext) + vector hybrid
|
||||
WITH lexical AS (
|
||||
SELECT id, paradedb.score(id) AS s
|
||||
FROM docs
|
||||
WHERE id @@@ 'description:earbuds'
|
||||
ORDER BY s DESC LIMIT 50
|
||||
),
|
||||
semantic AS (
|
||||
SELECT id, 1 - (embedding <=> $1::vector) AS s
|
||||
FROM docs
|
||||
ORDER BY embedding <=> $1::vector LIMIT 50
|
||||
)
|
||||
SELECT id,
|
||||
COALESCE(1.0/(60 + l.rk), 0) + COALESCE(1.0/(60 + s.rk), 0) AS rrf_score
|
||||
FROM (SELECT id, ROW_NUMBER() OVER (ORDER BY s DESC) rk FROM lexical) l
|
||||
FULL OUTER JOIN
|
||||
(SELECT id, ROW_NUMBER() OVER (ORDER BY s DESC) rk FROM semantic) s
|
||||
USING (id)
|
||||
ORDER BY rrf_score DESC LIMIT 10;
|
||||
```
|
||||
|
||||
### 매 evaluation (NDCG@10, 매 judgment list)
|
||||
```python
|
||||
import numpy as np
|
||||
|
||||
def dcg(rels):
|
||||
return sum(r / np.log2(i + 2) for i, r in enumerate(rels))
|
||||
|
||||
def ndcg(predicted_ids, judgments, k=10):
|
||||
rels = [judgments.get(pid, 0) for pid in predicted_ids[:k]]
|
||||
ideal = sorted(judgments.values(), reverse=True)[:k]
|
||||
return dcg(rels) / dcg(ideal) if dcg(ideal) > 0 else 0
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 keyword-heavy (code, IDs) | BM25 dominant, vector secondary |
|
||||
| 매 semantic (NL question) | vector dominant + BM25 floor |
|
||||
| 매 mixed (e-commerce) | hybrid RRF + cross-encoder rerank |
|
||||
| 매 high-precision top-3 | hybrid → cross-encoder rerank |
|
||||
| 매 query 가 짧음/모호 | LLM expand + HyDE |
|
||||
| 매 latency-critical (<50ms) | BM25 only or pre-computed embeddings |
|
||||
|
||||
**기본값**: hybrid (BM25 + dense) + Cohere rerank-v3.5 top-10 + LLM query expansion 옵션.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Information Retrieval]] · [[RAG]]
|
||||
- 변형: [[BM25]] · [[Vector Search]] · [[Hybrid Search]] · [[Reranker]]
|
||||
- 응용: [[Site Search]] · [[Semantic Search]] · [[Code Search]]
|
||||
- Adjacent: [[Embeddings]] · [[ColBERT]] · [[SPLADE]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 query expansion, HyDE, query rewrite. 매 reranker prompt-style. 매 result summarization (RAG).
|
||||
**언제 X**: 매 retrieval 자체 — 매 vector + BM25 가 더 cheap/fast. 매 LLM-as-retriever 의 latency 비합리.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Vector-only search**: 매 exact term (UUID, error code) 매 miss.
|
||||
- **No reranker**: 매 top-50 retrieval 의 noise → top-10 quality 저하.
|
||||
- **Default BM25 params**: 매 corpus 매 다름 — 매 tune.
|
||||
- **No eval set**: 매 judgment 없이 tune → 매 vibe-driven.
|
||||
- **Embedding drift**: 매 model upgrade 시 reindex 안 함.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Robertson & Zaragoza "BM25 and Beyond" 2009, BEIR benchmark, Cohere/Anthropic 2026 docs, Pinecone "Hybrid Search").
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — BM25 + vector hybrid + RRF + Cohere rerank-v3.5 + HyDE |
|
||||
|
||||
Reference in New Issue
Block a user