Ollama生态

Ollama 2026生态系统:本地LLM的最佳伙伴

引言 Ollama已经成为本地运行LLM最流行的工具。从2023年的简单命令行工具,到2026年的完整生态系统,Ollama让在本地运行大模型变得像安装App一样简单。本文将全面解析2026年的Ollama生态系统。 Ollama 2026核心特性 模型管理 # 拉取模型 ollama pull glm-5:32b ollama pull qwen3:7b ollama pull deepseek-v4:671b # 运行模型 ollama run glm-5:32b # 查看已安装模型 ollama list # 创建自定义模型 ollama create my-model -f Modelfile Modelfile 2026年的Modelfile支持更丰富的配置: # Modelfile 示例 FROM glm-5:32b # 系统提示 SYSTEM """ 你是一个专业的中文助手,请用中文回复。 """ # 参数 PARAMETER temperature 0.7 PARAMETER top_p 0.9 PARAMETER num_ctx 8192 PARAMETER stop "<|im_end|>" # 适配器(LoRA) ADAPTER ./my-lora.gguf # 许可证 LICENSE "MIT" 多模态支持 # 运行视觉模型 ollama run llava:34b # 在API中发送图像 curl http://localhost:11434/api/chat -d '{ "model": "llava", "messages": [ {"role": "user", "content": "描述这张图片", "images": ["base64_image_data"]} ] }' Ollama API REST API import requests # 对话 response = requests.post("http://localhost:11434/api/chat", json={ "model": "glm-5:32b", "messages": [ {"role": "system", "content": "你是一个助手"}, {"role": "user", "content": "你好"} ], "stream": False }) # 生成 response = requests.post("http://localhost:11434/api/generate", json={ "model": "glm-5:32b", "prompt": "写一首诗", "stream": False }) Python SDK from ollama import Client client = Client(host="http://localhost:11434") # 对话 response = client.chat( model="glm-5:32b", messages=[{"role": "user", "content": "你好"}] ) # 流式对话 for chunk in client.chat( model="glm-5:32b", messages=[{"role": "user", "content": "写一首诗"}], stream=True ): print(chunk["message"]["content"], end="") 生态工具 Open WebUI 最流行的Ollama前端: ...

2026-07-02 · 3 min · 475 words · 硅基 AGI 探索者
模型版本管理

模型版本管理MLOps实践

LLM版本管理的挑战 传统的软件版本管理(Git)无法处理大模型文件(数十GB)。LLM的版本管理需要同时追踪代码、配置、数据、模型权重和评估结果。 版本管理工具链 MLflow模型注册 import mlflow # 记录模型版本 with mlflow.start_run(run_name="qwen3-32b-v2"): mlflow.log_params({ "base_model": "Qwen-3-32B", "fine_tune_method": "LoRA", "learning_rate": 2e-4, "epochs": 3, "dataset": "instruction-v3", }) mlflow.log_metrics({ "eval_loss": 0.45, "eval_accuracy": 0.89, "human_eval_score": 4.2, }) # 注册模型 mlflow.register_model( "runs:/abc123/model", "qwen3-32b-instruct", tags={ "version": "v2.1", "stage": "staging", "creator": "team-agi", } ) DVC管理大文件 # 初始化DVC dvc init # 添加模型文件到DVC dvc add models/qwen3-32b-v2.1/ # 推送到远程存储 dvc remote add -d storage s3://my-bucket/models dvc push # Git只追踪.dvc文件(指针),不追踪实际大文件 git add models/qwen3-32b-v2.1/.dvc git commit -m "Add qwen3-32b v2.1" 版本发布流程 灰度发布 class CanaryDeployment: def __init__(self, stable_version, canary_version, canary_ratio=0.1): self.stable = stable_version self.canary = canary_version self.ratio = canary_ratio self.metrics = {"stable": [], "canary": []} def route(self, request): """灰度路由""" import random if random.random() < self.ratio: self.metrics["canary"].append({"time": time.time()}) return self.canary else: self.metrics["stable"].append({"time": time.time()}) return self.stable def evaluate(self): """评估灰度结果""" canary_latency = self.get_avg_latency("canary") stable_latency = self.get_avg_latency("stable") canary_error = self.get_error_rate("canary") stable_error = self.get_error_rate("stable") # 灰度通过条件 if canary_latency > stable_latency * 1.2: return "rollback", "Canary latency too high" if canary_error > stable_error * 2: return "rollback", "Canary error rate too high" return "promote", "Canary performing well" A/B测试 class ABTest: def __init__(self, models, weights=None): self.models = models self.weights = weights or [1/len(models)] * len(models) self.results = {m: {"satisfied": 0, "total": 0} for m in models} def route(self, user_id): # 基于用户ID的确定性路由 hash_val = int(hashlib.md5(user_id.encode()).hexdigest(), 16) cumulative = 0 for model, weight in zip(self.models, self.weights): cumulative += weight if (hash_val % 1000) / 1000 < cumulative: return model def record_feedback(self, model, satisfied): self.results[model]["total"] += 1 if satisfied: self.results[model]["satisfied"] += 1 def get_winner(self): rates = {m: r["satisfied"]/r["total"] for m, r in self.results.items() if r["total"] > 0} return max(rates, key=rates.get) if rates else None CI/CD管线 # .github/workflows/model-deploy.yml name: Model Deploy Pipeline on: push: tags: ['v*'] jobs: evaluate: runs-on: gpu-runner steps: - uses: actions/checkout@v4 - name: Run evaluation run: | python eval.py --model checkpoints/latest --benchmark mmlu,gsm8k,humaneval - name: Check quality gates run: | python check_gates.py --min_accuracy 0.85 --max_regression 0.02 deploy_staging: needs: evaluate runs-on: deploy-runner steps: - name: Deploy to staging run: | ./deploy.sh --env staging --version ${{ github.ref_name }} - name: Run smoke tests run: | python smoke_test.py --env staging canary: needs: deploy_staging runs-on: deploy-runner steps: - name: Canary deployment (10%) run: | ./deploy.sh --env production --version ${{ github.ref_name }} --canary 0.1 - name: Monitor for 1 hour run: | python monitor.py --duration 3600 --check latency,error_rate full_deploy: needs: canary runs-on: deploy-runner steps: - name: Full deployment run: | ./deploy.sh --env production --version ${{ github.ref_name }} --promote 模型回滚 class ModelRollback: def __init__(self, deployment_manager): self.deployment = deployment_manager self.version_history = [] async def rollback(self, target_version=None): """回滚到指定版本或上一个稳定版本""" if target_version is None: target_version = self.get_previous_stable() logger.info(f"Rolling back to {target_version}") # 快速切换流量 await self.deployment.switch_traffic( from_version="current", to_version=target_version, ratio=1.0 # 100%切换 ) # 验证回滚 health = await self.deployment.health_check(target_version) if not health: logger.error("Rollback target also unhealthy!") return False return True 结语 LLM的版本管理需要结合MLflow(实验追踪)、DVC(大文件管理)和CI/CD(自动化部署)。灰度发布和快速回滚是降低部署风险的关键能力。建立完善的MLOps流程,可以让模型迭代从"手动谨慎"变为"自动自信"。 加入讨论 这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。 ...

2026-07-02 · 3 min · 462 words · 硅基 AGI 探索者
评估数据策划

评估数据策划方法:好数据才能评出好模型

引言 评估数据的质量直接决定了评估结果的可信度。“垃圾进,垃圾出"在LLM评估中同样适用。一个有偏见的评估数据集可能让你做出错误的模型选择。2026年,评估数据策划已经成为一门专门的学问。本文将系统介绍评估数据策划的方法论。 评估数据的挑战 挑战一:代表性 评估数据是否代表了真实使用场景? 问题:评估数据全部来自新闻文本 真实场景:用户输入包含口语、错别字、混合语言 → 评估结果无法反映真实效果 挑战二:多样性 评估数据是否覆盖了各种输入类型? 问题:情感分析评估集只有明显正面/负面 缺失:讽刺、中性、混合情感 → 模型在边界情况上的表现未知 挑战三:数据污染 评估数据是否泄露到了训练集中? 挑战四:时效性 评估数据是否过时? 挑战五:偏见 评估数据是否对某些群体或观点有偏见? 评估数据策划流程 步骤一:需求分析 eval_data_requirements = { "task": "客服对话质量评估", "dimensions": { "准确性": "回复信息是否正确", "有用性": "是否解决了用户问题", "态度": "回复是否礼貌友好", "效率": "是否在3轮内解决" }, "coverage": { "query_types": ["咨询", "投诉", "退款", "技术支持"], "difficulty": ["简单", "中等", "困难"], "languages": ["中文"], "domains": ["电商", "金融", "教育"] }, "size": { "minimum": 500, "recommended": 2000, "ideal": 5000 } } 步骤二:数据收集 来源一:真实用户数据 def collect_real_user_data(production_logs, n=1000): """ 从生产日志中采样真实用户数据 """ # 随机采样 sampled = random.sample(production_logs, min(n, len(production_logs))) # 去敏处理 sanitized = [sanitize(data) for data in sampled] # 分类标注 categorized = categorize(sanitized) return categorized 来源二:人工构造 def generate_synthetic_data(task_description, n=500): """ 用LLM生成合成评估数据 """ prompt = f""" 请为以下任务生成{n}个评估用例: 任务:{task_description} 要求: 1. 覆盖不同难度(简单/中等/困难) 2. 包含边界情况 3. 包含对抗性输入 4. 输入多样化 以JSON格式输出。 """ return call_llm(prompt) 来源三:专家标注 def expert_annotation(raw_data, experts): """ 邀请领域专家标注数据 """ annotated = [] for item in raw_data: # 3位专家独立标注 labels = [expert.annotate(item) for expert in experts[:3]] # 计算一致性 agreement = compute_agreement(labels) if agreement > 0.8: # 一致性高,取多数意见 item["label"] = majority_vote(labels) else: # 一致性低,讨论后决定 item["label"] = expert_discussion(item, labels) annotated.append(item) return annotated 步骤三:数据清洗 def clean_eval_data(data): """ 清洗评估数据 """ cleaned = [] for item in data: # 去重 if is_duplicate(item, cleaned): continue # 去除敏感信息 item = remove_pii(item) # 检查标注质量 if not validate_annotation(item): continue # 检查输入长度 if len(item["input"]) < 5 or len(item["input"]) > 10000: continue cleaned.append(item) return cleaned 步骤四:数据分析 def analyze_eval_data(data): """ 分析评估数据集的分布 """ analysis = { "size": len(data), "difficulty_distribution": Counter(d["difficulty"] for d in data), "category_distribution": Counter(d["category"] for d in data), "length_distribution": [len(d["input"]) for d in data], "language_distribution": Counter(d["language"] for d in data), "bias_check": check_bias(data), "diversity_score": compute_diversity(data), "contamination_check": check_contamination(data) } return analysis 步骤五:数据平衡 def balance_eval_data(data, target_distribution=None): """ 平衡评估数据集 """ if target_distribution is None: # 默认均衡分布 categories = set(d["category"] for d in data) target_distribution = {c: 1/len(categories) for c in categories} # 按类别分组 by_category = defaultdict(list) for d in data: by_category[d["category"]].append(d) # 计算每个类别的目标数量 total = len(data) balanced = [] for category, items in by_category.items(): target_count = int(total * target_distribution[category]) if len(items) > target_count: # 过采样 sampled = random.sample(items, target_count) else: # 欠采样或数据增强 sampled = items + augment_data(items, target_count - len(items)) balanced.extend(sampled) return balanced 数据质量评估 评估维度 def evaluate_data_quality(data): """ 评估数据集质量 """ quality = {} # 1. 覆盖度:是否覆盖了所有需要评估的场景 quality["coverage"] = evaluate_coverage(data) # 2. 多样性:输入是否足够多样 quality["diversity"] = evaluate_diversity(data) # 3. 标注一致性:标注是否可靠 quality["annotation_consistency"] = evaluate_consistency(data) # 4. 偏见检测:是否存在偏见 quality["bias"] = detect_bias(data) # 5. 污染检测:是否与训练数据重叠 quality["contamination"] = detect_contamination(data) # 6. 难度分布:难度是否合理 quality["difficulty"] = evaluate_difficulty(data) return quality 偏见检测 def detect_bias(data): """ 检测数据集中的偏见 """ biases = [] # 性别偏见 male_terms = ["他", "男性", "先生"] female_terms = ["她", "女性", "女士"] male_count = sum(1 for d in data if any(t in d["input"] for t in male_terms)) female_count = sum(1 for d in data if any(t in d["input"] for t in female_terms)) if abs(male_count - female_count) / max(male_count, female_count) > 0.3: biases.append(f"性别分布不均:男性{male_count},女性{female_count}") # 地域偏见 # 年龄偏见 # 领域偏见 return biases 污染检测 def detect_contamination(eval_data, train_data_sample): """ 检测评估数据是否泄露到训练集中 """ contamination = [] for eval_item in eval_data: # 精确匹配 for train_item in train_data_sample: if eval_item["input"] == train_item: contamination.append(eval_item) break # 模糊匹配(n-gram重叠) eval_ngrams = set(get_ngrams(eval_item["input"], 8)) for train_item in train_data_sample: train_ngrams = set(get_ngrams(train_item, 8)) overlap = len(eval_ngrams & train_ngrams) / len(eval_ngrams) if overlap > 0.8: contamination.append(eval_item) break return { "contaminated_count": len(contamination), "contamination_rate": len(contamination) / len(eval_data), "contaminated_items": contamination } 评估数据管理 版本管理 class EvalDatasetVersion: def __init__(self, name, version, data): self.name = name self.version = version self.data = data self.created_at = datetime.now() self.hash = compute_hash(data) def diff(self, other_version): """计算版本差异""" added = [d for d in self.data if d not in other_version.data] removed = [d for d in other_version.data if d not in self.data] return {"added": added, "removed": removed} 数据集文档 # eval_dataset_card.yaml name: "客服对话评估集 v2.0" version: "2.0" created: "2026-06-01" size: 2000 description: "电商客服对话质量评估数据集" coverage: query_types: 咨询: 500 投诉: 400 退款: 350 技术支持: 350 其他: 400 difficulty: 简单: 600 中等: 900 困难: 500 quality: annotation_consistency: 0.87 diversity_score: 0.82 bias_check: "通过" contamination_check: "无污染" limitation: - "仅覆盖电商领域" - "中文数据为主" - "不含多轮对话" 2026年新趋势 1. 动态评估数据 评估数据集定期更新,防止数据污染和过时。 ...

2026-07-02 · 4 min · 657 words · 硅基 AGI 探索者
AI性能监控

AI性能监控体系:让系统运行在最佳状态

引言 AI应用的监控比传统软件复杂得多。除了常规的系统指标(CPU、内存、延迟),还需要监控AI特有的指标(输出质量、幻觉率、安全事件)。2026年,AI性能监控已经发展成为一个专门的领域。本文将系统介绍AI性能监控体系的构建。 AI监控的独特需求 传统软件监控 vs AI监控 维度 传统软件 AI应用 延迟 毫秒级 秒级(可接受) 错误类型 崩溃、超时 幻觉、不当内容 质量指标 功能正确性 输出准确性、相关性 成本 服务器成本 API调用成本(按token计) 变化来源 代码部署 代码+模型版本+提示 AI监控的核心指标 AI监控指标体系 ├── 性能指标 │ ├── 延迟(P50/P95/P99) │ ├── 吞吐量 │ └── 并发数 ├── 质量指标 │ ├── 输出准确率 │ ├── 幻觉率 │ ├── 拒绝率 │ └── 用户满意度 ├── 成本指标 │ ├── 每次请求成本 │ ├── 每日总成本 │ └── token效率 ├── 安全指标 │ ├── 有害内容率 │ ├── 注入攻击次数 │ └── 数据泄露事件 └── 可靠性指标 ├── 可用性 ├── 错误率 └── 降级率 监控架构 数据采集层 class MetricsCollector: def __init__(self): self.collectors = [ LatencyCollector(), QualityCollector(), CostCollector(), SafetyCollector(), ReliabilityCollector() ] def record_request(self, request_id, request, response, metadata): """记录每次请求""" for collector in self.collectors: collector.record(request_id, request, response, metadata) 指标计算层 class MetricsCalculator: def calculate(self, raw_metrics): return { "latency": { "p50": percentile(raw_metrics["latencies"], 50), "p95": percentile(raw_metrics["latencies"], 95), "p99": percentile(raw_metrics["latencies"], 99), }, "quality": { "accuracy": raw_metrics["correct"] / raw_metrics["total"], "hallucination_rate": raw_metrics["hallucinations"] / raw_metrics["total"], "refusal_rate": raw_metrics["refusals"] / raw_metrics["total"], }, "cost": { "per_request": raw_metrics["total_cost"] / raw_metrics["total"], "daily": raw_metrics["total_cost"], "token_efficiency": raw_metrics["output_tokens"] / raw_metrics["input_tokens"], }, "safety": { "harmful_rate": raw_metrics["harmful"] / raw_metrics["total"], "injection_attempts": raw_metrics["injections"], }, "reliability": { "availability": 1 - raw_metrics["downtime"] / raw_metrics["total_time"], "error_rate": raw_metrics["errors"] / raw_metrics["total"], } } 告警层 class AlertManager: def __init__(self): self.rules = [ AlertRule("high_latency", "p95_latency > 5000", severity="warning"), AlertRule("critical_latency", "p99_latency > 10000", severity="critical"), AlertRule("high_error", "error_rate > 0.05", severity="critical"), AlertRule("quality_drop", "accuracy < 0.85", severity="warning"), AlertRule("hallucination_spike", "hallucination_rate > 0.1", severity="critical"), AlertRule("cost_spike", "daily_cost > budget * 1.2", severity="warning"), AlertRule("safety_incident", "harmful_rate > 0.01", severity="critical"), ] def check(self, metrics): alerts = [] for rule in self.rules: if rule.evaluate(metrics): alerts.append(rule.create_alert(metrics)) if alerts: self.notify(alerts) return alerts 关键监控实现 延迟监控 class LatencyMonitor: def __init__(self): self.latencies = SlidingWindow(size=10000) def record(self, request_id, start_time, end_time): latency = end_time - start_time self.latencies.append(latency) # 实时检查 if latency > 10: # 超过10秒 self.alert(f"请求 {request_id} 延迟 {latency:.1f}s") def get_stats(self): return { "p50": self.latencies.percentile(50), "p95": self.latencies.percentile(95), "p99": self.latencies.percentile(99), "max": self.latencies.max(), "avg": self.latencies.mean() } 质量监控 class QualityMonitor: def __init__(self): self.sample_rate = 0.1 # 采样10%进行质量评估 self.evaluator = LLMJudge(model="gpt-5") # 用GPT-5评估 async def evaluate(self, request, response): """异步评估输出质量""" if random.random() > self.sample_rate: return # 采样 # 用LLM评估 score = await self.evaluator.evaluate( input=request, output=response, criteria=["accuracy", "relevance", "completeness"] ) if score["accuracy"] < 0.7: self.alert(f"低质量输出检测:{score}") return score 成本监控 class CostMonitor: def __init__(self, daily_budget=100): self.daily_budget = daily_budget self.today_cost = 0 self.costs = [] def record(self, input_tokens, output_tokens, model): cost = calculate_cost(input_tokens, output_tokens, model) self.today_cost += cost self.costs.append({"timestamp": datetime.now(), "cost": cost}) # 预算检查 if self.today_cost > self.daily_budget * 0.8: self.alert("日预算已用80%") if self.today_cost > self.daily_budget: self.alert("日预算超支!") return "stop" # 触发熔断 安全监控 class SafetyMonitor: def __init__(self): self.content_filter = ContentFilter() self.injection_detector = InjectionDetector() def check_input(self, user_input): """检查输入安全性""" if self.injection_detector.is_injection(user_input): self.log_incident("injection_attempt", user_input) return False if self.content_filter.is_harmful(user_input): self.log_incident("harmful_input", user_input) return False return True def check_output(self, output): """检查输出安全性""" if self.content_filter.is_harmful(output): self.log_incident("harmful_output", output) return False return True 可视化仪表板 class MonitoringDashboard: def render(self): return { "overview": { "status": "healthy", # healthy/warning/critical "uptime": "99.97%", "requests_today": 154289, "avg_latency": "1.2s", "cost_today": "$45.30" }, "latency_chart": self.render_latency_chart(), "quality_trend": self.render_quality_trend(), "cost_trend": self.render_cost_trend(), "alerts": self.get_active_alerts(), "top_errors": self.get_top_errors() } 告警策略 告警分级 级别 条件 响应时间 通知方式 P0 系统不可用 立即 电话+短信+邮件 P1 关键指标超标 15分钟 短信+邮件 P2 质量下降 1小时 邮件+IM P3 预警 4小时 IM 告警抑制 def should_suppress(alert, recent_alerts): """避免告警风暴""" # 同类告警5分钟内只发一次 for recent in recent_alerts: if (recent["type"] == alert["type"] and (datetime.now() - recent["timestamp"]).seconds < 300): return True return False 2026年新趋势 1. AI自监控 用AI监控AI:模型自己评估输出质量,自动发现异常。 ...

2026-07-02 · 3 min · 543 words · 硅基 AGI 探索者
LLM负载均衡

LLM负载均衡策略

LLM负载均衡的特殊性 传统Web服务的负载均衡(轮询、加权轮询)在LLM场景下效果不佳——LLM请求的长度差异巨大(10 token vs 10000 token),处理时间差异可达100倍。简单的轮询会导致某些节点被长请求占满,而短请求也被迫排队。 策略一:最小连接数 class LeastConnectionsBalancer: def __init__(self, backends): self.backends = {b: 0 for b in backends} # backend -> active_connections self.lock = asyncio.Lock() async def get_backend(self): async with self.lock: backend = min(self.backends, key=self.backends.get) self.backends[backend] += 1 return backend async def release(self, backend): async with self.lock: self.backends[backend] -= 1 策略二:基于队列长度 class QueueAwareBalancer: def __init__(self, backends): self.queues = {b: asyncio.Queue() for b in backends} async def route(self, request): # 选择队列最短的节点 backend = min(self.queues, key=lambda b: self.queues[b].qsize()) await self.queues[backend].put(request) return backend 策略三:延迟感知 class LatencyAwareBalancer: def __init__(self, backends): self.backends = backends self.latency_stats = {b: deque(maxlen=100) for b in backends} def record_latency(self, backend, latency): self.latency_stats[backend].append(latency) def get_backend(self): # 选择平均延迟最低的节点 avg_latencies = { b: sum(lats) / len(lats) if lats else 0 for b, lats in self.latency_stats.items() } return min(avg_latencies, key=avg_latencies.get) 策略四:请求长度路由 class LengthAwareRouter: def __init__(self, short_backends, long_backends, threshold=500): self.short_backends = short_backends # 小模型,处理短请求 self.long_backends = long_backends # 大模型,处理长请求 self.threshold = threshold def route(self, request): input_length = len(request["messages"][-1]["content"]) // 4 if input_length > self.threshold: return self.select_least_loaded(self.long_backends) else: return self.select_least_loaded(self.short_backends) 健康检查 class HealthChecker: def __init__(self, backends, check_interval=10): self.backends = {b: {"healthy": True, "last_check": 0} for b in backends} self.check_interval = check_interval async def check_backend(self, backend): try: async with httpx.AsyncClient() as client: resp = await client.get(f"{backend}/health", timeout=5) return resp.status_code == 200 except: return False async def run(self): while True: for backend in self.backends: healthy = await self.check_backend(backend) self.backends[backend]["healthy"] = healthy if not healthy: logger.warning(f"Backend {backend} unhealthy") await asyncio.sleep(self.check_interval) 结语 LLM负载均衡需要考虑请求长度差异、节点异构性和KV Cache状态。最小连接数+延迟感知的组合策略在大多数场景下表现最佳。配合健康检查和自动故障转移,可以构建高可用的LLM推理服务。 加入讨论 这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。 ...

2026-07-02 · 2 min · 252 words · 硅基 AGI 探索者
AI网关搭建

AI网关搭建2026

为什么需要AI网关? 当企业使用多个LLM提供商(OpenAI、Anthropic、本地模型等)时,直接对接各家API会面临:密钥管理分散、无法统一限流、缺乏请求日志、故障切换困难。AI网关统一管理所有LLM请求,提供路由、缓存、限流、监控等基础设施。 核心架构 客户端 → AI网关 → LLM提供商A → LLM提供商B → 本地vLLM 实现方案 统一API接口 from fastapi import FastAPI, Request from pydantic import BaseModel app = FastAPI() class ChatRequest(BaseModel): model: str messages: list temperature: float = 0.7 max_tokens: int = 2048 stream: bool = False # 提供商配置 PROVIDERS = { "openai": {"base_url": "https://api.openai.com/v1", "api_key": "..."}, "anthropic": {"base_url": "https://api.anthropic.com", "api_key": "..."}, "local": {"base_url": "http://localhost:8000/v1", "api_key": "..."}, } # 模型到提供商的路由 MODEL_ROUTING = { "gpt-4": "openai", "claude-3": "anthropic", "qwen3-32b": "local", } @app.post("/v1/chat/completions") async def chat_completions(request: ChatRequest): provider = MODEL_ROUTING.get(request.model, "local") config = PROVIDERS[provider] # 转发请求 async with httpx.AsyncClient() as client: response = await client.post( f"{config['base_url']}/chat/completions", json=request.dict(), headers={"Authorization": f"Bearer {config['api_key']}"}, timeout=120 ) return response.json() 故障切换 class FailoverRouter: def __init__(self, routing_config): self.routing = routing_config # {model: [provider1, provider2, ...]} self.health = {p: True for providers in routing_config.values() for p in providers} async def route(self, model, request): providers = self.routing.get(model, ["local"]) for provider in providers: if not self.health[provider]: continue try: result = await self.call_provider(provider, request) return result except Exception as e: logger.warning(f"Provider {provider} failed: {e}") self.health[provider] = False continue raise ServiceUnavailableError("All providers failed") 请求缓存 import hashlib import redis.asyncio as redis class ResponseCache: def __init__(self, redis_url="redis://localhost:6379"): self.redis = redis.from_url(redis_url) def cache_key(self, model, messages, temperature): content = json.dumps({"model": model, "messages": messages, "temp": temperature}) return hashlib.sha256(content.encode()).hexdigest() async def get(self, model, messages, temperature): key = self.cache_key(model, messages, temperature) cached = await self.redis.get(key) return json.loads(cached) if cached else None async def set(self, model, messages, temperature, response, ttl=3600): key = self.cache_key(model, messages, temperature) await self.redis.setex(key, ttl, json.dumps(response)) 限流 from datetime import datetime, timedelta class RateLimiter: def __init__(self, redis): self.redis = redis async def check(self, user_id, limit=60, window=60): key = f"rate:{user_id}:{datetime.now().strftime('%Y%m%d%H%M')}" current = await self.redis.incr(key) if current == 1: await self.redis.expire(key, window) if current > limit: return False return True 日志与监控 class RequestLogger: def __init__(self): self.logger = structlog.get_logger() async def log(self, request, response, user_id, duration): self.logger.info("llm_request", user_id=user_id, model=request.model, input_tokens=response.get("usage", {}).get("prompt_tokens", 0), output_tokens=response.get("usage", {}).get("completion_tokens", 0), duration_ms=duration * 1000, provider=response.get("provider", "unknown"), status="success" if response.get("choices") else "error" ) 部署配置 Docker Compose version: '3.8' services: gateway: build: . ports: - "8080:8080" environment: - REDIS_URL=redis://redis:6379 depends_on: - redis redis: image: redis:7-alpine ports: - "6379:6379" prometheus: image: prom/prometheus ports: - "9090:9090" grafana: image: grafana/grafana ports: - "3000:3000" 结语 AI网关是LLM生产基础设施的核心组件。统一API、故障切换、缓存、限流和监控这五大功能,让LLM服务具备企业级的可靠性和可观测性。 加入讨论 这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。 ...

2026-07-02 · 2 min · 375 words · 硅基 AGI 探索者
模型卡

模型卡2026模板与实践:AI透明度的新标准

引言 模型卡(Model Card)是AI透明度的核心工具。它像食品的营养标签一样,让用户清楚地了解AI模型的能力、局限和风险。2026年,随着AI法规的完善,模型卡已经成为AI系统的必备文档。本文将介绍2026年模型卡的最佳实践和模板。 模型卡的价值 对开发者 促进系统性评估 发现模型局限 建立用户信任 对用户 了解模型能力边界 评估适用性 知情决策 对监管机构 审查合规性 评估风险 追溯责任 2026年模型卡模板 # 模型卡:[模型名称] ## 1. 基本信息 | 字段 | 内容 | |------|------| | 模型名称 | GLM-5 | | 版本 | 5.0.2 | | 发布日期 | 2026-06-15 | | 开发者 | 智谱AI | | 许可证 | 商业许可 | | 联系方式 | support@zhipuai.cn | ## 2. 模型描述 ### 架构 - 类型:Transformer (MoE) - 参数量:未公开 - 上下文长度:256K tokens - 训练数据截止:2026-04 ### 预期用途 - 通用对话和问答 - 文本生成和摘要 - 代码生成和调试 - 中文理解和生成 ### 不建议用途 - 医疗诊断(未获医疗器械认证) - 法律建议(不构成法律意见) - 自动化决策(需人工审核) - 高风险场景(如自动驾驶) ## 3. 性能评估 ### 基准测试结果 | 基准 | 得分 | 评估条件 | |------|------|---------| | MMLU-Pro | 86.2% | 5-shot | | C-Eval 2026 | 92.1% | 5-shot | | GSM8K | 94.1% | 0-shot CoT | | HumanEval | 86.5% | 0-shot | | GPQA Diamond | 66.3% | 0-shot | ### 分群体性能 | 群体 | 准确率 | 样本量 | |------|--------|--------| | 中文用户 | 93.5% | 5000 | | 英文用户 | 87.2% | 5000 | | 低资源语言 | 72.3% | 1000 | ### 局限性 1. **知识截止**:训练数据截止2026年4月,之后的事件可能不知道 2. **幻觉**:在罕见话题上可能产生看似合理但错误的信息 3. **数学**:虽然GSM8K得分高,但在更高级数学上可能出错 4. **多模态**:不支持图像和视频输入 5. **实时性**:不支持实时信息检索 ## 4. 安全与伦理 ### 安全评估 | 测试 | 结果 | |------|------| | 有害内容拒绝率 | 98.7% | | 提示注入防御 | 通过 | | 隐私泄露测试 | 通过 | | 偏见测试 | 轻微性别偏见(已记录) | ### 已知风险 1. **社会偏见**:在职业描述上可能存在性别偏见 2. **信息幻觉**:在知识边界外可能编造信息 3. **提示注入**:虽然有多层防御,但不是100%安全 ### 缓解措施 1. RLHF对齐训练 2. 安全过滤器 3. 输出后处理 4. 持续红队测试 ## 5. 部署信息 ### 硬件要求 | 部署方式 | 最低配置 | |----------|---------| | API | 无需硬件 | | 自托管 | 8×A100 80GB | | 量化部署 | 4×A100 (INT4) | ### 性能指标 | 指标 | 数值 | |------|------| | 平均延迟 | 1.2s | | P95延迟 | 3.5s | | 吞吐量 | 245 t/s | | 可用性 | 99.9% | ### 成本 | 项目 | 价格 | |------|------| | 输入 | ¥2.0/百万token | | 输出 | ¥8.0/百万token | ## 6. 版本历史 | 版本 | 日期 | 变更 | |------|------|------| | 5.0.2 | 2026-06-15 | 修复安全漏洞 | | 5.0.1 | 2026-06-01 | 性能优化 | | 5.0.0 | 2026-05-20 | 初始发布 | ## 7. 引用 @misc{glm5_2026, title={GLM-5: …}, author={ZhipuAI}, year={2026} } ...

2026-07-02 · 3 min · 463 words · 硅基 AGI 探索者
AI质量保证

AI质量保证2026:从测试到全面质量管理

引言 AI应用的质量保证(QA)远比传统软件复杂。传统软件QA关注"功能是否正常",而AI应用QA还需要关注"输出是否准确"、“行为是否安全”、“体验是否良好"等多个维度。2026年,AI质量保证已经发展成为一个完整的学科。本文将系统介绍AI质量保证体系。 AI质量保证框架 框架组成 AI质量保证体系 ├── 开发阶段QA │ ├── 提示测试 │ ├── 模型评估 │ └── 安全审查 ├── 发布阶段QA │ ├── 回归测试 │ ├── A/B测试 │ └── 灰度发布 ├── 运行阶段QA │ ├── 实时监控 │ ├── 用户反馈 │ └── 异常检测 └── 治理阶段QA ├── 合规审查 ├── 审计日志 └── 持续改进 质量维度 维度 说明 评估方法 准确性 输出信息是否正确 事实核查、专家评估 完整性 是否完整回答了问题 人工评估、LLM评估 一致性 相似输入的输出是否一致 一致性测试 安全性 是否拒绝有害请求 红队测试 公平性 是否存在偏见 偏见检测 延迟 响应时间是否可接受 性能监控 可靠性 系统是否稳定运行 可用性监控 成本 单次调用成本是否合理 成本监控 开发阶段QA 提示质量审查 class PromptQA: def review(self, prompt, test_cases): """ 提示质量审查 """ report = { "accuracy": self.test_accuracy(prompt, test_cases), "format": self.test_format(prompt, test_cases), "robustness": self.test_robustness(prompt), "safety": self.test_safety(prompt), "cost": self.estimate_cost(prompt) } report["overall_score"] = self.calculate_overall(report) report["recommendation"] = self.recommend(report) return report 安全审查清单 ### AI安全审查清单 □ 提示注入防御 - 是否有输入隔离? - 是否有指令强化? - 是否有输出过滤? □ 有害内容防御 - 是否能拒绝暴力内容请求? - 是否能拒绝违法内容请求? - 是否有内容过滤器? □ 隐私保护 - 是否会泄露用户数据? - 是否会泄露系统信息? - 是否有数据脱敏? □ 公平性 - 是否存在性别偏见? - 是否存在种族偏见? - 是否存在年龄偏见? □ 可靠性 - 高负载下是否稳定? - 模型API故障时是否有兜底? - 是否有超时处理? 发布阶段QA 灰度发布流程 class CanaryRelease: def __init__(self, config): self.stages = [ {"name": "internal", "traffic": 0.0, "duration": "1d"}, {"name": "canary_1", "traffic": 0.01, "duration": "1d"}, {"name": "canary_5", "traffic": 0.05, "duration": "2d"}, {"name": "canary_20", "traffic": 0.20, "duration": "2d"}, {"name": "full", "traffic": 1.0, "duration": "permanent"} ] def evaluate_stage(self, stage, metrics): """ 评估灰度阶段是否可以推进 """ checks = { "error_rate_ok": metrics["error_rate"] < 0.01, "latency_ok": metrics["p95_latency"] < 3000, "satisfaction_ok": metrics["satisfaction"] > 4.0, "cost_ok": metrics["cost_per_request"] < 0.05, "no_safety_incidents": metrics["safety_incidents"] == 0 } return all(checks.values()) 运行阶段QA 实时监控系统 class AIQualityMonitor: def __init__(self): self.metrics = { "accuracy": RollingMetric(window=1000), "latency": PercentileMetric(), "error_rate": RateMetric(window=60), "user_satisfaction": RollingMetric(window=500), "cost": CostTracker(), "safety": SafetyMonitor() } def record_request(self, request, response, user_feedback=None): """记录每次请求""" self.metrics["latency"].record(response.latency) self.metrics["error_rate"].record(response.error) self.metrics["cost"].record(response.token_cost) if user_feedback: self.metrics["user_satisfaction"].record(user_feedback) # 异步分析准确性和安全性 asyncio.create_task(self.analyze_async(request, response)) def check_alerts(self): """检查告警""" alerts = [] if self.metrics["error_rate"].current > 0.05: alerts.append("错误率过高") if self.metrics["latency"].p95 > 5000: alerts.append("延迟超标") if self.metrics["user_satisfaction"].current < 3.5: alerts.append("用户满意度下降") if self.metrics["safety"].has_incident(): alerts.append("安全事件") return alerts 用户反馈收集 class FeedbackCollector: def collect(self, user_id, response_id, feedback_type, content): """ 收集用户反馈 """ feedback = { "user_id": user_id, "response_id": response_id, "type": feedback_type, # "thumbs_up", "thumbs_down", "rating", "text" "content": content, "timestamp": datetime.now() } # 存储 self.store(feedback) # 如果是负面反馈,触发分析 if feedback_type == "thumbs_down": asyncio.create_task(self.analyze_negative_feedback(feedback)) 异常检测 class AnomalyDetector: def detect(self, recent_outputs, baseline): """ 检测输出异常 """ anomalies = [] # 长度异常 recent_lengths = [len(o) for o in recent_outputs] if mean(recent_lengths) > baseline["length_mean"] * 1.5: anomalies.append("输出长度异常增加") # 拒绝率异常 recent_refusals = sum(1 for o in recent_outputs if "无法" in o) if recent_refusals / len(recent_outputs) > baseline["refusal_rate"] * 2: anomalies.append("拒绝率异常升高") # 重复率异常 if self.compute_diversity(recent_outputs) < 0.3: anomalies.append("输出多样性下降") return anomalies 质量治理 审计日志 class AuditLogger: def log(self, event_type, details): """ 记录审计日志 """ log_entry = { "timestamp": datetime.now().isoformat(), "event_type": event_type, "details": details, "version": self.current_version, "hash": self.compute_hash(details) } # 写入不可变日志 self.immutable_store.append(log_entry) 合规检查 ### AI合规检查清单 □ 数据合规 - 用户数据是否加密存储? - 是否有数据保留策略? - 是否满足GDPR/个人信息保护法? □ 算法合规 - 是否有算法备案? - 是否有安全评估报告? - 是否满足深度合成管理规定? □ 内容合规 - 是否有内容审核机制? - 是否有违法内容过滤? - 是否有未成年人保护? □ 透明度 - 是否告知用户在使用AI? - 是否提供反馈渠道? - 是否有人工替代方案? 持续改进 PDCA循环 Plan(计划): - 设定质量目标 - 制定改进计划 Do(执行): - 实施改进 - 收集数据 Check(检查): - 分析数据 - 评估效果 Act(行动): - 标准化成功经验 - 修正不成功的尝试 质量仪表板 class QualityDashboard: def generate(self): return { "overall_health": "green", # green/yellow/red "metrics": { "accuracy": {"current": 0.92, "trend": "↑", "target": 0.90}, "latency_p95": {"current": 1200, "trend": "→", "target": 2000}, "satisfaction": {"current": 4.3, "trend": "↑", "target": 4.0}, "error_rate": {"current": 0.003, "trend": "↓", "target": 0.01}, "cost_per_request": {"current": 0.02, "trend": "→", "target": 0.05} }, "recent_incidents": [...], "improvement_actions": [...] } 2026年新趋势 1. AI自监控 AI系统自己监控自己的输出质量,自动发现问题。 ...

2026-07-02 · 3 min · 563 words · 硅基 AGI 探索者
流式响应实现

流式响应实现详解

为什么需要流式响应? LLM生成一个完整回答可能需要5-30秒。如果等待完整响应再返回,用户体验极差。流式响应(Streaming)让用户看到"逐字打印"的效果,大幅降低感知延迟。 SSE(Server-Sent Events)方案 服务端实现 from fastapi import FastAPI from fastapi.responses import StreamingResponse import json app = FastAPI() @app.post("/chat/stream") async def chat_stream(request: dict): async def event_stream(): # 调用LLM的流式接口 async for chunk in llm.astream( messages=[{"role": "user", "content": request["message"]}] ): data = json.dumps({ "content": chunk.content, "role": "assistant" }, ensure_ascii=False) yield f"data: {data}\n\n" # 发送结束标记 yield f"data: [DONE]\n\n" return StreamingResponse( event_stream(), media_type="text/event-stream", headers={ "Cache-Control": "no-cache", "Connection": "keep-alive", "X-Accel-Buffering": "no", # Nginx不缓冲 } ) 客户端实现 // 浏览器端SSE const eventSource = new EventSource('/chat/stream'); eventSource.onmessage = (event) => { if (event.data === '[DONE]') { eventSource.close(); return; } const data = JSON.parse(event.data); document.getElementById('output').innerHTML += data.content; }; eventSource.onerror = (error) => { console.error('SSE error:', error); eventSource.close(); }; Python客户端 import httpx import json async def stream_chat(url, message): async with httpx.AsyncClient() as client: async with client.stream( "POST", f"{url}/chat/stream", json={"message": message}, timeout=60.0 ) as response: async for line in response.aiter_lines(): if line.startswith("data: "): data = line[6:] if data == "[DONE]": break chunk = json.loads(data) print(chunk["content"], end="", flush=True) WebSocket方案 服务端 from fastapi import FastAPI, WebSocket app = FastAPI() @app.websocket("/ws/chat") async def websocket_chat(ws: WebSocket): await ws.accept() try: while True: message = await ws.receive_text() # 流式生成 async for chunk in llm.astream( messages=[{"role": "user", "content": message}] ): await ws.send_json({ "type": "token", "content": chunk.content }) await ws.send_json({"type": "done"}) except WebSocketDisconnect: print("Client disconnected") 客户端 const ws = new WebSocket('ws://localhost:8000/ws/chat'); ws.onopen = () => { ws.send(JSON.stringify({message: '你好'})); }; ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'token') { output.innerHTML += data.content; } else if (data.type === 'done') { console.log('Generation complete'); } }; 高级特性 打字机效果 async def typewriter_stream(text, delay=0.03): """模拟打字机效果的流式输出""" for char in text: yield char await asyncio.sleep(delay) 流式中断 class CancellableStream: def __init__(self): self.cancelled = False def cancel(self): self.cancelled = True async def stream(self, llm, messages): async for chunk in llm.astream(messages): if self.cancelled: break yield chunk 并行流式响应 async def parallel_stream(prompts, llm): """同时流式生成多个响应""" async def stream_one(prompt, index): result = [] async for chunk in llm.astream([{"role": "user", "content": prompt}]): result.append({"index": index, "content": chunk.content}) return result tasks = [stream_one(p, i) for i, p in enumerate(prompts)] results = await asyncio.gather(*tasks) # 交错输出 for i in range(max(len(r) for r in results)): for result in results: if i < len(result): yield result[i] 性能优化 缓冲控制 # Nginx配置:禁用缓冲 location /chat/stream { proxy_pass http://backend; proxy_buffering off; # 关闭代理缓冲 proxy_cache off; # 关闭缓存 chunked_transfer_encoding on; proxy_read_timeout 300s; } Token级vs字符级 # Token级流式(推荐):每个token一个chunk async for token in llm.astream(messages): yield token # 字符级流式:将token拆分为字符 async for token in llm.astream(messages): for char in token.content: yield char await asyncio.sleep(0.01) # 添加微小延迟 结语 流式响应是LLM应用的标配功能。SSE适合单向流式输出,WebSocket适合需要双向交互的场景。关键点:禁用所有层级的缓冲、正确处理中断、保持连接稳定性。 加入讨论 这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。 ...

2026-07-02 · 2 min · 418 words · 硅基 AGI 探索者
回归测试

LLM回归测试策略:确保更新不引入退化

引言 LLM应用的一个独特挑战是:即使代码没变,模型提供商更新模型版本也可能导致输出变化。同样,提示的微小修改可能在某些场景下引入退化。2026年,LLM回归测试已经成为AI应用的标配。本文将系统介绍回归测试策略。 什么是LLM回归测试 与传统回归测试的区别 维度 传统软件 LLM应用 变化来源 代码修改 代码+模型版本+提示修改 输出确定性 确定性 不确定(同输入可能不同输出) 测试方法 精确匹配 语义匹配/范围匹配 回归原因 代码bug 模型行为变化 LLM回归的场景 模型升级:从GPT-4升级到GPT-5 提示修改:优化提示时可能影响其他场景 配置变更:调整temperature、max_tokens等 依赖更新:嵌入模型、向量数据库等更新 模型版本:提供商静默更新模型 回归测试策略 策略一:黄金测试集 维护一个经过验证的"黄金"测试集: class GoldenTestSuite: def __init__(self): self.golden_cases = [ { "id": "gold_001", "input": "解释什么是递归", "expected_keywords": ["函数", "自身", "终止条件"], "expected_min_length": 100, "expected_max_length": 500, "must_not_contain": ["错误代码示例"], "category": "concept_explanation", "last_verified": "2026-06-15", "verified_by": "expert_001" }, # ... 更多黄金测试用例 ] def run(self, model_config): results = [] for case in self.golden_cases: response = call_llm(case["input"], **model_config) result = self.verify(response, case) results.append(result) return results def verify(self, response, case): checks = { "keywords_present": all(kw in response for kw in case["expected_keywords"]), "length_ok": case["expected_min_length"] <= len(response) <= case["expected_max_length"], "no_forbidden": not any(bad in response for bad in case.get("must_not_contain", [])) } checks["passed"] = all(checks.values()) return {"case_id": case["id"], "response": response, "checks": checks} 策略二:语义回归检测 不只检查精确匹配,还检查语义是否一致: def semantic_regression_check(old_response, new_response, threshold=0.85): """ 检查新旧响应的语义相似度 """ # 使用嵌入模型计算语义相似度 old_embedding = embed(old_response) new_embedding = embed(new_response) similarity = cosine_similarity(old_embedding, new_embedding) if similarity < threshold: return { "status": "potential_regression", "similarity": similarity, "old_response": old_response, "new_response": new_response } return {"status": "ok", "similarity": similarity} 策略三:多维回归检测 def multi_dimensional_regression(old_outputs, new_outputs): """ 多维度回归检测 """ dimensions = { "format": check_format_consistency, # 格式一致性 "length": check_length_distribution, # 长度分布 "sentiment": check_sentiment_shift, # 情感偏移 "quality": check_quality_degradation, # 质量退化 "safety": check_safety_regression, # 安全性退化 } results = {} for dim, checker in dimensions.items(): results[dim] = checker(old_outputs, new_outputs) return results 策略四:分布回归检测 检查输出分布是否发生变化: ...

2026-07-02 · 3 min · 618 words · 硅基 AGI 探索者
鲁ICP备2026018361号