
RESTful Web API 设计中要避免的 6 个常见错误
在企业培训场景里,学员的提问往往千变万化:
传统 FAQ 页面更新慢、命中率低;而通用大模型又容易“幻觉”出本不存在的课程章节。
RAG(Retrieval-Augmented Generation) 把企业私域知识与大模型能力结合,成为当下最落地的方案之一。
模块 | 选型 | 关键指标 | 开源/官网 |
---|---|---|---|
文档解析 | LangChain | 支持 PDF、HTML、Markdown | https://python.langchain.com |
向量库 | Weaviate 🌿 | 平均检索 P99 22 ms | https://weaviate.io |
大模型 | Azure OpenAI GPT-4o | 首 token 延迟 350 ms | https://azure.microsoft.com/products/ai-services/openai-service |
API 框架 | FastAPI ⚡ | QPS 1k+ | https://fastapi.tiangolo.com |
监控 | Prometheus 📊 + Grafana | 告警延迟 15 s | https://prometheus.io |
维度 | 描述 |
---|---|
用户 | ADP 内部学员、讲师、助教 |
场景 | Web 端、企业微信机器人、IDE 插件 |
SLA | P95 问答延迟 ≤ 500 ms |
知识源 | 课程手册 38 份、实验手册 12 份、历届 FAQ 5k 条 |
课程编号: ADP-303
章节: Lab3 Kubernetes 网络
内容: 使用 Calico 作为 CNI,默认 IPPool 为 192.168.0.0/16...
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
loader = DirectoryLoader("data/", glob="**/*.pdf")
docs = loader.load()
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = splitter.split_documents(docs)
import weaviate
client = weaviate.Client("http://localhost:8080")
with client.batch as batch:
for c in chunks:
batch.add_data_object(
data_object={"text": c.page_content},
class_name="ADPKnowledge"
)
参数 | 值 |
---|---|
Embedding 模型 | text-embedding-3-small |
维度 | 1536 |
索引类型 | HNSW |
ef_construction | 128 |
from fastapi import FastAPI
from pydantic import BaseModel
import weaviate, openai, os
app = FastAPI()
client = weaviate.Client("http://localhost:8080")
openai.api_key = os.getenv("AZURE_OPENAI_KEY")
class Query(BaseModel):
q: str
@app.post("/ask")
def ask(query: Query):
near_text = {"concepts": [query.q]}
res = client.query.get("ADPKnowledge", ["text"])\
.with_near_text(near_text)\
.with_limit(5)\
.do()
context = " ".join([r["text"] for r in res["data"]["Get"]["ADPKnowledge"]])
prompt = f"根据以下内容回答:{context}\n问题:{query.q}"
gpt_resp = openai.ChatCompletion.create(
engine="gpt-4o",
messages=[{"role": "user", "content": prompt}],
max_tokens=256,
temperature=0.1
)
return {"answer": gpt_resp.choices[0].message.content}
并发 | 平均延迟 | P95 延迟 | 错误率 |
---|---|---|---|
10 | 190 ms | 260 ms | 0 % |
50 | 310 ms | 420 ms | 0 % |
100 | 480 ms | 560 ms | 0.2 % |
结论:单副本即可满足 SLA,后续可水平扩展。
指标 | 数值 | 备注 |
---|---|---|
问答总量 | 12,873 | 来源:Prometheus |
命中率 | 89.4 % | 人工抽检 200 条 |
用户满意度 | 4.6 / 5 | 企业微信投票 1,024 份 |
成本 | 0.003 美元/次 | Azure 账单 |
措施 | 说明 |
---|---|
内容过滤 | Azure Content Safety API 双层过滤 |
权限隔离 | Weaviate API Key + 子网 ACL |
审计日志 | 全链路 Request ID,保留 30 天 |
用户提问:
“Pod 无法跨节点通信,但同节点正常,如何排查?”
RAG 回答:
calico/node
Pod 日志是否有 BGP not ready
CALICO_IPV4POOL_IPIP=Always
结果:用户 3 分钟定位到防火墙策略问题,实验提前 40 分钟完成。
name: deploy-rag-api
on:
push:
branches: [main]
jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/build-push-action@v5
with:
tags: ghcr.io/adp-it/rag-api:latest
扩展点 | 说明 | 示例 |
---|---|---|
多租户 | Weaviate 类名加前缀 | TenantA_ADPKnowledge |
多语言 | 引入 zh_core_web_sm |
Spacy 中文分词 |
实时更新 | Kafka + Debezium CDC | 课程手册更新秒级同步 |
维度 | 传统 FAQ | RAG 方案 |
---|---|---|
更新周期 | 1~2 周 | 分钟级 |
命中率 | 45 % | 89 % |
扩展性 | 人工维护 | 自动切片 |
多轮对话 | 不支持 | 支持 |
通过 RAG 低延迟架构,我们在 2 天内将 ADP IT 课程的零散知识转化为可对话、可扩展、可观测的问答 API;在保证安全合规的同时,把平均响应时间控制在 500 ms 以内,用户体验和运维成本实现双赢。未来可继续接入更多企业知识库,打造统一的企业级 AI 助手底座。