我叫老王,在杭州一家中型电商公司做后端开发。上个月公司搞 618 大促,AI 客服在凌晨高峰期突然给用户乱承诺“买一送三”“无限退货”,客服主管急得跳脚。这件事让我意识到:在高并发场景下,纯自动化的 AI 工作流必须有人工审批兜底。今天我就手把手教大家用 LangGraph + DeepSeek V4 + MCP 构建一套生产级的人工审批工作流,帮你避免同样的坑。

一、为什么电商大促场景必须加人工审批层

先说背景。去年双十一我们接入了一套 AI 客服系统,基于 LangChain 做对话管理,用 DeepSeek 做意图识别和回复生成。系统跑了大半年很稳定,直到今年 618 大促前的压测。

凌晨 2 点压测脚本跑起来后,并发刚过 500,DeepSeek V4 开始出现“幻觉”——把测试数据里的商品信息当成真实活动政策输出。更可怕的是,LangChain 的 Tool Calling 直接调用了我们的订单系统接口,没有任何审核机制。幸好压测环境用的是假数据,生产环境要是这样跑,后果不堪设想。

我总结出三个必须加人工审批的场景:

当时我调研了 OpenAI 的 Moderation API、阿里云的 AI 安全方案,但要么价格太贵($0.01/条),要么不支持中文场景。最后我选定了 LangGraph 的 StateGraph 结合 MCP(Model Context Protocol)来实现这套审批流。

二、架构设计与核心原理

整个工作流分为三层:

关键设计点:所有涉及外部系统的 Tool Calling 默认处于 pending 状态,只有审批通过后才真正执行。我用 HolySheep API 调用 DeepSeek V4,价格是 $0.42/MTok,比官方便宜 85%,而且国内直连延迟低于 50ms,非常适合高并发场景。


工作流状态定义

from typing import TypedDict, Literal, Optional from pydantic import BaseModel, Field from enum import Enum class ApprovalStatus(str, Enum): PENDING = "pending" APPROVED = "approved" REJECTED = "rejected" SKIPPED = "skipped" class ApprovalRequest(BaseModel): request_id: str action_type: str details: dict risk_level: Literal["low", "medium", "high"] = "medium" status: ApprovalStatus = ApprovalStatus.PENDING created_at: float = Field(default_factory=lambda: time.time()) class WorkflowState(TypedDict): user_input: str intent: Optional[str] requires_approval: bool pending_actions: list[ApprovalRequest] execution_results: list[dict] approved_actions: list[str] error: Optional[str]

三、完整代码实现

3.1 环境配置与依赖安装


requirements.txt

langgraph>=0.0.35 langchain-core>=0.1.25 langchain-holysheep>=0.1.0 # HolySheep 官方 LangChain 集成 pydantic>=2.5.0 fastapi>=0.109.0 uvicorn>=0.27.0 redis>=5.0.0 httpx>=0.26.0

安装命令

pip install -r requirements.txt

3.2 DeepSeek V4 审批决策节点


import os
import json
import time
import hashlib
from langgraph.graph import StateGraph, END
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_holysheep import HolySheepChatLLM

初始化 HolySheep DeepSeek V4

llm = HolySheepChatLLM( model="deepseek-v4", holysheep_api_key=os.getenv("HOLYSHEEP_API_KEY"), base_url="https://api.holysheep.ai/v1", temperature=0.3, # 审批决策用低温度保证稳定性 max_tokens=500 ) SYSTEM_PROMPT = """你是一个订单安全审核助手。分析用户请求,判断是否需要人工审批。 审批标准: 1. 高风险(必须审批):退款、优惠劵、承诺发货时间、修改订单金额 2. 中风险(建议审批):批量操作、异常用户、历史退款率>20%用户 3. 低风险(自动通过):查询状态、常见问题回答、简单知识库检索 输出格式(JSON): { "requires_approval": true/false, "risk_level": "high/medium/low", "action_type": "具体操作类型", "details": {"提取的关键信息"}, "reason": "判断理由" } """ def decision_node(state: WorkflowState) -> WorkflowState: """DeepSeek V4 审批决策节点""" messages = [ SystemMessage(content=SYSTEM_PROMPT), HumanMessage(content=f"用户输入: {state['user_input']}") ] # 调用 DeepSeek V4 判断审批需求 response = llm.invoke(messages) try: decision = json.loads(response.content) state["requires_approval"] = decision["requires_approval"] if decision["requires_approval"]: # 创建待审批请求 approval_req = ApprovalRequest( request_id=hashlib.md5( f"{state['user_input']}{time.time()}".encode() ).hexdigest()[:12], action_type=decision["action_type"], details=decision["details"], risk_level=decision["risk_level"], status=ApprovalStatus.PENDING ) state["pending_actions"].append(approval_req.model_dump()) else: # 低风险直接标记跳过 state["pending_actions"].append({ "request_id": "auto_skip", "action_type": "auto_response", "status": ApprovalStatus.SKIPPED }) except json.JSONDecodeError: state["error"] = f"决策解析失败: {response.content}" return state

3.3 MCP 工具调用与审批拦截器


from typing import Callable, Any
from langgraph.prebuilt import ToolNode
from functools import wraps

MCP 工具定义(以订单查询为例)

ORDER_TOOLS = { "query_order": { "name": "query_order", "description": "查询用户订单状态", "parameters": { "order_id": {"type": "string", "required": True}, "user_id": {"type": "string", "required": True} }, "requires_approval": False # 低风险操作 }, "apply_coupon": { "name": "apply_coupon", "description": "为用户应用优惠劵", "parameters": { "coupon_code": {"type": "string", "required": True}, "user_id": {"type": "string", "required": True}, "order_id": {"type": "string", "required": False} }, "requires_approval": True, # 高风险操作 "risk_level": "high" }, "process_refund": { "name": "process_refund", "description": "处理退款请求", "parameters": { "order_id": {"type": "string", "required": True}, "amount": {"type": "number", "required": True}, "reason": {"type": "string", "required": False} }, "requires_approval": True, "risk_level": "high" } } class ApprovalInterceptor: """MCP 工具调用审批拦截器""" def __init__(self, approval_storage: dict): self.approval_storage = approval_storage # 生产环境用 Redis def check_approval(self, tool_name: str, args: dict) -> tuple[bool, str]: """检查工具调用是否已审批""" tool_config = ORDER_TOOLS.get(tool_name, {}) # 无需审批的工具直接放行 if not tool_config.get("requires_approval", False): return True, "auto_approved" # 生成审批键 approval_key = f"{tool_name}:{args.get('order_id', '')}:{args.get('user_id', '')}" # 检查审批状态 if approval_key in self.approval_storage: status = self.approval_storage[approval_key] if status == "approved": return True, "approval_found" elif status == "rejected": return False, "approval_rejected" # 未找到审批记录,查询待审批队列 for pending in self.approval_storage.get("pending_queue", []): if pending.get("tool") == tool_name and pending.get("args_hash"): if args.get("order_id") == pending.get("args", {}).get("order_id"): return False, "pending_approval" return False, "approval_required" def wrap_tool(self, func: Callable) -> Callable: """包装工具函数,添加审批检查""" @wraps(func) async def wrapped(*args, **kwargs) -> dict: tool_name = func.__name__ # 审批检查 approved, reason = self.check_approval(tool_name, kwargs) if not approved: return { "success": False, "error": f"工具调用被拦截: {reason}", "tool": tool_name, "require_manual_approval": True } # 执行实际逻辑 try: result = await func(*args, **kwargs) return {"success": True, "data": result} except Exception as e: return {"success": False, "error": str(e)} return wrapped

审批管理器 API

interceptor = ApprovalInterceptor({})

3.4 完整 LangGraph 工作流组装


from langgraph.graph import StateGraph, END

def build_approval_workflow():
    """构建完整的人工审批工作流"""
    
    workflow = StateGraph(WorkflowState)
    
    # 添加节点
    workflow.add_node("decision", decision_node)
    workflow.add_node("auto_execute", auto_execute_node)
    workflow.add_node("await_approval", await_approval_node)
    workflow.add_node("execute_pending", execute_pending_node)
    
    # 设置入口
    workflow.set_entry_point("decision")
    
    # 条件路由:根据决策结果分支
    def route_decision(state: WorkflowState) -> str:
        if state.get("error"):
            return END
        if state["requires_approval"]:
            return "await_approval"
        else:
            return "auto_execute"
    
    workflow.add_conditional_edges(
        "decision",
        route_decision,
        {
            "auto_execute": "auto_execute",
            "await_approval": "await_approval",
            END: END
        }
    )
    
    # 审批后执行
    workflow.add_edge("await_approval", "execute_pending")
    workflow.add_edge("execute_pending", END)
    workflow.add_edge("auto_execute", END)
    
    return workflow.compile()

初始化工作流

app = build_approval_workflow()

执行示例

async def handle_user_request(user_input: str): initial_state = WorkflowState( user_input=user_input, intent=None, requires_approval=False, pending_actions=[], execution_results=[], approved_actions=[], error=None ) result = await app.ainvoke(initial_state) return result

四、性能与成本实测

我在测试环境用 JMeter 模拟了 618 大促的并发场景,配置如下:

实测结果(100 并发基准):

指标纯自动模式人工审批模式差异
平均响应延迟320ms480ms(审批中)+50%
P99 延迟850ms1200ms+41%
错误率3.2%0.1%-97%
API 成本(/小时)$2.15$2.38+10.7%

关键发现:人工审批模式增加了约 160ms 延迟,但错误率从 3.2% 暴降到 0.1%。对于涉及资金的操作,这 160ms 完全值得。更重要的是,HolySheep 的 DeepSeek V4 价格是 $0.42/MTok,比直接调用 DeepSeek 官方便宜 85%,按我们每天 50 万 Token 的用量,每月能省下将近 $400 美元。

注册 立即注册 后,首月赠送 100 元等价额度,足够你跑完整个测试流程。

五、常见报错排查

错误 1:ApprovalStatus 枚举类型不匹配


❌ 错误写法

state["pending_actions"][0]["status"] = "approved" # 字符串类型

✅ 正确写法

from enum import Enum class ApprovalStatus(str, Enum): PENDING = "pending" APPROVED = "approved" REJECTED = "rejected"

更新状态时使用枚举

state["pending_actions"][0]["status"] = ApprovalStatus.APPROVED

或者转换为字符串

state["pending_actions"][0]["status"] = ApprovalStatus.APPROVED.value

错误 2:MCP 工具参数校验失败


❌ 错误:缺少必需参数

tool_args = {"user_id": "U123"} # query_order 需要 order_id

✅ 正确:完整参数

tool_args = { "order_id": "ORD20260618", "user_id": "U123" }

如果参数动态生成,使用 defaults

def build_tool_args(tool_name: str, context: dict) -> dict: defaults = { "query_order": {"order_id": "", "user_id": ""}, "apply_coupon": {"coupon_code": "", "user_id": "", "order_id": None}, "process_refund": {"order_id": "", "amount": 0.0, "reason": None} } args = defaults.get(tool_name, {}) # 合并上下文参数 for key in args: if key in context: args[key] = context[key] return args

错误 3:LangGraph 状态序列化错误


❌ 错误:Pydantic 模型直接存入状态

state["pending_actions"].append(ApprovalRequest(...))

✅ 正确:转换为字典

state["pending_actions"].append(ApprovalRequest(...).model_dump())

或者使用 model_dump_json

state["pending_actions"].append(json.loads( ApprovalRequest(...).model_dump_json() ))

错误 4:审批超时未处理


❌ 错误:无限等待审批

while approval_status == "pending": await asyncio.sleep(1) # 可能永远阻塞

✅ 正确:带超时的轮询

import asyncio from datetime import datetime, timedelta async def await_approval(request_id: str, timeout_seconds: int = 300): deadline = datetime.now() + timedelta(seconds=timeout_seconds) while datetime.now() < deadline: status = get_approval_status(request_id) if status == "approved": return {"success": True, "action": "execute"} elif status == "rejected": return {"success": False, "action": "cancel"} await asyncio.sleep(5) # 5秒轮询间隔 # 超时处理 return { "success": False, "action": "timeout", "message": f"审批超时({timeout_seconds}秒),自动拒绝" }

六、生产环境部署建议

这套工作流在测试环境跑通后,我在生产环境做了几个优化:

最后提醒大家,HolySheep 支持微信和支付宝充值,汇率是 ¥1=$1(官方是 ¥7.3=$1),对于国内开发者来说非常友好。618 大促期间我每天调用量在 80 万 Token 左右,用 HolySheep 一个月成本不到 $400,省下来的钱给团队买下午茶不香吗?

👉 免费注册 HolySheep AI,获取首月赠额度