进阶主题与部署

面试官:「线上出 bug 怎么排查?」

你:「看日志...」

面试官:「LangChain 有调试工具吗?」

你:「... 好像有 LangSmith」

面试官:「生产环境部署了解吗?Docker、K8s?」

你:「...」

🤔 前面几章是基础,这一章是拉开差距的关键。调试、监控、部署、安全 — 大厂标配。

7.1 调试与追踪

LLM 应用的调试比传统软件更具挑战性,因为模型的输出具有不确定性。LangChain 提供了多种调试工具。

7.1.1 Callback 机制

LangChain 的 Callback 系统允许你在链执行过程中插入自定义逻辑:

python callbacks.py
from langchain_openai import ChatOpenAI
from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.outputs import LLMResult
from typing import Any, List, Dict

# 自定义回调处理器
class DebugCallback(BaseCallbackHandler):
    def on_llm_start(self, serialized: Dict, prompts: List[str], **kwargs):
        print("🔵 LLM 开始调用")
        print(f"   提示词: {prompts[0][:100]}...")

    def on_llm_end(self, response: LLMResult, **kwargs):
        print("🟢 LLM 调用完成")
        print(f"   Token 使用: {response.llm_output.get('token_usage', {})}")

    def on_chain_start(self, serialized: Dict, inputs: Dict, **kwargs):
        print(f"🔵 Chain 开始: {serialized.get('name', 'unnamed')}")

    def on_chain_end(self, outputs: Dict, **kwargs):
        print("🟢 Chain 执行完成")

    def on_tool_start(self, serialized: Dict, inputs: Dict, **kwargs):
        print(f"⚡ 工具开始: {serialized.get('name', 'unnamed')}")

    def on_tool_end(self, output: str, **kwargs):
        print(f"✅ 工具完成: {output[:50]}...")

# 使用回调
llm = ChatOpenAI(model="gpt-4o-mini", callbacks=[DebugCallback()])
response = llm.invoke("你好")
print(f"最终回复: {response.content}")

7.1.2 内置回调工具

python builtin_callbacks.py
from langchain_core.callbacks import StdOutCallbackHandler
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate

# StdOutCallbackHandler - 打印到标准输出
handler = StdOutCallbackHandler()

llm = ChatOpenAI(model="gpt-4o-mini")
prompt = PromptTemplate.from_template("翻译成{lang}:{text}")

chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])

result = chain.invoke({"lang": "日语", "text": "Hello, World!"})
图 7-1:Callback 回调流程
用户输入 Chain LLM 输出 Callback Handlers on_chain_start — Chain 开始执行时触发 on_llm_start — LLM 开始调用时触发 on_llm_end — LLM 调用完成时触发 on_chain_end — Chain 执行完成时触发

7.2 LangSmith 使用指南

LangSmith 是 LangChain 官方提供的调试、追踪和评估平台,帮助你深入了解 LLM 应用的行为。

🔧 LangSmith 核心功能

功能 作用
Trace 追踪 记录每个 Chain、Agent、Tool 的执行详情
Dataset 数据集 创建测试数据集,批量评估应用效果
Evaluation 评估 自动评估输出质量,对比不同版本
Monitor 监控 监控生产环境性能,及时发现问题

7.2.1 快速集成

python langsmith_setup.py
# 1. 安装
pip install langsmith

# 2. 设置环境变量
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-api-key"  # 从 langsmith.ai 获取
os.environ["LANGCHAIN_PROJECT"] = "my-langchain-app"  # 项目名称

# 3. 使用(自动追踪)
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")
response = llm.invoke("你好,请介绍一下自己")

7.2.2 添加数据集和评估

python langsmith_eval.py
from langchain_openai import ChatOpenAI
from langchain.smith import RunEvalConfig, run_on_dataset
from langchain_core.output_parsers import StrOutputParser

# 定义评估配置
eval_config = RunEvalConfig(
    evaluators=[
        # 检查输出是否包含关键词
        "qa",
        # 自定义评估器
        {
            "criteria": {
                "helpfulness": {
                    "scale": 1,
                    "prompt": "评估回答是否有帮助..."
                }
            }
        }
    ]
)

# 创建 Chain
llm = ChatOpenAI(model="gpt-4o-mini")
chain = prompt | llm | StrOutputParser()

# 在数据集上运行评估
run_on_dataset(
    client=None,
    dataset_name="qa-test-dataset",
    llm_or_chain_factory=chain,
    evaluation=eval_config,
)
💡 获取 LangSmith API Key

1. 访问 smith.langchain.com
2. 注册并登录账号
3. 在 Settings -> API Keys 中创建新 Key
4. 免费版有每月 5000 条追踪额度

7.3 性能优化

LLM 应用通常延迟较高,以下是常用的优化策略。

7.3.1 缓存优化

python caching.py
from langchain_openai import ChatOpenAI
from langchain.cache import InMemoryCache
from langchain.globals import set_llm_cache

# 启用 LLM 响应缓存
set_llm_cache(InMemoryCache())

llm = ChatOpenAI(model="gpt-4o-mini")

# 相同输入直接返回缓存结果
response1 = llm.invoke("什么是人工智能")
response2 = llm.invoke("什么是人工智能")  # 几乎瞬时返回

7.3.2 并行处理

python parallel.py
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage
from langchain.utilities import SerpAPIWrapper
import asyncio

llm = ChatOpenAI(model="gpt-4o-mini")

# 并行执行多个独立任务
async def parallel_tasks():
    # 创建多个任务
    tasks = [
        llm.agenerate([[HumanMessage(content="解释 Python")]]),
        llm.agenerate([[HumanMessage(content="解释 JavaScript")]]),
        llm.agenerate([[HumanMessage(content="解释 Rust")]]),
    ]
    
    # 并行执行
    results = await asyncio.gather(*tasks)
    return results

# 运行
results = asyncio.run(parallel_tasks())

7.3.3 Token 控制

📊 Token 优化策略

策略 说明 节省比例
减少 Context 只传递必要的对话历史 30-50%
使用 Compact 摘要历史消息 40-60%
限制 Max Tokens 设置输出上限 可变
选择小模型 简单任务用 GPT-4o-mini ~80%

7.4 生产环境部署

7.4.1 Docker 部署

dockerfile Dockerfile
FROM python:3.11-slim

WORKDIR /app

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

# 复制代码
COPY . .

# 设置环境变量
ENV PYTHONUNBUFFERED=1

# 启动命令
CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8000"]
yaml docker-compose.yml
version: '3.8'

services:
  api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - LANGCHAIN_TRACING_V2=true
      - LANGCHAIN_API_KEY=${LANGCHAIN_API_KEY}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

7.4.2 Kubernetes 部署

yaml deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: langchain-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: langchain-api
  template:
    metadata:
      labels:
        app: langchain-api
    spec:
      containers:
      - name: api
        image: your-registry/langchain-api:latest
        ports:
        - containerPort: 8000
        env:
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: api-secrets
              key: openai-api-key
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "2Gi"
            cpu: "1000m"

7.4.3 API 服务封装

python api.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

app = FastAPI(title="LangChain API", version="1.0")

# 初始化 Chain
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)
prompt = ChatPromptTemplate.from_template("{question}")
chain = prompt | llm | StrOutputParser()

class Question(BaseModel):
    question: str

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

@app.post("/ask")
async def ask(question: Question):
    try:
        result = chain.invoke({"question": question.question})
        return {"answer": result}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

7.5 安全与最佳实践

7.5.1 敏感信息处理

⚠️ 重要安全提示
  • 永远不要在代码中硬编码 API Key
  • 永远不要将用户输入直接用于 Prompt
  • 永远不要在日志中记录敏感信息
python security.py
import os
from dotenv import load_dotenv

# 从环境变量读取密钥(安全)
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")

# 输入验证和清理
import re
def sanitize_input(user_input: str) -> str:
    """清理用户输入,防止注入"""
    # 移除潜在的危险字符
    cleaned = re.sub(r'[\x00-\x1f\x7f-\x9f]', '', user_input)
    # 限制长度
    return cleaned[:2000]

# 使用清理后的输入
def create_safe_prompt(user_input: str) -> str:
    safe_input = sanitize_input(user_input)
    return f"用户问题: {safe_input}\n请简要回答。"

7.5.2 速率限制

python rate_limit.py
from fastapi import FastAPI, Request
from slowapi import Limiter
from slowapi.util import get_remote_address

app = FastAPI()
limiter = Limiter(key_func=get_remote_address)

@app.post("/ask")
@limiter.limit("10/minute")  # 每分钟10次请求
async def ask(request: Request):
    # 处理请求
    pass

# 或者使用 token bucket 算法
from ratelimit import limits

@limits(calls=10, period=60)  # 60秒内最多10次
def call_llm(prompt: str):
    # 调用 LLM
    pass

7.5.3 最佳实践清单

生产环境检查清单

类别 检查项
安全 API Key 存储、环境变量、输入验证、输出过滤
监控 日志记录、错误追踪、性能监控、LangSmith
性能 缓存、异步处理、Token 优化、模型选择
可靠性 重试机制、熔断器、超时设置、备份方案
成本 用量监控、预算告警、模型降级策略

7.6 本章小结

本章学习了 LangChain 进阶主题与生产环境部署的核心内容:

📚 本章要点

主题 核心技能
调试追踪 Callback 机制、自定义处理器
LangSmith Trace、Dataset、Evaluation
性能优化 缓存、并行、Token 控制
生产部署 Docker、K8s、API 服务
安全实践 输入验证、速率限制、环境变量
🎉 恭喜完成!

你已经完成了「图解 LangChain」的全部内容。从基础概念到项目实战,从调试追踪到生产部署,你已经具备了构建生产级 LLM 应用的能力。

继续探索更多 AI 开发技巧,关注我们获取最新内容!