乐于分享
好东西不私藏

从 LangChain 到 OpenClaw:AI Agent 工程化的五层拼图与生产落地全攻略

从 LangChain 到 OpenClaw:AI Agent 工程化的五层拼图与生产落地全攻略

从 LangChain 到 OpenClaw:AI Agent 工程化的五层拼图与生产落地全攻略

真正能上线的 Agent,从来不是“模型 + Prompt”这么简单。它本质上是一套分层系统:底层要有可靠的推理运行时,中层要有工作流和知识编排,上层要有能力封装、渠道接入与工程化交付,外围还要补齐安全、观测、弹性和治理。本文以 LangChain、Dify、Agent Skills、OpenClaw、Harness 为线索,系统讲清 AI Agent 从原理到架构、从代码到生产的完整落地路径。


一、先把问题说透:为什么很多 Agent Demo 一上线就失灵

过去一年,很多团队都经历过类似路径:

  1. 1. 用一个大模型加几个 Tool,很快做出一个“会对话、会查数据、会调接口”的 Demo。
  2. 2. 在测试环境里效果惊艳,产品、运营、老板都觉得“这事快成了”。
  3. 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 在复杂任务里如何可靠执行
Dify
工作流、知识库、模型运营
非研发如何参与配置与运营
Skills
领域能力封装
如何把经验固化成可复用资产
OpenClaw
多渠道接入、会话统一
用户从哪里来,Agent 就在哪里服务
Harness
构建、测试、发布、验证
如何把 Agent 当生产系统运维

三、第一层:LangChain / LangGraph 是 Agent 的运行时内核

3.1 为什么说 Agent 不是函数调用,而是状态机

很多人把 Agent 理解成:

用户输入 -> LLM -> 输出答案

而生产级 Agent 更接近:

用户输入
  -> 意图识别
  -> 状态装载
  -> 检索上下文
  -> 规划动作
  -> 调用工具
  -> 验证结果
  -> 可能人工审批
  -> 写入记忆
  -> 输出答案

这已经不是一个普通函数,而是一个可中断、可恢复、可追踪的有状态流程。

从原理上看,Agent 至少包含五个核心部件:

  1. 1. Planner:决定下一步做什么。
  2. 2. Tool Executor:真正执行外部动作。
  3. 3. Memory Manager:管理短期上下文、长期记忆与摘要。
  4. 4. Policy Layer:审批、脱敏、限流、重试、审计。
  5. 5. State Store:让流程可恢复、可重放、可追踪。

LangChain 提供高层 Agent 抽象,LangGraph 更像底层状态图运行时。对于简单场景,create_agent 很高效;对于多步骤、长流程、可恢复任务,图式编排更稳。

3.2 单 Agent 的上限,往往不是模型,而是上下文和副作用

一个只读型 FAQ Agent 很容易做;难的是具备真实业务动作的 Agent,例如:

  • • 查订单
  • • 发起退款
  • • 查询库存
  • • 修改收货地址
  • • 触发人工审批
  • • 通知物流系统

这些动作会带来三个工程问题:

  • • 副作用:一旦写库、发消息、调支付接口,就必须考虑幂等。
  • • 不确定性:模型可能反复调用工具,也可能输出错误参数。
  • • 长耗时:库存、物流、审批这类调用可能横跨秒级到分钟级。

因此,生产级 LangChain 方案不应该只是“把 Tool 注册进去”,而应该建立明确边界:

  • • Agent 只负责决策,不直接持有关键写操作权限。
  • • 所有写操作必须经由受控应用服务。
  • • 工具调用结果必须结构化、可验证、可审计。
  • • 高风险动作必须支持人工确认和异步补偿。

3.3 一个更接近生产的 LangChain 服务骨架

下面这段代码不是玩具 Demo,而是一个更接近真实生产的最小骨架。重点在四件事:

  1. 1. 结构化输出
  2. 2. 工具超时与重试
  3. 3. 幂等键
  4. 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

Receive Request

Load Session State

Classify Intent

Retrieve Context

Plan Action

Need Approval?

Create Approval Task

Wait For Human

Resume Workflow

Execute Tool

Success?

Retry / Compensate

Escalate or Fail

Persist Memory

Return Response

从架构视角看,LangGraph 的价值不只是“能画图”,而是它天然适合承载这些生产需求:

  • • 中断恢复:审批回来后接着跑,而不是整段重来。
  • • 状态持久化:支持 checkpoint,方便恢复和调试。
  • • 显式节点边界:每一步都可以埋点、限流、熔断。
  • • 多 Agent 协作:Supervisor 分配给 FAQ Agent、Order Agent、Risk Agent。

四、第二层:Dify 的价值,不是替代代码,而是承接业务运营面

4.1 Dify 最适合解决什么问题

如果 LangChain 擅长的是“深度定制”,那 Dify 擅长的是“规模化配置”。

当一个团队进入下面这个阶段时,Dify 的价值会迅速放大:

  • • 产品希望自己调 Prompt、调流程、调知识库。
  • • 运营需要可视化测试和回放,而不是让研发帮忙打印日志。
  • • 不同场景要切换不同模型、不同知识源、不同输出模板。
  • • 同一个 Agent 要暴露成 UI 应用、内部 API、测试沙箱。

Dify 本质上提供了四块控制面:

  1. 1. Workflow Control Plane:把流程从代码抽成可视化编排。
  2. 2. Knowledge Control Plane:文档切分、索引、召回、重建。
  3. 3. Prompt / Model Ops:多模型配置、版本切换、评测对比。
  4. 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. 1. Prompt 越来越长,维护成本越来越高。
  2. 2. 规则散落在不同 Agent、不同项目中,无法复用。
  3. 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. 1. Identity:用户、租户、组织、角色
  2. 2. Session:会话标识、线程标识、渠道标识
  3. 3. Message:文本、附件、事件、命令
  4. 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. 1. 渠道层快速 ACK。
  2. 2. 后台异步执行 Agent。
  3. 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. 1. Prompt Regression Test:关键样例是否稳定。
  2. 2. Tool Call Verification:模型有没有调用错误工具、传错参数。
  3. 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 总体架构

Slack User

OpenClaw Gateway

Feishu User

Web User

Session Service

Dify Workflow

LangChain Agent Service

Redis

PostgreSQL

Vector DB

Kafka

Order Service

Approval Service

Ticket Service

Async Worker

Harness Pipeline

Prometheus / Grafana / OTEL

8.2 请求流转过程

  1. 1. 用户在飞书发起“帮我退款订单 A20260430001”。
  2. 2. OpenClaw 做身份归一、会话归一、幂等去重。
  3. 3. Dify 先做基础意图分流和知识召回。
  4. 4. 命中退款场景后,调用 LangChain Agent Service。
  5. 5. Agent 先查订单、判断资格、评估风险。
  6. 6. 若金额超过阈值,调用审批服务创建审批单,而非直接退款。
  7. 7. 审批通过后,异步 Worker 消费 Kafka 事件执行退款。
  8. 8. 最终结果通过 OpenClaw 回写到飞书线程。

这个过程有一个非常重要的架构特征:

同一个用户请求,在“智能决策链”和“事务执行链”之间被显式切开。

前者偏推理,后者偏事务。

这样做的好处是:

  • • 模型不直接触碰核心资金动作。
  • • 可重试、可补偿、可审计。
  • • 长耗时动作不会阻塞前台对话。

九、工程化升级重点:高并发、可扩展、可恢复

这一节是很多文章最缺的部分。真正的生产难题基本都集中在这里。

9.1 高并发场景下,Agent 服务最怕什么

不是怕 QPS 高本身,而是怕下面这些“放大器”叠加:

  • • 单请求内多次模型调用
  • • 检索和工具调用串行
  • • 长上下文导致响应时间飙升
  • • 外部依赖慢导致线程堆积
  • • 多租户互相争抢模型配额

所以,Agent 的并发治理不能只看应用服务器线程池,而要看整条链路。

9.2 生产级并发控制模型

推荐至少做五层限流与隔离:

  1. 1. 入口限流:按租户、按渠道、按用户限流。
  2. 2. 会话串行:同一会话内高风险写操作串行执行,防止状态竞争。
  3. 3. 模型配额池:不同租户或场景使用不同模型并发池。
  4. 4. 工具舱壁隔离:订单、审批、物流等工具调用分开线程池或异步池。
  5. 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 一个建议的异步退款流程

Order ServiceRefund WorkerKafkaApproval ServiceAgent ServiceOpenClawUserOrder ServiceRefund WorkerKafkaApproval ServiceAgent ServiceOpenClawUser请求退款归一化请求查询订单返回订单信息创建审批单PENDING_APPROVAL告知用户等待审批审批通过事件consume refund.approved执行退款SUCCESS回写结果

这个流程比“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. 1. 模型指标:调用次数、平均延迟、Token 输入输出、单位成本。
  2. 2. 工具指标:每个 Tool 的调用成功率、P95、重试次数。
  3. 3. 对话指标:平均轮次、澄清率、转人工率、完成率。
  4. 4. 质量指标:任务成功率、错误工具率、幻觉率、评测得分。
  5. 5. 安全指标:PII 命中次数、审批拦截次数、策略拒绝次数。
  6. 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. 1. 你的 Agent 是停留在 Demo,还是要承接真实业务副作用?
  2. 2. 你的团队是研发单兵作战,还是需要产品、运营、安全、运维共同参与?
  3. 3. 你要的是“做出一个会聊天的机器人”,还是“建设一个可迭代、可治理、可审计的智能系统”?

如果答案偏向后者,那么你需要的就不再是单一框架,而是一整套分层架构。

一句话收束全文:

LangChain 负责把智能跑起来,Dify 负责把业务配起来,Skills 负责把经验沉下来,OpenClaw 负责把能力送出去,Harness 负责把系统稳住;五层协同,才是 AI Agent 真正走向生产的完整路径。

本站作品均采用知识共享署名-非商业性使用-相同方式共享 4.0进行许可,资源收集于网络仅供用于学习和交流,本站一切资源不代表本站立场,我们尊重软件和教程作者的版权,如有不妥请联系本站处理!

 沪ICP备2023009708号

© 2017-2026 夜雨聆风   | sitemap | 网站地图