AI Gateway
Vecstruct AI Gateway 讓你透過一個統一 API 存取 OpenAI、Anthropic、Google 等多家 AI 服務。格式與 OpenAI 100% 相容,現有的 OpenAI 整合只需替換 base_url 就能切換。
支援的功能
- Chat Completions — 對話生成,支援串流回應
- Embeddings — 文字向量化,用於語義搜尋、相似度計算
- Rerank — 重新排序搜尋結果,提升相關性精準度
- Models — 查詢可用模型清單
模型代碼格式
所有模型以 provider/model-name 格式指定:
openai/gpt-4o
anthropic/claude-3-5-sonnet-20241022
google/gemini-2.0-flash
baai/bge-reranker-v2-m3
可用模型清單:vecstruct.com/models 或透過 Models API 查詢。
Chat Completions
基本對話
- Node.js
- Python
- Go
import { Vecstruct } from '@vecstruct/sdk';
const client = new Vecstruct({ apiKey: process.env.VECSTRUCT_API_KEY });
const reply = await client.chat.completions.create({
model: 'openai/gpt-4o',
messages: [
{ role: 'system', content: '你是一位資深工程師,擅長解釋技術概念。' },
{ role: 'user', content: '什麼是向量搜尋?' },
],
temperature: 0.7,
max_tokens: 1024,
});
console.log(reply.choices[0].message.content);
console.log('使用 token 數:', reply.usage.total_tokens);
from vecstruct import AsyncVecstruct
import os
async with AsyncVecstruct(api_key=os.environ["VECSTRUCT_API_KEY"]) as client:
reply = await client.chat.completions.create(
model="openai/gpt-4o",
messages=[
{"role": "system", "content": "你是一位資深工程師,擅長解釋技術概念。"},
{"role": "user", "content": "什麼是向量搜尋?"},
],
temperature=0.7,
max_tokens=1024,
)
print(reply["choices"][0]["message"]["content"])
resp, err := client.CreateChatCompletion(ctx, vecstruct.ChatCompletionRequest{
Model: "openai/gpt-4o",
Messages: []vecstruct.ChatMessage{
{Role: "system", Content: "你是一位資深工程師,擅長解釋技術概念。"},
{Role: "user", Content: "什麼是向量搜尋?"},
},
Temperature: 0.7,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Choices[0].Message.Content)
串流回應
串流模式下,AI 生成的文字會即時分段推送,適合需要即時顯示的使用者介面。
- Node.js
- Python
- Go
for await (const event of client.chat.completions.stream({
model: 'openai/gpt-4o',
messages: [{ role: 'user', content: '寫一段關於向量搜尋的說明' }],
})) {
if (event.type === 'chunk') {
process.stdout.write(event.chunk.choices[0]?.delta.content ?? '');
} else if (event.type === 'vecstruct') {
// 串流結束後的統計資訊(消耗 token 數、audit ID 等)
console.log('\n--- 統計:', event.vecstruct);
}
}
async for chunk in client.chat.completions.stream(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "寫一段關於向量搜尋的說明"}],
):
if "choices" in chunk:
content = chunk["choices"][0]["delta"].get("content", "")
print(content, end="", flush=True)
stream, err := client.StreamChatCompletion(ctx, vecstruct.ChatCompletionRequest{
Model: "openai/gpt-4o",
Messages: []vecstruct.ChatMessage{
{Role: "user", Content: "寫一段關於向量搜尋的說明"},
},
})
if err != nil {
log.Fatal(err)
}
defer stream.Close()
for {
chunk, err := stream.Next()
if errors.Is(err, io.EOF) {
break
}
if len(chunk.Choices) > 0 {
fmt.Print(chunk.Choices[0].Delta.Content)
}
}
Embeddings
Embedding 把文字轉成一組數字(向量),讓你可以計算兩段文字的語義相似度。常用於搜尋、推薦、分群等場景。
通俗解釋:想像把每段文字映射到一個多維空間上的點,語義相近的文字在空間中距離更近。
- Node.js
- Python
- Go
const res = await client.embeddings.create({
model: 'openai/text-embedding-3-small',
input: ['向量搜尋是什麼', '機器學習的基本概念'],
});
console.log('向量維度:', res.data[0].embedding.length); // 1536
res = await client.embeddings.create(
model="openai/text-embedding-3-small",
input=["向量搜尋是什麼", "機器學習的基本概念"],
)
print("向量維度:", len(res["data"][0]["embedding"])) # 1536
emb, err := client.CreateEmbedding(ctx, vecstruct.EmbeddingRequest{
Model: "openai/text-embedding-3-small",
Input: []string{"向量搜尋是什麼", "機器學習的基本概念"},
})
fmt.Println("向量維度:", len(emb.Data[0].Embedding)) // 1536
應用場景:
- 語義搜尋:計算用戶查詢與文件的相似度
- 推薦系統:找到與當前內容相似的其他內容
- 文字分群:把相似主題的文章自動歸類
Rerank
Rerank 把一組候選文件按照與查詢的相關性重新排序,讓最相關的結果排在最前面。比單純的向量搜尋更精準。
通俗解釋:向量搜尋好比用關鍵字找出一批候選,Rerank 則是精讀每篇候選文章後,挑出真正最符合問題的那幾篇。
- Node.js
- Python
- Go
const res = await client.rerank.create({
model: 'baai/bge-reranker-v2-m3',
query: '如何申請退貨?',
documents: [
'我們提供 7 天無理由退貨服務,商品需保持原始包裝。',
'配送通常需要 3-5 個工作天。',
'退貨申請請至會員中心點擊「申請退貨」按鈕。',
'運費計算方式依重量和地區而定。',
],
top_n: 2,
});
for (const r of res.results) {
console.log(`相關度: ${r.relevance_score.toFixed(3)} | ${r.document}`);
}
res = await client.rerank.create(
model="baai/bge-reranker-v2-m3",
query="如何申請退貨?",
documents=[
"我們提供 7 天無理由退貨服務,商品需保持原始包裝。",
"配送通常需要 3-5 個工作天。",
"退貨申請請至會員中心點擊「申請退貨」按鈕。",
"運費計算方式依重量和地區而定。",
],
top_n=2,
)
for r in res["results"]:
print(f"相關度: {r['relevance_score']:.3f} | {r['document']}")
rr, err := client.Rerank(ctx, vecstruct.RerankRequest{
Model: "baai/bge-reranker-v2-m3",
Query: "如何申請退貨?",
Documents: []string{
"我們提供 7 天無理由退貨服務,商品需保持原始包裝。",
"配送通常需要 3-5 個工作天。",
"退貨申請請至會員中心點擊「申請退貨」按鈕。",
"運費計算方式依重量和地區而定。",
},
TopN: 2,
})
for _, hit := range rr.Results {
fmt.Printf("相關度: %.3f | 原始索引: %d\n", hit.RelevanceScore, hit.Index)
}
應用場景:
- 精確化 RAG 結果:先向量搜尋取 20 篇,再用 Rerank 篩出最相關的 5 篇
- 搜尋引擎優化:電商產品搜尋、文件搜尋
應用場景範例
範例一:客服機器人
讓 AI 根據你的產品說明書、FAQ 回答客戶問題,回答都有文件來源可追溯。
// 客戶詢問退貨問題
const reply = await client.chat.completions.create({
model: 'openai/gpt-4o',
messages: [
{ role: 'system', content: '你是客服助理,根據公司政策回答問題。如果不知道就說不知道,不要捏造答案。' },
{ role: 'user', content: '我買的商品壞了,可以退貨嗎?' },
],
vecstruct: {
rag: true, // 開啟知識庫查詢
rag_top_k: 5,
},
});
// 回覆加上引用來源,讓客戶可以自行核實
console.log(reply.choices[0].message.content);
if (reply.vecstruct?.rag_sources?.length) {
console.log('引用來源:');
for (const src of reply.vecstruct.rag_sources) {
console.log(` - ${src.title} (相似度 ${src.similarity.toFixed(2)})`);
}
}
範例二:企業內部知識搜尋
員工直接詢問 SOP、人資政策,不再需要翻閱 SharePoint。
const reply = await client.chat.completions.create({
model: 'openai/gpt-4o',
messages: [
{ role: 'user', content: '出差報銷的流程和截止日期是什麼?' },
],
vecstruct: {
project_id: 'proj-hr-knowledge',
rag: true,
},
});
範例三:多模型切換
根據任務複雜度選擇不同模型,控制成本。
// 簡單問答 → 用便宜的模型
const quickReply = await client.chat.completions.create({
model: 'openai/gpt-4o-mini',
messages: [{ role: 'user', content: '今天星期幾?' }],
});
// 複雜分析 → 用能力更強的模型
const deepReply = await client.chat.completions.create({
model: 'anthropic/claude-3-5-sonnet-20241022',
messages: [{ role: 'user', content: '分析這份財報的風險因素...' }],
});
注意事項
- 模型代碼大小寫敏感,需與 Models API 回傳的完全一致
max_tokens未設定時,由各 provider 決定最大輸出長度- 串流模式下,Vecstruct 的統計資訊(RAG 引用、消耗費用等)在最後的
event: vecstruct事件中回傳