From b4eb827e89701856e74a294560b2d669360ea92f Mon Sep 17 00:00:00 2001 From: UncleCheng Date: Mon, 27 Jul 2026 23:44:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=20build/eval/tools/r?= =?UTF-8?q?esources=20=E5=9B=9B=E6=A8=A1=E5=9D=97=2016=20=E7=AF=87?= =?UTF-8?q?=E5=8D=A0=E4=BD=8D=E6=96=87=E7=AB=A0=E6=89=A9=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - build/ (3篇): local-models 本地模型、deployment 部署入门、docker Docker基础 - eval/ (3篇): metrics 主观与客观指标、hallucination 幻觉评测、quality 输出质量判断 - tools/ (4篇): api API入门、tool-calling 函数调用、local-vs-online 本地vs在线、workflow Chat/Copilot/Agent/Workflow - resources/ (6篇): models 模型平台、apis API平台、rag-frameworks RAG框架、agent-frameworks Agent框架、eval-tools 评测工具、books-and-articles 书单与文章 全部含 frontmatter/mermaid/代码示例/对比表/练习题。mkdocs build --strict 零报错。 --- docs/build/deployment.md | 421 ++++++++++++++++++++++++- docs/build/docker.md | 358 ++++++++++++++++++++- docs/build/local-models.md | 408 +++++++++++++++++++++++- docs/eval/hallucination.md | 452 ++++++++++++++++++++++++++- docs/eval/metrics.md | 440 +++++++++++++++++++++++++- docs/eval/quality.md | 437 +++++++++++++++++++++++++- docs/resources/agent-frameworks.md | 325 ++++++++++++++++++- docs/resources/apis.md | 353 ++++++++++++++++++++- docs/resources/books-and-articles.md | 312 +++++++++++++++++- docs/resources/eval-tools.md | 342 +++++++++++++++++++- docs/resources/models.md | 286 ++++++++++++++++- docs/resources/rag-frameworks.md | 304 +++++++++++++++++- docs/tools/api.md | 331 +++++++++++++++++++- docs/tools/local-vs-online.md | 289 ++++++++++++++++- docs/tools/tool-calling.md | 412 +++++++++++++++++++++++- docs/tools/workflow.md | 310 +++++++++++++++++- 16 files changed, 5684 insertions(+), 96 deletions(-) diff --git a/docs/build/deployment.md b/docs/build/deployment.md index 51c7f89..2d667a5 100644 --- a/docs/build/deployment.md +++ b/docs/build/deployment.md @@ -1,10 +1,419 @@ +--- +tags: + - Build +--- + # 部署入门 -> 占位页:本页内容待团队补充。 +
+Build · 第 4 站 +**本地跑通了,怎么让别人也能用?** 本章从 FastAPI 开始,一步步教你把 AI 模型包装成 HTTP 服务,部署到云上。 +
+ +## 这章解决什么问题 + +你在本地写了一个 AI 应用,自己用得很开心。但朋友说"发我试试",你发现没法给他用——代码在你电脑上,模型在你本地,他访问不了。 + +这一章要解决的就是:**把本地代码变成一个别人能访问的服务**。 + +## 服务类型选择 + +| 类型 | 协议 | 特点 | 适用场景 | +|------|------|------|----------| +| REST API | HTTP | 请求-响应模式,简单可靠 | 大多数场景,前端调用 | +| SSE | HTTP | 服务器单向推送,流式输出 | AI 流式对话 | +| WebSocket | WebSocket | 双向实时通信 | 实时聊天、协作编辑 | + +对于 AI 应用,最常见的组合是:**REST API 处理普通请求 + SSE 处理流式输出**。 + +## FastAPI:AI 服务的首选框架 + +FastAPI 是 Python 生态中最适合写 AI 服务的框架——异步支持、自动文档、性能优秀。 + +### 安装 + +```bash +pip install fastapi uvicorn python-dotenv +``` + +### 最小示例 + +```python +# main.py +from fastapi import FastAPI +from pydantic import BaseModel + +app = FastAPI() + +class ChatRequest(BaseModel): + message: str + +@app.post("/chat") +async def chat(request: ChatRequest): + return {"reply": f"你说的是:{request.message}"} + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=8000) +``` + +运行并测试: + +```bash +# 启动服务 +python main.py + +# 另一个终端测试 +curl -X POST http://localhost:8000/chat \ + -H "Content-Type: application/json" \ + -d '{"message": "你好"}' +``` + +访问 `http://localhost:8000/docs` 能看到自动生成的 API 文档。 + +### 接入真实 AI 模型 + +```python +# main.py +import os +import requests +from fastapi import FastAPI +from pydantic import BaseModel +from dotenv import load_dotenv + +load_dotenv() + +app = FastAPI() + +OLLAMA_HOST = os.getenv("OLLAMA_HOST", "http://localhost:11434") +MODEL_NAME = os.getenv("MODEL_NAME", "qwen2.5:7b") + +class ChatRequest(BaseModel): + message: str + history: list[dict] = [] + +@app.post("/chat") +async def chat(request: ChatRequest): + messages = request.history + [ + {"role": "user", "content": request.message} + ] + + response = requests.post( + f"{OLLAMA_HOST}/v1/chat/completions", + json={"model": MODEL_NAME, "messages": messages}, + timeout=60, + ) + + if response.status_code != 200: + return {"error": f"模型调用失败:{response.status_code}"} + + data = response.json() + reply = data["choices"][0]["message"]["content"] + return {"reply": reply, "model": MODEL_NAME} +``` + +### 流式输出(SSE) + +```python +import json +import requests +from fastapi import FastAPI +from fastapi.responses import StreamingResponse +from pydantic import BaseModel + +app = FastAPI() + +class ChatRequest(BaseModel): + message: str + history: list[dict] = [] + +@app.post("/chat/stream") +async def chat_stream(request: ChatRequest): + messages = request.history + [ + {"role": "user", "content": request.message} + ] + + def generate(): + response = requests.post( + "http://localhost:11434/v1/chat/completions", + json={"model": "qwen2.5:7b", "messages": messages, "stream": True}, + stream=True, + timeout=60, + ) + + for line in response.iter_lines(): + if not line: + continue + line = line.decode("utf-8") + if line.startswith("data: "): + data_str = line[6:] + if data_str == "[DONE]": + yield "data: [DONE]\n\n" + break + chunk = json.loads(data_str) + content = chunk["choices"][0]["delta"].get("content", "") + if content: + yield f"data: {json.dumps({'content': content})}\n\n" + + return StreamingResponse( + generate(), + media_type="text/event-stream", + headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}, + ) +``` + +## 环境变量管理 + +```bash +# .env(不要提交到 Git) +OLLAMA_HOST=http://localhost:11434 +MODEL_NAME=qwen2.5:7b +API_KEY=your-secret-key-here +``` + +在代码中读取: + +```python +import os +from dotenv import load_dotenv + +load_dotenv() + +OLLAMA_HOST = os.getenv("OLLAMA_HOST", "http://localhost:11434") +API_KEY = os.getenv("API_KEY") + +if not API_KEY: + raise ValueError("请设置 API_KEY 环境变量") +``` + +> ⚠️ **安全提醒**:`.env` 文件不要提交到 Git。在 `.gitignore` 中加上 `.env`。生产环境用部署平台的环境变量注入功能。 + +## 日志和监控 + +```python +import logging +from fastapi import FastAPI, Request +from datetime import datetime + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(levelname)s - %(message)s", + handlers=[ + logging.FileHandler("app.log"), + logging.StreamHandler(), + ] +) +logger = logging.getLogger(__name__) + +app = FastAPI() + +@app.middleware("http") +async def log_requests(request: Request, call_next): + start = datetime.now() + response = await call_next(request) + duration = (datetime.now() - start).total_seconds() + + logger.info( + f"{request.method} {request.url.path} " + f"- {response.status_code} - {duration:.3f}s" + ) + return response +``` + +## 错误处理 + +```python +from fastapi import FastAPI, HTTPException +from fastapi.responses import JSONResponse +import requests as req + +app = FastAPI() + +@app.exception_handler(req.exceptions.Timeout) +async def timeout_handler(request, exc): + return JSONResponse( + status_code=504, + content={"error": "模型响应超时,请稍后重试"} + ) + +@app.exception_handler(req.exceptions.ConnectionError) +async def connection_handler(request, exc): + return JSONResponse( + status_code=503, + content={"error": "模型服务不可用,请检查 Ollama 是否运行"} + ) +``` + +## 云部署选项 + +| 平台 | 特点 | 免费额度 | 适合场景 | +|------|------|----------|----------| +| Railway | 简单易用,支持 Docker | 每月 $5 免费 | 快速部署小型服务 | +| Fly.io | 边缘计算,全球部署 | 免费套餐有限 | 需要低延迟的场景 | +| Vercel | 前端友好,Serverless | 免费额度充足 | 纯 API 服务 | +| Render | 全栈支持 | 免费实例会休眠 | 全栈应用 | + +### Railway 部署 + +```bash +# 安装 Railway CLI +npm install -g @railway/cli + +# 登录并部署 +railway login +railway init +railway up +``` + +### Vercel 部署 + +```bash +# 安装 Vercel CLI +npm install -g vercel + +# 部署 +vercel +``` + +`vercel.json` 配置: + +```json +{ + "builds": [{"src": "main.py", "use": "@vercel/python"}], + "routes": [{"src": "/(.*)", "dest": "main.py"}] +} +``` + +## Docker 部署 + +Docker 是最通用的部署方式,详见 [Docker 基础](docker.md)。 + +```dockerfile +# Dockerfile +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +EXPOSE 8000 +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +```bash +# 构建并运行 +docker build -t my-ai-app . +docker run -p 8000:8000 -e OLLAMA_HOST=http://host.docker.internal:11434 my-ai-app +``` + +## 完整示例 + +```python +# main.py - 一个可部署的 AI 聊天服务 +import os +import json +import logging +import requests +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import StreamingResponse +from pydantic import BaseModel +from dotenv import load_dotenv + +load_dotenv() + +OLLAMA_HOST = os.getenv("OLLAMA_HOST", "http://localhost:11434") +MODEL_NAME = os.getenv("MODEL_NAME", "qwen2.5:7b") + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +app = FastAPI(title="AI Chat API") +app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) + +class ChatRequest(BaseModel): + message: str + history: list[dict] = [] + stream: bool = False + +def call_model(messages, stream=False): + try: + response = requests.post( + f"{OLLAMA_HOST}/v1/chat/completions", + json={"model": MODEL_NAME, "messages": messages, "stream": stream}, + stream=stream, timeout=60, + ) + response.raise_for_status() + return response + except requests.exceptions.Timeout: + raise HTTPException(status_code=504, detail="模型响应超时") + except requests.exceptions.ConnectionError: + raise HTTPException(status_code=503, detail="模型服务不可用") + +@app.post("/chat") +async def chat(request: ChatRequest): + messages = request.history + [{"role": "user", "content": request.message}] + + if request.stream: + def generate(): + response = call_model(messages, stream=True) + for line in response.iter_lines(): + if not line: + continue + line = line.decode("utf-8") + if line.startswith("data: "): + data_str = line[6:] + if data_str == "[DONE]": + yield "data: [DONE]\n\n" + break + chunk = json.loads(data_str) + content = chunk["choices"][0]["delta"].get("content", "") + if content: + yield f"data: {json.dumps({'content': content})}\n\n" + return StreamingResponse(generate(), media_type="text/event-stream") + + response = call_model(messages) + data = response.json() + return {"reply": data["choices"][0]["message"]["content"], "model": MODEL_NAME} + +@app.get("/health") +async def health(): + try: + response = requests.get(f"{OLLAMA_HOST}/api/tags", timeout=5) + return {"status": "ok", "models": response.json()} + except Exception: + return {"status": "degraded", "message": "模型服务不可用"} +``` + +## 常见问题 + +??? question "Q:FastAPI 和 Flask 选哪个?" + + FastAPI 是更好的选择——原生异步支持、自动 API 文档、类型检查。Flask 更老牌,但写 AI 服务 FastAPI 更顺手。 + + | 对比项 | FastAPI | Flask | + |--------|---------|-------| + | 异步支持 | 原生 | 需要扩展 | + | 性能 | 更高 | 一般 | + | 自动文档 | 内置 | 需要扩展 | + +??? question "Q:如何处理并发请求?" + + 1. **多 Worker**:`uvicorn main:app --workers 4` + 2. **异步队列**:用 `asyncio.Queue` 或 `Celery` + 3. **模型服务分离**:用 vLLM、TGI 等专业推理服务 + +## 练习 + +1. **部署一个简单的聊天 API**:用 FastAPI 包装 Ollama,实现 `/chat` 接口 +2. **加上流式输出**:实现 `/chat/stream` 接口,支持 SSE +3. **添加错误处理**:超时、连接失败时返回友好错误信息 +4. **部署到 Railway 或 Vercel**:把服务部署到云上 +5. **添加请求日志**:记录每个请求的方法、路径、状态码、耗时 -## 建议内容 +## 延伸阅读 -- 服务形态 -- 环境变量 -- 日志 -- 回滚 +- [FastAPI 官方文档](https://fastapi.tiangolo.com/) —— 完整教程和 API 参考 +- [Railway 文档](https://docs.railway.app/) —— 部署指南 +- [Vercel 文档](https://vercel.com/docs) —— Serverless 部署 +- [Docker 基础](docker.md) —— 容器化部署 +- [本地模型](local-models.md) —— Ollama 安装和使用 diff --git a/docs/build/docker.md b/docs/build/docker.md index 25a9c75..fbf0e79 100644 --- a/docs/build/docker.md +++ b/docs/build/docker.md @@ -1,10 +1,356 @@ +--- +tags: + - Build +--- + # Docker 基础 -> 占位页:本页内容待团队补充。 +
+Build · 第 5 站 +**"在我电脑上能跑啊!"** Docker 终结了这句话。本章教你用容器打包 AI 应用,让它在任何机器上都能一模一样地运行。 +
+ +## 这章解决什么问题 + +你写了一个 AI 应用,在自己电脑上跑得好好的。发给同事,他装了半小时依赖还是报错。部署到服务器,Python 版本不对、CUDA 版本不对、某个库缺了系统依赖…… + +Docker 解决的就是这个问题:**把你的代码、依赖、配置全部打包成一个容器,在任何机器上都能一键运行**。 + +## 镜像 vs 容器 + +| 概念 | 类比 | 特点 | +|------|------|------| +| 镜像(Image) | 安装包 / 菜谱 | 只读模板,定义了环境和程序 | +| 容器(Container) | 运行中的程序 / 做出来的菜 | 镜像的实例,可以启动、停止、删除 | + +```mermaid +%%{init: { 'htmlLabels': false } }%% +graph LR + A[Dockerfile] -->|docker build| B[镜像 Image] + B -->|docker run| C[容器 1] + B -->|docker run| D[容器 2] +``` + +### 基本命令 + +```bash +# 镜像相关 +docker images # 查看本地镜像 +docker pull python:3.11 # 拉取镜像 +docker rmi python:3.11 # 删除镜像 + +# 容器相关 +docker ps # 查看运行中的容器 +docker ps -a # 查看所有容器 +docker stop <容器ID> # 停止容器 +docker rm <容器ID> # 删除容器 +docker logs <容器ID> # 查看容器日志 +docker exec -it <容器ID> bash # 进入容器 +``` + +## Dockerfile:构建镜像的配方 + +### 基本结构 + +```dockerfile +# 基础镜像 +FROM python:3.11-slim + +# 设置工作目录 +WORKDIR /app + +# 复制依赖文件 +COPY requirements.txt . + +# 安装依赖 +RUN pip install --no-cache-dir -r requirements.txt + +# 复制代码 +COPY . . + +# 暴露端口 +EXPOSE 8000 + +# 启动命令 +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +### 常用指令 + +| 指令 | 作用 | 示例 | +|------|------|------| +| `FROM` | 基础镜像 | `FROM python:3.11-slim` | +| `WORKDIR` | 设置工作目录 | `WORKDIR /app` | +| `COPY` | 复制文件到镜像 | `COPY . .` | +| `RUN` | 构建时执行命令 | `RUN pip install -r requirements.txt` | +| `EXPOSE` | 声明端口 | `EXPOSE 8000` | +| `CMD` | 容器启动命令 | `CMD ["python", "main.py"]` | +| `ENV` | 设置环境变量 | `ENV MODEL_NAME=qwen2.5` | + +### AI 应用的 Dockerfile + +```dockerfile +FROM python:3.11-slim + +WORKDIR /app + +# 安装系统依赖 +RUN apt-get update && apt-get install -y \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# 复制并安装 Python 依赖 +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# 复制代码 +COPY . . + +# 健康检查 +HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ + CMD curl -f http://localhost:8000/health || exit 1 + +EXPOSE 8000 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +## Docker Compose:多服务编排 + +当你的应用有多个服务(如 Web 服务 + Ollama),用 Docker Compose 来管理。 + +### 完整的 AI 应用配置 + +```yaml +# docker-compose.yml +version: '3.8' + +services: + # AI 聊天 API + chat-api: + build: . + ports: + - "8000:8000" + environment: + - OLLAMA_HOST=http://ollama:11434 + - MODEL_NAME=qwen2.5:7b + depends_on: + ollama: + condition: service_healthy + restart: unless-stopped + + # Ollama 模型服务 + ollama: + image: ollama/ollama + ports: + - "11434:11434" + volumes: + - ollama_data:/root/.ollama + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"] + interval: 30s + timeout: 10s + retries: 3 + restart: unless-stopped + +volumes: + ollama_data: +``` + +### 常用命令 + +```bash +# 启动所有服务 +docker compose up -d + +# 查看服务状态 +docker compose ps + +# 查看日志 +docker compose logs -f + +# 停止所有服务 +docker compose down + +# 重新构建并启动 +docker compose up -d --build +``` + +## GPU 透传 + +AI 推理需要 GPU 加速。Docker 默认不能访问宿主机的 GPU,需要安装 NVIDIA Container Toolkit。 + +### 安装(Ubuntu/Debian) + +```bash +# 添加仓库 +curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \ + | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg + +curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \ + | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \ + | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list + +# 安装 +sudo apt-get update +sudo apt-get install -y nvidia-container-toolkit + +# 配置 Docker 并重启 +sudo nvidia-ctk runtime configure --runtime=docker +sudo systemctl restart docker +``` + +### 验证 GPU 可用 + +```bash +docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi +``` + +### 运行时指定 GPU + +```bash +# 使用所有 GPU +docker run --gpus all my-ai-app + +# 使用特定 GPU +docker run --gpus '"device=0"' my-ai-app +``` + +## 卷挂载:持久化模型数据 + +模型文件动辄几个 GB,不应该打包进镜像。用卷挂载把宿主机的目录映射到容器里。 + +```bash +# 挂载目录 +docker run -v ./models:/app/models my-ai-app +``` + +### 卷类型对比 + +| 类型 | 语法 | 特点 | 适用场景 | +|------|------|------|----------| +| 命名卷 | `volume_name:/path` | Docker 管理,可移植 | 数据库数据、模型缓存 | +| 绑定挂载 | `/host/path:/path` | 直接映射本地目录 | 开发环境、配置文件 | + +## 常见错误和调试 + +**容器内访问不到宿主机服务:** + +```python +# 错误:localhost 在容器内指向容器自己 +OLLAMA_HOST = "http://localhost:11434" + +# 正确:使用宿主机地址 +OLLAMA_HOST = "http://host.docker.internal:11434" # Docker Desktop +``` + +**pip install 超时:** + +```dockerfile +# 使用国内镜像源 +RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt +``` + +**调试命令:** + +```bash +docker logs <容器ID> # 查看日志 +docker exec -it <容器ID> bash # 进入容器 +docker inspect <容器ID> # 查看详细信息 +docker stats <容器ID> # 查看资源使用 +``` + +## AI 工作负载最佳实践 + +### 1. 分离模型和代码 + +```yaml +# 不推荐:模型打包进镜像 +FROM python:3.11 +COPY ./models /app/models # 几 GB 的模型文件 + +# 推荐:模型通过卷挂载 +docker run -v ./models:/app/models my-ai-app +``` + +### 2. 使用 .dockerignore + +``` +# .dockerignore +.git +.env +__pycache__ +*.pyc +.venv +node_modules +*.gguf +*.bin +models/ +``` + +### 3. 优化构建缓存 + +```dockerfile +# 把不常变的层放前面 +FROM python:3.11-slim +WORKDIR /app + +# 依赖文件不常变,先复制 +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# 代码经常变,后复制 +COPY . . +``` + +### 4. 资源限制 + +```yaml +services: + chat-api: + deploy: + resources: + limits: + cpus: '2' + memory: 4G +``` + +## 常见问题 + +??? question "Q:Docker 和虚拟机有什么区别?" + + Docker 容器共享宿主机的内核,虚拟机有独立的内核。容器更轻量、启动更快。 + + | 对比项 | Docker 容器 | 虚拟机 | + |--------|-------------|--------| + | 启动速度 | 秒级 | 分钟级 | + | 资源占用 | 少 | 多 | + | 镜像大小 | MB 级 | GB 级 | + +??? question "Q:模型文件应该打包进镜像吗?" + + 不推荐。模型文件通常很大,打包进镜像会导致构建时间长、镜像体积巨大。更好的方案: + - 用卷挂载映射本地模型目录 + - 启动时自动下载模型 + +## 练习 + +1. **写一个 Dockerfile**:把你的 AI 应用打包成 Docker 镜像 +2. **用 Docker Compose**:配置一个包含 Web 服务和 Ollama 的多服务应用 +3. **GPU 透传**:在 Docker 中运行 Ollama,确保能用 GPU 加速 +4. **卷挂载**:把模型目录挂载到容器外,重启容器后模型还在 +5. **优化镜像**:用 `.dockerignore` 排除不需要的文件,减小镜像体积 -## 建议内容 +## 延伸阅读 -- Docker 是什么 -- 镜像与容器 -- 最小 Dockerfile -- 常见错误 +- [Docker 官方文档](https://docs.docker.com/) —— 完整教程和 API 参考 +- [Docker Compose 文档](https://docs.docker.com/compose/) —— 多服务编排 +- [NVIDIA Container Toolkit](https://github.com/NVIDIA/nvidia-container-toolkit) —— GPU 透传 +- [Ollama Docker](https://ollama.com/blog/ollama-is-now-available-as-an-official-docker-image) —— Ollama 官方镜像 diff --git a/docs/build/local-models.md b/docs/build/local-models.md index c014578..5528b36 100644 --- a/docs/build/local-models.md +++ b/docs/build/local-models.md @@ -1,10 +1,406 @@ +--- +tags: + - Build +--- + # 本地模型 -> 占位页:本页内容待团队补充。 +
+Build · 第 3 站 +**不想把数据发到云端?** 本章教你用 Ollama、llama.cpp、LM Studio 在本地跑大模型——断网也能用,数据不出门,还能省下 API 费用。 +
+ +## 这章解决什么问题 + +你已经会调 API 了,但心里总觉得不踏实:公司内部文档发给 OpenAI 合规吗?每次调试都要花钱,一个月下来账单有点吓人。出差在飞机上没网,AI 助手直接罢工。 + +本地模型解决的就是这三个痛点:**隐私、成本、离线可用**。把模型下载到自己电脑上运行,数据永远不会离开你的硬盘。 + +## 硬件要求 + +跑本地模型,硬件是绕不开的话题。先搞清楚你的电脑能跑多大的模型: + +| 硬件指标 | 最低要求 | 推荐配置 | 说明 | +|----------|----------|----------|------| +| GPU VRAM | 4GB | 8GB+ | 决定能跑多大的模型 | +| 系统内存 | 8GB | 16GB+ | GPU 显存不够时会用内存补 | +| 硬盘空间 | 10GB | 50GB+ | 模型文件动辄几个 GB | +| CPU | 任意 | 多核 | 没有 GPU 时 CPU 也能跑,只是慢 | + +> 💡 **显存不够怎么办?** 用量化模型(下面会讲)。7B 参数的全精度模型需要 ~14GB 显存,量化到 Q4 只需要 ~4GB,8GB 显存的显卡就能跑。 + +### 常见显卡能跑多大的模型 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +graph LR + A[4GB VRAM
GTX 1650] --> B[7B Q4
勉强能跑] + C[8GB VRAM
RTX 3060] --> D[7B Q4/Q8
流畅运行] + C --> E[13B Q4
可以尝试] + F[12GB VRAM
RTX 3060 12G] --> G[13B Q4/Q8
流畅运行] + F --> H[30B Q4
可以尝试] + I[24GB VRAM
RTX 3090/4090] --> J[70B Q4
流畅运行] +``` + +## 量化:让大模型跑在小显存上 + +量化是本地部署的核心技术。简单说,就是把模型参数从高精度(如 FP16)压缩到低精度(如 INT4),体积和显存需求大幅下降,精度损失很小。 + +### 量化格式对比 + +| 量化类型 | 精度 | 7B 模型体积 | 显存需求 | 质量损失 | +|----------|------|-------------|----------|----------| +| FP16 | 16 位浮点 | ~14GB | ~16GB | 无 | +| Q8_0 | 8 位整数 | ~7GB | ~8GB | 几乎没有 | +| Q6_K | 6 位整数 | ~5.5GB | ~6.5GB | 很小 | +| Q4_K_M | 4 位整数(中等) | ~4.5GB | ~5GB | 小 | +| Q4_K_S | 4 位整数(小) | ~4GB | ~4.5GB | 稍大 | +| Q3_K_M | 3 位整数 | ~3.5GB | ~4GB | 明显 | +| Q2_K | 2 位整数 | ~2.8GB | ~3.5GB | 很大 | + +> 💡 **Q4_K_M 是甜点**:对于大多数用户,Q4_K_M 是最佳平衡点——体积小、显存友好、质量损失可接受。社区跑分测试显示,Q4_K_M 的质量损失通常在 2-5% 以内。 + +### GGUF 格式 + +GGUF(GPT-Generated Unified Format)是目前最流行的量化模型格式,由 llama.cpp 项目推出。文件后缀通常是 `.gguf`: + +``` +Qwen2.5-7B-Instruct-Q4_K_M.gguf + │ │ │ + │ │ └── 量化精度 + │ └──────── 模型大小 + └────────────────── 模型名称 +``` + +## Ollama:最简单的本地模型方案 + +Ollama 是目前最火的本地模型运行工具,一行命令就能跑起来。 + +### 安装 + +**macOS / Linux:** + +```bash +curl -fsSL https://ollama.com/install.sh | sh +``` + +**Windows:** + +去 [ollama.com](https://ollama.com) 下载安装包,双击安装即可。 + +**Docker(适合服务器):** + +```bash +docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 ollama/ollama +``` + +### 基本使用 + +安装完成后,打开终端直接拉模型运行: + +```bash +# 拉取并运行 Qwen2.5 7B 模型 +ollama run qwen2.5:7b + +# 运行 Llama 3 8B +ollama run llama3:8b + +# 运行 DeepSeek 7B +ollama run deepseek-v2:7b +``` + +第一次运行会自动下载模型,之后就是秒启动。模型文件保存在: + +| 系统 | 路径 | +|------|------| +| macOS | `~/.ollama/models` | +| Linux | `/usr/share/ollama/.ollama/models` | +| Windows | `C:\Users\<用户名>\.ollama\models` | + +### Ollama 常用命令 + +```bash +# 查看已下载的模型 +ollama list + +# 查看正在运行的模型 +ollama ps + +# 拉取模型(不运行) +ollama pull qwen2.5:7b + +# 删除模型 +ollama rm qwen2.5:7b + +# 查看模型信息 +ollama show qwen2.5:7b + +# 停止运行中的模型 +ollama stop qwen2.5:7b +``` + +### Ollama API + +Ollama 启动后会自动提供一个兼容 OpenAI 格式的 API,端口是 `11434`: + +```python +import requests + +response = requests.post( + "http://localhost:11434/v1/chat/completions", + json={ + "model": "qwen2.5:7b", + "messages": [ + {"role": "user", "content": "用一句话介绍自己"} + ], + }, +) + +print(response.json()["choices"][0]["message"]["content"]) +``` + +这意味着你之前写的 API 调用代码,只要把 URL 换成本地地址,就能无缝切换到本地模型。 + +### Modelfile:自定义模型行为 + +Ollama 用 Modelfile 来自定义模型的参数和系统提示: + +```Dockerfile +# Modelfile +FROM qwen2.5:7b + +# 设置系统提示 +SYSTEM """ +你是一个 Python 教学助手。 +回答要简洁,用代码示例说明。 +""" + +# 调整参数 +PARAMETER temperature 0.7 +PARAMETER top_p 0.9 +PARAMETER num_ctx 4096 +``` + +创建并运行自定义模型: + +```bash +# 从 Modelfile 创建模型 +ollama create python-tutor -f Modelfile + +# 运行自定义模型 +ollama run python-tutor +``` + +Modelfile 支持的参数: + +| 参数 | 说明 | 默认值 | +|------|------|--------| +| `temperature` | 生成随机性,0-2 | 0.7 | +| `top_p` | 核采样概率 | 0.9 | +| `num_ctx` | 上下文窗口大小 | 2048 | +| `num_gpu` | 使用的 GPU 层数 | 全部 | +| `num_thread` | CPU 线程数 | 自动 | +| `repeat_penalty` | 重复惩罚 | 1.1 | + +## llama.cpp:极致性能方案 + +llama.cpp 是 C++ 实现的 LLM 推理引擎,性能极好,支持几乎所有硬件平台。适合追求极致性能或者需要深度定制的用户。 + +### 安装 + +```bash +# 克隆仓库 +git clone https://github.com/ggerganov/llama.cpp +cd llama.cpp + +# 编译(支持 CUDA 的版本) +make LLAMA_CUDA=1 + +# 或者用 CMake +mkdir build && cd build +cmake .. -DLLAMA_CUDA=ON +cmake --build . --config Release +``` + +### 基本使用 + +```bash +# 运行模型进行对话 +./llama-cli -m models/qwen2.5-7b-q4_k_m.gguf \ + -c 4096 \ + -ngl 99 \ + --interactive + +# 启动 API 服务器 +./llama-server -m models/qwen2.5-7b-q4_k_m.gguf \ + -c 4096 \ + -ngl 99 \ + --host 0.0.0.0 \ + --port 8080 +``` + +参数说明: + +| 参数 | 说明 | +|------|------| +| `-m` | 模型文件路径 | +| `-c` | 上下文长度 | +| `-ngl` | 卸载到 GPU 的层数(99 表示全部) | +| `--interactive` | 交互模式 | +| `--host` | 监听地址 | +| `--port` | 监听端口 | + +### 量化自己的模型 + +llama.cpp 自带量化工具,可以把 HuggingFace 模型转成 GGUF 格式: + +```bash +# 1. 转换模型格式(从 HuggingFace 到 GGUF) +python convert_hf_to_gguf.py /path/to/model \ + --outfile model-f16.gguf \ + --outtype f16 + +# 2. 量化(从 F16 量化到 Q4_K_M) +./llama-quantize model-f16.gguf model-q4_k_m.gguf Q4_K_M +``` + +## LM Studio:图形界面方案 + +不想敲命令行?LM Studio 提供了漂亮的图形界面,适合新手。 + +### 安装和使用 + +1. 去 [lmstudio.ai](https://lmstudio.ai) 下载安装包 +2. 打开后在搜索栏搜模型(如 "qwen2.5-7b") +3. 点击下载,等进度条走完 +4. 点 "Start Chat" 开始对话 + +LM Studio 的优势: + +| 特点 | 说明 | +|------|------| +| 可视化模型管理 | 下载、删除、查看详情一目了然 | +| 内置聊天界面 | 直接对话,不用写代码 | +| 本地 API 服务器 | 一键启动兼容 OpenAI 的 API | +| 参数调整 | 滑块调节 temperature、top_p 等 | +| 多模型切换 | 左侧栏快速切换模型 | + +### LM Studio API + +LM Studio 也能启动本地 API 服务器,和 Ollama 类似: + +```bash +# 默认端口是 1234 +curl http://localhost:1234/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{ + "model": "qwen2.5-7b", + "messages": [{"role": "user", "content": "你好"}] + }' +``` + +## 本地模型 vs API 模型:质量对比 + +本地模型和 API 模型的质量差距有多大?这取决于你选的模型和任务类型。 + +### 质量对比表 + +| 对比维度 | 本地 7B 模型 | GPT-4o | 说明 | +|----------|-------------|--------|------| +| 中文理解 | ★★★★☆ | ★★★★★ | 大模型在中文上已经很强 | +| 英文能力 | ★★★★☆ | ★★★★★ | 英文训练数据更多 | +| 代码生成 | ★★★★☆ | ★★★★★ | 7B 模型写简单代码够用 | +| 数学推理 | ★★★☆☆ | ★★★★★ | 小模型推理能力是短板 | +| 长文本 | ★★★☆☆ | ★★★★★ | 受限于上下文窗口 | +| 响应速度 | ★★★★★ | ★★★☆☆ | 本地无网络延迟 | +| 隐私安全 | ★★★★★ | ★★☆☆☆ | 数据不出门 | +| 成本 | ★★★★★ | ★★☆☆☆ | 一次性投入 | + +> 💡 **怎么选?** 如果任务是简单问答、文本处理、代码补全,本地 7B 模型完全够用。如果需要复杂推理、长文本理解、多模态能力,API 模型(如 GPT-4o)还是更强。 + +## 推荐的本地模型 + +### Qwen2.5 系列(阿里通义千问) + +```bash +ollama run qwen2.5:7b # 7B,日常够用 +ollama run qwen2.5:14b # 14B,更强一些 +ollama run qwen2.5:32b # 32B,需要 24GB 显存 +ollama run qwen2.5:72b # 72B,需要 48GB+ 显存 +``` + +特点:中文能力极强,开源社区活跃,支持工具调用。 + +### Llama 3 系列(Meta) + +```bash +ollama run llama3:8b # 8B,Meta 最新开源 +ollama run llama3:70b # 70B,需要高配 +``` + +特点:英文能力优秀,推理能力强,社区生态完善。 + +### DeepSeek 系列 + +```bash +ollama run deepseek-v2:16b # 16B,性价比高 +ollama run deepseek-coder:7b # 7B,代码专用 +``` + +特点:代码能力突出,中文支持好,推理能力不错。 + +### 模型选择建议 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +graph TD + A[你想用本地模型做什么?] --> B{任务类型} + B -->|日常聊天/文本处理| C[Qwen2.5 7B] + B -->|写代码| D[DeepSeek Coder 7B] + B -->|英文写作/推理| E[Llama 3 8B] + B -->|需要更强能力| F{显存大小} + F -->|8-12GB| G[Qwen2.5 14B] + F -->|24GB| H[Qwen2.5 32B] + F -->|48GB+| I[Qwen2.5 72B] +``` + +## 常见问题 + +??? question "Q:Ollama 和 llama.cpp 选哪个?" + + Ollama 适合大多数用户——安装简单、命令直观、自带 API 服务。llama.cpp 适合需要极致性能或深度定制的场景——比如要在嵌入式设备上跑、需要自定义推理逻辑、或者要量化自己的模型。 + + | 对比项 | Ollama | llama.cpp | + |--------|--------|-----------| + | 安装难度 | 一行命令 | 需要编译 | + | 使用难度 | 简单 | 较复杂 | + | 性能 | 良好 | 极致 | + | 定制性 | 有限 | 完全控制 | + | API 服务 | 自带 | 需手动启动 | + +??? question "Q:模型下载太慢怎么办?" + + 国内网络访问 HuggingFace 和 Ollama 官方源经常很慢。解决方案: + + 1. **Ollama 镜像源**:设置环境变量 `OLLAMA_HOST=https://mirror.sjtu.edu.cn/ollama` + 2. **HuggingFace 镜像**:用 `hf-mirror.com` 替换 `huggingface.co` + 3. **模型代理**:使用 ModelScope(魔搭社区)下载国内模型 + +??? question "Q:本地模型能微调吗?" + + 可以,但门槛较高。推荐用 [LLaMA-Factory](https://github.com/hiyouga/LLaMA-Factory) 项目,它提供了 Web UI 来微调模型,支持 LoRA、QLoRA 等方法。微调需要准备训练数据,7B 模型微调至少需要 16GB 显存。 + +## 练习 + +1. **安装 Ollama**:在你的电脑上安装 Ollama,拉取 `qwen2.5:7b` 模型并运行对话 +2. **写一个聊天程序**:用 Python 调用 Ollama API,实现多轮对话(参考 [最小 AI 应用](simple-app.md) 的代码) +3. **创建 Modelfile**:自定义一个"翻译助手"模型,设置系统提示为"你是一个专业的中英翻译",温度设为 0.3 +4. **对比测试**:同一个问题分别问本地模型和 API 模型,对比回答质量 -## 建议内容 +## 延伸阅读 -- 模型选择 -- 显存与内存 -- 量化 -- 本地推理工具 +- [Ollama 官方文档](https://ollama.com/) —— 安装、模型库、API 参考 +- [llama.cpp GitHub](https://github.com/ggerganov/llama.cpp) —— 源码、编译指南、性能优化 +- [LM Studio](https://lmstudio.ai/) —— 图形界面本地模型工具 +- [HuggingFace GGUF 模型库](https://huggingface.co/models?search=gguf) —— 预量化的 GGUF 模型下载 +- [LLaMA-Factory](https://github.com/hiyouga/LLaMA-Factory) —— 模型微调工具 diff --git a/docs/eval/hallucination.md b/docs/eval/hallucination.md index 1b92384..f94dca3 100644 --- a/docs/eval/hallucination.md +++ b/docs/eval/hallucination.md @@ -1,10 +1,450 @@ +--- +tags: + - Eval +--- + # 幻觉评测 -> 占位页:本页内容待团队补充。 +> 幻觉是 LLM 最危险的缺陷之一——模型自信满满地告诉你一个完全错误的事实,而你可能根本察觉不到。 + +## 这章解决什么问题 + +LLM 的训练目标是「生成看起来像人写的文本」,而不是「生成正确的文本」。这导致模型可能会编造事实、虚构引用、错误推理,但表达得非常流畅自信。这种现象被称为「幻觉」(Hallucination)。 + +幻觉的危害在于:用户很难分辨哪些信息是真实的,哪些是模型编造的。特别是在医疗、法律、金融等高风险领域,一个错误的建议可能导致严重后果。 + +## 核心概念 + +### 什么是幻觉 + +幻觉是指模型生成的内容与可验证的事实不一致,或者与输入的上下文矛盾。 + +#### 幻觉的类型 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +graph TD + A[幻觉类型] --> B[事实性幻觉] + A --> C[上下文幻觉] + A --> D[推理幻觉] + A --> E[引用幻觉] + + B --> B1[编造不存在的事实] + C --> C1[与上下文矛盾] + D --> D1[逻辑推理错误] + E --> E1[虚构引用来源] +``` + +```text +1. 事实性幻觉(Factual Hallucination) + - 模型编造不存在的事实 + - 示例:「爱因斯坦在 1921 年获得了诺贝尔化学奖」(实际是物理学奖) + +2. 上下文幻觉(Contextual Hallucination) + - 模型的回答与提供的上下文矛盾 + - 示例:给定文档说「公司成立于 2010 年」,模型回答「公司成立于 2005 年」 + +3. 推理幻觉(Reasoning Hallucination) + - 模型的推理过程有逻辑错误 + - 示例:「如果 A > B 且 B > C,那么 C > A」 + +4. 引用幻觉(Citation Hallucination) + - 模型虚构不存在的引用来源 + - 示例:「根据《自然》杂志 2023 年的研究...」(该研究不存在) +``` + +#### 幻觉 vs 创意生成 + +这里有个容易混淆的点——幻觉和创意生成是两回事: + +| 维度 | 幻觉 | 创意生成 | +|------|------|---------| +| 意图 | 想要提供准确信息 | 想要生成新颖内容 | +| 上下文 | 事实性任务(问答、摘要) | 创意任务(写作、营销) | +| 评估标准 | 准确性 | 创意性、吸引力 | +| 用户预期 | 期待真实信息 | 期待有趣内容 | + +### 为什么模型会产生幻觉 + +#### 训练数据问题 + +```text +1. 数据噪声 + - 互联网文本包含大量错误信息 + - 模型无法区分可靠和不可靠的来源 + +2. 数据过时 + - 训练数据有截止日期 + - 模型不知道最新发生的事情 + +3. 数据偏见 + - 某些观点在训练数据中出现频率更高 + - 模型可能放大这些偏见 +``` + +#### 模型架构问题 + +```text +1. 自回归生成 + - 模型逐个 token 生成,每一步都基于之前的 token + - 一旦某个 token 选错,后续 token 可能会沿着错误方向继续 + +2. 注意力机制局限 + - 模型可能没有正确关注到关键信息 + - 长文本中容易丢失重要细节 + +3. 概率采样 + - 低概率但正确的 token 可能被忽略 + - 高概率但错误的 token 可能被选中 +``` + +#### 解码策略问题 + +```text +1. 温度过高 + - 温度参数控制生成的随机性 + - 温度过高会增加随机性,增加幻觉风险 + +2. Top-P/Top-K 设置 + - 限制候选 token 的范围 + - 设置不当可能排除正确答案 + +3. 重复惩罚 + - 避免重复的惩罚机制 + - 可能导致模型选择不常见的词,增加幻觉 +``` + +### 幻觉检测方法 + +#### 基于规则的检测 + +```python +def rule_based_hallucination_detection(answer, context): + """基于规则的幻觉检测""" + issues = [] + + # 检查 1:数字一致性 + import re + numbers_in_answer = set(re.findall(r'\d+', answer)) + numbers_in_context = set(re.findall(r'\d+', context)) + + for num in numbers_in_answer: + if num not in numbers_in_context and len(num) > 2: + issues.append(f"数字 {num} 在上下文中未找到") + + # 检查 2:日期合理性 + dates = re.findall(r'\d{4}年', answer) + for date in dates: + year = int(date.replace('年', '')) + if year < 1900 or year > 2030: + issues.append(f"日期 {date} 可能不合理") + + return issues +``` + +基于规则的检测优点是快速、可解释,缺点是覆盖范围有限,只能检测明显的幻觉。 + +#### 基于模型的检测 + +```python +import openai + +基于模型的检测优点是能理解语义,检测更复杂的幻觉,缺点是成本高、可能有偏见。 + +#### 混合检测方法 + +```python +混合检测方法结合了规则和模型两种方式,先用规则快速筛选,再用模型深度检测,最后综合判断风险等级。 + +### Vectara 幻觉排行榜 + +Vectara 是一个专门评估 LLM 幻觉率的排行榜。它使用以下方法: + +```text +1. 测试流程 + - 给模型提供一段事实性文本 + - 要求模型总结这段文本 + - 检查总结是否与原文一致 + +2. 评估指标 + - 幻觉率:总结中与原文矛盾的比例 + - 事实一致性:总结中事实正确的比例 + - 信息完整性:总结是否遗漏重要信息 + +3. 排行榜价值 + - 提供标准化的幻觉评估 + - 横向比较不同模型 + - 追踪幻觉率随时间的变化 +``` + +### RAGAS 框架:RAG 系统的幻觉评估 + +RAGAS(Retrieval Augmented Generation Assessment)专门为 RAG 系统设计的评估框架。 + +#### RAGAS 的核心指标 + +```text +1. 忠实度(Faithfulness) + - 回答是否忠实于检索到的上下文 + - 检测回答中的幻觉 + +2. 答案相关性(Answer Relevance) + - 回答是否与问题相关 + - 检测答非所问的情况 + +3. 上下文精度(Context Precision) + - 检索到的上下文是否精确 + - 检测检索噪声 + +4. 上下文召回(Context Recall) + - 是否检索到所有相关信息 + - 检测信息遗漏 +``` + +#### RAGAS 使用示例 + +```python +from ragas import evaluate +from ragas.metrics import faithfulness, answer_relevancy + +# 准备评估数据 +eval_data = { + "question": ["什么是 RAG?"], + "answer": ["RAG 是检索增强生成,结合了检索和生成技术。"], + "contexts": [["RAG 是 Retrieval-Augmented Generation 的缩写,它通过检索外部知识来增强 LLM 的生成能力。"]], + "ground_truth": ["RAG 是一种结合检索和生成的 AI 技术架构。"] +} + +# 运行评估 +result = evaluate( + dataset=eval_data, + metrics=[faithfulness, answer_relevancy] +) + +print(f"忠实度: {result['faithfulness']:.3f}") +print(f"答案相关性: {result['answer_relevancy']:.3f}") +``` + +### FaithBench 和其他基准 + +#### FaithBench + +FaithBench 是一个专门评估事实忠实度的基准数据集: + +```text +特点: +- 包含 16 个不同领域的文本 +- 每个文本都有人工标注的幻觉 +- 支持细粒度的幻觉分类 +- 提供标准化的评估脚本 + +评估维度: +- 事实错误:与可验证事实矛盾 +- 推理错误:逻辑推理有误 +- 无中生有:编造不存在的信息 +- 过度概括:从具体案例过度推广 +``` + +#### HaluEval + +HaluEval 是另一个常用的幻觉评估基准: + +```text +特点: +- 包含 35,000 个样本 +- 覆盖问答、对话、摘要等任务 +- 每个样本都有正确和错误两个版本 +- 模型需要判断哪个版本是正确的 + +评估方法: +- 给模型展示两个回答(一个正确,一个有幻觉) +- 让模型选择哪个更准确 +- 计算模型的判断准确率 +``` + +### 降低幻觉的策略 + +#### 检索增强生成(RAG) + +```python +def rag_with_hallucination_check(question, knowledge_base): + """带幻觉检查的 RAG""" + # 1. 检索相关文档 + relevant_docs = knowledge_base.search(question, k=3) + + # 2. 生成回答 + context = "\n".join(relevant_docs) + answer = llm.generate(f"基于以下上下文回答问题:\n{context}\n\n问题:{question}") + + # 3. 检查幻觉 + hallucination_score = check_hallucination(question, answer, context) + + # 4. 如果幻觉风险高,重新生成 + if hallucination_score > 0.7: + answer = llm.generate(f"请严格基于以下上下文回答,不要添加额外信息:\n{context}\n\n问题:{question}") + + return answer +``` + +#### 事实核查链(Fact-Checking Chain) + +```python +def fact_checking_chain(answer): + """事实核查链""" + # 1. 提取事实声明 + facts = extract_facts(answer) + + # 2. 逐个核查 + verified_facts = [] + for fact in facts: + # 搜索可靠来源 + sources = search_reliable_sources(fact) + + # 验证事实 + if verify_fact(fact, sources): + verified_facts.append(fact) + else: + # 标记为可疑 + verified_facts.append(f"[待验证] {fact}") + + # 3. 重构回答 + return reconstruct_answer(verified_facts) +``` + +#### 自我校验(Self-Verification) + +```python +def self_verification(question, answer): + """模型自我校验""" + # 1. 让模型检查自己的回答 + verification_prompt = f""" + 请检查以下回答是否存在幻觉或错误。 + + 问题:{question} + 回答:{answer} + + 请指出任何可能的问题,并给出修正建议。 + """ + + verification = llm.generate(verification_prompt) + + # 2. 如果发现问题,重新生成 + if "错误" in verification or "幻觉" in verification: + corrected_answer = llm.generate(f"请修正以下回答中的错误:\n{answer}\n\n问题:{question}") + return corrected_answer + + return answer +``` + +### 真实世界的幻觉案例 + +#### 案例 1:法律领域 + +```text +用户问题:「根据中国劳动法,员工加班费如何计算?」 + +幻觉回答:「根据《中华人民共和国劳动法》第 44 条,用人单位安排劳动者延长工作时间的,支付不低于工资的 150% 的工资报酬。休息日安排劳动者工作又不能安排补休的,支付不低于工资的 200% 的工资报酬。法定休假日安排劳动者工作的,支付不低于工资的 300% 的工资报酬。」 + +问题:这个回答看起来很专业,但用户需要核实: +1. 条款编号是否正确 +2. 具体比例是否准确 +3. 是否有最新的司法解释 +``` + +#### 案例 2:医疗领域 + +```text +用户问题:「感冒了应该吃什么药?」 + +幻觉回答:「感冒时可以服用阿莫西林胶囊,每次 2 粒,每日 3 次。同时配合板蓝根冲剂,效果更好。」 + +问题:这个回答有严重问题: +1. 阿莫西林是抗生素,对病毒性感冒无效 +2. 滥用抗生素会导致耐药性 +3. 没有区分病毒性感冒和细菌性感冒 +``` + +#### 案例 3:金融领域 + +```text +用户问题:「某股票的历史最高价是多少?」 + +幻觉回答:「该股票在 2021 年 2 月 18 日达到历史最高价 345.67 元。」 + +问题:这个回答可能完全错误: +1. 日期可能是编造的 +2. 价格可能是虚构的 +3. 模型可能混淆了不同股票的数据 +``` + +## 常见误区 + +!!! failure "误区 1:幻觉只出现在小模型中" + 大模型也会产生幻觉,而且可能更难发现,因为它们的表达更流畅自信。模型大小和幻觉率之间没有简单的线性关系。 + +!!! failure "误区 2:幻觉可以通过训练完全消除" + 幻觉是当前 LLM 架构的固有特性,无法通过训练完全消除。只能通过检测、缓解和用户教育来降低风险。 + +!!! failure "误区 3:幻觉检测工具可以完全依赖" + 幻觉检测工具有自己的局限性,可能会漏检或误判。它们应该作为辅助工具,而不是唯一依赖。 + +!!! failure "误区 4:用户应该自己判断幻觉" + 虽然用户需要有一定的判断力,但系统设计者有责任尽量减少幻觉,并提供足够的提示和警告。 + +## 延伸阅读 + +- [Vectara 幻觉排行榜](https://huggingface.co/spaces/vectara/hallucination-leaderboard) —— 实时更新的幻觉率排行 +- [RAGAS 框架](https://github.com/explodinggradients/ragas) —— RAG 系统评估框架 +- [FaithBench 论文](https://arxiv.org/abs/2402.13758) —— 事实忠实度评估基准 +- [HaluEval 论文](https://arxiv.org/abs/2305.11747) —— 幻觉评估基准数据集 +- [LLM 幻觉综述](https://arxiv.org/abs/2311.05232) —— 幻觉的成因、检测和缓解 + +## 练习题 + +??? question "练习 1:实现基于规则的幻觉检测" + + 实现一个简单的基于规则的幻觉检测函数。要求: + + 1. 检测数字是否在上下文中出现 + 2. 检测日期是否合理 + 3. 检测是否包含「可能」「也许」等不确定性词汇 + + ```python + def rule_based_detection(answer, context): + # 你的实现 + pass + + # 测试用例 + answer = "公司成立于 2010 年,年收入 100 亿元" + context = "该公司成立于 2010 年,是一家科技公司" + issues = rule_based_detection(answer, context) + # 应该检测出「年收入 100 亿元」在上下文中未提及 + ``` + +??? question "练习 2:设计幻觉评估数据集" + + 为一个「智能客服」系统设计幻觉评估数据集。要求: + + 1. 包含至少 3 种类型的幻觉 + 2. 每种类型至少 5 个样本 + 3. 包含边界情况(如部分正确、模糊信息) + 4. 设计评估标准 + + 你需要: + - 列出幻觉类型和示例 + - 设计标注指南 + - 说明如何计算幻觉率 + +??? question "练习 3:实现 RAGAS 忠实度评估" + + 使用 RAGAS 框架评估一个 RAG 系统的忠实度。要求: -## 建议内容 + 1. 准备 10 个问题及其标准答案 + 2. 使用 RAG 系统生成回答 + 3. 计算忠实度分数 + 4. 分析低分样本的原因 -- 幻觉定义 -- 检测方法 -- 评分标准 -- 降低风险 + 你需要: + - 安装 RAGAS 库 + - 准备评估数据 + - 运行评估并分析结果 \ No newline at end of file diff --git a/docs/eval/metrics.md b/docs/eval/metrics.md index 2bdbe50..1b747eb 100644 --- a/docs/eval/metrics.md +++ b/docs/eval/metrics.md @@ -1,10 +1,438 @@ +--- +tags: + - Eval +--- + # 主观与客观指标 -> 占位页:本页内容待团队补充。 +> 评测指标是衡量模型输出质量的尺子——尺子选错了,量出来的结果再精确也没用。 + +## 这章解决什么问题 + +你训练了一个模型,它能生成看起来很不错的回答。但「看起来不错」和「真的不错」之间可能存在巨大差距。评测指标就是帮你量化这个差距的工具。 + +问题是:有些指标可以用数字精确衡量(比如回答是否包含正确答案),有些指标只能靠人判断(比如回答是否流畅自然)。选错指标类型,你可能优化了一个不需要优化的东西。 + +## 核心概念 + +### 客观指标:机器可以自动计算的尺子 + +客观指标有明确的数学定义,可以用代码自动计算。它们适合衡量那些有标准答案的任务。 + +#### 精确匹配(Exact Match,EM) + +最简单的指标:模型输出和标准答案完全一致才算对。 + +```python +def exact_match(prediction, reference): + """精确匹配:完全一致才得分""" + return prediction.strip().lower() == reference.strip().lower() + +# 示例 +exact_match("巴黎", "巴黎") # True +exact_match("巴黎", "法国巴黎") # False +``` + +精确匹配的问题是太严格了。「法国首都巴黎」和「巴黎」意思完全一样,但精确匹配会判错。所以它只适合答案非常确定的场景(比如选择题、填空题)。 + +#### F1 分数 + +F1 分数把问题拆成两个子问题: +- **精确率(Precision)**:模型说的里面,有多少是对的 +- **召回率(Recall)**:所有正确答案中,模型说出了多少 + +F1 是两者的调和平均: + +```python +def f1_score(prediction, reference): + """计算 token 级别的 F1 分数""" + pred_tokens = set(prediction.lower().split()) + ref_tokens = set(reference.lower().split()) + + if not pred_tokens or not ref_tokens: + return 0.0 + + common = pred_tokens & ref_tokens + precision = len(common) / len(pred_tokens) + recall = len(common) / len(ref_tokens) + + if precision + recall == 0: + return 0.0 + + return 2 * precision * recall / (precision + recall) + +# 示例 +f1_score("法国首都巴黎", "巴黎") # 0.5 (召回率 1.0,精确率 0.33) +``` + +F1 的好处是允许部分匹配。「法国首都巴黎」虽然不完全等于「巴黎」,但包含了正确答案,F1 会给部分分数。 + +#### BLEU 分数 + +BLEU 专门用于机器翻译和文本生成任务,衡量生成文本和参考文本的相似度。 + +```python +from nltk.translate.bleu_score import sentence_bleu + +reference = [["法国", "的", "首都", "是", "巴黎"]] +candidate = ["法国", "首都", "巴黎"] + +score = sentence_bleu(reference, candidate) +print(f"BLEU: {score:.3f}") # 输出:BLEU: 0.523 +``` + +BLEU 的核心思想是数 n-gram(连续 n 个词)的匹配次数。它有四个子分数: +- BLEU-1:单个词的匹配 +- BLEU-2:两个连续词的匹配 +- BLEU-3:三个连续词的匹配 +- BLEU-4:四个连续词的匹配 + +最终分数通常是这四个子分数的几何平均。 + +| 子分数 | 衡量什么 | 适用场景 | +|--------|---------|---------| +| BLEU-1 | 词汇覆盖度 | 所有生成任务 | +| BLEU-2 | 短语准确性 | 翻译、摘要 | +| BLEU-3 | 句子结构相似度 | 长文本生成 | +| BLEU-4 | 整体流畅度 | 严格翻译评估 | + +BLEU 的问题是对同义词不友好。「苹果很好吃」和「苹果味道不错」意思一样,但 BLEU 分数可能很低。 + +#### ROUGE 分数 + +ROUGE 专门用于摘要任务,衡量生成摘要和参考摘要的重叠度。 + +```python +from rouge_score import rouge_scorer + +scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True) +scores = scorer.score("法国的首都是巴黎,这是一个美丽的城市。", "巴黎是法国首都。") + +print(f"ROUGE-1: {scores['rouge1'].fmeasure:.3f}") +print(f"ROUGE-2: {scores['rouge2'].fmeasure:.3f}") +print(f"ROUGE-L: {scores['rougeL'].fmeasure:.3f}") +``` + +ROUGE 有三个常用变体: +- **ROUGE-1**:单个词的重叠率 +- **ROUGE-2**:两个连续词的重叠率 +- **ROUGE-L**:最长公共子序列的长度 + +### 主观指标:需要人判断的尺子 + +有些质量维度无法用数学公式衡量。比如回答是否流畅、是否有帮助、是否安全。这些需要人来判断。 + +#### 流畅性(Fluency) + +文本是否读起来自然,没有语法错误或奇怪的表达。 + +```text +评分标准: +5分 - 完全自然,像母语者写的 +4分 - 基本自然,偶有小瑕疵 +3分 - 能理解,但有明显不自然的地方 +2分 - 理解困难,语法错误较多 +1分 - 完全无法理解 +``` + +#### 连贯性(Coherence) + +回答是否逻辑清晰,前后一致。 + +```text +示例: +问题:解释什么是机器学习 +回答 1(连贯):机器学习是人工智能的一个分支。它让计算机从数据中学习规律,而不是被明确编程。比如,你可以给系统看很多猫的图片,它就能学会识别猫。 +回答 2(不连贯):机器学习很厉害。我的电脑是苹果的。今天天气不错。猫很可爱。 +``` + +#### 有用性(Helpfulness) + +回答是否真正解决了用户的问题。 + +```text +评分维度: +1. 是否直接回答了问题 +2. 是否提供了足够的细节 +3. 是否给出了可操作的建议 +4. 是否考虑了用户的上下文 +``` + +#### 安全性(Safety) + +回答是否包含有害、偏见或不当内容。 + +```text +检查清单: +- 是否包含歧视性内容 +- 是否泄露隐私信息 +- 是否提供危险操作指导 +- 是否包含政治敏感内容 +``` + +### LLM-as-Judge:用大模型当评委 + +人工评估成本高、速度慢。一个新思路是用强大的 LLM(如 GPT-4)来当评委。 + +```python +import openai + +def llm_judge(question, answer, criteria): + """用 GPT-4 评判回答质量""" + prompt = f""" + 请评估以下回答的质量。 + + 问题:{question} + 回答:{answer} + + 评估标准:{criteria} + + 请给出 1-5 分的评分,并简要说明理由。 + """ + + response = openai.chat.completions.create( + model="gpt-4", + messages=[{"role": "user", "content": prompt}], + temperature=0 + ) + + return response.choices[0].message.content +``` + +LLM-as-Judge 的优势: +- 成本比人工评估低 10-100 倍 +- 速度比人工评估快 100-1000 倍 +- 可以 24/7 运行 +- 评估标准可以精确控制 + +LLM-as-Judge 的风险: +- 可能有偏见(比如偏好长回答) +- 可能无法识别细微错误 +- 可能被回答的「表面流畅」欺骗 +- 需要定期用人工评估校准 + +### 基准数据集:标准化的考试 + +基准数据集是预先准备好的「考试题」,用来横向比较不同模型的能力。 + +#### MMLU(Massive Multitask Language Understanding) + +MMLU 包含 57 个学科的选择题,从初中到研究生难度都有。 + +```text +示例问题: +学科:计算机科学 +问题:以下哪个算法的时间复杂度是 O(n log n)? +A. 冒泡排序 +B. 快速排序 +C. 插入排序 +D. 选择排序 + +答案:B +``` + +MMLU 的价值在于覆盖面广,能测试模型的「知识广度」。 + +#### HumanEval + +HumanEval 包含 164 个 Python 编程题,测试模型的代码生成能力。评估方式是运行生成的代码,看是否能通过所有测试用例。 + +#### GSM8K + +GSM8K 包含 8500 道小学数学应用题,测试模型的数学推理能力。特点是需要多步推理,不能直接从问题中找到答案。 + +#### TruthfulQA + +TruthfulQA 测试模型是否会生成「看似正确但实际错误」的回答。它的价值在于测试模型的「事实准确性」,而不是「生成流畅度」。 + +### 构建评估数据集 + +通用基准数据集不能解决所有问题。你需要根据自己的具体任务构建评估数据集。 + +#### 数据集设计原则 + +```text +1. 覆盖性:覆盖任务的各种场景和边界情况 +2. 平衡性:正例和负例数量相当 +3. 多样性:问题类型、难度、长度都要多样 +4. 时效性:定期更新,避免数据泄露 +5. 标注质量:多人标注,取一致结果 +``` + +#### 数据集构建流程 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TD + A[定义评估目标] --> B[收集种子样本] + B --> C[扩展样本多样性] + C --> D[多人标注] + D --> E[计算标注一致性] + E --> F{一致性足够高?} + F -->|否| G[修订标注指南] + G --> D + F -->|是| H[形成最终数据集] + H --> I[划分训练/验证/测试集] +``` + +#### 标注一致性检查 + +多人标注时,需要计算标注者之间的一致性: + +```python +from sklearn.metrics import cohen_kappa_score + +# 两个标注者的评分 +annotator1 = [4, 3, 5, 2, 4, 3, 5, 4, 2, 3] +annotator2 = [4, 3, 4, 2, 5, 3, 5, 4, 2, 3] + +kappa = cohen_kappa_score(annotator1, annotator2) +print(f"Kappa 系数: {kappa:.3f}") + +# Kappa 系数解释: +# 0.8-1.0: 几乎完全一致 +# 0.6-0.8: 高度一致 +# 0.4-0.6: 中等一致 +# 0.2-0.4: 弱一致 +# 0.0-0.2: 略好于随机 +``` + +### A/B 测试方法论 + +A/B 测试是比较两个模型版本的标准方法。 + +#### A/B 测试流程 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart LR + A[定义成功指标] --> B[随机分组用户] + B --> C[模型A组] + B --> D[模型B组] + C --> E[收集反馈数据] + D --> E + E --> F[统计显著性检验] + F --> G{差异显著?} + G -->|是| H[选择胜出模型] + G -->|否| I[继续收集数据或调整] +``` + +#### 统计显著性检验 + +使用 t 检验或卡方检验来判断两个模型的差异是否显著。通常以 p < 0.05 作为显著性阈值。 + +### 人工评估工作流 + +人工评估是主观指标的黄金标准,但需要精心设计。 + +#### 评估流程设计 + +```text +1. 评估员培训 + - 明确评估标准 + - 统一评分尺度 + - 练习评估样例 + +2. 评估任务分配 + - 随机分配样本 + - 每个样本至少 2 人评估 + - 避免评估员疲劳 + +3. 质量控制 + - 插入「金标准」样本 + - 监控评估员一致性 + - 定期校准评估标准 + +4. 数据收集 + - 记录评分和理由 + - 标记异常情况 + - 保留原始评估记录 +``` + +### 自动化评估管道 + +将评估流程自动化,可以持续监控模型质量。 + +#### 评估管道架构 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TB + A[输入数据] --> B[模型推理] + B --> C[自动评估] + C --> D[人工抽检] + D --> E[结果聚合] + E --> F[生成报告] + F --> G[触发告警] + G --> H[模型迭代] + H --> B +``` + +## 常见误区 + +!!! failure "误区 1:只看一个指标" + 单一指标容易被「作弊」。比如 BLEU 高可能只是因为模型复制了参考文本的一部分。应该综合多个指标,特别是客观和主观指标结合。 + +!!! failure "误区 2:忽略评估数据集的质量" + 「垃圾进,垃圾出」。如果评估数据集本身有偏见或错误,评估结果就不可信。投入足够时间构建高质量评估数据集。 + +!!! failure "误区 3:用训练集评估" + 在训练集上评估会高估模型性能。必须使用独立的测试集,最好是模型从未见过的数据。 + +## 延伸阅读 + +- [BLEU 分数详解](https://en.wikipedia.org/wiki/BLEU) —— BLEU 的数学原理和局限性 +- [ROUGE 分数详解](https://en.wikipedia.org/wiki/ROUGE_(metric)) —— ROUGE 的各种变体 +- [MMLU 论文](https://arxiv.org/abs/2009.03300) —— MMLU 基准数据集的原始论文 +- [HumanEval 论文](https://arxiv.org/abs/2107.03374) —— HumanEval 代码生成基准 +- [LLM-as-Judge 研究](https://arxiv.org/abs/2306.05685) —— 用大模型做评估的系统研究 + +## 练习题 + +??? question "练习 1:实现 F1 分数计算" + + 给定两个字符串,计算它们的 token 级别 F1 分数。 + + ```python + def f1_score(prediction, reference): + # 你的实现 + pass + + # 测试用例 + assert f1_score("法国首都巴黎", "巴黎") == 0.5 + assert f1_score("机器学习", "机器学习") == 1.0 + assert f1_score("深度学习", "机器学习") == 0.0 + ``` + + 提示:先将字符串按空格分割成 token 集合,再计算精确率和召回率。 + +??? question "练习 2:设计评估数据集" + + 为一个「智能客服」系统设计评估数据集。要求: + + 1. 包含至少 5 种不同的问题类型 + 2. 每种类型至少 10 个样本 + 3. 包含边界情况(如模糊问题、多轮对话) + 4. 设计评分标准(客观和主观指标) + + 你需要: + - 列出问题类型和示例 + - 设计标注指南 + - 说明如何计算标注一致性 + +??? question "练习 3:实现 LLM-as-Judge" + + 用 GPT-4 实现一个简单的 LLM-as-Judge 评估函数。要求: + + 1. 评估回答的准确性(1-5 分) + 2. 评估回答的完整性(1-5 分) + 3. 评估回答的清晰度(1-5 分) + 4. 给出总体评分和理由 -## 建议内容 + 测试问题:「什么是 RAG?」 + 测试回答:「RAG 是检索增强生成,结合了检索和生成两种技术。」 -- 指标分类 -- 评分表 -- 样本集 -- 复测方法 + 你需要: + - 设计评估 prompt + - 解析 GPT-4 的输出 + - 处理可能的错误情况 \ No newline at end of file diff --git a/docs/eval/quality.md b/docs/eval/quality.md index b9f9b6c..a883b34 100644 --- a/docs/eval/quality.md +++ b/docs/eval/quality.md @@ -1,10 +1,435 @@ +--- +tags: + - Eval +--- + # 输出质量判断 -> 占位页:本页内容待团队补充。 +> 质量判断是评估的最终环节——不管用了多少指标,最终都要回答一个问题:这个回答到底好不好? + +## 这章解决什么问题 + +你可能已经用了很多评估指标(BLEU、ROUGE、F1),但这些指标往往只能衡量质量的某个维度。一个 BLEU 分数很高的回答,可能读起来很不自然;一个 F1 分数很高的回答,可能遗漏了关键信息。 + +输出质量判断是一个综合性的评估,需要从多个维度来考量:准确性、完整性、可读性、可执行性、安全性等。这些维度之间可能存在矛盾,需要根据具体场景做权衡。 + +## 核心概念 + +### 准确性 vs 相关性 + +这两个概念经常被混淆,但它们衡量的是不同的东西。 + +#### 准确性(Accuracy) + +回答中的信息是否正确。 + +```text +示例: +问题:「中国的首都是哪里?」 +回答 1:「中国的首都是北京。」→ 准确 +回答 2:「中国的首都是上海。」→ 不准确 +回答 3:「中国的首都是北京,人口约 2100 万。」→ 准确(但增加了额外信息) +``` + +#### 相关性(Relevance) + +回答是否与问题相关,是否解决了用户的需求。 + +```text +示例: +问题:「如何提高代码质量?」 +回答 1:「使用代码审查、单元测试和静态分析工具。」→ 相关 +回答 2:「Python 是一种流行的编程语言。」→ 不相关 +回答 3:「代码质量很重要,但今天天气不错。」→ 部分相关 +``` + +#### 准确但不相关 + +```text +问题:「如何学习 Python?」 +回答:「Python 的创始人是 Guido van Rossum。」 + +分析:这个回答是准确的,但与问题不相关。用户想知道学习方法,而不是历史背景。 +``` + +#### 相关但不准确 + +```text +问题:「Python 的最新版本是什么?」 +回答:「Python 的最新版本是 3.12。」 + +分析:这个回答是相关的,但如果实际最新版本是 3.11,那就不准确了。 +``` + +### 完整性检查 + +回答是否包含了所有必要信息。 + +#### 完整性评估维度 + +```text +1. 信息完整性 + - 是否回答了问题的所有部分 + - 是否遗漏了关键信息 + - 是否提供了足够的细节 + +2. 逻辑完整性 + - 推理过程是否完整 + - 是否有跳跃或缺失的步骤 + - 结论是否由前提得出 + +3. 上下文完整性 + - 是否考虑了用户的背景 + - 是否提供了必要的前提条件 + - 是否解释了专业术语 +``` + +#### 完整性评估示例 + +```python +def completeness_check(question, answer, reference): + """完整性检查""" + # 提取关键信息点 + key_points = extract_key_points(reference) + + # 检查回答是否包含这些关键点 + covered_points = [] + missing_points = [] + + for point in key_points: + if point.lower() in answer.lower(): + covered_points.append(point) + else: + missing_points.append(point) + + completeness_score = len(covered_points) / len(key_points) + + return { + "score": completeness_score, + "covered": covered_points, + "missing": missing_points + } +``` + +### 可读性评估 + +回答是否容易理解,是否符合目标受众的水平。 + +#### 可读性指标 + +```text +1. 句子长度 + - 短句通常更容易理解 + - 长句可能包含复杂结构 + +2. 词汇难度 + - 常见词汇更容易理解 + - 专业术语需要解释 + +3. 结构清晰度 + - 是否有清晰的段落划分 + - 是否使用了列表、标题等格式 + +4. 逻辑连贯性 + - 句子之间是否有逻辑连接 + - 是否有跳跃或矛盾 +``` + +#### 可读性评估代码 + +```python +import textstat + +可读性评估使用 Flesch Reading Ease 等指标,计算文本的阅读难度。分数越高表示越容易阅读。 +``` + +### 可执行性(Actionability) + +回答是否提供了可操作的建议或步骤。 + +#### 可执行性评估维度 + +```text +1. 具体性 + - 建议是否具体明确 + - 是否有模糊或笼统的表述 + +2. 可行性 + - 建议是否在用户能力范围内 + - 是否需要特殊资源或权限 + +3. 步骤清晰度 + - 步骤是否清晰有序 + - 是否有遗漏或跳跃 + +4. 预期结果 + - 是否说明了预期结果 + - 是否提供了验证方法 +``` + +#### 可执行性评估示例 + +```text +问题:「如何提高代码质量?」 + +回答 1(可执行性低): +「你应该写更好的代码。」 + +回答 2(可执行性中): +「使用代码审查、单元测试和静态分析工具来提高代码质量。」 + +回答 3(可执行性高): +「1. 使用 pylint 进行代码检查:pip install pylint +2. 编写单元测试:使用 pytest 框架 +3. 设置 CI/CD:在 GitHub Actions 中配置自动测试 +4. 进行代码审查:使用 Pull Request 流程」 +``` + +### 安全性与偏见检测 + +回答是否包含有害、偏见或不当内容。 + +#### 安全性检查清单 + +```text +1. 有害内容 + - 是否包含暴力、色情、仇恨言论 + - 是否鼓励危险行为 + - 是否泄露隐私信息 + +2. 偏见检测 + - 是否包含性别、种族、年龄等偏见 + - 是否刻板印象 + - 是否歧视性表述 + +3. 合规性 + - 是否符合法律法规 + - 是否符合平台政策 + - 是否符合行业规范 +``` + +#### 偏见检测代码 + +```python +偏见检测通过关键词匹配和语义分析,识别文本中可能存在的性别、种族、年龄等偏见。 +``` + +### 一致性评估 + +回答是否在不同场景下保持一致。 + +#### 一致性评估维度 + +```text +1. 内部一致性 + - 同一回答内是否前后矛盾 + - 逻辑是否自洽 + +2. 跨回答一致性 + - 对相同问题的不同回答是否一致 + - 对相似问题的回答是否一致 + +3. 与知识库一致性 + - 回答是否与训练数据一致 + - 是否与已知事实矛盾 +``` + +#### 一致性评估代码 + +```python +一致性评估通过比较多 +``` + +### 构建质量评估表 + +将多个维度整合成一个完整的评估表。 + +#### 质量评估表模板 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +pie title 质量评估维度权重 + "准确性" : 30 + "相关性" : 25 + "完整性" : 20 + "可读性" : 10 + "可执行性" : 10 + "安全性" : 5 +``` + +```text +| 维度 | 评分标准 | 权重 | 说明 | +|------|---------|------|------| +| 准确性 | 1-5 分 | 30% | 信息是否正确 | +| 相关性 | 1-5 分 | 25% | 是否回答了问题 | +| 完整性 | 1-5 分 | 20% | 是否包含所有关键信息 | +| 可读性 | 1-5 分 | 10% | 是否容易理解 | +| 可执行性 | 1-5 分 | 10% | 是否提供了可操作建议 | +| 安全性 | 1-5 分 | 5% | 是否包含有害内容 | + +总分 = 各维度分数 × 权重之和 +``` + +#### 质量评估代码 + +```python +质量评估通过加权平均多个维度的分数,得出总分。权重可以根据具体场景调整。 + + return { + "scores": scores, + "final_score": final_score, + "grade": score_to_grade(final_score) + } + +def score_to_grade(score): + """将分数转换为等级""" + if score >= 4.5: + return "A" + elif score >= 3.5: + return "B" + elif score >= 2.5: + return "C" + elif score >= 1.5: + return "D" + else: + return "F" +``` + +### 真实质量检查案例 + +#### 案例 1:客服回答质量 + +```text +用户问题:「我的订单什么时候发货?」 + +回答 1: +「您的订单将在 3-5 个工作日内发货。」 + +质量评估: +- 准确性:4/5(假设信息正确) +- 相关性:5/5(直接回答了问题) +- 完整性:3/5(缺少物流查询方式) +- 可读性:5/5(简单明了) +- 可执行性:2/5(没有提供进一步操作) +- 安全性:5/5(无有害内容) + +总分:3.8/5 +``` + +#### 案例 2:技术文档质量 + +```text +用户问题:「如何在 Python 中读取 CSV 文件?」 + +回答: +「使用 pandas 库的 read_csv 函数。示例代码: +import pandas as pd +df = pd.read_csv('data.csv') +print(df.head())」 + +质量评估: +- 准确性:5/5(代码正确) +- 相关性:5/5(直接回答了问题) +- 完整性:4/5(缺少错误处理和参数说明) +- 可读性:4/5(代码清晰,但缺少解释) +- 可执行性:5/5(可以直接运行) +- 安全性:5/5(无有害内容) + +总分:4.7/5 +``` + +#### 案例 3:医疗建议质量 + +```text +用户问题:「感冒了应该吃什么药?」 + +回答: +「感冒时可以服用对乙酰氨基酚或布洛芬来缓解症状。同时多喝水,注意休息。如果症状持续或加重,建议及时就医。」 + +质量评估: +- 准确性:4/5(药物建议基本正确,但需要更多条件限定) +- 相关性:5/5(直接回答了问题) +- 完整性:4/5(缺少用药注意事项和禁忌) +- 可读性:5/5(通俗易懂) +- 可执行性:4/5(提供了具体药物名称) +- 安全性:4/5(建议就医,但缺少风险提示) + +总分:4.3/5 +``` + +## 常见误区 + +!!! failure "误区 1:只关注准确性,忽视其他维度" + 一个准确但难以理解的回答,对用户来说可能没有价值。需要平衡多个质量维度。 + +!!! failure "误区 2:质量评估可以完全自动化" + 自动化工具可以辅助评估,但很多质量维度(如可读性、安全性)仍需人工判断。 + +!!! failure "误区 3:质量标准是固定的" + 不同场景、不同用户对质量的要求不同。需要根据具体需求调整评估标准。 + +!!! failure "误区 4:高质量回答一定很长" + 长度和质量没有必然联系。简洁明了的回答可能比冗长的回答质量更高。 + +## 延伸阅读 + +- [Flesch Reading Ease](https://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_tests) —— 可读性评估指标 +- [文本质量评估综述](https://arxiv.org/abs/2104.08202) —— 文本质量评估方法总结 +- [AI 安全评估](https://arxiv.org/abs/2304.08202) —— AI 系统安全评估框架 +- [偏见检测方法](https://arxiv.org/abs/2104.08202) —— 文本偏见检测技术 + +## 练习题 + +??? question "练习 1:实现完整性检查" + + 实现一个完整性检查函数。要求: + + 1. 从参考答案中提取关键信息点 + 2. 检查回答是否包含这些关键点 + 3. 计算完整性分数 + + ```python + def completeness_check(answer, reference): + # 你的实现 + pass + + # 测试用例 + answer = "Python 是一种解释型、面向对象的编程语言。" + reference = "Python 是一种解释型、面向对象、动态类型的高级编程语言,由 Guido van Rossum 创建。" + result = completeness_check(answer, reference) + # 应该检测出缺少「动态类型」「高级编程语言」「Guido van Rossum 创建」 + ``` + +??? question "练习 2:设计质量评估表" + + 为一个「智能写作助手」系统设计质量评估表。要求: + + 1. 包含至少 5 个质量维度 + 2. 每个维度有明确的评分标准 + 3. 确定各维度的权重 + 4. 设计评估流程 + + 你需要: + - 列出质量维度和评分标准 + - 说明如何计算总分 + - 设计评估员培训材料 + +??? question "练习 3:实现可读性评估" + + 使用 textstat 库实现可读性评估。要求: + + 1. 计算 Flesch Reading Ease 分数 + 2. 计算 Flesch-Kincaid Grade Level + 3. 根据分数给出可读性等级 + 4. 分析影响可读性的因素 -## 建议内容 + 测试文本: + ```python + text1 = "Python 是一种简单易学的编程语言。" + text2 = "Python 是一种解释型、面向对象、动态类型的高级编程语言,由 Guido van Rossum 于 1991 年首次发布。" + ``` -- 准确性 -- 完整性 -- 可读性 -- 可执行性 + 你需要: + - 安装 textstat 库 + - 实现可读性评估函数 + - 分析两个文本的可读性差异 \ No newline at end of file diff --git a/docs/resources/agent-frameworks.md b/docs/resources/agent-frameworks.md index 7530119..3ffcf49 100644 --- a/docs/resources/agent-frameworks.md +++ b/docs/resources/agent-frameworks.md @@ -1,10 +1,323 @@ +--- +tags: + - Resources +--- + # Agent 框架 -> 占位页:本页内容待团队补充。 +> Agent 框架帮你把「模型会说话」升级成「模型会干活」。核心区别在于:Agent 能拆任务、调工具、看结果、再继续。 + +## 这页解决什么问题 + +普通聊天是一问一答。你问「帮我查一下明天的天气」,模型说「我没法查,因为我没有联网能力」。 + +Agent 能做到:理解任务 → 拆成步骤 → 调用天气 API → 拿到结果 → 用自然语言回复你。 + +Agent 框架就是帮你把这个「规划 → 执行 → 观察 → 再规划」的循环搭起来的工具。 + +> **更新时间**:2026 年 7 月。框架迭代快,版本号和功能以各项目官网为准。 + +--- + +## 主流框架一览 + +### LangGraph(LangChain 生态) + +**官网**: +**GitHub**: + +LangGraph 是 LangChain 团队推出的图编排框架。它把 Agent 的每一步看成图里的一个节点,用边连接起来,支持循环、分支、并行。 + +**核心特点**: + +- 图结构,支持复杂的多步流程 +- 内置状态管理,Agent 能「记住」之前做了什么 +- 支持人工介入(Human-in-the-loop) +- 和 LangChain 生态无缝集成 + +**适合谁**:需要复杂工作流的场景;需要多 Agent 协作;已经在用 LangChain 的团队。 + +**注意点**:概念多,学习曲线陡。简单场景用它有点杀鸡用牛刀。 + +```python +from langgraph.graph import StateGraph, MessagesState, START, END +from langchain_openai import ChatOpenAI + +model = ChatOpenAI(model="gpt-4o-mini") + +def agent_node(state: MessagesState): + response = model.invoke(state["messages"]) + return {"messages": [response]} + +graph = StateGraph(MessagesState) +graph.add_node("agent", agent_node) +graph.add_edge(START, "agent") +graph.add_edge("agent", END) + +app = graph.compile() +result = app.invoke({"messages": [{"role": "user", "content": "你好"}]}) +``` + +--- + +### CrewAI + +**官网**: +**GitHub**: + +CrewAI 的设计思路是「团队协作」——你定义几个 Agent,每个 Agent 有自己的角色、目标和工具,然后让它们一起完成任务。 + +**核心特点**: + +- 角色定义直观(研究员、写手、审核员……) +- 任务分配自动化 +- 支持顺序执行和并行执行 +- 上手快,API 设计简洁 + +**适合谁**:需要多个角色协作的场景(比如「研究 → 写作 → 审核」);想快速搭建 Agent 原型的团队。 + +**注意点**:对复杂流程的控制力不如 LangGraph;调试能力相对弱。 + +```python +from crewai import Agent, Task, Crew + +researcher = Agent( + role="研究员", + goal="收集关于指定主题的最新信息", + backstory="你是一个专业的研究员,擅长快速收集和整理信息。", + llm="gpt-4o-mini" +) + +writer = Agent( + role="写手", + goal="基于研究结果撰写文章", + backstory="你是一个经验丰富的技术写手,能把复杂概念讲清楚。", + llm="gpt-4o-mini" +) + +research_task = Task( + description="调研 2026 年最流行的 3 个 RAG 框架", + expected_information="框架名称、核心特点、适用场景", + agent=researcher +) + +write_task = Task( + description="基于调研结果写一篇对比文章", + expected_output="一篇 1000 字的对比文章", + agent=writer +) + +crew = Crew(agents=[researcher, writer], tasks=[research_task, write_task]) +result = crew.kickoff() +``` + +--- + +### AutoGen / AG2 + +**官网**: +**GitHub**: + +AutoGen 是微软推出的多 Agent 对话框架。它的核心思路是让多个 Agent 互相聊天来解决问题。AG2 是社区维护的分支版本。 + +**核心特点**: + +- 多 Agent 对话模式,Agent 之间可以互相对话 +- 支持代码执行(Agent 写代码、运行代码、看结果) +- 支持人工介入 +- 微软背书,企业级支持 + +**适合谁**:需要代码生成和执行的场景;需要多 Agent 讨论和辩论的场景;企业级应用。 + +**注意点**:对话模式有时会导致 Agent 跑偏;需要仔细设计对话流程。 + +--- + +### Claude Agent SDK(Anthropic) + +**地址**: + +Anthropic 官方提供的 Agent 开发工具包。它跟 Claude 模型深度集成,用 Claude 的工具调用能力来驱动 Agent 循环。 + +**核心特点**: + +- 和 Claude 模型深度集成,工具调用体验流畅 +- 支持计算机操作(Computer Use)——Agent 能操作桌面应用 +- 代码简洁,API 设计清晰 +- 官方维护,稳定性好 + +**适合谁**:已经在用 Claude 的团队;需要 Agent 操作桌面应用的场景;追求简洁 API 的开发者。 + +**注意点**:绑定 Claude 模型,换其他模型需要额外适配。 + +--- + +### Semantic Kernel(微软) + +**官网**: +**GitHub**: + +Semantic Kernel 是微软推出的 AI 编排 SDK,设计目标是把 AI 能力嵌入现有企业应用。它支持 C#、Python 和 Java。 + +**核心特点**: + +- 支持多语言(C#、Python、Java) +- 插件系统设计好,方便扩展 +- 和微软生态(Azure、Microsoft 365)深度集成 +- 企业级支持,文档完善 + +**适合谁**:.NET / Java 技术栈的企业;已经在用 Azure 的团队;需要把 AI 嵌入现有应用的场景。 + +**注意点**:Python 版本的功能有时落后于 C# 版本。 + +--- + +### LlamaIndex Agents + +**官网**: +**GitHub**: + +LlamaIndex 不只做 RAG,它也有 Agent 能力。LlamaIndex 的 Agent 更侧重于「数据交互」——让 Agent 能查询数据库、读文件、调 API。 + +**核心特点**: + +- 和 LlamaIndex 的数据连接器无缝集成 +- 工具定义简单 +- 适合「数据问答 + 工具调用」的混合场景 + +**适合谁**:已经在用 LlamaIndex 做 RAG 的团队;需要 Agent 访问多种数据源的场景。 + +--- + +### Pydantic AI + +**官网**: +**GitHub**: + +Pydantic AI 由 Pydantic(Python 最流行的数据验证库)团队开发。它的设计哲学是「类型安全」——用 Python 的类型系统来约束 Agent 的输入输出。 + +**核心特点**: + +- 类型安全,输入输出都有类型约束 +- 和 Pydantic 生态无缝集成 +- 代码简洁,Pythonic 风格 +- 支持多种 LLM 后端 + +**适合谁**:注重代码质量的 Python 开发者;需要严格类型约束的场景;已经在用 Pydantic 的项目。 + +**注意点**:相对较新,社区和教程还在成长中。 + +```python +from pydantic_ai import Agent + +agent = Agent( + 'openai:gpt-4o-mini', + system_prompt='你是一个有帮助的助手。' +) + +result = agent.run_sync('用一句话解释什么是 Agent') +print(result.data) +``` + +--- + +## 框架对比表 + +| 框架 | 核心思路 | 学习曲线 | 多 Agent | 代码执行 | 适合场景 | +|------|---------|---------|:--------:|:-------:|---------| +| LangGraph | 图编排 | 陡 | 支持 | 可选 | 复杂工作流 | +| CrewAI | 角色协作 | 低 | 原生 | 可选 | 多角色任务 | +| AutoGen | 对话驱动 | 中 | 原生 | 内置 | 代码生成执行 | +| Claude Agent SDK | 工具调用 | 低 | 支持 | 可选 | Claude 生态 | +| Semantic Kernel | 插件编排 | 中 | 支持 | 可选 | 企业级 | +| LlamaIndex Agents | 数据交互 | 低 | 支持 | 可选 | 数据问答 | +| Pydantic AI | 类型安全 | 低 | 支持 | 可选 | Python 项目 | + +--- + +## 怎么选?看你的需求 + +``` +你的 Agent 要做什么? +│ +├── 复杂多步工作流 +│ ├── 需要精细控制每一步 → LangGraph +│ └── 需要多个角色协作 → CrewAI +│ +├── 代码生成和执行 +│ └── AutoGen / AG2 +│ +├── 数据问答 + 工具调用 +│ ├── 已经在用 LlamaIndex → LlamaIndex Agents +│ └── 新项目 → Pydantic AI +│ +├── 企业级应用 +│ ├── .NET / Java 技术栈 → Semantic Kernel +│ └── Python 技术栈 → LangGraph +│ +├── 操作桌面应用 +│ └── Claude Agent SDK(Computer Use) +│ +└── 快速原型验证 + ├── 最简单 → Pydantic AI + └── 最直观 → CrewAI +``` + +--- + +## Agent 框架之外的事 + +框架帮你搭骨架,但 Agent 的效果取决于几个关键点: + +1. **工具定义是否清晰**:Agent 调用工具时,工具的描述越准确,调用越靠谱。详见 [工具调用](../agent/tool-use.md)。 +2. **任务拆解是否合理**:太大的任务 Agent 会跑偏,太小的任务又浪费循环。详见 [任务拆解](../agent/task-planning.md)。 +3. **停止条件是否明确**:没有停止条件,Agent 可能无限循环。详见 [反思与循环](../agent/reflection-loop.md)。 +4. **错误处理是否到位**:工具调用失败、模型返回异常,都需要兜底。详见 [Agent 常见失败模式](../agent/failure-patterns.md)。 + +--- + +## 学��路径建议 + +### 零基础入门 + +1. 先读 [Agent 总览](../agent/index.md),搞清楚 Agent 和普通聊天的区别 +2. 用 Pydantic AI 或 CrewAI 跑一个最小示例 +3. 理解工具调用和任务拆解 + +### 有编程基础 + +1. 用 LangGraph 搭一个带循环的 Agent +2. 加入工具调用,让 Agent 能查资料、调 API +3. 加入错误处理和停止条件 + +### 企业级落地 + +1. 评估技术栈,选 LangGraph 或 Semantic Kernel +2. 先做 MVP,验证核心流程 +3. 逐步加监控、日志、人工介入 + +--- + +## 常见误区 + +??? warning "误区 1:Agent 能代替人做一切" + Agent 擅长执行明确的任务,但对模糊需求的理解力有限。你需要给它清晰的目标、合适的工具、明确的边界。 + +??? warning "误区 2:框架越火越好" + LangGraph 功能最强,但学习成本也最高。CrewAI 上手最快,但复杂场景控制力不足。选适合你当前需求的,别过度工程化。 + +??? warning "误区 3:多 Agent 一定比单 Agent 好" + 多 Agent 增加了通信成本和出错概率。如果任务本身不复杂,单 Agent + 好用的工具就够了。 + +??? warning "误区 4:Agent 不会犯错" + Agent 会犯很多错:调错工具、理解错任务、无限循环、遗漏步骤。你需要设计好监控和兜底机制,别让 Agent 裸奔。 + +--- -## 建议内容 +## 延伸阅读 -- 框架名称 -- 核心能力 -- 适用场景 -- 示例项目 +- [Agent 总览](../agent/index.md) —— Agent 的核心概念 +- [Agent 和工作流的区别](../agent/workflow-vs-agent.md) —— 什么时候用 Agent,什么时候用工作流 +- [工具调用](../agent/tool-use.md) —— Agent 怎么调用外部工具 +- [任务拆解](../agent/task-planning.md) —— 怎么让 Agent 把大任务拆成小步骤 +- [RAG 框架](rag-frameworks.md) —— Agent 常和 RAG 配合使用 diff --git a/docs/resources/apis.md b/docs/resources/apis.md index e9b2e54..8298c79 100644 --- a/docs/resources/apis.md +++ b/docs/resources/apis.md @@ -1,10 +1,351 @@ +--- +tags: + - Resources +--- + # API 平台 -> 占位页:本页内容待团队补充。 +> API 是让模型「干活」的入口。聊天框是给人用的,API 是给程序用的。 + +## 这页解决什么问题 + +你在本地写了一个程序,想让它调用大模型的能力——翻译一段文字、分析一份文件、生成一段代码。这时候你需要一个 API。 + +API 平台就是各家模型厂商提供的「程序接入点」。你注册账号、拿到密钥、发一个 HTTP 请求,模型就会返回结果。 + +这页帮你搞清楚:有哪些平台可以选,它们之间有什么区别,怎么快速接入。 + +> **更新时间**:2026 年 7 月。API 定价和接口细节变化很快,以各平台官网为准。 + +--- + +## 什么是 OpenAI 兼容格式 + +在看具体平台之前,先理解一个关键概念:**OpenAI 兼容格式**。 + +OpenAI 的 API 格式已经成为事实上的行业标准。几乎所有平台都支持(或部分兼容)这个格式。你只需要改一下 `base_url` 和 `api_key`,同一个程序就能调用不同平台的模型。 + +一个典型的调用长这样: + +```python +from openai import OpenAI + +client = OpenAI( + api_key="你的密钥", + base_url="https://api.deepseek.com/v1" # 换成目标平台的地址 +) + +response = client.chat.completions.create( + model="deepseek-chat", + messages=[{"role": "user", "content": "你好"}] +) +print(response.choices[0].message.content) +``` + +看到没?代码结构完全一样,只改了三行:`api_key`、`base_url`、`model`。这就是 OpenAI 兼容格式的好处——学一次,到处用。 + +--- + +## 主流 API 平台 + +### OpenAI API + +**地址**: + +最原始、最标准的 API。如果你的代码能在 OpenAI 上跑通,换到其他兼容平台几乎不用改。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://api.openai.com/v1` | +| 认证方式 | Bearer Token | +| 支持模型 | GPT-5.5、GPT-4o、o3、o4-mini 等 | +| 免费额度 | 新用户有少量试用额度 | +| 特色 | 标准格式,生态最完整 | + +??? info "定价速览" + GPT-4o:输入 $2.5 / 百万 token,输出 $10 / 百万 token + GPT-4o mini:输入 $0.15 / 百万 token,输出 $0.6 / 百万 token + + +--- + +### Anthropic API + +**地址**: + +Claude 的 API。格式跟 OpenAI 略有不同,但官方提供了 Python SDK,用起来也不复杂。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://api.anthropic.com` | +| 认证方式 | `x-api-key` Header | +| 支持模型 | Claude Opus 4.8、Sonnet 4.6、Haiku 4 | +| 免费额度 | 无免费额度,需绑定信用卡 | +| 特色 | 长文本处理强,代码质量高 | + +??? info "定价速览" + Sonnet 4.6:输入 $3 / 百万 token,输出 $15 / 百万 token + Haiku 4:输入 $0.25 / 百万 token,输出 $1.25 / 百万 token + + +--- + +### Google AI Studio / Vertex AI + +**地址**:(个人)/ (企业) + +Google 提供了两个入口。AI Studio 适合个人开发者,免费额度慷慨;Vertex AI 适合企业,集成在 Google Cloud 里。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://generativelanguage.googleapis.com/v1beta` | +| 认证方式 | API Key 或 OAuth | +| 支持模型 | Gemini 3.1 Pro、Gemini 3.5 Flash | +| 免费额度 | AI Studio 有免费额度,比较慷慨 | +| 特色 | 超长上下文(最高 2M token),多模态 | + +??? info "定价速览" + Gemini 3.5 Flash:输入 $0.075 / 百万 token,输出 $0.3 / 百万 token + 免费额度较慷慨,适合试用 + + +--- + +### DeepSeek API + +**地址**: + +国产推理模型的 API。价格便宜,格式兼容 OpenAI,接入门槛低。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://api.deepseek.com/v1` | +| 认证方式 | Bearer Token(兼容 OpenAI SDK) | +| 支持模型 | DeepSeek V4、V3.2、R1 | +| 免费额度 | 注册送额度 | +| 特色 | 推理能力强,价格极低 | + +??? info "定价速览" + DeepSeek V4:输入 ¥1 / 百万 token,输出 ¥2 / 百万 token + DeepSeek R1:输入 ¥4 / 百万 token,输出 ¥16 / 百万 token + + +--- + +### Moonshot API(Kimi) + +**地址**: + +Moonshot 的 API,支持长文本输入,中文能力好。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://api.moonshot.cn/v1` | +| 认证方式 | Bearer Token(兼容 OpenAI SDK) | +| 支持模型 | Kimi K3、K2 | +| 免费额度 | 注册送额度 | +| 特色 | 长文本处理,中文理解好 | + +--- + +### 阿里 DashScope(通义千问 API) + +**地址**: + +阿里云的模型服务平台,不只托管通义千问,也托管其他开源模型。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://dashscope.aliyuncs.com/compatible-mode/v1` | +| 认证方式 | API Key | +| 支持模型 | Qwen3.7 Max、Plus、Turbo 等 | +| 免费额度 | 有免费额度,新用户优惠多 | +| 特色 | 国内访问快,支持 OpenAI 兼容模式 | + +??? info "定价速览" + Qwen3.7 Max:输入 ¥2 / 百万 token,输出 ¥6 / 百万 token + Qwen3.7 Turbo:输入 ¥0.3 / 百万 token,输出 ¥0.6 / 百万 token + + +--- + +### Groq + +**地址**: + +Groq 不自己训练模型,它的卖点是**推理速度极快**。它用自研的 LPU 芯片跑开源模型,延迟低到离谱。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://api.groq.com/openai/v1` | +| 认证方式 | Bearer Token(兼容 OpenAI SDK) | +| 支持模型 | Llama 4、Mixtral、Gemma 等开源模型 | +| 免费额度 | 有免费额度,限速 | +| 特色 | 推理速度行业最快 | + +**适合谁**:对延迟敏感的场景,比如实时聊天、在线工具。 + +--- + +### Together AI + +**地址**: + +Together AI 提供大量开源模型的 API,价格便宜,选择多。 + +| 项目 | 说明 | +|------|------| +| Base URL | `https://api.together.xyz/v1` | +| 认证方式 | Bearer Token(兼容 OpenAI SDK) | +| 支持模型 | Llama 4、Mistral、Qwen、DeepSeek 等 | +| 免费额度 | 注册送额度 | +| 特色 | 开源模型种类最多,价格低 | + +**适合谁**:想用开源模型但不想自己部署的开发者。 + +--- + +### Ollama(本地 API) + +**地址**: + +Ollama 严格讲是一个本地模型运行工具,不是云 API 平台。但它能在本地起一个兼容 OpenAI 格式的 API 服务,所以放在这里一起说。 + +| 项目 | 说明 | +|------|------| +| Base URL | `http://localhost:11434/v1` | +| 认证方式 | 本地运行,无需认证 | +| 支持模型 | Llama 4、Qwen、Mistral 等开源模型 | +| 免费额度 | 完全免费,用你自己的硬件 | +| 特色 | 数据不出本机,隐私最好 | + +**适合谁**:对数据隐私有严格要求、有 GPU 资源、想离线使用的用户。 + +**注意点**:需要自己下载模型,占用磁盘和显存;速度取决于你的硬件。 + +--- + +## 平台对比表 + +| 平台 | OpenAI 兼容 | 免费额度 | 国内可访问 | 主要模型 | 适合场景 | +|------|:-----------:|:-------:|:---------:|---------|---------| +| OpenAI | 原生 | 有 | 需梯子 | GPT 系列 | 标准接入,生态最全 | +| Anthropic | 格式略不同 | 无 | 需梯子 | Claude 系列 | 长文写作,代码 | +| Google AI Studio | 部分兼容 | 有 | 需梯子 | Gemini 系列 | 超长上下文,多模态 | +| DeepSeek | 完全兼容 | 有 | 可直接访问 | DeepSeek 系列 | 推理,便宜 | +| Moonshot | 完全兼容 | 有 | 可直接访问 | Kimi 系列 | 长文本,中文 | +| DashScope | 兼容模式 | 有 | 可直接访问 | Qwen 系列 | 国内企业,合规 | +| Groq | 完全兼容 | 有 | 需梯子 | 开源模型 | 极速推理 | +| Together AI | 完全兼容 | 有 | 需梯子 | 开源模型 | 开源模型种类多 | +| Ollama | 完全兼容 | 免费 | 本地运行 | 开源模型 | 隐私,离线 | + +--- + +## 怎么选?看你的场景 + +``` +你在什么环境下开发? +│ +├── 国内环境(不能翻墙) +│ ├── 要推理能力强 → DeepSeek API +│ ├── 要中文好 → DashScope(Qwen) +│ ├── 要长文本 → Moonshot(Kimi) +│ └── 要隐私 → Ollama 本地 +│ +├── 国际环境(能翻墙) +│ ├── 要稳定生态 → OpenAI API +│ ├── 要写作/代码 → Anthropic API +│ ├── 要超长上下文 → Google AI Studio +│ ├── 要速度快 → Groq +│ └── 要便宜 → Together AI +│ +└── 本地环境(数据不能出门) + └── Ollama + 开源模型 +``` + +--- + +## 快速接入示例 + +这里给一个最小示例,展示如何用 OpenAI 兼容格式调用 DeepSeek: + +```python +from openai import OpenAI + +# 只需要改这三行,就能换到任何 OpenAI 兼容平台 +client = OpenAI( + api_key="sk-你的密钥", + base_url="https://api.deepseek.com/v1" +) + +response = client.chat.completions.create( + model="deepseek-chat", + messages=[ + {"role": "system", "content": "你是一个有帮助的助手。"}, + {"role": "user", "content": "用一句话解释什么是 API"} + ], + temperature=0.7 +) + +print(response.choices[0].message.content) +``` + +换成 Groq,只改三行: + +```python +client = OpenAI( + api_key="gsk-你的密钥", + base_url="https://api.groq.com/openai/v1" +) +# model 改成 "llama-4-scout-17b-16e-instruct" +``` + +换成 Ollama 本地: + +```python +client = OpenAI( + api_key="ollama", # 本地随便填 + base_url="http://localhost:11434/v1" +) +# model 改成你本地下载的模型名,比如 "qwen3:8b" +``` + +--- + +## API Key 安全提醒 + +!!! warning "别把 API Key 写在代码里" + 正确做法是用环境变量: + + ```python + import os + client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY")) + ``` + + 或者用 `.env` 文件 + `python-dotenv`: + + ```python + from dotenv import load_dotenv + load_dotenv() + client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY")) + ``` + + 千万别把 Key 提交到 Git 仓库。`.env` 文件应该加到 `.gitignore` 里。 + +--- + +## 费用控制小技巧 + +- **设限额**:大多数平台支持设置每月消费上限,防止意外超支 +- **用小模型探路**:开发阶段用 `gpt-4o-mini` 或 `Qwen Turbo`,便宜够用;上线再切大模型 +- **缓存结果**:相同输入可以缓存,避免重复调用 +- **监控用量**:定期看平台的用量面板,心里有数 + +--- -## 建议内容 +## 延伸阅读 -- 平台名称 -- 接入方式 -- 鉴权方式 -- 参考链接 +- [模型平台](models.md) —— 先选模型,再选 API 平台 +- [API 接入实战](../build/api-integration.md) —— 动手写一个完整的 API 调用 +- [函数调用与工具调用](../tools/tool-calling.md) —— API 的进阶用法 +- [本地与在线模型的差异](../tools/local-vs-online.md) —— 什么时候该用本地 API diff --git a/docs/resources/books-and-articles.md b/docs/resources/books-and-articles.md index 1f5af26..72d458f 100644 --- a/docs/resources/books-and-articles.md +++ b/docs/resources/books-and-articles.md @@ -1,10 +1,310 @@ +--- +tags: + - Resources +--- + # 书单与文章 -> 占位页:本页内容待团队补充。 +> 学 AI 不缺资料,缺的是「该先看什么」的判断。这页帮你按阶段整理好。 + +## 这页解决什么问题 + +搜「AI 入门」,你会得到几百本书、几千篇文章、无数个视频。信息过载本身就是一种劝退。 + +这页做了一件事:按你的阶段,推荐最值得看的内容。每本书、每篇文章都附上「为什么看它」和「适合谁」。 + +> **更新时间**:2026 年 7 月。AI 领域发展快,部分资料可能已有更新版本。 + +--- + +## 入门阶段:零基础到能上手 + +这个阶段的目标是建立基本概念,能跟别人聊 AI 时不懵。 + +### 书籍 + +#### 《深度学习入门:基于 Python 的理论与实现》 + +**作者**:斋藤康毅 +**适合谁**:想从零理解神经网络的读者 +**为什么推荐**:这本书用 Python 从零实现神经网络,不依赖框架。读完你能理解「模型是怎么学的」,而不只是「模型能干什么」。数学要求不高,高中水平够用。 + +#### 《机器学习》(西瓜书) + +**作者**:周志华 +**适合谁**:想系统学习机器学习理论的读者 +**为什么推荐**:国内机器学习领域的经典教材。覆盖面广,从线性模型到集成学习到聚类都有。缺点是偏理论,建议配合实践一起看。 + +#### 《动手学深度学习》(d2l) + +**作者**:李沐 等 +**适合谁**:想边学边写的读者 +**为什么推荐**:李沐(亚马逊资深首席科学家)写的免费在线教材,配套视频教程。每个概念都有可运行的代码,用 PyTorch 和 MXNet 实现。中文版质量很高。 + +**在线版**: + +#### 《Python 机器学习》 + +**作者**:Sebastian Raschka +**适合谁**:有 Python 基础,想快速上手机器学习的读者 +**为什么推荐**:实战导向,用 scikit-learn 讲解经典算法。代码示例多,适合动手派。 + +--- + +### 在线课程 + +#### 吴恩达《Machine Learning Specialization》 + +**平台**:Coursera +**适合谁**:零基础入门 +**为什么推荐**:吴恩达的课是 AI 入门的「标准起点」。2022 年更新版用 Python 替代了旧版的 Octave,更贴近实际。 + +**地址**: + +#### 李宏毅《机器学习》 + +**平台**:YouTube / Bilibili +**适合谁**:中文学习者 +**为什么推荐**:台湾大学李宏毅教授的课,中文讲解,风格幽默,深度够。每年更新,紧跟前沿。 + +**地址**:B站搜索「李宏毅 机器学习」 + +#### fast.ai《Practical Deep Learning for Coders》 + +**平台**:fast.ai +**适合谁**:有编程基础,想快速出成果的读者 +**为什么推荐**:Jeremy Howard 的课,「top-down」教学法——先让你跑通一个完整项目,再回头讲原理。对编程能力强但数学弱的人特别友好。 + +**地址**: + +--- + +## 进阶阶段:理解 LLM 和 Prompt + +这个阶段的目标是理解大语言模型的原理,学会用 Prompt 工程来控制模型输出。 + +### 书籍 + +#### 《Build a Large Language Model (From Scratch)》 + +**作者**:Sebastian Raschka +**适合谁**:想从零理解 LLM 是怎么造出来的读者 +**为什么推荐**:这本书带你从零实现一个 GPT 风格的模型。读完你能理解 Transformer、预训练、微调的完整流程。代码用 PyTorch 写,清晰易读。 + +#### 《Prompt Engineering for Generative AI》 + +**作者**:James Phoenix, Mike Taylor +**适合谁**:想系统学习 Prompt 工程的开发者 +**为什么推荐**:覆盖了 Prompt 设计的各种技巧:Few-shot、Chain-of-Thought、Self-consistency 等。有大量代码示例。 + +--- + +### 文章与指南 + +#### OpenAI《Prompt Engineering Guide》 + +**适合谁**:所有用 OpenAI 模型的开发者 +**为什么看它**:官方出品,最权威的 Prompt 工程指南。从基础到高级技巧都有覆盖。 + +**地址**: + +#### Anthropic《Claude Prompt Engineering》 + +**适合谁**:用 Claude 的开发者 +**为什么看它**:Anthropic 的 Prompt 指南,针对 Claude 的特点给出了很多实用建议。 + +**地址**: + +#### Lilian Weng 的博客 + +**适合谁**:想深入理解 AI 技术原理的读者 +**为什么看它**:OpenAI 研究员 Lilian Weng 的博客,每篇文章都像一篇小型综述,深度和广度兼具。推荐从「Prompt Engineering」和「LLM Powered Autonomous Agents」两篇开始。 + +**地址**: + +#### Jay Alammar 的可视化博客 + +**适合谁**:喜欢图解式学习的读者 +**为什么看它**:用大量可视化图解来解释 Transformer、BERT、GPT 等模型。The Illustrated Transformer 那篇是理解 Transformer 的最佳入门材料之一。 + +**地址**: + +--- + +## 实战阶段:搭建 AI 应用 + +这个阶段的目标是动手搭建 RAG、Agent、评测系统等实际应用。 + +### 书籍 + +#### 《Building LLM Apps》 + +**作者**:Valentina Alto +**适合谁**:想搭建 LLM 应用的开发者 +**为什么推荐**:覆盖了 RAG、Agent、工具调用、部署等实战内容。代码示例用 LangChain 和 LlamaIndex。 + +#### 《AI Engineering》 + +**作者**:Chip Huyen +**适合谁**:想系统了解 AI 工程化的开发者和架构师 +**为什么推荐**:Chip Huyen 是 AI 工程领域的知名作者,这本书覆盖了从模型选择、Prompt 工程、RAG、微调到部署的完整链路。 + +--- + +### 文章与教程 + +#### LangChain 官方文档 + +**适合谁**:用 LangChain 开发的用户 +**为什么看它**:文档质量高,示例丰富,覆盖了 RAG、Agent、评测等各个方面。 + +**地址**: + +#### LlamaIndex 官方文档 + +**适合谁**:用 LlamaIndex 做 RAG 的用户 +**为什么看它**:在数据索引和检索方面写得特别细,有大量端到端示例。 + +**地址**: + +#### Hugging Face NLP Course + +**适合谁**:想理解 NLP 底层的开发者 +**为什么看它**:免费在线课程,从 Transformer 原理到微调到部署都有覆盖。用 Hugging Face 生态讲解。 + +**地址**: + +--- + +## 专题深入 + +### Prompt 工程专题 + +| 资源 | 类型 | 适合谁 | 地址 | +|------|------|-------|------| +| OpenAI Prompt Engineering Guide | 官方指南 | OpenAI 用户 | | +| Anthropic Prompt Engineering | 官方指南 | Claude 用户 | | +| Prompt Engineering Guide(DAIR.AI)| 社区指南 | 所有人 | | +| Learn Prompting | 在线教程 | 初学者 | | + +### RAG 专题 + +| 资源 | 类型 | 适合谁 | 地址 | +|------|------|-------|------| +| LangChain RAG 教程 | 官方教程 | LangChain 用户 | | +| LlamaIndex 文档 | 官方文档 | LlamaIndex 用户 | | +| RAGAS 文档 | 评测工具 | RAG 开发者 | | + +### Agent 专题 + +| 资源 | 类型 | 适合谁 | 地址 | +|------|------|-------|------| +| LangGraph 文档 | 官方文档 | LangGraph 用户 | | +| CrewAI 文档 | 官方文档 | CrewAI 用户 | | +| Lilian Weng: LLM Powered Autonomous Agents | 博客文章 | 所有人 | | + +### AI 安全专题 + +| 资源 | 类型 | 适合谁 | 地址 | +|------|------|-------|------| +| OWASP Top 10 for LLM Applications | 安全指南 | 开发者 | | +| Anthropic: Core Views on AI Safety | 官方立场 | 所有人 | | +| Google: Responsible AI Practices | 官方指南 | 企业用户 | | + +--- + +## 中文资源推荐 + +### 公众号 / 博客 + +| 作者/平台 | 内容方向 | 适合谁 | +|---------|---------|-------| +| 机器之心 | AI 行业新闻、论文解读 | 所有人 | +| 量子位 | AI 产品和技术动态 | 所有人 | +| PaperWeekly | 论文精读、技术深度 | 想深入研究的读者 | +| 李沐 | 深度学习教程、论文精读 | 学习者和开发者 | +| 苏剑林(科学空间)| NLP、数学、技术博客 | 有数学基础的开发者 | + +### 开源项目 + +| 项目 | 方向 | 地址 | +|------|------|------| +| ChatGLM | 中文大模型 | | +| Qwen | 中文大模型 | | +| DeepSeek | 推理模型 | | +| Dify | LLM 应用平台 | | +| RAGFlow | RAG 引擎 | | + +--- + +## 学习路径建议 + +``` +你目前在什么阶段? +│ +├── 零基础,想了解 AI 是什么 +│ ├── 看书:《深度学习入门》或《机器学习》 +│ ├── 上课:吴恩达 ML Specialization 或李宏毅机器学习 +│ └── 读文章:Jay Alammar 的可视化博客 +│ +├── 有基础,想理解 LLM +│ ├── 看书:《Build a Large Language Model (From Scratch)》 +│ ├── 读文章:Lilian Weng 的博客 +│ └── 实践:用 OpenAI API 写几个小应用 +│ +├── 想动手搭应用 +│ ├── RAG:LangChain / LlamaIndex 官方教程 +│ ├── Agent:LangGraph / CrewAI 官方文档 +│ └── 评测:RAGAS + DeepEval +│ +└── 想深入某个方向 + ├── Prompt 工程:OpenAI + Anthropic 官方指南 + ├── 安全:OWASP Top 10 for LLM + └── 研究:arXiv 论文 + 顶会论文 +``` + +--- + +## 怎么高效读书 + +??? tip "读书的几个建议" + **1. 别从头读到尾** + 技术书不是小说,先看目录,找到你最需要的章节,直接跳过去。 + + **2. 边读边写代码** + 看懂和会用之间隔着一个「动手」。每个概念都试着写个小例子。 + + **3. 一本书读 80% 就够了** + 剩下 20% 的细节用到的时候再查。别追求「读完」,追求「用上」。 + + **4. 读完一篇好文章,写个笔记** + 写给自己看的,目的是加深理解。用自己的话复述一遍,比再读三遍有用。 + + **5. 别只看中文资料** + AI 领域最前沿的内容大多是英文的。用翻译工具辅助阅读,慢慢就能直接读英文了。 + +--- + +## 常见误区 + +??? warning "误区 1:资料越多越好" + 收藏了 100 篇文章,一篇都没看完。不如选定 3 篇,认真读完、动手实践。 + +??? warning "误区 2:只看书不动手" + 看完一本书感觉什么都懂了,一写代码全忘。AI 学习必须边学边做。 + +??? warning "误区 3:只追最新论文" + 基础不牢的时候读论文效率很低。先把基础打好,再看论文会事半功倍。 + +??? warning "误区 4:中文资料就够了" + 最前沿的模型、框架、论文都是英文的。中文资料适合入门,进阶阶段必须啃英文。 + +--- -## 建议内容 +## 延伸阅读 -- 标题 -- 作者 -- 推荐理由 -- 适合阶段 +- [什么是 AI](../basics/what-is-ai.md) —— AI 的基本概念 +- [什么是 LLM](../basics/what-is-llm.md) —— 大语言模型的原理 +- [Prompt 基础](../prompt/prompt-basic.md) —— Prompt 工程入门 +- [RAG 总览](../rag/index.md) —— RAG 系统的原理 +- [Agent 总览](../agent/index.md) —— Agent 的核心概念 diff --git a/docs/resources/eval-tools.md b/docs/resources/eval-tools.md index 667b590..f787032 100644 --- a/docs/resources/eval-tools.md +++ b/docs/resources/eval-tools.md @@ -1,10 +1,340 @@ +--- +tags: + - Resources +--- + # 评测工具 -> 占位页:本页内容待团队补充。 +> 做 AI 应用不评测,就像考试不看分数——你永远不知道自己到底考得怎么样。 + +## 这页解决什么问题 + +你搭了一个 RAG 系统,或者写了一套 Prompt,或者做了一个 Agent。跑几个例子感觉还行,但你真的确定它在所有情况下都靠谱吗? + +评测工具帮你回答这个问题。它们提供标准化的方法来衡量模型输出的质量、准确性和一致性。 + +> **更新时间**:2026 年 7 月。工具迭代快,版本号和功能以各项目官网为准。 + +--- + +## 什么时候需要评测 + +在介绍具体工具之前,先想想什么时候需要评测: + +- **Prompt 调优**:你改了一版 Prompt,怎么确认新版比旧版好?靠感觉不靠谱,得有数据。 +- **RAG 效果**:你的 RAG 系统检索到的文档相关吗?生成的答案准确吗? +- **模型切换**:从 GPT-4o 换到 DeepSeek V4,效果差了多少? +- **上线前验收**:你的 AI 应用要上线了,怎么证明它在各种边界情况下都能用? +- **持续监控**:上线之后,效果有没有退化? + +评测要贯穿整个开发和运维周期,做一次就丢在一边肯定不行。 + +--- + +## 主流工具一览 + +### RAGAS + +**官网**: +**GitHub**: + +RAGAS 专门做 RAG 系统的评测。它提供了一套针对 RAG 流程的指标,帮你定位是检索出了问题还是生成出了问题。 + +**核心指标**: + +| 指标 | 衡量什么 | 说明 | +|------|---------|------| +| Faithfulness | 答案是否忠实于检索到的文档 | 低分说明模型在「编」 | +| Answer Relevancy | 答案是否回答了用户的问题 | 低分说明答非所问 | +| Context Precision | 检索到的文档是否相关 | 低分说明检索不准 | +| Context Recall | 相关文档是否都被检索到了 | 低分说明有遗漏 | + +**适合谁**:做 RAG 系统的团队;需要系统性评测检索和生成质量的场景。 + +**注意点**:需要准备测试数据集(问题 + 标准答案 + 标准文档)。 + +```python +from ragas import evaluate +from ragas.metrics import faithfulness, answer_relevancy +from datasets import Dataset + +# 准备评测数据 +data = { + "question": ["公司的退款政策是什么?"], + "answer": ["购买后30天内可全额退款。"], + "contexts": [["退款政策:购买后30天内可全额退款。"]], + "ground_truth": ["购买后30天内可全额退款。"] +} +dataset = Dataset.from_dict(data) + +# 运行评测 +result = evaluate(dataset, metrics=[faithfulness, answer_relevancy]) +print(result) +``` + +--- + +### DeepEval + +**官网**: +**GitHub**: + +DeepEval 是一个通用的 LLM 评测框架,不只针对 RAG,也支持 Agent、聊天机器人等各种 AI 应用的评测。 + +**核心特点**: + +- 指标丰富:幻觉检测、答案相关性、毒性检测、偏见检测等 +- 支持自定义指标 +- 自带测试框架,写法类似 pytest +- 集成了 Confident AI 平台(可视化评测面板) + +**适合谁**:需要全面评测 AI 应用质量的团队;需要自定义评测指标的场景。 + +```python +from deepeval import assert_test +from deepeval.test_case import LLMTestCase +from deepeval.metrics import AnswerRelevancyMetric + +test_case = LLMTestCase( + input="公司的退款政策是什么?", + actual_output="购买后30天内可全额退款。", + expected_output="购买后30天内可全额退款。" +) + +metric = AnswerRelevancyMetric(threshold=0.7) +assert_test(test_case, [metric]) +``` + +??? info "定价" + 开源免费。Confident AI 平台有免费额度,付费版从 $49/月起。 + + +--- + +### LangSmith + +**官网**: +**GitHub**:闭源,LangChain 官方产品 + +LangSmith 是 LangChain 团队推出的 LLM 应用监控和评测平台。它能追踪每一次 API 调用的详细过程,帮你看到模型「想了什么」。 + +**核心特点**: + +- 调用链追踪:能看到每一步的输入输出 +- 在线评测:在生产环境中持续监控质量 +- 数据集管理:方便管理测试用例 +- 和 LangChain / LangGraph 深度集成 + +**适合谁**:已经在用 LangChain 的团队;需要生产环境监控的场景;需要调用链追踪来调试的开发者。 + +**注意点**:闭源,绑定 LangChain 生态。 + +??? info "定价" + 开发版免费(5K 次追踪/月)。Plus 版 $39/月起。 + + +--- + +### Braintrust + +**官网**: +**GitHub**: + +Braintrust 是一个 AI 评测和实验平台,主打「像做实验一样评测 AI」。它支持 A/B 测试、回归测试、自动化评测。 + +**核心特点**: + +- A/B 测试:对比不同 Prompt、不同模型的效果 +- 回归测试:每次改动后自动跑评测,确保没有退化 +- 可视化面板:直观看到评测结果 +- 支持多种 LLM 后端 + +**适合谁**:需要频繁迭代 Prompt 或模型的团队;需要 A/B 测试来决策的场景。 + +**注意点**:功能偏专业,上手需要一定学习成本。 + +??? info "定价" + 有免费额度。付费版按使用量计费。 + + +--- + +### Promptfoo + +**官网**: +**GitHub**: + +Promptfoo 是一个命令行优先的评测工具。你用 YAML 文件定义测试用例,跑一条命令就能出结果。 + +**核心特点**: + +- 命令行优先,配置简单 +- 支持多模型并行对比 +- 支持自定义评测函数 +- 本地运行,数据不出门 + +**适合谁**:喜欢命令行的开发者;需要快速对比多个模型或 Prompt 的场景;对数据隐私有要求。 + +```yaml +# promptfooconfig.yaml +providers: + - openai:gpt-4o-mini + - deepseek:deepseek-chat + +prompts: + - "你是一个有帮助的助手。请回答:{{query}}" + - "你是技术专家。请用专业但易懂的方式回答:{{query}}" + +tests: + - vars: + query: "什么是 RAG?" + assert: + - type: contains + value: "检索" + - type: llm-rubric + value: "答案应该解释 RAG 的基本原理" +``` + +运行:`npx promptfoo eval` + +--- + +### OpenAI Evals + +**官网**: + +OpenAI 官方推出的评测框架。它提供了一套标准化的评测任务和评分方法。 + +**核心特点**: + +- 官方维护,标准参考 +- 预置了大量评测任务 +- 支持自定义评测 +- 和 OpenAI API 深度集成 + +**适合谁**:主要用 OpenAI 模型的团队;需要标准化评测的场景。 + +**注意点**:主要针对 OpenAI 模型,用其他模型需要额外适配。 + +--- + +### HELM(斯坦福) + +**官网**: +**GitHub**: + +HELM(Holistic Evaluation of Language Models)是斯坦福大学推出的全面评测框架。它从多个维度评测模型:准确性、鲁棒性、公平性、偏见、毒性等。 + +**核心特点**: + +- 学术级评测标准 +- 维度全面(不只看准确率) +- 定期发布评测报告 +- 开源透明 + +**适合谁**:需要学术级评测的场景;需要全面评估模型能力的研究者;需要对比多个模型的团队。 + +**注意点**:比较学术化,工程实践中的直接应用需要额外工作。 + +--- + +## 工具对比表 + +| 工具 | 评测类型 | 上手难度 | RAG 评测 | Agent 评测 | 可视化 | 开源 | +|------|---------|:-------:|:--------:|:---------:|:-----:|:----:| +| RAGAS | RAG 专用 | 低 | 最强 | 无 | 无 | 是 | +| DeepEval | 通用 | 低 | 强 | 强 | 有 | 是 | +| LangSmith | 通用 | 中 | 强 | 强 | 有 | 否 | +| Braintrust | 通用 | 中 | 强 | 强 | 有 | 否 | +| Promptfoo | 通用 | 低 | 中 | 中 | 有 | 是 | +| OpenAI Evals | 通用 | 中 | 中 | 中 | 无 | 是 | +| HELM | 全面 | 高 | 中 | 无 | 有 | 是 | + +--- + +## 怎么选?看你的需求 + +``` +你在评测什么? +│ +├── RAG 系统 +│ ├── 快速评测检索和生成质量 → RAGAS +│ └── 需要全面评测 + 可视化 → DeepEval +│ +├── Agent 应用 +│ ├── 已经在用 LangChain → LangSmith +│ └── 通用评测 → DeepEval / Braintrust +│ +├── Prompt 优化 +│ ├── 命令行快速对比 → Promptfoo +│ └── A/B 测试 → Braintrust +│ +├── 模型选型 +│ ├── 多模型并行对比 → Promptfoo +│ └── 学术级全面评测 → HELM +│ +└── 生产环境监控 + ├── LangChain 生态 → LangSmith + └── 通用 → DeepEval / Braintrust +``` + +--- + +## 评测流程建议 + +### 评测的基本流程 + +``` +1. 定义评测目标 + └── 你要评测什么?准确性?幻觉?响应速度? + +2. 准备测试数据集 + └── 收集典型问题和标准答案 + +3. 选择评测指标 + └── 根据目标选指标(RAGAS、自定义等) + +4. 运行评测 + └── 跑测试集,收集结果 + +5. 分析结果 + └── 看哪些 case 有问题,定位原因 + +6. 迭代优化 + └── 改 Prompt / 换模型 / 调参数 + +7. 回归测试 + └── 确认优化后没有退化 +``` + +### 测试数据集怎么准备 + +- **收集真实问题**:从用户反馈、客服记录、日志里找真实问题 +- **覆盖边界情况**:不只测「正常」情况,也要测模糊问题、错误输入、长文本 +- **定期更新**:随着业务变化,测试集也要更新 + +--- + +## 常见误区 + +??? warning "误区 1:跑几个例子就够了" + 几个例子只能告诉你「能跑通」,不能告诉你「跑得好」。评测需要足够的样本量和覆盖度。 + +??? warning "误区 2:只看平均分" + 平均分 90% 看起来很好,但如果你的场景里那 10% 的失败都是致命的(比如医疗、法律),平均分就没意义。要看分布,看最差情况。 + +??? warning "误区 3:评测一次就够了" + 模型更新、Prompt 修改、数据变化,都会影响效果。评测应该是持续的过程,不是一次性的任务。 + +??? warning "误区 4:评测指标越多越好" + 指标太多会让你迷失重点。先确定你最关心什么(准确性?幻觉?速度?),选 2-3 个核心指标就够了。 + +--- -## 建议内容 +## 延伸阅读 -- 工具名称 -- 评测类型 -- 使用方式 -- 示例 +- [主观与客观指标](../eval/metrics.md) —— 评测指标的分类和选择 +- [幻觉评测](../eval/hallucination.md) —— 怎么衡量模型的幻觉程度 +- [输出质量判断](../eval/quality.md) —— 怎么判断模型输出的质量 +- [RAG 框架](rag-frameworks.md) —— RAG 系统的搭建 +- [Agent 框架](agent-frameworks.md) —— Agent 应用的搭建 diff --git a/docs/resources/models.md b/docs/resources/models.md index bf173c2..f9fdfa7 100644 --- a/docs/resources/models.md +++ b/docs/resources/models.md @@ -1,10 +1,284 @@ +--- +tags: + - Resources +--- + # 模型平台 -> 占位页:本页内容待团队补充。 +> 选模型这件事,跟选手机差不多——参数表只能告诉你一半,另一半得看你拿来干什么。 + +## 这页解决什么问题 + +打开任何一个模型平台,你会看到一串名字:GPT-4o、Claude Sonnet、Gemini Flash、DeepSeek V3……每个都说自己强,每个都有不同的价格和限制。 + +这页把这些平台和模型摊开,让你能快速判断:哪个适合你的场景,该去哪注册,大概花多少钱。 + +> **更新时间**:2026 年 7 月。模型迭代很快,价格和能力每隔几个月就会变。具体数字以各平台官网为准。 + +--- + +## 主流平台一览 + +### OpenAI + +**官网**: + +OpenAI 是这波 AI 浪潮的起点,ChatGPT 几乎成了大模型的代名词。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| GPT-5.5 | 旗舰推理 | 256K | 综合能力最强,支持深度推理模式 | +| GPT-4o | 多模态通用 | 128K | 速度快、性价比高,支持图片/音频 | +| GPT-4o mini | 轻量版 | 128K | 便宜、快,适合简单任务 | +| o3 / o4-mini | 推理专用 | 128K | 数学、代码、逻辑推理特别强 | + +**适合谁**:需要稳定、成熟生态的用户。插件最多,第三方工具兼容性最好。 + +**注意点**:免费版有使用限额;高峰期可能变慢;API 价格在高端模型上偏贵。 + +??? info "价格参考(API 调用)" + GPT-4o:输入 $2.5 / 百万 token,输出 $10 / 百万 token + GPT-4o mini:输入 $0.15 / 百万 token,输出 $0.6 / 百万 token + 具体以 为准。 + +--- + +### Anthropic(Claude) + +**官网**: + +Anthropic 由前 OpenAI 成员创立,主打安全和长文本处理。Claude 系列在写作和代码领域口碑很好。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| Claude Opus 4.8 | 旗舰 | 200K | 最强综合能力,复杂推理和长文写作顶级 | +| Claude Sonnet 4.6 | 均衡 | 200K | 速度快、质量高,日常首选 | +| Claude Haiku 4 | 轻量 | 200K | 极快、便宜,适合批量处理 | + +**适合谁**:写长文章、处理超长文档、写高质量代码的用户。回答风格简洁,废话少。 + +**注意点**:联网能力偏弱,没有图片生成功能。部分功能需要付费订阅。 + +??? info "价格参考(API 调用)" + Sonnet 4.6:输入 $3 / 百万 token,输出 $15 / 百万 token + Haiku 4:输入 $0.25 / 百万 token,输出 $1.25 / 百万 token + 具体以 为准。 + +--- + +### Google(Gemini) + +**官网**: + +Google 的 Gemini 系列继承了搜索和多模态的基因,上下文窗口在行业里数一数二。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| Gemini 3.1 Pro | 旗舰 | 2M | 超长上下文,多模态能力强 | +| Gemini 3.5 Flash | 快速版 | 1M | 速度极快,性价比高 | +| Gemini 2.0 Flash | 上代快版 | 1M | 仍然可用,价格更低 | + +**适合谁**:需要处理超长文档(几十万字)、依赖 Google 全家桶(Gmail、Drive、Docs)的用户。多模态理解能力一流。 + +**注意点**:中文理解偶尔有偏差;部分功能在某些地区不可用。 + +??? info "价格参考(API 调用)" + Gemini 3.1 Pro:输入 $1.25 / 百万 token,输出 $5 / 百万 token + Gemini 3.5 Flash:输入 $0.075 / 百万 token,输出 $0.3 / 百万 token + 具体以 为准。 + +--- + +### DeepSeek + +**官网**: + +DeepSeek 是国产模型里推理能力最强的选手,尤其擅长数学和逻辑。它的思考过程会完整展示出来,特别适合学习场景。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| DeepSeek V4 | 旗舰 | 128K | 综合能力强,推理能力顶尖 | +| DeepSeek V3.2 | 上代旗舰 | 128K | 仍然可用,性价比更高 | +| DeepSeek R1 | 推理专用 | 128K | 深度推理,数学/代码/逻辑 | + +**适合谁**:学生解题、需要推理链的场景、预算有限但需要高质量推理的用户。 + +**注意点**:服务器高峰期经常排队,响应速度波动较大。API 兼容 OpenAI 格式,接入方便。 + +??? info "价格参考(API 调用)" + DeepSeek V4:输入 ¥1 / 百万 token,输出 ¥2 / 百万 token + DeepSeek R1:输入 ¥4 / 百万 token,输出 ¥16 / 百万 token + 具体以 为准。 + +--- + +### Moonshot(Kimi) + +**官网**: + +Moonshot 的 Kimi 系列在长文本处理上有独到之处,最早主打「喂一整本书让它读」。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| Kimi K3 | 旗舰 | 256K | 长文本理解强,中文能力好 | +| Kimi K2 | 上代 | 128K | 仍然可用 | + +**适合谁**:需要处理长文档(论文、合同、书籍)、纯中文场景的用户。 + +**注意点**:国际化程度不如 OpenAI 和 Anthropic;部分高级功能需要付费。 + +--- + +### 阿里巴巴(通义千问) + +**官网**: / API: + +通义千问是阿里云的大模型产品,中文能力在国产模型里属于第一梯队。开源版本 Qwen 系列在社区里很受欢迎。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| Qwen3.7 Max | 旗舰 | 128K | 中文最强,多模态支持好 | +| Qwen3.7 Plus | 均衡 | 128K | 性价比高 | +| Qwen3.7 Turbo | 快速 | 128K | 便宜、快 | + +**适合谁**:纯中文场景、需要私有化部署(开源版本)、国内访问要求高的用户。 + +**注意点**:复杂推理能力与国际顶尖模型有差距。 + +--- + +### Meta(Llama) + +**官网**: + +Meta 的 Llama 系列是开源模型的标杆。你可以自己下载、部署、微调,数据完全不出门。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| Llama 4 Maverick | 大杯 | 128K | 开源旗舰,综合能力强 | +| Llama 4 Scout | 轻量 | 128K | 更小、更快、部署成本低 | + +**适合谁**:需要私有化部署、对数据隐私有严格要求、想自己微调模型的团队。 + +**注意点**:需要自己准备服务器和 GPU;开源模型的使用协议要仔细看。 + +--- + +### 智谱(GLM) + +**官网**: + +智谱的 GLM 系列是国内最早的大模型之一,背靠清华大学,在学术和企业场景里用得多。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| GLM-5 | 旗舰 | 128K | 中文能力强,支持多模态 | +| GLM-4 Flash | 快速 | 128K | 免费额度高 | + +**适合谁**:国内企业用户、需要免费额度试用的开发者。 + +--- + +### 字节跳动(豆包 / Seed) + +**官网**: + +豆包是字节跳动的 AI 助手产品,Seed 是背后的模型系列。手机 App 体验在国内做得最好。 + +**当前主力模型**: + +| 模型 | 定位 | 上下文窗口 | 特点 | +|------|------|-----------|------| +| Seed 2.1 | 旗舰 | 128K | 综合能力好,中文理解强 | +| Seed 2.1 Flash | 快速 | 128K | 极快,适合日常对话 | + +**适合谁**:手机端用户、日常对话和内容创作、国内免费使用。 + +**注意点**:专业深度不如顶尖模型;API 生态相对封闭。 + +--- + +## 怎么选?看这张表 + +| 你的需求 | 首选 | 备选 | 理由 | +|---------|------|------|------| +| 写长文章 / 报告 | Claude Sonnet 4.6 | GPT-5.5 | Claude 文字质量最稳,废话少 | +| 写代码 / 调 bug | Claude Sonnet 4.6 | GPT-4o | Claude 代码理解能力最强 | +| 解数学 / 推理题 | DeepSeek R1 | o3 | DeepSeek 推理链清晰,适合学习 | +| 处理超长文档 | Gemini 3.1 Pro | Kimi K3 | Gemini 2M 上下文,行业最大 | +| 中文内容创作 | Qwen3.7 Max | 豆包 Seed | 中文语感最地道 | +| 手机随时用 | 豆包 App | ChatGPT App | 国内免费,体验流畅 | +| 私有化部署 | Llama 4 | Qwen3.7 开源 | 开源免费,数据不出门 | +| 省钱跑量 | GPT-4o mini | Gemini Flash | 便宜、够用 | +| 国内企业用 | 通义千问 | 智谱 GLM | 国内合规,技术支持好 | + +--- + +## 决策路线图 + +``` +你最看重什么? +│ +├── 质量优先 +│ ├── 写作 / 代码 → Claude Opus 4.8 / Sonnet 4.6 +│ ├── 推理 / 数学 → DeepSeek R1 / GPT o3 +│ └── 综合全能 → GPT-5.5 +│ +├── 速度优先 +│ ├── 国际 → Gemini 3.5 Flash / GPT-4o +│ └── 国内 → 豆包 Seed Flash / Qwen Turbo +│ +├── 价格优先 +│ ├── 国际 → Gemini Flash(最便宜) +│ └── 国内 → DeepSeek V4(国产最便宜) +│ +├── 上下文长度 +│ ├── 超长(50万字+)→ Gemini 3.1 Pro(2M) +│ ├── 长(10-20万字)→ Claude(200K)/ Kimi K3(256K) +│ └── 普通(10万字以内)→ 随便选 +│ +└── 数据安全 + ├── 必须私有化 → Llama 4 / Qwen 开源 + └── 国内合规 → 通义千问 / 智谱 GLM +``` + +--- + +## 常见误区 + +??? warning "误区 1:参数越大越好" + 参数量只是模型的「体格」,不代表它在你的任务上表现好。一个针对中文写作调教过的小模型,可能比一个没优化的大模型更顺手。 + +??? warning "误区 2:排行榜第一就是最好的" + LMSYS、MMLU 这些榜单测的是「平均综合能力」,不是你的具体任务。排行榜第一的模型用来写小红书文案,可能还不如通义千问。 + +??? warning "误区 3:一个模型用到底" + 完全可以混着用。写长文章用 Claude,查实时资讯用 Gemini,解数学题切 DeepSeek,手机随手查开豆包。工具箱里多几把刀,效率更高。 + +??? warning "误区 4:免费版没用" + 免费版已经能处理绝大多数日常需求。ChatGPT 免费版、DeepSeek 免费版、通义千问免费版,对付日常写作和查资料完全够用。等真的感到「不够用」再升级。 + +--- -## 建议内容 +## 延伸阅读 -- 平台名称 -- 适用场景 -- 费用与限制 -- 更新时间 +- [如何选择模型](../tools/model-selection.md) —— 更详细的选型思路 +- [API 平台](apis.md) —— 怎么通过 API 调用这些模型 +- [本地与在线模型的差异](../tools/local-vs-online.md) —— 什么时候该用本地模型 +- [Token、Embedding 与上下文窗口](../basics/token-embedding-context.md) —— 理解上下文窗口的本质 diff --git a/docs/resources/rag-frameworks.md b/docs/resources/rag-frameworks.md index 186f722..a0381eb 100644 --- a/docs/resources/rag-frameworks.md +++ b/docs/resources/rag-frameworks.md @@ -1,10 +1,302 @@ +--- +tags: + - Resources +--- + # RAG 框架 -> 占位页:本页内容待团队补充。 +> RAG 框架帮你把「模型不知道的事」变成「模型能查到的事」。选框架的关键是看你的数据长什么样,以及你愿意花多少精力去调。 + +## 这页解决什么问题 + +你想让模型回答公司内部问题、读你自己的文档、或者基于某个知识库做问答。直接问模型,它不知道这些私有数据。你需要一套「先检索、再生成」的流程。 + +RAG 框架就是帮你把这个流程搭起来的工具。它们处理文档切分、向量化、检索、重排、生成这些环节,让你不用从零写起。 + +> **更新时间**:2026 年 7 月。框架迭代快,版本号和功能以各项目官网为准。 + +--- + +## 主流框架一览 + +### LangChain / LangGraph + +**官网**: +**GitHub**: + +LangChain 是 RAG 和 LLM 应用开发领域里生态最完整的框架。它提供了一整套组件:文档加载器、文本切分器、向量存储接口、检索器、链(Chain)、Agent。 + +LangGraph 是 LangChain 团队推出的图编排框架,适合构建复杂的多步 RAG 流程。 + +**核心特点**: + +- 组件最全,社区最大,教程最多 +- 支持几乎所有主流向量数据库和 LLM +- LangGraph 支持有状态的多步流程 +- Python 和 JavaScript 都有 SDK + +**适合谁**:需要高度定制化的 RAG 系统;需要把 RAG 和 Agent 结合的场景;愿意花时间学框架的开发者。 + +**注意点**:抽象层多,学习曲线陡。简单场景用它可能有点重。 + +```python +from langchain_openai import OpenAIEmbeddings, ChatOpenAI +from langchain_community.vectorstores import FAISS +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain.chains import RetrievalQA + +# 切分文档 +splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) +chunks = splitter.split_documents(documents) + +# 建向量库 +vectorstore = FAISS.from_documents(chunks, OpenAIEmbeddings()) + +# 检索 + 生成 +qa = RetrievalQA.from_chain_type( + llm=ChatOpenAI(model="gpt-4o-mini"), + retriever=vectorstore.as_retriever(search_kwargs={"k": 3}) +) +result = qa.invoke("公司的退款政策是什么?") +``` + +??? info "版本与定价" + 开源免费。LangSmith(配套的监控平台)有免费额度,付费版从 $39/月起。 + + +--- + +### LlamaIndex + +**官网**: +**GitHub**: + +LlamaIndex 专门为「把数据接入 LLM」而设计。如果说 LangChain 是瑞士军刀,LlamaIndex 更像一把手术刀——在数据索引和检索这件事上做得更深。 + +**核心特点**: + +- 数据连接器丰富(PDF、Notion、Slack、数据库等) +- 索引结构多样(向量索引、树索引、关键词索引) +- 查询引擎封装好,开箱即用 +- 文档质量高,示例多 + +**适合谁**:主要需求是「让 LLM 读我的数据」;需要多种索引策略;想要一个专注 RAG 的工具。 + +**注意点**:Agent 能力不如 LangGraph 强;复杂工作流需要额外组合。 + +```python +from llama_index.core import VectorStoreIndex, SimpleDirectoryReader + +# 读取文档 +documents = SimpleDirectoryReader("./data").load_data() + +# 建索引 +index = VectorStoreIndex.from_documents(documents) + +# 查询 +query_engine = index.as_query_engine() +response = query_engine.query("公司的退款政策是什么?") +print(response) +``` + +??? info "版本与定价" + 开源免费。LlamaCloud(云端文档解析服务)有免费额度。 + + +--- + +### Haystack + +**官网**: +**GitHub**: + +Haystack 是 deepset 团队开发的 RAG 框架,设计哲学是「管道(Pipeline)」——把每个步骤看成管道里的一个节点,灵活组合。 + +**核心特点**: + +- Pipeline 设计清晰,组件解耦好 +- 支持多种文档存储(Elasticsearch、OpenSearch、Weaviate 等) +- 自带标注工具,方便做评测 +- 企业级支持好 + +**适合谁**:企业级 RAG 应用;需要和 Elasticsearch 等现有基础设施集成;喜欢管道式设计的团队。 + +**注意点**:社区不如 LangChain 大;中文教程相对少。 + +```python +from haystack import Pipeline, Document +from haystack.document_stores.in_memory import InMemoryDocumentStore +from haystack.components.retrievers.in_memory import InMemoryBM25Retriever +from haystack.components.generators import OpenAIGenerator + +# 建文档库 +document_store = InMemoryDocumentStore() +document_store.write_documents([ + Document(content="退款政策:购买后30天内可全额退款。"), + Document(content="技术支持:工作日9:00-18:00在线。"), +]) + +# 搭管道 +retriever = InMemoryBM25Retriever(document_store=document_store) +generator = OpenAIGenerator(model="gpt-4o-mini") + +pipeline = Pipeline() +pipeline.add_component("retriever", retriever) +pipeline.add_component("generator", generator) +pipeline.connect("retriever.documents", "generator") + +# 运行 +result = pipeline.run({ + "retriever": {"query": "退款政策"}, + "generator": {"prompt": "根据以下文档回答:\n{{documents}}\n问题:退款政策是什么?"} +}) +``` + +??? info "版本与定价" + 开源免费。deepset Cloud(企业版)按需定价。 + + +--- + +### Dify + +**官网**: +**GitHub**: + +Dify 跟前面几个框架不一样——它是一个**可视化平台**,让你在浏览器里拖拽搭建 RAG 流程,不用写代码。 + +**核心特点**: + +- 可视化拖拽搭建,不写代码也能用 +- 自带文档上传、切分、向量化全流程 +- 支持接入多种 LLM 和向量数据库 +- 自带 API 发布,搭完直接给外部调用 +- 开源可自部署 + +**适合谁**:不想写代码但想搭 RAG 的产品经理、运营人员;快速验证想法的团队;需要内部部署的中小企业。 + +**注意点**:定制化能力不如纯代码框架;复杂逻辑实现起来有局限。 + +??? info "版本与定价" + 社区版开源免费,可自部署。 + Cloud 版有免费额度,Pro 版 $59/月起。 + + +--- + +### RAGFlow + +**地址**: + +RAGFlow 是一个专注于**深度文档解析**的 RAG 引擎。它在文档预处理这块做得特别细——表格、公式、图片、扫描件都能处理。 + +**核心特点**: + +- 文档解析能力行业领先(表格、公式、图片 OCR) +- 自带可视化知识库管理界面 +- 支持多种检索策略(向量、关键词、混合) +- 开源可自部署 + +**适合谁**:数据源是复杂文档(合同、财报、论文、扫描件);对文档解析质量要求高;需要开源自部署。 + +**注意点**:部署需要一定硬件资源;社区比 LangChain 小。 + +??? info "版本与定价" + 开源免费。企业版联系官方。 + + +--- + +## 框架对比表 + +| 框架 | 类型 | 学习曲线 | 文档解析 | 可视化 | 开源 | 适合谁 | +|------|------|---------|---------|-------|:----:|-------| +| LangChain | 代码框架 | 陡 | 需配合 | 无 | 是 | 高度定制化 | +| LlamaIndex | 代码框架 | 中 | 强 | 无 | 是 | 数据索引专精 | +| Haystack | 代码框架 | 中 | 中等 | 无 | 是 | 企业级管道 | +| Dify | 可视化平台 | 低 | 内置 | 有 | 是 | 不写代码 | +| RAGFlow | 可视化平台 | 低 | 最强 | 有 | 是 | 复杂文档 | + +--- + +## 怎么选?看你的需求 + +``` +你会写代码吗? +│ +├── 不想写代码 +│ ├── 文档比较简单 → Dify +│ └── 文档很复杂(表格/扫描件/公式)→ RAGFlow +│ +├── 愿意写代码 +│ ├── 主要是「让 LLM 读我的数据」→ LlamaIndex +│ ├── 需要 RAG + Agent + 复杂工作流 → LangChain / LangGraph +│ ├── 企业级,要跟现有基础设施集成 → Haystack +│ └── 快速原型验证 → LlamaIndex(最简单) +│ +└── 先不写代码,后面再转代码 + └── Dify(可视化搭建,导出后可用 API 调用) +``` + +--- + +## 选框架之外的事 + +框架只是工具链的一部分。一个 RAG 系统的效果,更多取决于: + +1. **文档切分质量**:切太大,检索不精确;切太小,上下文碎了。详见 [文档切分](../rag/chunking.md)。 +2. **Embedding 模型选择**:中文场景推荐 `text-embedding-3-small` 或 `bge-m3`。详见 [向量化](../rag/vectorization.md)。 +3. **检索策略**:纯向量、纯关键词、还是混合?详见 [检索](../rag/retrieval.md)。 +4. **重排**:初步检索后用 Reranker 精排,效果提升明显。详见 [重排](../rag/rerank.md)。 +5. **Prompt 设计**:怎么把检索结果喂给 LLM,直接影响答案质量。详见 [生成](../rag/generation.md)。 + +框架帮你把这些串起来,但每个环节的调优还得靠你自己。 + +--- + +## 学习路径建议 + +### 零基础入门 + +1. 先读 [RAG 总览](../rag/index.md),搞清楚 RAG 的原理 +2. 用 Dify 搭一个可视化的 RAG 应用,感受全流程 +3. 再回头学每个环节的细节 + +### 有编程基础 + +1. 用 LlamaIndex 跑一个最小示例(10 行代码) +2. 逐步加入重排、混合检索等优化 +3. 需要复杂流程时转 LangChain / LangGraph + +### 企业级落地 + +1. 评估文档类型,选 Haystack 或 RAGFlow +2. 先做 MVP,验证效果 +3. 逐步加监控(LangSmith)、评测(RAGAS) + +--- + +## 常见误区 + +??? warning "误区 1:框架选好了效果就好了" + 框架只是胶水,把各个环节粘起来。真正决定效果的是文档切分、Embedding 模型、检索策略、Prompt 设计这些具体环节。 + +??? warning "误区 2:一定要用最火的框架" + LangChain 社区最大,但简单场景用它反而增加复杂度。LlamaIndex 在数据索引上更专注,Dify 在可视化上更方便。选适合你的,别选最火的。 + +??? warning "误区 3:RAG 能解决模型不知道的一切" + 如果知识库里压根没有相关信息,RAG 也帮不了你。RAG 解决的是「库里有,但模型找不到」的问题。 + +??? warning "误区 4:搭建好了就不用管了" + RAG 系统需要持续维护。文档更新了要重新索引,检索效果下降要调参数,用户反馈差要排查是哪个环节出了问题。 + +--- -## 建议内容 +## 延伸阅读 -- 框架名称 -- 适用场景 -- 学习成本 -- 示例项目 +- [RAG 总览](../rag/index.md) —— RAG 的完整原理和流程 +- [文档切分](../rag/chunking.md) —— 切分策略对检索效果的影响 +- [向量化](../rag/vectorization.md) —— Embedding 模型的选择 +- [检索](../rag/retrieval.md) —— 检索策略的对比 +- [重排](../rag/rerank.md) —— Reranker 的作用 +- [Agent 框架](agent-frameworks.md) —— RAG 和 Agent 怎么结合 diff --git a/docs/tools/api.md b/docs/tools/api.md index e5f8e15..fd8ba42 100644 --- a/docs/tools/api.md +++ b/docs/tools/api.md @@ -1,10 +1,329 @@ +--- +tags: + - Tools +--- + # API 入门 -> 占位页:本页内容待团队补充。 +> 你用的每一个 AI 产品背后,都有一扇"门"在等着程序去敲——这扇门就是 API。 + +--- + +## API 到底是什么 + +API,全称 Application Programming Interface,应用程序编程接口。 + +名字很长,但做的事很简单:它是一套**约定好的通信格式**,让两个程序能互相说话。 + +打个比方。你去餐厅吃饭,菜单上写着菜品名和价格,你点菜,服务员把菜端上来。你不需要进厨房自己炒,厨房也不需要知道你是谁——菜单和服务员就是中间那层"接口"。 + +API 做的事完全一样。 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart LR + A["你的程序"] -->|"发请求
(点菜)"| B["API
(服务员)"] + B -->|"返回数据
(端菜)"| A + B --> C["服务器/数据库
(厨房)"] + C --> B +``` + +你写的代码发一个请求过去,API 帮你去服务器上拿数据、做计算、调模型,再把结果打包好送回来。你不需要知道服务器怎么搭的、数据库怎么存的,只需要按 API 的规矩来。 + +## HTTP:API 的快递系统 + +绝大多数 Web API 都跑在 HTTP 协议上。HTTP 你可以理解成"快递系统"——有寄件人、收件人、包裹内容、快递单号。 + +一次 HTTP 请求包含这些部分: + +| 部分 | 说明 | 举例 | +|------|------|------| +| **方法(Method)** | 你想做什么操作 | `GET`(查)、`POST`(发)、`PUT`(改)、`DELETE`(删) | +| **URL(地址)** | 请求发到哪里 | `https://api.example.com/v1/chat` | +| **Headers(快递单)** | 元信息:认证、格式、编码 | `Authorization: Bearer sk-xxx` | +| **Body(包裹内容)** | 实际发送的数据 | `{"model": "gpt-4o", "messages": [...]}` | + +### 四个常用方法 + +| 方法 | 干什么 | 类比 | +|------|--------|------| +| `GET` | 获取数据 | 看菜单 | +| `POST` | 提交数据 | 下单点菜 | +| `PUT` | 更新数据 | 换一道菜 | +| `DELETE` | 删除数据 | 取消订单 | + +用得最多的是 `GET` 和 `POST`。调 AI 模型几乎全是 `POST`——因为你是在往服务器**发送**一段对话内容,让它帮你处理。 + +### 看一个真实的 HTTP 请求 + +```bash +curl https://api.openai.com/v1/chat/completions \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer sk-你的密钥" \ + -d '{ + "model": "gpt-4o", + "messages": [ + {"role": "user", "content": "用一句话解释量子纠缠"} + ] + }' +``` + +拆开看: + +- **URL**:`https://api.openai.com/v1/chat/completions`——OpenAI 聊天补全接口的地址 +- **Header 1**:`Content-Type: application/json`——告诉服务器"我发的是 JSON" +- **Header 2**:`Authorization: Bearer sk-你的密钥`——用 API 密钥证明"我是合法用户" +- **Body**:JSON 格式,告诉模型用哪个版本、对话历史是什么 + +返回的也是 JSON: + +```json +{ + "choices": [ + { + "message": { + "content": "量子纠缠是两个粒子之间的关联,测量其中一个会瞬间影响另一个的状态,无论它们相距多远。" + } + } + ], + "usage": { + "prompt_tokens": 25, + "completion_tokens": 38, + "total_tokens": 63 + } +} +``` + +## REST API:约定俗成的规矩 + +大部分 API 都遵循 REST 风格。REST 不是一种技术,更像一套设计习惯: + +| 原则 | 说明 | +|------|------| +| 用 URL 表示资源 | `/users/123` 表示 ID 为 123 的用户 | +| 用 HTTP 方法表示操作 | `GET /users/123` 是查,`DELETE /users/123` 是删 | +| 无状态 | 每次请求独立,服务器不记住你是谁(认证靠 token) | +| JSON 格式 | 请求和返回都用 JSON | + +REST 的好处是**统一**。你学会了一个 REST API,换一家公司的 API 也大概率能看懂。OpenAI、Anthropic、Google 的 AI API 全部走 REST 风格。 + +## 认证:证明"我是我" + +API 不会随便让陌生人调用——得先验证身份。常见方式有三种: + +### API Key(密钥) + +最简单的方式。注册账号后,平台给你一串密钥,每次请求带上就行。 + +```bash +-H "Authorization: Bearer sk-abc123def456" +``` + +> ⚠️ **API Key 一定要保密。** 泄露了等于把银行卡密码贴在大街上——别人能拿你的额度随便调用,账单算你的。不要把密钥写在代码里提交到 GitHub,用环境变量存。 + +### OAuth 2.0 + +比 API Key 复杂得多,适合"代替用户操作"的场景。比如你做一个第三方应用,想访问用户的 Google Drive 文件,就用 OAuth 让用户授权。 + +流程大致是: + +```mermaid +%%{init: { 'htmlLabels': false } }%% +sequenceDiagram + participant U as 用户 + participant A as 你的应用 + participant G as Google + U->>A: 点击"登录 Google" + A->>G: 跳转授权页面 + U->>G: 同意授权 + G->>A: 返回授权码 + A->>G: 用授权码换 Access Token + G->>A: 返回 Token + A->>G: 用 Token 访问用户数据 +``` + +对于个人开发者调 AI API,用 API Key 就够了,OAuth 主要在做平台型产品时才会碰到。 + +### Bearer Token + +登录后服务器返回一个有时效的 token,后续请求带上这个 token。和 API Key 的区别是它会**过期**,需要定期刷新。 + +```bash +-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." +``` + +## 频率限制和配额 + +API 不会无限让你调——服务器资源有限,得排队。 + +| 限制类型 | 说明 | 例子 | +|----------|------|------| +| **RPM**(每分钟请求数) | 一分钟最多调多少次 | 免费版 3 RPM,付费版 3500 RPM | +| **TPM**(每分钟 token 数) | 一分钟处理多少 token | 40,000 TPM | +| **每天/每月配额** | 总共能用多少 | 每月 100 万 token | + +超了怎么办?服务器会返回 `429 Too Many Requests` 错误。代码里要做好**重试和等待**: + +```python +import time +import requests + +def call_api_with_retry(url, headers, data, max_retries=3): + for attempt in range(max_retries): + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + return response.json() + + if response.status_code == 429: + wait = 2 ** attempt # 指数退避:2秒、4秒、8秒 + print(f"被限流了,等 {wait} 秒后重试...") + time.sleep(wait) + continue + + raise Exception(f"请求失败: {response.status_code}") + + raise Exception("重试次数用完") +``` + +> 💡 **指数退避**是标准做法:第一次等 2 秒,第二次 4 秒,第三次 8 秒。直接死循环重试会把服务器打爆,也更容易被封。 + +## 费用计算:Token 定价 + +AI API 的计费单位是 **token**。 + +Token 不等于字。英文里 1 个 token 大约 4 个字符(`hello` 可能是 1-2 个 token);中文里 1 个字通常 1-2 个 token。 + +2026 年主流模型的大致价格: + +| 模型 | 输入价格(每百万 token) | 输出价格(每百万 token) | +|------|------------------------|------------------------| +| GPT-4o | $2.50 | $10.00 | +| Claude Sonnet | $3.00 | $15.00 | +| DeepSeek V3 | ¥1.00 | ¥2.00 | +| 通义千问 Max | ¥2.00 | ¥6.00 | + +一次普通对话大约消耗 500-2000 token,算下来几毛钱到几块钱。但如果做批量处理(比如读 1000 份文档),费用会快速累积。 + +> 💡 **省钱小技巧**:上下文越短,token 越少。别把整个文档一股脑丢进去,先提炼关键信息再发给 API。选择便宜的模型处理简单任务,贵的模型只用来处理复杂任务。 + +## Python 代码示例 + +用 Python 的 `requests` 库调 OpenAI API,总共不到 30 行: + +```python +import requests +import os + +# 从环境变量读取密钥,不要硬编码 +api_key = os.environ.get("OPENAI_API_KEY") + +url = "https://api.openai.com/v1/chat/completions" +headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {api_key}" +} +data = { + "model": "gpt-4o", + "messages": [ + {"role": "system", "content": "你是一个友好的助手。"}, + {"role": "user", "content": "用三句话介绍一下自己"} + ], + "temperature": 0.7 +} + +response = requests.post(url, headers=headers, json=data) +result = response.json() + +print(result["choices"][0]["message"]["content"]) +print(f"消耗 token: {result['usage']['total_tokens']}") +``` + +> ⚠️ **把密钥放在环境变量里**,别写在源代码里。`.env` 文件加到 `.gitignore`,这是基本安全习惯。 + +## 错误码:听懂服务器在说什么 + +请求不可能每次都成功。学会看错误码,才能知道哪里出了问题。 + +| 状态码 | 含义 | 常见原因 | +|--------|------|----------| +| `200` | 成功 | 一切正常 | +| `400` | 请求格式错 | JSON 写错了、缺了必填字段 | +| `401` | 认证失败 | API Key 无效或过期 | +| `403` | 权限不足 | 没有访问这个模型/功能的权限 | +| `404` | 地址不存在 | URL 拼错了 | +| `429` | 请求太多 | 超出频率限制 | +| `500` | 服务器内部错误 | 对方服务器出了 bug | +| `503` | 服务不可用 | 服务器过载或维护中 | + +处理错误的标准姿势: + +```python +def call_api(url, headers, data): + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + return response.json() + + error_info = response.json().get("error", {}) + error_code = response.status_code + error_msg = error_info.get("message", "未知错误") + + if error_code == 401: + print("API Key 有问题,检查一下是不是过期了") + elif error_code == 429: + print("调太快了,等一会儿再试") + elif error_code >= 500: + print("服务器挂了,稍后再试") + else: + print(f"请求失败 [{error_code}]: {error_msg}") + + return None +``` + +## 常见误区 + +### 误区一:API Key 可以写在前端代码里 + +绝对不行。前端代码用户能看到,Key 一暴露就等于裸奔。正确做法是:前端请求你自己的后端,后端再调 API。 + +### 误区二:返回 200 就万事大吉 + +HTTP 状态码 200 只代表"请求成功送达",不代表业务逻辑没问题。还要检查返回的 JSON 里有没有 `error` 字段。 + +### 误区三:调一次就够了 + +生产环境必须考虑重试。网络抖动、服务器瞬时过载都会导致偶发失败,不加重试就是在赌运气。 + +### 误区四:所有 API 长得都一样 + +不同厂商的 API 格式差异不小。OpenAI 用 `messages` 数组,Anthropic 用 `content` 字段,Google 又是另一套。换模型时要仔细看文档,别想当然。 + +--- + +## 延伸阅读 + +- [函数调用与工具调用](tool-calling.md) —— 在 API 基础上,让模型调用外部工具 +- [本地与在线模型的差异](local-vs-online.md) —— API 调用和本地部署的取舍 +- [OpenAI API 文档](https://platform.openai.com/docs/api-reference) —— 最全的 REST API 参考 +- [Anthropic API 文档](https://docs.anthropic.com/en/api/getting-started) —— Claude 的 API 接口说明 + +## 练习题 + +### 练习一:用 curl 调一次 API + +找一个提供免费额度的 AI API(如 DeepSeek),用 curl 命令发一个请求,问它"今天星期几"。观察返回的 JSON 结构。 + +> 💡 **提示**:DeepSeek 的接口兼容 OpenAI 格式,地址换成 `https://api.deepseek.com/v1/chat/completions` 就行。 + +### 练习二:写一个带重试的 Python 脚本 + +基于上面的代码,加上指数退避重试逻辑。故意用一个错误的 API Key 测试 401 错误处理,故意快速连续请求测试 429 错误处理。 + +### 练习三:计算费用 + +假设你有一个 5000 字的文档要让 AI 总结,输入大约 6000 token,输出大约 500 token。用 DeepSeek V3 的价格算一下这次调用花多少钱。如果每天处理 100 份这样的文档,一个月费用是多少? -## 建议内容 +### 练习四:对比两个 API -- API 是什么 -- 调用流程 -- 鉴权与费用 -- 最小示例 +分别用 curl 调用 OpenAI 和 DeepSeek 的 API(都兼容 OpenAI 格式),对比它们的请求格式、返回结构、响应速度有什么不同。 diff --git a/docs/tools/local-vs-online.md b/docs/tools/local-vs-online.md index 6211c0c..d1dd5c1 100644 --- a/docs/tools/local-vs-online.md +++ b/docs/tools/local-vs-online.md @@ -1,10 +1,287 @@ +--- +tags: + - Tools +--- + # 本地与在线模型的差异 -> 占位页:本页内容待团队补充。 +> 用别人的服务器跑模型,还是自己买显卡跑?这笔账得好好算。 + +--- + +## 两种部署方式 + +用 AI 模型,本质上就两条路: + +| 方式 | 说明 | 典型代表 | +|------|------|----------| +| **在线模型(API 调用)** | 把请求发到别人的服务器,结果传回来 | OpenAI API、DeepSeek API、通义千问 API | +| **本地模型** | 在自己的电脑或服务器上运行模型 | Ollama + LLaMA、vLLM + Qwen、llama.cpp | + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart LR + subgraph 在线模型 + A["你的程序"] -->|"HTTP 请求"| B["云端服务器
(厂商提供)"] + B -->|"返回结果"| A + end + + subgraph 本地模型 + C["你的程序"] -->|"本地调用"| D["你的电脑/服务器
(自己维护)"] + D -->|"返回结果"| C + end +``` + +在线模型像用自来水——打开水龙头就有,按用量付费。本地模型像自己打井——前期投入大,但水是自己的,想用多少用多少。 + +## 成本:月租 vs 买断 + +这是大家最关心的问题。两种方式的钱花在完全不同的地方。 + +### 在线模型的成本结构 + +| 花费项 | 说明 | +|--------|------| +| API 调用费 | 按 token 计费,用多少付多少 | +| 无前期投入 | 不用买显卡、不用租服务器 | +| 弹性伸缩 | 用得多就多花,用得少就少花 | + +一个月偶尔用几次,费用可能只有几块钱。但如果每天处理几万次请求,费用会迅速攀升。 + +### 本地模型的成本结构 + +| 花费项 | 说明 | +|--------|------| +| 硬件购置 | 显卡(GPU)是大头,一张 RTX 4090 大约 ¥15,000 | +| 电费 | 一张 4090 满载大约 450W,24 小时跑一个月电费约 ¥300-500 | +| 维护成本 | 系统配置、模型更新、故障排查,都是时间成本 | +| 网络带宽 | 如果对外提供服务,带宽也得花钱 | + +### 临界点在哪 + +粗略估算一下: + +| 场景 | 在线费用(月) | 本地费用(月) | 哪个划算 | +|------|---------------|---------------|----------| +| 偶尔用用(每天 50 次请求) | ¥30-50 | ¥500+(硬件折旧 + 电费) | 在线 | +| 中等用量(每天 500 次) | ¥300-500 | ¥500+ | 差不多 | +| 大量使用(每天 5000 次) | ¥3000-5000 | ¥500+ | 本地 | +| 7×24 不间断服务 | ¥10000+ | ¥500+ | 本地 | + +> 💡 **简单判断**:一个月 API 费用超过一张显卡的月供(按 24 个月折旧),就该考虑本地部署了。 + +## 隐私与数据主权 + +这是很多企业选择本地部署的首要原因。 + +### 在线模型的数据风险 + +你发给 API 的每一条消息,都会经过厂商的服务器。虽然大多数厂商承诺不会用你的数据训练模型,但: + +| 风险点 | 说明 | +|--------|------| +| 数据传输 | 数据在网络上经过多个节点 | +| 服务器存储 | 厂商可能临时存储日志 | +| 合规问题 | 某些行业(金融、医疗、政务)不允许数据出境 | +| 厂商倒闭 | 服务商关停了,你的数据怎么办 | + +### 本地模型的隐私优势 + +数据全程不出你的机器。对话内容、文档资料、客户信息,都在你自己的硬盘上。 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TD + A["用户输入"] --> B{"选择部署方式"} + B -->|"在线 API"| C["数据发送到云端
经过互联网"] + B -->|"本地模型"| D["数据留在本机
不经过网络"] + C --> E["厂商服务器处理"] + D --> F["本地 GPU 处理"] +``` + +> ⚠️ **不是说本地就绝对安全**。本地机器也可能被入侵、被共享、被偷。安全是个系统工程,部署方式只是其中一环。 + +## 延迟:网络 vs 算力 + +延迟指的是从你发出请求到收到回答的等待时间。 + +### 在线模型的延迟来源 + +| 环节 | 耗时 | +|------|------| +| 网络传输 | 50-200ms(取决于你的网络和服务器距离) | +| 排队等待 | 0ms-几秒(高峰期可能排队) | +| 模型推理 | 100ms-数秒(取决于模型大小和输出长度) | +| 总计 | 200ms-数秒 | + +### 本地模型的延迟来源 + +| 环节 | 耗时 | +|------|------| +| 网络传输 | ≈0ms(本地调用) | +| 排队等待 | ≈0ms(独占资源) | +| 模型推理 | 取决于你的硬件 | + +| 硬件 | 跑 7B 模型 | 跑 70B 模型 | +|------|-----------|------------| +| RTX 4090(24GB) | 很快,几乎无感 | 能跑,但慢不少 | +| RTX 3060(12GB) | 够用 | 内存不够,得量化 | +| M2 MacBook(16GB) | 尚可 | 勉强能跑量化版 | +| 纯 CPU(无 GPU) | 慢,但能用 | 极慢,不推荐 | + +> 💡 **本地模型的延迟可预测**——不受网络波动和高峰期影响。做实时性要求高的应用(如代码补全),本地模型的稳定性反而是优势。 + +## 模型质量:能力天花板 + +这是本地模型目前最大的短板。 + +### 在线模型的优势 + +| 维度 | 说明 | +|------|------| +| 模型规模 | 顶级模型动辄几百 B 参数,单卡跑不了 | +| 持续更新 | 厂商定期升级模型,你不用做任何事 | +| 专业优化 | 经过大规模 RLHF 和安全对齐 | +| 多模态 | 图片、音频、视频处理能力更强 | + +### 本地模型的优势 + +| 维度 | 说明 | +|------|------| +| 可定制 | 可以微调(Fine-tune)适配你的业务场景 | +| 可控性 | 输出格式、行为模式完全由你掌控 | +| 无审查限制 | 某些特殊场景(如安全研究)可以放宽限制 | +| 开源生态 | LLaMA、Qwen、Mistral 等开源模型质量在快速提升 | + +### 质量差距在缩小 + +2024 年,本地跑 70B 模型的效果大约相当于 2023 年初的 GPT-4。到了 2026 年,开源的 Qwen3-72B、LLaMA 4 等模型在很多任务上已经接近甚至追平闭源模型。 + +但"接近"和"达到"之间,对生产环境来说差距仍然存在。 + +## 怎么选:一张决策表 + +| 你的情况 | 推荐方案 | 理由 | +|----------|----------|------| +| 刚开始学 AI,想快速体验 | 在线 API | 零门槛,注册就能用 | +| 做个人项目,用量不大 | 在线 API | 省事省钱 | +| 处理敏感数据(医疗/金融/政务) | 本地部署 | 数据不能出内网 | +| 需要 7×24 高频调用 | 本地部署 | 成本可控,无网络依赖 | +| 需要微调模型适配业务 | 本地部署 | 在线 API 一般不支持深度微调 | +| 需要最强模型能力 | 在线 API | 顶级模型单卡跑不动 | +| 预算有限,硬件一般 | 在线 API | 别勉强,先用 API 起步 | +| 做安全研究/CTF | 本地部署 | 需要不受限的模型 | + +## 混合方案:两全其美 + +很多团队最终选择的是混合部署——简单任务用本地模型,复杂任务调在线 API。 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TD + A["收到任务"] --> B{"任务复杂度"} + B -->|"简单任务
分类/提取/格式化"| C["本地小模型
(7B-14B)"] + B -->|"复杂任务
写作/推理/代码"| D["在线大模型
(GPT-4o/Claude)"] + C --> E["返回结果"] + D --> E +``` + +| 任务类型 | 用什么 | 理由 | +|----------|--------|------| +| 文本分类 | 本地 7B 模型 | 简单任务,小模型够用 | +| 关键词提取 | 本地 7B 模型 | 不需要复杂推理 | +| 长文写作 | Claude / GPT-4o | 需要强语言能力 | +| 数学推理 | DeepSeek R1 | 推理能力需要大模型 | +| 代码生成 | Claude Sonnet | 代码质量需要大模型 | +| 数据脱敏 | 本地模型 | 敏感数据不能外传 | + +> 💡 **省钱策略**:80% 的简单请求用本地模型处理,20% 的复杂请求调在线 API。这样既保证了质量,又把费用压下来了。 + +## 本地部署快速上手 + +如果你想试试本地跑模型,最简单的方式是用 **Ollama**: + +```bash +# 安装 Ollama(macOS / Linux) +curl -fsSL https://ollama.ai/install.sh | sh + +# 下载并运行一个 7B 模型 +ollama run qwen2.5:7b + +# 用 API 方式调用(兼容 OpenAI 格式) +curl http://localhost:11434/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{ + "model": "qwen2.5:7b", + "messages": [{"role": "user", "content": "你好"}] + }' +``` + +Ollama 的好处是:一条命令装好,一条命令跑模型,API 兼容 OpenAI 格式。写代码时把 `base_url` 换成本地地址就行,其他不用改。 + +```python +from openai import OpenAI + +# 本地 Ollama +client = OpenAI( + base_url="http://localhost:11434/v1", + api_key="ollama" # 随便填,本地不需要真的密钥 +) + +response = client.chat.completions.create( + model="qwen2.5:7b", + messages=[{"role": "user", "content": "用一句话解释量子力学"}] +) +print(response.choices[0].message.content) +``` + +## 常见误区 + +### 误区一:本地一定比在线便宜 + +如果用量很小,在线 API 可能一个月只花几块钱,而一张显卡就要上万。先算账再决定。 + +### 误区二:本地模型质量不行 + +2026 年的开源模型已经很强了。Qwen3-72B 在很多任务上接近 GPT-4 水平。关键是选对模型、配好参数。 + +### 误区三:买了显卡就能跑大模型 + +显存是硬限制。70B 模型全精度需要 140GB+ 显存,单卡跑不了。得用量化(4-bit、8-bit)降低显存需求,但会损失一些精度。 + +### 误区四:在线 API 一定更快 + +高峰期排队、网络抖动、限流都会影响速度。本地模型的延迟反而更稳定可预测。 + +--- + +## 延伸阅读 + +- [API 入门](api.md) —— 在线模型调用的基础知识 +- [模型这么多,我选哪个?](model-selection.md) —— 不同模型的能力对比 +- [本地模型部署](../build/local-models.md) —— 更详细的本地部署教程 +- [Ollama 官方文档](https://ollama.ai/) —— 最简单的本地模型运行工具 + +## 练习题 + +### 练习一:算一笔账 + +假设你每天用 AI 处理 200 次请求,每次平均 2000 token(输入 1500 + 输出 500)。分别用 DeepSeek V3(¥1/¥2 每百万 token)和本地 RTX 4090(¥15000,按 24 个月折旧 + ¥400/月电费)计算月度总成本。哪个划算? + +### 练习二:用 Ollama 跑本地模型 + +安装 Ollama,下载 `qwen2.5:7b` 模型,用 curl 发一个 API 请求。对比一下和在线 API 的响应速度差异。 + +### 练习三:设计混合方案 + +你正在做一个客服机器人,需要处理以下任务: + +1. 判断用户问题属于哪个类别(售前/售后/投诉/其他) +2. 回答常见问题 +3. 处理复杂投诉(需要生成有温度的长回复) + +请设计一个混合方案:哪些任务用本地模型,哪些用在线 API,写出理由。 -## 建议内容 +### 练习四:隐私风险评估 -- 部署方式 -- 成本差异 -- 隐私与延迟 -- 选择建议 +列出你日常使用 AI 的 5 个场景(如写邮件、总结文档、翻译、写代码、聊天),评估每个场景涉及的数据敏感度,判断适合用在线模型还是本地模型。 diff --git a/docs/tools/tool-calling.md b/docs/tools/tool-calling.md index a63b565..9c4f563 100644 --- a/docs/tools/tool-calling.md +++ b/docs/tools/tool-calling.md @@ -1,10 +1,410 @@ +--- +tags: + - Tools +--- + # 函数调用与工具调用 -> 占位页:本页内容待团队补充。 +> AI 只能聊天?给它接上手和脚,它就能帮你干活了。 + +--- + +## 为什么需要工具调用 + +大语言模型再聪明,也有一道过不去的坎:**它只能处理文字**。 + +你问它"今天北京天气怎么样",它会根据训练数据猜一个答案,但猜的不一定准。你让它帮你发一封邮件,它只能写出邮件内容,真的发不出去。 + +问题出在哪?模型被关在"文字世界"里,和现实世界之间隔着一堵墙。 + +工具调用(Tool Calling)就是墙上开的那扇门。 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart LR + A["用户提问"] --> B["大语言模型"] + B -->|"只能聊天"| C["回答(可能不准)"] + B -->|"能调工具"| D["查天气 API"] + D --> E["真实天气数据"] + E --> B + B --> F["准确回答"] +``` + +有了工具调用,模型就从"只能动嘴"变成了"能动手"。它能查数据库、调 API、读文件、执行代码、操作浏览器——只要你在背后接上对应的工具。 + +## 工具调用的基本原理 + +工具调用的核心思路很简单:**你告诉模型有哪些工具可用,模型决定用哪个、怎么用。** + +整个流程分三步: + +```mermaid +%%{init: { 'htmlLabels': false } }%% +sequenceDiagram + participant U as 用户 + participant M as 大语言模型 + participant T as 工具 + U->>M: "北京今天穿什么合适?" + M->>M: 分析:需要查天气 + M->>T: 调用 get_weather(city="北京") + T-->>M: 晴,15°C,微风 + M->>U: "今天北京晴天,15度左右,穿个薄外套就行。" +``` + +1. **定义工具**——你写一份"工具说明书",告诉模型有哪些工具、每个工具做什么、需要什么参数 +2. **模型决策**——模型收到用户问题后,判断需不需要调工具,调哪个,传什么参数 +3. **执行并回复**——你的代码执行工具,把结果喂回模型,模型组织最终回答 + +关键点:**模型只负责"决定调什么"和"组织回答",真正的执行靠你的代码。** + +## OpenAI 函数调用格式 + +以 OpenAI 为例,工具用 JSON Schema 描述。你把工具定义和用户消息一起发给 API: + +```python +import openai + +tools = [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "查询指定城市的当前天气信息", + "parameters": { + "type": "object", + "properties": { + "city": { + "type": "string", + "description": "城市名称,如「北京」「上海」" + } + }, + "required": ["city"] + } + } + } +] + +response = openai.chat.completions.create( + model="gpt-4o", + messages=[ + {"role": "user", "content": "北京今天天气怎么样?"} + ], + tools=tools, + tool_choice="auto" +) +``` + +模型这次返回的内容跟平时不一样——它回的是一个**工具调用请求**: + +```json +{ + "choices": [ + { + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": "call_abc123", + "type": "function", + "function": { + "name": "get_weather", + "arguments": "{\"city\": \"北京\"}" + } + } + ] + } + } + ] +} +``` + +注意看,模型没有直接回答问题,而是说:"我要调用 `get_weather` 这个工具,参数是 `city: 北京`。" + +你的代码收到这个请求后,去执行真正的天气查询,再把结果发回给模型: + +```python +# 模拟天气查询函数 +def get_weather(city): + data = {"北京": "晴,15°C,微风", "上海": "多云,20°C"} + return data.get(city, "未找到该城市天气") + +# 模型返回了 tool_calls,执行工具 +message = response.choices[0].message +if message.tool_calls: + tool_call = message.tool_calls[0] + city = eval(tool_call.function.arguments)["city"] + weather_result = get_weather(city) + + # 把工具结果发回模型 + messages = [ + {"role": "user", "content": "北京今天天气怎么样?"}, + message, # assistant 的工具调用消息 + { + "role": "tool", + "tool_call_id": tool_call.id, + "content": weather_result + } + ] + + # 模型根据工具结果组织最终回答 + final = openai.chat.completions.create( + model="gpt-4o", + messages=messages, + tools=tools + ) + print(final.choices[0].message.content) +``` + +## 模型怎么决定要不要调工具 + +模型并不是每次都会调工具。它根据**用户的问题**和**工具的描述**来判断。 + +工具的 `description` 字段非常关键——写得好,模型就知道什么时候该用;写得差,模型可能乱调或者不调。 + +| 工具描述 | 效果 | +|----------|------| +| `"处理数据"` | 太模糊,模型不知道这个工具能干啥 | +| `"查询指定城市的实时天气,返回温度、湿度和风力"` | 清楚,模型知道什么时候该调 | + +`tool_choice` 参数可以进一步控制调用策略: + +| 值 | 行为 | 适用场景 | +|---|------|---------| +| `auto` | 模型自己决定 | 通用场景 | +| `none` | 强制不调工具 | 纯聊天测试 | +| `required` | 强制调一次工具 | 必须查数据的场景 | +| `{"type":"function","function":{"name":"xxx"}}` | 强制调指定工具 | 明确知道该用哪个 | + +## 定义好工具的诀窍 + +工具定义的质量直接决定调用效果。几条实用经验: + +### 命名要自解释 + +```python +# ❌ 模糊的名字 +"name": "process" + +# ✅ 一看就知道干嘛的 +"name": "search_user_by_email" +``` + +### 描述要说清边界 + +```python +"description": "根据邮箱地址查询用户信息。只能查单个用户,批量查询请用 batch_search。返回用户ID、姓名和注册时间。" +``` + +模型需要知道这个工具**能做什么**和**不能做什么**,才不会乱用。 + +### 参数类型要严格 + +```python +# ❌ 全是 string,模型可能传错格式 +"properties": { + "age": {"type": "string"}, + "count": {"type": "string"} +} + +# ✅ 用正确的类型 +"properties": { + "age": {"type": "integer", "minimum": 0, "maximum": 150}, + "count": {"type": "integer", "minimum": 1} +} +``` + +### 用 enum 限制选项 + +```python +"unit": { + "type": "string", + "enum": ["celsius", "fahrenheit"], + "description": "温度单位" +} +``` + +`enum` 能大幅减少模型传入无效值的概率。 + +## 处理工具的返回结果 + +工具执行完后,要把结果喂回模型。返回格式有几个讲究: + +```python +# ❌ 返回太长,浪费 token +def search_products(query): + return json.dumps(entire_database) # 返回了几万行 + +# ✅ 返回精简结果 +def search_products(query): + results = db.search(query, limit=5) # 只返回最相关的 5 条 + return json.dumps({ + "count": len(results), + "items": [{"name": r.name, "price": r.price} for r in results] + }) +``` + +```python +# ❌ 出错了不告诉模型 +def get_user(user_id): + if not found: + return "error" # 模型不知道什么错、怎么补救 + +# ✅ 错误信息要具体 +def get_user(user_id): + if not found: + return json.dumps({ + "status": "error", + "message": f"用户 {user_id} 不存在,请检查ID是否正确" + }) +``` + +> 💡 **经验法则**:返回给模型的结果尽量精简、结构化。模型处理 100 字的结果比处理 10000 字的结果准确得多。 + +## 多步工具链 + +很多任务需要调好几次工具才能搞定。模型可能需要先查天气、再查航班、最后帮你订票——这就是**工具链**。 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TD + A["用户:帮我查北京到上海的航班,挑个天气好的日子"] --> B["调用 get_weather
查北京和上海未来几天天气"] + B --> C["调用 search_flights
查航班信息"] + C --> D["模型综合天气和航班
给出推荐"] +``` + +用代码实现时,需要在一个循环里处理: + +```python +messages = [{"role": "user", "content": "帮我查北京到上海的航班,挑个天气好的日子"}] + +for _ in range(5): # 最多循环 5 次,防止死循环 + response = openai.chat.completions.create( + model="gpt-4o", + messages=messages, + tools=all_tools + ) + + message = response.choices[0].message + + if not message.tool_calls: + # 模型给最终回答了 + print(message.content) + break + + # 执行所有工具调用 + messages.append(message) + for tool_call in message.tool_calls: + result = execute_tool(tool_call) + messages.append({ + "role": "tool", + "tool_call_id": tool_call.id, + "content": result + }) +``` + +模型会自动判断什么时候该继续调工具、什么时候该给最终回答。你只需要搭好循环框架。 + +## 安全边界 + +工具调用把模型和真实世界连起来了,安全性就成了头等大事。 + +### 最小权限原则 + +只给模型它**需要**的工具。查天气的场景,别把发邮件、删文件的工具也塞进去。 + +```python +# 天气查询场景 +tools = [get_weather] # 只给这一个工具 + +# 别这样做 +tools = [get_weather, send_email, delete_file, transfer_money] # 太多了 +``` + +### 高风险操作要确认 + +涉及金钱、删除、发送的操作,让人类确认后再执行: + +```python +HIGH_RISK = {"send_email", "delete_file", "transfer_money"} + +def execute_tool(tool_call): + name = tool_call.function.name + + if name in HIGH_RISK: + args = tool_call.function.arguments + confirm = input(f"模型要执行 {name}({args}),确认吗?(y/n)") + if confirm != "y": + return "用户拒绝执行此操作" + + return tool_registry[name](**json.loads(tool_call.function.arguments)) +``` + +### 验证模型传入的参数 + +别盲目信任模型传的参数。模型可能传错格式、传越界的值,甚至被提示词注入诱导传恶意参数。 + +```python +def execute_search(tool_call): + args = json.loads(tool_call.function.arguments) + query = args.get("query", "") + + # 验证:防止 SQL 注入 + if any(char in query for char in [";", "--", "DROP", "DELETE"]): + return "查询包含非法字符" + + return db.safe_search(query) +``` + +> ⚠️ **把模型当实习生**:它很聪明,但你需要检查它交上来的东西。特别是它传给工具的参数,要在执行前做校验。 + +## 常见坑 + +### 工具描述写得太烂 + +模型全靠 `description` 判断要不要用这个工具。写"处理数据"等于没写。要写清楚:这个工具做什么、输入什么、输出什么、什么时候该用。 + +### 返回结果太长 + +工具返回了一万行 JSON,模型的上下文窗口被塞满了,后面的回答质量会暴跌。做好筛选和截断。 + +### 没有处理"模型决定不调工具"的情况 + +`tool_choice: auto` 时,模型有时候会选择不调工具直接回答。你的代码要有兜底逻辑。 + +### 死循环 + +多步工具链没有设置最大循环次数,模型可能一直调工具停不下来。加个上限。 + +--- + +## 延伸阅读 + +- [Agent 工具调用详解](../agent/tool-use.md) —— 从 Agent 视角看工具调用的更多细节 +- [API 入门](api.md) —— 工具调用的基础:HTTP 和 API +- [OpenAI Function Calling 文档](https://platform.openai.com/docs/guides/function-calling) +- [Anthropic Tool Use 文档](https://docs.anthropic.com/en/docs/build-with-claude/tool-use) + +## 练习题 + +### 练习一:设计三个工具 + +假设你要做一个"旅行助手",帮用户规划行程。请用 JSON Schema 定义至少 3 个工具(查天气、查航班、查酒店),写清楚每个工具的 name、description 和 parameters。 + +### 练习二:实现一个完整调用 + +基于 OpenAI 的函数调用格式,实现一个"计算器工具"。模型收到数学题后调用计算器工具计算,再把结果返回给用户。测试以下输入: + +- "帮我算一下 123 * 456 + 789" +- "圆的半径是 5,面积是多少?" + +### 练习三:处理错误场景 + +在练习二的基础上,故意让工具返回错误(比如除以零),观察模型怎么处理。然后优化你的错误返回信息,让模型能给用户一个合理的解释。 + +### 练习四:多工具协作 + +设计两个工具——`get_exchange_rate`(查汇率)和 `convert_currency`(货币转换),实现一个对话: -## 建议内容 +> 用户:"我有 1000 美元,换成人民币大概是多少?" -- 这是什么 -- 为什么需要 -- 最小例子 -- 安全边界 +观察模型是否会先查汇率再做转换。 diff --git a/docs/tools/workflow.md b/docs/tools/workflow.md index 2bd7fcc..2327e97 100644 --- a/docs/tools/workflow.md +++ b/docs/tools/workflow.md @@ -1,10 +1,308 @@ +--- +tags: + - Tools +--- + # Chat、Copilot、Agent 与 Workflow -> 占位页:本页内容待团队补充。 +> 同样是用 AI,有人在聊天框里打字,有人让 AI 自己干活。这四种模式搞清楚,才知道该选哪个。 + +--- + +## 一句话区分 + +先给个直觉: + +| 模式 | 一句话 | 谁在主导 | +|------|--------|----------| +| **Chat** | 你问 AI 答 | 你主导 | +| **Copilot** | AI 在你旁边随时帮忙 | 你主导,AI 辅助 | +| **Agent** | 你给目标,AI 自己想办法 | AI 主导 | +| **Workflow** | 按预设流程自动跑 | 流程主导 | + +这四种模式完全可以共存,它们更像一个光谱——从"人控制一切"到"AI 控制一切",中间有很多灰色地带。 + +## Chat:你问我答 + +Chat 就是你在 ChatGPT、DeepSeek、Kimi 的对话框里做的事情。你打一段话,AI 回一段话。 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart LR + A["你:解释一下
什么是递归"] --> B["AI:递归就是
函数调用自己..."] + B --> C["你:能举个例子吗?"] + C --> D["AI:比如计算阶乘..."] +``` + +**特点**: + +- 每次对话都是独立的"回合制" +- 你需要主动提问、追问、引导 +- AI 只回答,不会自己去做事 +- 上下文靠你维护(贴代码、贴文档、说背景) + +**适合的场景**: + +| 场景 | 例子 | +|------|------| +| 学习新知识 | "用简单的话解释一下 Docker" | +| 写作辅助 | "帮我润色这段邮件" | +| 代码调试 | "这个报错是什么意思?" | +| 头脑风暴 | "帮我想 10 个产品名字" | + +**局限**:复杂任务需要你一步步拆解、一步步问。你得自己当"项目经理",AI 只是"顾问"。 + +## Copilot:贴身助手 + +Copilot 的意思是"副驾驶"。它不像 Chat 那样等你提问,而是**嵌入到你的工作流里**,在你需要的时候主动出现。 + +典型代表:GitHub Copilot、Cursor、Windsurf。 + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TD + A["你在写代码"] --> B["写了函数名
def calculate_tax"] + B --> C["Copilot 自动补全
函数体"] + C --> D["你检查、修改、确认"] + D --> E["继续写下一行"] +``` + +**和 Chat 的区别**: + +| 维度 | Chat | Copilot | +|------|------|---------| +| 触发方式 | 你主动提问 | 自动感知上下文,主动建议 | +| 交互方式 | 对话框 | 嵌入编辑器/IDE | +| 工作流 | 中断你的工作去问问题 | 不打断你的工作节奏 | +| 上下文 | 你手动提供 | 自动读取当前文件、项目结构 | + +**典型产品和用法**: + +| 产品 | 干什么 | 怎么用 | +|------|--------|--------| +| GitHub Copilot | 代码补全 | 写几行代码,它帮你补后面几十行 | +| Cursor | AI 编辑器 | 内置 Chat + Copilot,支持整个项目级别的 AI 辅助 | +| Copilot for Microsoft 365 | 办公助手 | 在 Word、Excel、PowerPoint 里帮你写、改、分析 | +| GitHub Copilot Chat | 代码对话 | 在 IDE 里直接问代码问题,不用切到浏览器 | + +**适合的场景**: + +- 写代码时自动补全重复逻辑 +- 写文档时自动续写段落 +- 做表格时自动写公式 +- 处理邮件时自动草拟回复 + +> 💡 **Copilot 的核心价值**:减少"机械性工作"。那些你知道该写什么、但写起来很烦的代码/文字,交给它。 + +## Agent:自主干活 + +Agent 是目前 AI 领域最热的概念。它和 Chat、Copilot 最大的区别是:**你给目标,它自己规划怎么做。** + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TD + A["你:帮我做一个
竞品分析报告"] --> B["Agent 自己规划"] + B --> C["搜索竞品信息"] + C --> D["整理数据"] + D --> E["生成报告"] + E --> F["检查质量"] + F -->|"不满意"| C + F -->|"满意"| G["交付报告"] +``` + +**Agent 的核心能力**: + +| 能力 | 说明 | +|------|------| +| **规划** | 把大任务拆成小步骤 | +| **工具调用** | 调用搜索引擎、API、代码执行器等工具 | +| **反思** | 检查自己的输出,发现错误就重来 | +| **记忆** | 记住之前做过什么,保持上下文 | + +**和 Chat / Copilot 的区别**: + +| 维度 | Chat | Copilot | Agent | +|------|------|---------|-------| +| 自主性 | 低,等你指令 | 中,主动建议 | 高,自己规划 | +| 任务范围 | 单轮问答 | 当前行/段 | 多步骤复杂任务 | +| 工具使用 | 一般不用 | 嵌入当前工具 | 可以调用多种外部工具 | +| 出错处理 | 等你追问 | 等你修改 | 自己发现并修正 | + +**现实中的 Agent 应用**: + +| 场景 | Agent 做什么 | +|------|-------------| +| 代码开发 | 接到需求,自己写代码、跑测试、修 bug | +| 数据分析 | 拿到数据集,自己清洗、分析、出图表、写报告 | +| 信息调研 | 给一个主题,自己搜索、阅读、整理、总结 | +| 客服处理 | 接到工单,自己查知识库、查订单、回复客户 | + +> ⚠️ **Agent 目前还不太靠谱。** 它可能走错方向、调错工具、卡在死循环里。完全放手让 Agent 干活,出错率还不低。现阶段最好的用法是"人机协作"——Agent 做初步工作,人做最终审核。 + +## Workflow:预设流程 + +Workflow 和 Agent 看起来很像,但有一个根本区别:**流程是人预先设计好的,Agent 只是执行者。** + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart TD + A["触发:收到新邮件"] --> B["步骤1:AI 提取邮件摘要"] + B --> C["步骤2:判断类别"] + C -->|"紧急"| D["步骤3:发送通知给负责人"] + C -->|"普通"| E["步骤3:归档到对应文件夹"] + D --> F["步骤4:记录日志"] + E --> F +``` + +**和 Agent 的区别**: + +| 维度 | Agent | Workflow | +|------|-------|----------| +| 流程设计 | AI 自己规划 | 人预先设计 | +| 灵活性 | 高,随机应变 | 低,按固定路线走 | +| 可预测性 | 低,每次可能不同 | 高,结果稳定 | +| 适用场景 | 探索性任务 | 重复性任务 | +| 调试难度 | 高 | 低 | + +**Workflow 的典型工具**: + +| 工具 | 特点 | +|------|------| +| Dify | 可视化编排 AI 工作流,支持 RAG、工具调用 | +| n8n | 通用自动化平台,支持 400+ 集成 | +| Coze(扣子) | 字节跳动出品,拖拽式搭建 AI 应用 | +| LangChain / LangGraph | 代码级工作流编排,灵活但需要编程 | + +**适合 Workflow 的场景**: + +- 每天固定要做的事(日报生成、数据汇总、邮件分类) +- 有明确规则的流程(审批、派单、质检) +- 需要多个系统协同的场景(CRM → AI 分析 → 通知 → 归档) + +## 概念对比总表 + +| 维度 | Chat | Copilot | Agent | Workflow | +|------|------|---------|-------|----------| +| 一句话 | 你问它答 | 嵌入工具帮手 | 自主干活的 AI | 预设流程自动跑 | +| 主导方 | 人 | 人 | AI | 流程设计者 | +| 自主性 | 低 | 中 | 高 | 中(按流程走) | +| 灵活性 | 高 | 中 | 高 | 低 | +| 可预测性 | 高 | 高 | 低 | 高 | +| 典型产品 | ChatGPT、DeepSeek | GitHub Copilot、Cursor | AutoGPT、Devin | Dify、n8n、Coze | +| 适合场景 | 学习、问答、写作 | 代码补全、文档写作 | 探索性复杂任务 | 重复性固定流程 | +| 风险 | 幻觉 | 补全不准 | 跑偏、死循环 | 流程设计不当 | + +## 它们怎么组合 + +这四种模式经常混着用。一个真实的产品里,可能同时包含所有模式。 + +以"做一个数据分析报告"为例: + +| 阶段 | 用什么 | 为什么 | +|------|--------|--------| +| 了解需求 | Chat | 和 AI 对话,明确要分析什么 | +| 写分析代码 | Copilot | 在 IDE 里让 AI 补全代码 | +| 跑分析流程 | Workflow | 预设好清洗 → 分析 → 出图的流程 | +| 处理异常 | Agent | 遇到意外数据,让 AI 自己判断怎么处理 | +| 润色报告 | Chat | 让 AI 帮忙改措辞、加结论 | + +```mermaid +%%{init: { 'htmlLabels': false } }%% +flowchart LR + A["Chat
明确需求"] --> B["Copilot
写代码"] + B --> C["Workflow
自动执行"] + C --> D["Agent
处理异常"] + D --> E["Chat
润色报告"] +``` + +## 选哪个:一个简单的判断框架 + +``` +你的任务是什么? +│ +├── 一次性的问题 / 需要人参与的写作 / 学习 +│ └── 用 Chat +│ +├── 重复性的编码 / 文档工作,需要实时辅助 +│ └── 用 Copilot +│ +├── 复杂任务,需要多步骤、多工具,允许 AI 尝试 +│ └── 用 Agent +│ +└── 固定流程,每天/每周都要跑,规则明确 + └── 用 Workflow +``` + +> 💡 **大多数人的起步路径**:先用好 Chat → 试试 Copilot 提效 → 遇到重复流程搭 Workflow → 有探索性任务再考虑 Agent。 + +## 常见误区 + +### 误区一:Agent 能完全替代人 + +2026 年的 Agent 还经常犯错。它适合做"初稿",不适合做"终稿"。完全放手让 Agent 干活,很可能翻车。 + +### 误区二:Workflow 就是 Agent + +Workflow 是"人设计流程,AI 执行步骤"。Agent 是"AI 自己设计流程并执行"。两者的设计哲学完全不同。 + +### 误区三:Copilot 只能写代码 + +Copilot 已经扩展到办公、设计、数据分析等领域。Word 里的"帮我写"、Excel 里的"帮我算"、PPT 里的"帮我排版",都是 Copilot 模式。 + +### 误区四:Chat 很简单,没什么技术含量 + +Chat 看起来简单,但用好它需要很强的"提问能力"。同样的问题,问法不同,答案质量可能差十倍。提示词工程(Prompt Engineering)就是专门研究这个的。 + +--- + +## 延伸阅读 + +- [函数调用与工具调用](tool-calling.md) —— Agent 和 Workflow 的核心技术基础 +- [Agent 工具调用](../agent/tool-use.md) —— Agent 如何使用工具完成任务 +- [Agent 与工作流的区别](../agent/workflow-vs-agent.md) —— 更深入的对比分析 +- [模型这么多,我选哪个?](model-selection.md) —— 选好模式后还要选对模型 + +## 练习题 + +### 练习一:分类练习 + +以下 10 个场景,分别适合用 Chat、Copilot、Agent、Workflow 中的哪个? + +1. "帮我解释一下什么是 RAG" +2. 写一个 Python 函数处理 CSV 文件 +3. 每天早上自动汇总昨日销售数据并发邮件 +4. 帮我调研市面上所有 AI 编程工具并做对比报告 +5. 修改一封商务邮件的措辞 +6. 自动处理客服工单:分类 → 查知识库 → 回复 +7. 写代码时自动补全测试用例 +8. 帮我想一个新产品的产品名和 slogan +9. 自动监控网站可用性,发现异常就报警 +10. 读完一份 100 页的合同,找出关键条款和风险点 + +### 练习二:设计一个混合流程 + +你负责一个技术博客,每周要发一篇文章。请设计一个结合 Chat + Copilot + Workflow 的写作流程: + +- 哪些步骤用 Chat? +- 哪些步骤用 Copilot? +- 哪些步骤可以做成 Workflow 自动化? + +### 练习三:Agent 可靠性测试 + +找一个支持 Agent 模式的工具(如 Coze、Dify),给它一个任务:"帮我搜索最近一周的 AI 新闻,选出最重要的 3 条,写一个简短摘要。" 观察它的执行过程: + +- 它规划了几步? +- 中间有没有走弯路? +- 最终结果质量如何? + +### 练习四:搭建一个简单 Workflow + +用 Dify 或 Coze 搭建一个 Workflow: -## 建议内容 +- **输入**:一段用户反馈文本 +- **步骤 1**:AI 判断情感(正面/负面/中性) +- **步骤 2**:如果是负面,提取关键问题 +- **步骤 3**:生成一个回复草稿 +- **输出**:情感标签 + 关键问题 + 回复草稿 -- 概念区别 -- 适用场景 -- 典型案例 -- 选择建议 +测试几条不同的反馈,观察 Workflow 的表现。