搜尋與對話
Search & Chat
以下為前端整合最常用的端點。
These are the most commonly used endpoints for frontend integration.
語意搜尋
Semantic Search
POST /api/v1/search
透過混合語意搜尋 + 關鍵字搜尋,並支援同義詞擴展,搜尋知識庫。
Search the knowledge base using hybrid semantic + keyword search with synonym expansion.
請求
Request
{
"query": "How to improve Core Web Vitals",
"top_k": 5,
"category": "Technical SEO"
}
| 欄位 / Field | 型別 / Type | 必填 / Required | 說明 / Description |
|---|---|---|---|
query |
string | Yes | 搜尋查詢(1-500 字元) Search query (1-500 chars) |
top_k |
number | No | 回傳結果數(預設:5,最大:20) Number of results (default: 5, max: 20) |
category |
string | No | 依分類篩選 Filter by category |
extraction_model |
string | No | 依萃取模型篩選(例如 "claude-code")Filter by extraction model (e.g. "claude-code") |
maturity_level |
string | No | 提升符合指定成熟度等級的結果排序("L1"–"L4")Boost results matching this maturity level ( "L1"–"L4") |
回應
Response
{
"results": [
{
"question": "What are Core Web Vitals and how do they impact SEO?",
"answer": "Core Web Vitals are a set of metrics...",
"score": 0.89,
"source_type": "meeting",
"source_collection": "weekly-meetings",
"category": "Technical SEO",
"difficulty": "advanced",
"id": "a1b2c3d4e5f67890"
}
],
"total": 5,
"mode": "hybrid"
}
搜尋模式(自動)
Search Modes (automatic)
| 條件 / Condition | Mode | 說明 / Description |
|---|---|---|
| 已設定 Supabase Supabase configured |
hybrid |
pgvector embedding + 關鍵字加權 pgvector embedding + keyword boost |
| 僅有 OpenAI Key OpenAI key only |
hybrid |
Embedding 相似度 + 關鍵字加權 Embedding similarity + keyword boost |
| 無 OpenAI Key No OpenAI key |
keyword |
純關鍵字搜尋,支援同義詞擴展 Keyword-only search with synonym expansion |
前端範例
Frontend Example
async function searchKnowledgeBase(query: string, category?: string) {
const res = await fetch("/api/proxy/search", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query, top_k: 10, category }),
});
const data = await res.json();
return data.results; // { question, answer, score, source_type, category }[]
}
RAG 對話
RAG Chat
POST /api/v1/chat
單輪問答,自動從知識庫檢索相關內容。
Single-turn question answering with automatic knowledge base retrieval.
請求
Request
{
"message": "What is the difference between canonical URL and 301 redirect?",
"history": [
{ "role": "user", "content": "What is canonical URL?" },
{ "role": "assistant", "content": "A canonical URL is..." }
],
"mode": "rag"
}
| 欄位 / Field | 型別 / Type | 必填 / Required | 說明 / Description |
|---|---|---|---|
message |
string | Yes | 使用者訊息(1-2000 字元) User message (1-2000 chars) |
history |
array | No | 上下文用的歷史訊息(最多 20 條) Previous messages for context (max 20) |
mode |
string | No | "rag" 或 "agent"(預設:auto)"rag" or "agent" (default: auto) |
maturity_level |
string | No | 客戶 SEO 成熟度("L1"–"L4"),用於調整回應深度Client SEO maturity level ( "L1"–"L4") for response depth tuning |
回應
Response
{
"answer": "Canonical URLs and 301 redirects serve different purposes...",
"sources": [
{
"question": "What is canonical URL?",
"answer": "...",
"source_type": "meeting",
"category": "Technical SEO",
"id": "abc123def456"
}
],
"mode": "rag",
"metadata": {
"model": "gpt-5.4-nano",
"provider": "openai",
"mode": "rag",
"input_tokens": 1250,
"output_tokens": 380,
"total_tokens": 1630,
"duration_ms": 2340,
"retrieval_count": 5
}
}
模式比較
Mode Comparison
| Mode | 行為 / Behavior | 延遲 / Latency | 適用情境 / Use Case |
|---|---|---|---|
rag |
單次檢索 + 生成 Single retrieval + generation |
~2-3s | 簡單事實性問題 Simple factual questions |
agent |
多輪搜尋(最多 5 輪) Multi-turn search (up to 5 rounds) |
~5-15s | 複雜的比較型問題 Complex comparison questions |
context-only |
不呼叫 LLM,直接回傳來源 No LLM, returns sources only |
~0.5s | 未設定 OpenAI Key 時 When no OpenAI key |
前端範例
Frontend Example
interface ChatResponse {
answer: string | null;
sources: Array<{
question: string;
answer: string;
source_type: string;
category: string;
id: string;
}>;
mode: "rag" | "agent" | "context-only";
metadata?: {
model: string;
duration_ms: number;
total_tokens: number;
};
}
async function askQuestion(message: string, mode?: "rag" | "agent") {
const res = await fetch("/api/proxy/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message, mode }),
});
return (await res.json()) as ChatResponse;
}
Session 對話
Session-Based Chat
適用於需要跨訊息保留對話上下文的多輪對話情境。
For multi-turn conversations where context needs to be preserved across messages.
建立 Session
Create Session
const session = await fetch("/api/proxy/sessions", { method: "POST" });
const { id } = await session.json();
// id: "550e8400-e29b-41d4-a716-446655440000"
發送訊息
Send Message
const response = await fetch(`/api/proxy/sessions/${sessionId}/messages`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: "What is structured data?", mode: "rag" }),
});
回應包含 Metadata
Response includes metadata
{
"role": "assistant",
"content": "Structured data is...",
"metadata": {
"model": "gpt-5.4-nano",
"mode": "rag",
"duration_ms": 1820,
"retrieval_count": 3
}
}
取得對話歷史
Get Session History
const session = await fetch(`/api/proxy/sessions/${sessionId}`);
const { messages } = await session.json();
// messages: Array<{ role, content, metadata?, created_at }>