从 LangChain 到 OpenClaw:AI Agent 工程化的五层拼图与生产落地全攻略
从 LangChain 到 OpenClaw:AI Agent 工程化的五层拼图与生产落地全攻略
真正能上线的 Agent,从来不是“模型 + Prompt”这么简单。它本质上是一套分层系统:底层要有可靠的推理运行时,中层要有工作流和知识编排,上层要有能力封装、渠道接入与工程化交付,外围还要补齐安全、观测、弹性和治理。本文以 LangChain、Dify、Agent Skills、OpenClaw、Harness 为线索,系统讲清 AI Agent 从原理到架构、从代码到生产的完整落地路径。
一、先把问题说透:为什么很多 Agent Demo 一上线就失灵
过去一年,很多团队都经历过类似路径:
-
1. 用一个大模型加几个 Tool,很快做出一个“会对话、会查数据、会调接口”的 Demo。 -
2. 在测试环境里效果惊艳,产品、运营、老板都觉得“这事快成了”。 -
3. 一旦接入真实业务流量,问题开始集中爆发。
典型故障几乎总是这几类:
-
• 对话轮次一长,上下文爆炸,响应时间和 Token 成本同时失控。 -
• Tool 调用缺少边界控制,Agent 把“查询订单”一路推演成“自动退款”。 -
• 模型输出不稳定,JSON 时好时坏,下游服务一片报错。 -
• 接入多个业务系统后,幂等、超时、重试、补偿没人兜底。 -
• 研发能写,运营不会改;产品想调流程,必须找工程师发版。 -
• 出了线上问题,日志里只有一句 “LLM call failed”,根本追不到是模型、向量检索、审批服务还是消息通道出了问题。
这说明一个关键事实:
Agent 的核心难点,不是“让模型回答问题”,而是“让智能行为在工程系统中可控地运行”。
所以,成熟的 Agent 体系必须同时解决五类问题:
-
• 运行时问题:模型如何思考、调用工具、维护状态。 -
• 平台问题:流程怎么编排,知识怎么治理,业务怎么配置。 -
• 能力复用问题:领域知识和动作模板如何沉淀,而不是每个项目从零写 Prompt。 -
• 触达问题:用户在 Slack、飞书、Web、CLI 等多个入口发起请求时,如何共享上下文与策略。 -
• 交付问题:如何测试、发布、灰度、回滚、观测、审计。
这正是本文五层拼图的由来:
-
• LangChain / LangGraph:运行时层 -
• Dify:平台层 -
• Agent Skills:能力层 -
• OpenClaw:渠道与执行入口层 -
• Harness:交付与治理层
二、五层拼图不是“选型列表”,而是一张生产架构图
很多文章把这些工具写成横向对比,仿佛只能五选一。实际恰恰相反,它们更多是纵向协作关系。
可以先看一张简化分层图:
┌──────────────────────────────────────────────────────────────┐
│ OpenClaw / 渠道接入层 │
│ Slack / 飞书 / Teams / Web / CLI / Mobile / Bot │
├──────────────────────────────────────────────────────────────┤
│ Dify / 平台编排层 │
│ Workflow / RAG / PromptOps / Model Routing / API │
├──────────────────────────────────────────────────────────────┤
│ LangChain + LangGraph / 运行时层 │
│ Agent Loop / State Graph / Tool Calling / Memory / HITL │
├──────────────────────────────────────────────────────────────┤
│ Agent Skills / 能力封装层 │
│ Domain Prompt / SOP / Script / Policy / Reference / Asset │
├──────────────────────────────────────────────────────────────┤
│ Harness / 工程化交付与治理层 │
│ CI/CD / Verification / Canary / Rollback / Audit / SRE │
└──────────────────────────────────────────────────────────────┘
如果用一句话概括:
LangChain 决定 Agent “怎么运行”,Dify 决定业务“怎么配置”,Skills 决定能力“怎么复用”,OpenClaw 决定结果“怎么到达用户”,Harness 决定系统“怎么稳定上线”。
这五层分别解决不同控制面:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
三、第一层:LangChain / LangGraph 是 Agent 的运行时内核
3.1 为什么说 Agent 不是函数调用,而是状态机
很多人把 Agent 理解成:
用户输入 -> LLM -> 输出答案
而生产级 Agent 更接近:
用户输入
-> 意图识别
-> 状态装载
-> 检索上下文
-> 规划动作
-> 调用工具
-> 验证结果
-> 可能人工审批
-> 写入记忆
-> 输出答案
这已经不是一个普通函数,而是一个可中断、可恢复、可追踪的有状态流程。
从原理上看,Agent 至少包含五个核心部件:
-
1. Planner:决定下一步做什么。 -
2. Tool Executor:真正执行外部动作。 -
3. Memory Manager:管理短期上下文、长期记忆与摘要。 -
4. Policy Layer:审批、脱敏、限流、重试、审计。 -
5. State Store:让流程可恢复、可重放、可追踪。
LangChain 提供高层 Agent 抽象,LangGraph 更像底层状态图运行时。对于简单场景,create_agent 很高效;对于多步骤、长流程、可恢复任务,图式编排更稳。
3.2 单 Agent 的上限,往往不是模型,而是上下文和副作用
一个只读型 FAQ Agent 很容易做;难的是具备真实业务动作的 Agent,例如:
-
• 查订单 -
• 发起退款 -
• 查询库存 -
• 修改收货地址 -
• 触发人工审批 -
• 通知物流系统
这些动作会带来三个工程问题:
-
• 副作用:一旦写库、发消息、调支付接口,就必须考虑幂等。 -
• 不确定性:模型可能反复调用工具,也可能输出错误参数。 -
• 长耗时:库存、物流、审批这类调用可能横跨秒级到分钟级。
因此,生产级 LangChain 方案不应该只是“把 Tool 注册进去”,而应该建立明确边界:
-
• Agent 只负责决策,不直接持有关键写操作权限。 -
• 所有写操作必须经由受控应用服务。 -
• 工具调用结果必须结构化、可验证、可审计。 -
• 高风险动作必须支持人工确认和异步补偿。
3.3 一个更接近生产的 LangChain 服务骨架
下面这段代码不是玩具 Demo,而是一个更接近真实生产的最小骨架。重点在四件事:
-
1. 结构化输出 -
2. 工具超时与重试 -
3. 幂等键 -
4. 审批与审计边界
from __future__ import annotations
import asyncio
import json
import time
import uuid
from dataclasses import dataclass
from typing import Any
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI
class ChatRequest(BaseModel):
session_id: str
user_id: str
message: str
tenant_id: str
class ChatResponse(BaseModel):
session_id: str
answer: str
trace_id: str
requires_approval: bool = False
approval_task_id: str | None = None
@dataclass
class ToolContext:
tenant_id: str
user_id: str
trace_id: str
request_id: str
class OrderGateway:
async def query_order(self, tenant_id: str, order_id: str) -> dict[str, Any]:
await asyncio.sleep(0.05)
return {
"order_id": order_id,
"status": "SHIPPED",
"amount": 299.0,
"currency": "CNY",
"can_refund": True,
}
async def create_refund_request(
self,
tenant_id: str,
order_id: str,
reason: str,
idempotency_key: str,
) -> dict[str, Any]:
await asyncio.sleep(0.05)
return {
"refund_request_id": f"rf-{order_id}",
"status": "PENDING_APPROVAL",
"reason": reason,
"idempotency_key": idempotency_key,
}
order_gateway = OrderGateway()
app = FastAPI(title="agent-service")
def with_timeout(seconds: float):
def decorator(fn):
async def wrapper(*args, **kwargs):
return await asyncio.wait_for(fn(*args, **kwargs), timeout=seconds)
return wrapper
return decorator
@tool
@with_timeout(2.0)
async def query_order(order_id: str, tenant_id: str) -> str:
"""查询订单详情,只读工具。"""
result = await order_gateway.query_order(tenant_id=tenant_id, order_id=order_id)
return json.dumps(result, ensure_ascii=False)
@tool
@with_timeout(2.0)
async def apply_refund(order_id: str, reason: str, tenant_id: str, request_id: str) -> str:
"""提交退款申请,该工具只创建审批单,不直接退款。"""
result = await order_gateway.create_refund_request(
tenant_id=tenant_id,
order_id=order_id,
reason=reason,
idempotency_key=request_id,
)
return json.dumps(result, ensure_ascii=False)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
agent = create_agent(
model=llm,
tools=[query_order, apply_refund],
system_prompt=(
"你是电商订单助理。"
"必须优先调用工具获取事实。"
"涉及退款时只能创建退款申请,不得声称已经完成退款。"
"如果工具返回 PENDING_APPROVAL,必须明确告知用户等待审批。"
),
)
@app.post("/chat", response_model=ChatResponse)
async def chat(req: ChatRequest) -> ChatResponse:
trace_id = str(uuid.uuid4())
request_id = f"{req.session_id}-{int(time.time() * 1000)}"
try:
result = await agent.ainvoke(
{
"messages": [{"role": "user", "content": req.message}],
"tenant_id": req.tenant_id,
"request_id": request_id,
}
)
except asyncio.TimeoutError as exc:
raise HTTPException(status_code=504, detail="agent timeout") from exc
except Exception as exc:
raise HTTPException(status_code=500, detail=f"agent failed: {exc}") from exc
final_message = result["messages"][-1].content
requires_approval = "PENDING_APPROVAL" in str(result)
return ChatResponse(
session_id=req.session_id,
answer=final_message,
trace_id=trace_id,
requires_approval=requires_approval,
approval_task_id=request_id if requires_approval else None,
)
这段代码体现了一个非常关键的设计原则:
Agent 可以发起“业务意图”,但不能绕过业务系统直接执行“最终动作”。
也就是说,“退款”不等于“直接调用支付系统出款”,而应该是“创建退款申请 -> 进入审批流 -> 审批通过后由事务型服务执行”。
这会让 Agent 从“危险的自动脚本”变成“受控的智能入口”。
3.4 为什么复杂场景必须上 LangGraph
当你遇到以下需求时,单次 ReAct Loop 就不够了:
-
• 一个任务要跑 10 分钟以上 -
• 中途需要人工介入 -
• 失败后要从中间步骤恢复 -
• 多个 Specialist Agent 协作 -
• 同一个会话里要维护长期状态
这时,图式状态机比“无限循环 + if/else”更可靠。一个典型状态图如下:
Yes
No
No
Yes
从架构视角看,LangGraph 的价值不只是“能画图”,而是它天然适合承载这些生产需求:
-
• 中断恢复:审批回来后接着跑,而不是整段重来。 -
• 状态持久化:支持 checkpoint,方便恢复和调试。 -
• 显式节点边界:每一步都可以埋点、限流、熔断。 -
• 多 Agent 协作:Supervisor 分配给 FAQ Agent、Order Agent、Risk Agent。
四、第二层:Dify 的价值,不是替代代码,而是承接业务运营面
4.1 Dify 最适合解决什么问题
如果 LangChain 擅长的是“深度定制”,那 Dify 擅长的是“规模化配置”。
当一个团队进入下面这个阶段时,Dify 的价值会迅速放大:
-
• 产品希望自己调 Prompt、调流程、调知识库。 -
• 运营需要可视化测试和回放,而不是让研发帮忙打印日志。 -
• 不同场景要切换不同模型、不同知识源、不同输出模板。 -
• 同一个 Agent 要暴露成 UI 应用、内部 API、测试沙箱。
Dify 本质上提供了四块控制面:
-
1. Workflow Control Plane:把流程从代码抽成可视化编排。 -
2. Knowledge Control Plane:文档切分、索引、召回、重建。 -
3. Prompt / Model Ops:多模型配置、版本切换、评测对比。 -
4. Application Surface:快速给业务方可操作的入口。
4.2 Dify 和 LangChain 的正确协作方式
很多团队会走两个极端:
-
• 纯 Dify:上手很快,但一旦遇到复杂逻辑就会越来越重。 -
• 纯 LangChain:灵活,但所有配置都要发版,业务协作成本高。
更合理的模式是:
Dify 负责流程装配和业务配置,LangChain 负责复杂智能能力与敏感动作控制。
一个常见组合方案:
-
• Dify 工作流中处理用户入口、知识库检索、Prompt 组织、常规节点编排。 -
• 对复杂决策节点,通过 HTTP Tool 调 LangChain 微服务。 -
• LangChain 微服务内部再调模型、审批、风控、数据库和异步任务系统。
示意如下:
Dify Workflow
-> Knowledge Retrieve
-> Intent Route
-> HTTP Node (invoke LangChain Agent)
-> Format Response
-> Return to User
这样分工的好处是:
-
• 产品可以调流程,不用每次改代码。 -
• 工程师可以把高复杂度逻辑留在服务侧,不被低代码平台牵制。 -
• 线上安全规则、审计规则集中在服务层,不依赖平台节点拼装是否严谨。
4.3 一个推荐的 Dify 集成边界
在企业项目里,我建议把 Dify 放在这些职责范围内:
-
• 场景编排 -
• Prompt 模板管理 -
• 知识库接入与灰度 -
• 模型试验场 -
• API 出口
不要把这些职责完全丢给 Dify:
-
• 支付、退款、工单创建等关键写操作 -
• 高并发队列调度 -
• 严格审批流 -
• 核心审计日志 -
• 租户级权限控制
原因很简单:这些能力本质上属于事务型后端系统,不属于对话编排平台。
五、第三层:Agent Skills 是把“专家经验”编译成标准资产
5.1 为什么 Prompt 不能承载全部业务知识
很多团队一开始会把所有规则都写进 System Prompt:
-
• 退款金额超过 500 需要审批 -
• VIP 用户优先走绿色通道 -
• 改地址只能在发货前处理 -
• 物流异常 48 小时后触发工单
短期看这样很快,长期看会出三个问题:
-
1. Prompt 越来越长,维护成本越来越高。 -
2. 规则散落在不同 Agent、不同项目中,无法复用。 -
3. 没有版本边界,不知道哪条规则何时修改、谁改的、影响了谁。
Skills 的意义,就是把“会做这件事”的知识固化成一个标准包,而不是一段越来越失控的 Prompt。
5.2 一个生产可用的 Skill 包应该长什么样
推荐目录:
order-processing-skill/
├── SKILL.md
├── manifest.yaml
├── references/
│ ├── refund-policy.md
│ ├── shipping-sla.md
│ └── risk-control.md
├── scripts/
│ ├── normalize_order.py
│ └── validate_refund.py
└── tests/
└── skill_cases.yaml
其中,SKILL.md 不是文档装饰,而是能力契约。至少应该包含:
-
• 触发条件 -
• 输入要求 -
• 输出格式 -
• 执行 SOP -
• 风险边界 -
• 禁止事项 -
• 依赖工具 -
• 回退策略
示例:
---
name: order-processing
version: 1.3.0
owner: commerce-platform
allowed-tools:
- order.query
- refund.apply
- approval.create
compatibility:
tenant_mode: required
pii_masking: required
---
# 订单处理技能
## 适用场景
用户咨询订单状态、物流进度、退款申请、地址修改。
## 标准流程
1. 优先提取 order_id。
2. 缺少订单号时,引导用户补充,不允许编造查询结果。
3. 涉及退款时先查询订单状态与退款资格。
4. 超过风险阈值时必须创建审批单。
5. 输出中不得暴露完整手机号、身份证号、住址。
## 禁止事项
- 不得宣称退款已到账,除非 payment_refund_status=SUCCESS。
- 不得跳过 approval.create 直接执行退款。
- 不得在缺少事实数据时猜测物流状态。
5.3 Skill 的工程化关键,不是“能被读懂”,而是“能被验证”
生产环境里,Skill 不应该只是被模型读,还要被测试系统读。
最少要有两类测试:
-
• 规则一致性测试:关键场景是否都触发正确 SOP。 -
• 回归测试:升级 Skill 版本后,老场景是否退化。
例如:
- name: refund_over_limit_requires_approval
input: "订单 A20260430001 申请退款,金额 899 元"
expected:
must_call_tools:
- order.query
- approval.create
must_not_claim:
- "退款已完成"
- name: missing_order_id_should_clarify
input: "帮我查一下订单"
expected:
should_ask_for:
- order_id
这一步非常重要,因为它把“经验资产”从文本提升成了可自动化验证的配置资产。
六、第四层:OpenClaw 解决的不是聊天,而是“统一入口与统一执行语义”
6.1 多渠道接入真正难的不是适配 API,而是语义统一
如果你的 Agent 只在 Web 页面里使用,事情还比较简单。但一旦要接 Slack、飞书、Teams、邮件、CLI,问题会迅速复杂化:
-
• 用户标识不统一 -
• 会话 ID 规则不同 -
• 文件上传方式不同 -
• 消息回执机制不同 -
• 重试投递语义不同 -
• 富文本卡片能力不同
所以 OpenClaw 这类层的价值,不是“多接几个 Bot 平台”,而是把这些差异统一成标准会话协议。
建议在这一层统一四种数据结构:
-
1. Identity:用户、租户、组织、角色 -
2. Session:会话标识、线程标识、渠道标识 -
3. Message:文本、附件、事件、命令 -
4. Delivery:回执、重试、超时、幂等键
6.2 渠道层必须自己做的三件事
第一件事:幂等去重
消息平台在超时或网络抖动时,通常会重复投递事件。如果渠道层不做幂等,Agent 可能会:
-
• 重复发起退款申请 -
• 重复建工单 -
• 重复发送通知
因此,每条入口事件都必须有渠道级幂等键,例如:
idempotency_key = channel + tenant_id + external_message_id
第二件事:会话归一
不要直接让后端依赖 Slack thread_ts、飞书 open_id 这类外部字段,而应该先归一:
{
"tenant_id": "acme",
"channel": "feishu",
"external_user_id": "ou_xxx",
"external_thread_id": "om_xxx",
"normalized_session_id": "acme:feishu:ou_xxx:om_xxx"
}
第三件事:异步回写
对于长耗时任务,不应该占住用户通道请求。正确方式是:
-
1. 渠道层快速 ACK。 -
2. 后台异步执行 Agent。 -
3. 执行完成后再回写消息、卡片或审批结果。
这能显著减少渠道超时和重复投递。
6.3 一个更合理的 OpenClaw 接入架构
Slack / 飞书 / Teams / Web
|
v
OpenClaw Gateway
- identity normalize
- session normalize
- dedupe
- rate limit
- callback adapter
|
v
Agent API / Dify API / Approval API
|
v
Async Worker / Event Bus
这层在架构上非常像 API Gateway + Bot Gateway + Session Gateway 的组合体。
七、第五层:Harness 让 Agent 系统具备“可持续上线能力”
7.1 Agent 的 CI/CD,不能只测接口通不通
传统后端发布,跑单测、集成测试、构建镜像、部署完成,往往就够了。
但 Agent 不是确定性代码,它引入了:
-
• 模型随机性 -
• Prompt 回归 -
• 工具调用偏差 -
• 检索质量波动 -
• 长上下文退化
因此,Agent 的发布流水线至少要补三类验证:
-
1. Prompt Regression Test:关键样例是否稳定。 -
2. Tool Call Verification:模型有没有调用错误工具、传错参数。 -
3. Behavioral Verification:关键业务行为有没有偏离边界。
7.2 一条更适合 Agent 的发布流水线
代码提交
-> 单元测试
-> Skill 用例测试
-> Prompt 回归测试
-> 构建镜像
-> 部署到预发
-> E2E 对话回放
-> Canary 发布
-> 在线指标验证
-> 全量发布 / 自动回滚
如果把 Harness 放进来,它最重要的价值不是“又一个 CI 工具”,而是把验证、灰度、回滚和环境治理接到一条统一流水线上。
7.3 一个生产导向的流水线样例
pipeline:
name: agent-prod-release
identifier: agent_prod_release
stages:
- stage:
name: unit-and-contract-test
type: CI
spec:
execution:
steps:
- step:
type: Run
name: pytest
spec:
shell: bash
command: |
pytest tests/unit tests/contract -q
- step:
type: Run
name: skill-regression
spec:
shell: bash
command: |
python scripts/run_skill_regression.py
- step:
type: Run
name: prompt-regression
spec:
shell: bash
command: |
python scripts/run_prompt_eval.py --dataset evals/core.yaml
- stage:
name: build-image
type: CI
spec:
execution:
steps:
- step:
type: BuildAndPushDockerRegistry
name: build-agent-image
spec:
connectorRef: docker_registry
repo: ai/agent-service
tags:
- "<+pipeline.sequenceId>"
- stage:
name: deploy-canary
type: CD
spec:
execution:
steps:
- step:
type: K8sCanaryDeploy
name: canary-10-percent
- step:
type: ShellScript
name: online-smoke
spec:
shell: Bash
script: |
python scripts/run_online_smoke.py --traffic-sample 200
- step:
type: AIVerification
name: verify-latency-error-cost
spec:
duration: 10m
sensitivity: MEDIUM
rollbackSteps:
- step:
type: K8sRollingRollback
name: rollback-canary
- stage:
name: full-release
type: CD
spec:
execution:
steps:
- step:
type: K8sRollingDeploy
name: full-rollout
这条流水线的关键不是 YAML 本身,而是它体现了 Agent 发布的四个原则:
-
• 上线前要测“行为”,不是只测“接口”。 -
• 灰度后要看“答案质量 + 工具成功率 + 成本”,不是只看 CPU。 -
• 回滚必须自动,不应依赖人工读日志后再决定。 -
• 评测集要长期维护,形成自己的 Agent 质量基线。
八、把五层拼起来:一套电商订单 Agent 的完整生产方案
下面给出一套能落地的参考架构。场景是:
电商平台要做一个智能客服 Agent,支持订单查询、退款申请、物流追踪、地址修改、人工升级工单,并要求支持飞书、Slack、Web 三个入口,具备多租户隔离、审批、审计和高并发能力。
8.1 总体架构
8.2 请求流转过程
-
1. 用户在飞书发起“帮我退款订单 A20260430001”。 -
2. OpenClaw 做身份归一、会话归一、幂等去重。 -
3. Dify 先做基础意图分流和知识召回。 -
4. 命中退款场景后,调用 LangChain Agent Service。 -
5. Agent 先查订单、判断资格、评估风险。 -
6. 若金额超过阈值,调用审批服务创建审批单,而非直接退款。 -
7. 审批通过后,异步 Worker 消费 Kafka 事件执行退款。 -
8. 最终结果通过 OpenClaw 回写到飞书线程。
这个过程有一个非常重要的架构特征:
同一个用户请求,在“智能决策链”和“事务执行链”之间被显式切开。
前者偏推理,后者偏事务。
这样做的好处是:
-
• 模型不直接触碰核心资金动作。 -
• 可重试、可补偿、可审计。 -
• 长耗时动作不会阻塞前台对话。
九、工程化升级重点:高并发、可扩展、可恢复
这一节是很多文章最缺的部分。真正的生产难题基本都集中在这里。
9.1 高并发场景下,Agent 服务最怕什么
不是怕 QPS 高本身,而是怕下面这些“放大器”叠加:
-
• 单请求内多次模型调用 -
• 检索和工具调用串行 -
• 长上下文导致响应时间飙升 -
• 外部依赖慢导致线程堆积 -
• 多租户互相争抢模型配额
所以,Agent 的并发治理不能只看应用服务器线程池,而要看整条链路。
9.2 生产级并发控制模型
推荐至少做五层限流与隔离:
-
1. 入口限流:按租户、按渠道、按用户限流。 -
2. 会话串行:同一会话内高风险写操作串行执行,防止状态竞争。 -
3. 模型配额池:不同租户或场景使用不同模型并发池。 -
4. 工具舱壁隔离:订单、审批、物流等工具调用分开线程池或异步池。 -
5. 异步解耦:超过阈值的任务改为消息驱动。
示意:
Request
-> API Rate Limit
-> Session Lock
-> Agent Concurrency Pool
-> Model Token Budget
-> Tool Bulkhead
-> Async Queue (if long running)
9.3 一个更真实的异步任务拆分策略
把 Agent 动作分成三类:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
这样拆分后,可以避免把所有任务都塞进对话请求里。
9.4 Kafka / Redis / 数据库在 Agent 架构中的职责边界
-
• Redis:会话态、短期缓存、分布式锁、限流计数。 -
• PostgreSQL:订单事实、审批记录、审计日志、任务状态。 -
• Kafka:长任务解耦、事件驱动、重试与补偿流。 -
• Vector DB:长文本知识检索,不承担事务事实源。
一个很常见的反模式是把向量库当“主数据源”。这是危险的。向量库适合“语义近似召回”,不适合“退款金额是否为 899 元”这种强事实判断。
9.5 一个建议的异步退款流程
这个流程比“Agent 直接退款”多了几步,但它有生产价值:
-
• 退款链路可审计 -
• 失败可重试 -
• 幂等好做 -
• 容易加风控和人工兜底
十、代码生产级补全:从 Demo 走向服务化实现
10.1 FastAPI 网关层示例
from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel
app = FastAPI()
class GatewayRequest(BaseModel):
channel: str
tenant_id: str
external_user_id: str
external_message_id: str
session_id: str
text: str
async def dedupe(message_id: str) -> bool:
# 生产中应落 Redis SETNX + TTL
return True
@app.post("/gateway/invoke")
async def invoke(req: GatewayRequest, x_signature: str = Header(default="")):
if not x_signature:
raise HTTPException(status_code=401, detail="missing signature")
ok = await dedupe(req.external_message_id)
if not ok:
return {"status": "duplicate_ignored"}
normalized = {
"tenant_id": req.tenant_id,
"channel": req.channel,
"user_id": f"{req.channel}:{req.external_user_id}",
"session_id": f"{req.tenant_id}:{req.session_id}",
"message": req.text,
}
# 这里可以调用 Dify 或 LangChain 服务
return {"status": "accepted", "payload": normalized}
10.2 LangGraph 风格的状态定义示例
from typing import Literal, TypedDict
class OrderAgentState(TypedDict, total=False):
tenant_id: str
session_id: str
user_message: str
intent: Literal["query_order", "refund", "modify_address", "fallback"]
order_id: str
order_info: dict
risk_level: Literal["low", "medium", "high"]
approval_required: bool
tool_result: dict
final_answer: str
关键点不在语法,而在于:
-
• 状态字段是显式的,便于观测与恢复。 -
• 节点之间靠状态传递,而不是隐式共享变量。 -
• 任何一步失败,都能从状态判断补偿策略。
10.3 Worker 侧的幂等消费示例
import json
from aiokafka import AIOKafkaConsumer
class RefundExecutor:
async def execute(self, refund_request_id: str) -> None:
# 生产中调用支付/订单域服务
print("execute refund", refund_request_id)
async def consume_refund_events():
consumer = AIOKafkaConsumer(
"refund.approved",
bootstrap_servers="kafka:9092",
group_id="refund-worker",
)
executor = RefundExecutor()
await consumer.start()
try:
async for msg in consumer:
event = json.loads(msg.value.decode("utf-8"))
refund_request_id = event["refund_request_id"]
dedupe_key = event["event_id"]
if await is_processed(dedupe_key):
continue
await executor.execute(refund_request_id)
await mark_processed(dedupe_key)
finally:
await consumer.stop()
这里的核心不是 Kafka 用法,而是:
-
• 消费者必须显式幂等。 -
• 业务成功和消息提交要一致设计。 -
• 强副作用动作要有补偿机制。
十一、可观测性不是锦上添花,而是 Agent 生产化的生命线
11.1 只看 QPS 和错误率,根本看不懂 Agent
Agent 系统至少要额外观测六类指标:
-
1. 模型指标:调用次数、平均延迟、Token 输入输出、单位成本。 -
2. 工具指标:每个 Tool 的调用成功率、P95、重试次数。 -
3. 对话指标:平均轮次、澄清率、转人工率、完成率。 -
4. 质量指标:任务成功率、错误工具率、幻觉率、评测得分。 -
5. 安全指标:PII 命中次数、审批拦截次数、策略拒绝次数。 -
6. 业务指标:退款完成时长、订单查询命中率、工单创建率。
11.2 推荐的 Trace 结构
一条完整 Trace 最好串起这些 Span:
gateway.receive
-> session.load
-> retrieval.search
-> agent.plan
-> tool.order.query
-> tool.approval.create
-> memory.persist
-> gateway.reply
这样你在排障时就能快速回答:
-
• 慢在模型,还是慢在工具? -
• 成本高是因为上下文太长,还是多次重试? -
• 用户说“Agent 没做事”,到底是审批卡住了,还是工具失败了?
11.3 建议埋点的 Prometheus 指标
agent_request_total{tenant, channel, intent}
agent_request_latency_ms_bucket{tenant, intent}
agent_llm_tokens_total{model, direction}
agent_tool_call_total{tool, status}
agent_tool_latency_ms_bucket{tool}
agent_approval_required_total{tenant}
agent_policy_block_total{policy}
agent_eval_score{dataset, version}
这些指标会直接决定你有没有能力做:
-
• 租户级成本核算 -
• 渠道级容量规划 -
• 模型级 ROI 优化 -
• 版本级回归对比
十二、安全与治理:Agent 不只是“会做事”,还必须“做得合规”
12.1 最容易被忽略的四类风险
-
• PII 外泄:手机号、身份证、地址、邮箱被直接送到外部模型。 -
• 越权执行:普通客服身份触发管理员动作。 -
• Prompt Injection:用户通过输入诱导 Agent 绕过规则。 -
• 工具越权:一个本该只读的 Agent 拿到了写权限工具。
12.2 安全治理建议
身份与权限
-
• 每个渠道请求必须映射到内部身份。 -
• 工具权限按租户、角色、场景最小化发放。 -
• 模型层不可信,策略层必须独立判定授权。
数据与合规
-
• 敏感字段在进入模型前脱敏。 -
• 审计日志记录谁在什么时候触发了什么动作。 -
• 关键结果保留原始事实来源,避免“只留最终答案”。
Prompt 与 Tool 防护
-
• System Prompt 明确禁止绕过业务策略。 -
• Tool Schema 要求强类型参数校验。 -
• 对所有外部文本执行注入风险过滤,不把检索文档直接当系统指令。
12.3 一个实用的策略分层模型
L1: Channel Policy -> 签名校验、IP 白名单、限流
L2: Identity Policy -> 用户/租户/角色鉴权
L3: Agent Policy -> 场景可用模型、最大上下文、技能白名单
L4: Tool Policy -> 可调用工具、参数范围、审批门槛
L5: Data Policy -> 脱敏、审计、存储与保留
这比把所有规则堆在一个 Prompt 里可靠得多。
十三、文章结构升级后的落地路线图
对于大多数团队,我建议按下面五个阶段推进,而不是一开始就追求“全栈大平台”。
Phase 1:可验证原型
-
• 用 LangChain 做最小 Agent 闭环。 -
• 明确只读 Tool 与写 Tool 边界。 -
• 建立最初的 20 到 50 条评测样例。
目标:
验证业务价值,不追求复杂架构。
Phase 2:服务化与基本治理
-
• 把 Agent 封装成独立微服务。 -
• 接入 Redis、PostgreSQL、基础日志与指标。 -
• 增加超时、重试、结构化输出、幂等。
目标:
从“能跑”升级到“能部署”。
Phase 3:平台化与多人协作
-
• 引入 Dify 承接工作流与知识库配置。 -
• 把核心领域流程抽成 Skills。 -
• 建立 Prompt / Skill 回归测试。
目标:
从“研发驱动”升级到“产品、运营可参与”。
Phase 4:高并发与异步化
-
• 接入 Kafka 处理长任务。 -
• 渠道层做幂等和会话归一。 -
• 加入审批流、补偿流、异步回写。
目标:
从“能上线”升级到“能扛流量”。
Phase 5:多 Agent 与企业治理
-
• 用 LangGraph 构建多 Agent 协作。 -
• 用 Harness 打通评测、灰度、回滚。 -
• 建立租户级成本、质量、安全治理闭环。
目标:
从“单点应用”升级到“企业级 Agent 平台”。
十四、最后给出一份生产级 Kubernetes 部署参考
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-service
namespace: ai-agent
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: agent-service
template:
metadata:
labels:
app: agent-service
spec:
containers:
- name: agent-service
image: registry.example.com/ai/agent-service:1.0.0
ports:
- containerPort: 8080
env:
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: agent-secret
key: redis-url
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: agent-secret
key: database-url
- name: MODEL_API_KEY
valueFrom:
secretKeyRef:
name: agent-secret
key: model-api-key
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "4Gi"
readinessProbe:
httpGet:
path: /health/readiness
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health/liveness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: agent-service-hpa
namespace: ai-agent
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: agent-service
minReplicas: 4
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75
部署侧还建议再补三样东西:
-
• PodDisruptionBudget:避免节点维护时服务瞬时掉空。 -
• PriorityClass:关键 Agent 服务优先保活。 -
• NetworkPolicy:把模型网关、数据库、消息队列访问边界收紧。
十五、总结:五层拼图真正拼出来的,不是工具链,而是 Agent 生产方法论
如果只看表面,LangChain、Dify、Skills、OpenClaw、Harness 像是五个不同方向的产品;但从工程角度看,它们拼出的其实是一条完整的生产链路:
-
• LangChain / LangGraph 解决“智能行为如何可靠执行”。 -
• Dify 解决“业务流程如何被非研发角色参与配置”。 -
• Skills 解决“领域经验如何标准化沉淀与复用”。 -
• OpenClaw 解决“多渠道入口如何统一会话与执行语义”。 -
• Harness 解决“Agent 系统如何持续发布、验证、回滚和治理”。
所以,真正成熟的选型问题不是“这五个谁更强”,而是下面三个更本质的问题:
-
1. 你的 Agent 是停留在 Demo,还是要承接真实业务副作用? -
2. 你的团队是研发单兵作战,还是需要产品、运营、安全、运维共同参与? -
3. 你要的是“做出一个会聊天的机器人”,还是“建设一个可迭代、可治理、可审计的智能系统”?
如果答案偏向后者,那么你需要的就不再是单一框架,而是一整套分层架构。
一句话收束全文:
LangChain 负责把智能跑起来,Dify 负责把业务配起来,Skills 负责把经验沉下来,OpenClaw 负责把能力送出去,Harness 负责把系统稳住;五层协同,才是 AI Agent 真正走向生产的完整路径。
夜雨聆风