篇七:部署 —— 从本地脚本到 API 服务,再到生产环境架构选型

先放结论:部署不是"把代码扔上服务器",而是从"脚本思维"切换到"服务思维"。 脚本跑一次就完事,服务要面对并发、超时、状态持久化、故障恢复。搞懂这三层,你的 Agent 才算真正能用。

第一层:从脚本到 API 服务

你在本地跑 Agent 的方式通常是:

ini 复制代码
const result = await agent.invoke({ messages: [...] });
console.log(result);

这没问题,但别人怎么用?总不能让你同事 clone 你的代码、装依赖、配环境变量、再跑一遍。正确的做法是:把 Agent 包装成一个 HTTP 服务,别人通过 API 调用。

方案一:LangServe(LangChain 官方推荐)

LangServe 是 LangChain 官方的"一键部署神器",核心就一个函数 add_routes,把你的 Chain 或 Agent 自动变成 REST API。

python 复制代码
# server.py
from fastapi import FastAPI
from langserve import add_routes
from my_agent import my_agent  # 你写好的 Agent

app = FastAPI(title="My Agent API", version="1.0.0")

# 一行代码注册 API
add_routes(app, my_agent, path="/agent")

启动:

lua 复制代码
pip install langserve fastapi uvicorn
uvicorn server:app --host 0.0.0.0 --port 8000

访问 http://localhost:8000/docs 就能看到自动生成的 Swagger 文档,直接在浏览器里测试接口。

优点 :零代码适配,自动文档,支持流式输出、批量请求。 缺点:只适合 LangChain 生态,Python 专属。

方案二:FastAPI 手写(更灵活)

如果你需要自定义请求校验、权限控制、响应格式,手写 FastAPI 更灵活:

python 复制代码
# app/main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field

app = FastAPI(title="Agentic Helpdesk API", version="0.1.0")

class QueryRequest(BaseModel):
    input: str = Field(description="用户输入", min_length=1, max_length=2000)

class QueryResponse(BaseModel):
    answer: str
    tool_calls: list[str] = Field(default_factory=list)

@app.post("/agent", response_model=QueryResponse)
async def run_agent(req: QueryRequest) -> QueryResponse:
    try:
        result = await agent_executor.ainvoke({"input": req.input})
        used_tools = [
            s["tool"] for s in result.get("intermediate_steps", [])
            if isinstance(s, tuple) and s and hasattr(s[0], "tool")
        ]
        return QueryResponse(answer=result["output"], tool_calls=used_tools)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/health")
def health() -> dict:
    return {"status": "ok"}

关键点:

  • async def + ainvoke:异步非阻塞,吞吐量远优于同步阻塞
  • Pydantic 模型:约束请求和响应,类型安全
  • /health 端点:健康检查,给负载均衡器用

方案三:LangGraph 独立服务器(适合有状态 Agent)

如果你的 Agent 基于 LangGraph(有状态、有循环),LangGraph 提供了专门的部署方式:

bash 复制代码
# 本地开发
langgraph dev  # 启动开发服务器,默认监听 http://127.0.0.1:2024

生产环境打包成 Docker 镜像:

perl 复制代码
langgraph build -t my-agent:latest

然后部署到 Kubernetes 或 Docker Swarm。

优点 :原生支持状态持久化、断点续跑、Studio 可视化调试。 缺点:需要 PostgreSQL/Redis 作为后端存储,运维成本略高。

第二层:容器化部署

脚本跑在本地没问题,但上生产环境必须容器化。为什么?

  • 环境隔离:避免"在我机器上能跑"的问题
  • 资源限制:CPU、内存可控,不会把服务器跑崩
  • 快速扩缩容:一个命令启动 10 个实例

最小 Dockerfile

bash 复制代码
FROM python:3.11-slim

WORKDIR /app

# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制代码
COPY . .

# 启动服务
CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8000"]

docker-compose 编排(含数据库)

如果你的 Agent 需要持久化状态(LangGraph Checkpointer),需要配套数据库:

yaml 复制代码
# docker-compose.yml
version: '3.8'
services:
  agent-api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URI=postgresql://user:pass@postgres:5432/agentdb
      - REDIS_URI=redis://redis:6379
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: agentdb
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    volumes:
      - redisdata:/data

volumes:
  pgdata:
  redisdata:

启动:

复制代码
docker compose up -d

关键点:

  • 生产环境禁止用 MemorySaver :容器重启后状态全丢,必须用 PostgresSaver 或 RedisSaver
  • 环境变量管理 :API Key、数据库密码放 .env 文件,通过 env_file 注入容器,禁止硬编码
  • 数据卷挂载:PostgreSQL 和 Redis 的数据要持久化,否则容器重启数据丢失

第三层:生产环境架构选型

到了生产环境,问题就不只是"跑起来"了。你需要考虑:并发、高可用、监控、成本。

架构选型决策树

场景 推荐架构 理由
简单任务(步骤≤3、规则明确) LangChain + LangServe 开发快、成本低、稳定性高
中等复杂(步骤 3-5、流程固定) LangChain + FastAPI 平衡灵活性与开发效率
高复杂(步骤>5、需循环/分支) LangGraph + 独立服务器 支持流程回溯、状态持久化
高并发(QPS>1000) LangGraph + Kubernetes + 负载均衡 水平扩展、弹性伸缩
多 Agent 协作 LangGraph + Bedrock AgentCore / AWS Lambda 无服务器运行时,自动扩缩容
非技术团队快速上线 Dify / CrewAI 低代码、开箱即用

生产环境必须做的五件事

1. 超时防护

LLM 调用可能卡住,工具调用可能超时。不配超时,一个请求就能拖垮整个服务。

三层超时:

  • 模型层超时 :ChatOpenAI(timeout=30)
  • 工具层超时:每个工具设置独立超时
  • 节点层超时:LangGraph 节点设置超时,超时后走降级路由

2. 重试与熔断

网络抖动是常态。无脑重试会加重下游压力,甚至引发雪崩。

精准重试策略:

  • 瞬时故障(超时、限流、网络抖动):指数退避 + jitter 重试
  • 永久故障(参数错误、权限不足、接口不存在):直接拦截,不重试

熔断:连续失败 N 次后触发熔断,暂停请求下游,等待恢复后再半开探测。

3. 降级策略

当模型挂了、工具不可用时,不能直接返回 500。要有降级方案:

  • 模型切换:GPT-4 挂了切 GPT-3.5,再挂了切本地 Ollama
  • 逻辑裁剪:跳过非核心步骤,只保留主流程
  • 结果兜底:返回预设的友好提示,而不是堆栈信息

4. 可观测性

生产环境出问题,你不能靠"猜"。需要完整的监控体系:

  • 链路追踪:LangSmith Trace 或 OpenTelemetry,可视化整个工作流的调用链和耗时
  • 指标监控:Prometheus + Grafana,监控请求量、延迟、错误率、Token 消耗
  • 集中化日志:ELK 或 Loki,汇总所有实例的日志,便于检索和分析

5. 水平扩展

单实例扛不住高并发。需要:

  • 无状态计算层:LangGraph 执行器部署为无状态微服务,任何实例都能处理任何请求
  • 共享状态存储:PostgreSQL 或 Redis 持久化状态,实例故障后其他实例能接管
  • 负载均衡:Nginx 或 Kubernetes Service 分发请求
  • 弹性伸缩:Kubernetes HPA 根据 CPU/内存使用率自动增减实例

参考架构图

css 复制代码
用户请求
    ↓
[API 网关 / 负载均衡器]  ← 限流、鉴权、SSL 终端
    ↓
[Agent 服务集群]  ← 无状态,可水平扩展
    ├── 实例 1
    ├── 实例 2
    └── 实例 N
    ↓
[状态存储]  ← PostgreSQL(Checkpointer)+ Redis(缓存)
    ↓
[外部依赖]
    ├── LLM API(OpenAI / 本地 Ollama)
    ├── 向量数据库(RAG)
    └── 第三方工具(天气、邮件、数据库...)

部署的三个阶段

阶段 目标 推荐方案
开发期 快速验证,本地调试 langgraph dev 或 uvicorn 本地启动
测试期 模拟生产环境,压测 Docker Compose 本地编排,含数据库
生产期 高可用、可扩展、可监控 Kubernetes + PostgreSQL + Redis + LangSmith + Prometheus

不要一开始就上 Kubernetes。先从 LangServe 或 FastAPI 跑起来,验证价值后再逐步升级架构。

一个实用建议:从"最小可部署单元"开始

不要一上来就搞复杂的微服务架构。先做一件事:把你的 Agent 包装成一个 FastAPI 服务,用 Docker 跑起来,能被人通过 HTTP 调用。

做到这一步,你就已经超过了 80% 的 Agent 开发者。剩下的并发、监控、扩缩容,等真正需要的时候再加。

小结

  • 部署的本质:从"脚本思维"切换到"服务思维"
  • 三种 API 方案:LangServe(零代码)、FastAPI 手写(灵活)、LangGraph 独立服务器(有状态)
  • 容器化必做:Docker 隔离环境,docker-compose 编排数据库
  • 生产五件事:超时防护、重试熔断、降级策略、可观测性、水平扩展
  • 架构选型原则:简单场景用 LangServe,复杂场景用 LangGraph,高并发上 Kubernetes
  • 从最小可部署单元开始:先跑起来,再优化

到这里实战系列的七篇内容全部完结。我们从最基础的 Agent 工具调用出发,一路走到 LangGraph 框架、记忆持久化、RAG 外挂知识库、科学评估、生产部署------覆盖了构建一个生产级 Agent 的完整链路。

但故事还没结束。Agent 技术还在快速演进,Multi-Agent 协作、自主规划、长程记忆、具身智能......这些方向值得持续关注。保持学习,保持动手,我们下一个系列见。

相关推荐
杨杨杨大侠1 小时前
MCP 到底接在了哪一层?从“Agent 调工具”说起
agent·ai编程·mcp
阿里云大数据AI技术1 小时前
云栖2026 | 阿里云 OpenLake 迈向 Agentic Lake,一份全模态数据驱动智能体就绪
大数据·人工智能·agent
杨杨杨大侠1 小时前
Codex 本地自定义 Agent 与模型配置实战:TOML、AGENTS.md 和优先级
人工智能·openai·agent
阿祖zu1 小时前
只说真话,十分钟快速理解如何开始设计一个 Agent 产品
llm·agent
杨杨杨大侠1 小时前
给 Agent 加一个“判断器”:聊聊 Laya、Jev,以及怎么部署和选择
人工智能·python·agent
杨杨杨大侠1 小时前
多 Agent 协作到底靠什么?从 Codex 内部机制到 A2A 企业服务
java·人工智能·agent
Csvn2 小时前
第 24 章 参数体系与调优
人工智能·aigc·agent
dong_junshuai2 小时前
每天一个开源项目#108 36K星Claude金融Agent模板库
开源·github·agent
后端小肥肠2 小时前
我做了个 Skill,一句话生成小程序原型,需求文档都帮你写好了
人工智能·aigc·agent