为什么我们在生产中用原始 Anthropic SDK 替代了 LangChain
Source: Dev.to

症状
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 重写的基准测试。你可能会感到惊讶。