目标是“尽快跑起来 + 便于维护”,而不是堆砌复杂度。 注:本文为“1 月份重点篇”,给出一套最小可行的本地与云端方案清单。
🎯 文章目标
- 本地/云端一套打通的最小栈:模型调用、RAG、观测
- 明确项目脚手架与环境变量规范
- 提供可直接复用的命令与配置
📚 背景/前置
- 开发语言:Node.js 或 Python 均可(示例两者各一)
- 模型来源:本地(Ollama/vLLM)与云端(OpenAI 兼容)
- 可选能力:向量库(Qdrant/Chroma)、监控(简单日志 + 指标)
🔧 核心内容
1) 目录与环境变量约定
- 根目录放置 .env(不要提交仓库),约定:
- OPENAI_API_BASE / OPENAI_API_KEY
- EMBEDDING_MODEL / CHAT_MODEL
- 代码中只读取 env,不在代码里硬编码 key 与 URL
2) 本地方案 A:Ollama + Node.js(OpenAI 兼容调用)
bash
# 安装 Ollama 与常见模型
brew install ollama || curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5:7b-instruct
# Node 项目初始化
mkdir llm-mvp && cd llm-mvp && npm init -y && npm i openai dotenv
cat > .env <<'EOF'
OPENAI_API_BASE=http://localhost:11434/v1
OPENAI_API_KEY=ollama
CHAT_MODEL=llama3.1:8b-instruct
EOF
javascript
// index.js
import 'dotenv/config'
import OpenAI from 'openai'
const client = new OpenAI({ baseURL: process.env.OPENAI_API_BASE, apiKey: process.env.OPENAI_API_KEY })
const resp = await client.chat.completions.create({
model: process.env.CHAT_MODEL,
messages: [{ role: 'user', content: '用两句话解释 RAG 的关键步骤' }],
temperature: 0.3
})
console.log(resp.choices[0].message.content)
3) 本地方案 B:Chroma + Python(简单 RAG)
bash
pip install chromadb openai python-dotenv
cat > .env <<'EOF'
OPENAI_API_BASE=http://localhost:11434/v1
OPENAI_API_KEY=ollama
EMBEDDING_MODEL=nomic-embed-text
CHAT_MODEL=llama3.1:8b-instruct
EOF
python
# rag_demo.py
import os, chromadb
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
chroma = chromadb.Client()
col = chroma.get_or_create_collection('kb')
col.add(ids=['1','2'], documents=['RAG 包含检索与重写','向量召回后可做重排'])
cli = OpenAI(base_url=os.getenv('OPENAI_API_BASE'), api_key=os.getenv('OPENAI_API_KEY'))
q = 'RAG 的关键步骤是什么?'
# 粗略召回
hits = col.query(query_texts=[q], n_results=2)
ctx = '\n'.join(hits['documents'][0])
msg = [
{"role":"system","content":"仅基于上下文回答"},
{"role":"user","content":f"上下文:\n{ctx}\n\n问题:{q}"}
]
print(cli.chat.completions.create(model=os.getenv('CHAT_MODEL'), messages=msg).choices[0].message.content)
4) 云端最小方案:API Key 分层 + 只读权限
- 使用“服务账号”而非个人 Key;发布前上 Secret 管理
- 后端网关做限速与埋点;对不同模型/供应商做路由与熔断
- 生产环境日志脱敏并设置保留期
5) 观测与排障
- 每次调用记录:模型/版本、延迟、token 量、失败原因
- 出问题先回放请求/上下文,再看模型/版本差异
💡 实战示例:Nginx 反代与限速(可选)
nginx
location /v1/ {
proxy_pass https://api.example.com/v1/;
limit_req zone=api burst=10 nodelay;
proxy_set_header Authorization "Bearer $openai_key";
}
📊 对比/取舍(速查)
- 本地:可控/低成本/受算力限制
- 云端:能力强/迭代快/成本可控性一般
- 建议:本地开发验证 → 小流量灰度上云 → 路由/缓存/评估治理
🧪 踩坑与经验
- key 暴露:始终把 Key 放后端,不在前端环境暴露
- 版本漂移:固定 SDK 与模型版本,记录变更
- .env 扩散:使用 .env.example + 文档化变量说明
📎 参考与延伸
- Ollama/vLLM/TGI/LMDeploy 引擎对比
- Chroma/Qdrant/Weaviate 等向量库
- 网关限速/鉴权与日志审计实践
💭 总结
- 用最小方案先串通“调用—存储—观测”,小步快跑
- 把 Key、路由、日志与限速的工程治理放在首位