为什么我们在生产中用原始 Anthropic SDK 替代了 LangChain

发布: (2026年4月21日 GMT+8 19:40)
5 分钟阅读
原文: Dev.to

Source: Dev.to

《为什么我们在生产中用原始 Anthropic SDK 替代 LangChain》封面图片

症状

LangChain 的抽象在我们超出演示的 happy‑path 时就开始泄漏。三件事一直困扰着我们:

来自地狱的堆栈跟踪。 单次 AgentExecutor.invoke() 调用要穿过 14 层 LangChain 内部代码,才到达我们的代码。调试格式错误的工具调用感觉像在进行考古。

版本 churn。 每一次小幅升级都会重命名、迁移或废弃我们依赖的某些内容。我们的 CI 为了保持绿色状态,整整六个月都固定在某个特定的 LangChain SHA 上。

抽象掉的可观测性。 我们无法在不对内部类进行猴子补丁的情况下,干净地追踪 token 使用、缓存命中或每个工具的延迟。

与此同时,Anthropic 的原生 SDK 正在变得更好。原生工具调用、提示缓存、扩展思考、流式输出——全部是一等公民并且有文档支持。

重构

我们使用 LangChain 的逻辑并不复杂:

  • 从模板构建系统提示
  • 使用工具列表调用 Claude
  • 将工具调用路由到我们的内部处理程序
  • 返回结果

我们用以下代码取代了约 800 行 LangChain 粘合代码:

from anthropic import Anthropic

client = Anthropic()

def run_agent(user_input: str, tools: list[dict], tool_handlers: dict):
    messages = [{"role": "user", "content": user_input}]

    while True:
        response = client.messages.create(
            model="claude-opus-4-7",
            max_tokens=4096,
            tools=tools,
            messages=messages,
            system=SYSTEM_PROMPT,
        )

        if response.stop_reason == "end_turn":
            return response.content[0].text

        # Handle tool use
        tool_calls = [b for b in response.content if b.type == "tool_use"]
        messages.append({"role": "assistant", "content": response.content})

        tool_results = []
        for call in tool_calls:
            result = tool_handlers[call.name](**call.input)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": call.id,
                "content": str(result),
            })
        messages.append({"role": "user", "content": tool_results})

就是这样。没有 AgentExecutor,没有 Callback,没有 ConversationBufferMemory。只有模型和我们的代码。

指标

我们在 Vettio 的面试机器人服务上并行运行旧路径和新路径两周,得到以下结果:

  • p50 latency: 2.1 s → 1.4 s (‑33%)
  • p95 latency: 4.8 s → 3.2 s (‑33%)
  • Error rate: 0.9 % → 0.2 %
  • Stack trace depth on errors: 14 → 4 frames
  • Lines of integration code: 812 → 187

延迟的提升主要来源于消除了 LangChain 在工具使用不匹配时的隐式“重试‑再重试”行为。使用直接的 SDK 调用时,若工具模式错误会立即报错,而不是悄悄重试三次。

当 LangChain 仍然有意义

这并不是一篇“一概不使用 LangChain”的帖子。如果你需要以下情况,它仍然是值得选择的:

  • 多提供商抽象。 在一个稳定的接口后面,能够在 Claude、GPT‑4 和 Gemini 之间切换。
  • LangGraph 工作流,用于图形化的代理拓扑结构,而无需从头自行构建。
  • LangSmith 可观测性,你不想自己重新实现。

对于已经承诺使用某一家提供商(我们全力投入 Claude)并且希望对提示、工具模式以及可观测性拥有完整控制的团队来说,原生 SDK 是 2026 年的正确工具。

课程

抽象在底层 API 表现不佳时能够自行收回成本。Anthropic 的 API 并不糟糕。它干净、文档完善且稳定。抽象的代价是真实存在的;抽象的收益已经悄然消失。

如果你在生产环境的 Claude 应用中仍然使用 LangChain,请对关键路径进行直接 SDK 重写的基准测试。你可能会感到惊讶。

0 浏览
Back to Blog

相关文章

阅读更多 »