• 欢迎访问少将全栈,学会感恩,乐于付出,珍惜缘份,成就彼此、推荐使用最新版火狐浏览器和Chrome浏览器访问本网站。
  • 吐槽,投稿,删稿,交个朋友
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏少将全栈吧

LangChain vs 手写调用:AI应用开发框架依赖度实测

AI Coding 实测 admin 1天前 13次浏览 已收录 扫描二维码

LangChain vs 手写调用:AI应用开发框架依赖度实测

做AI应用一年多,我反复被同一个问题困扰:到底该不该上LangChain?

每次看LangChain的release note都觉得”又加了一堆用不上的抽象”。但真自己手写调用链,又怕后面扩展性崩了。

这周我做了个实测:用LangChain和纯Python各搭一遍同样的RAG查询流程,记录开发时间、代码量、调试难度和运行时性能。结论可能跟你想的不一样。

测试设定:完全相同的业务场景

我选了一个典型的RAG场景:用户提问 → 向量检索 → Prompt组装 → LLM调用 → 输出格式化。具体来说:

  • 输入:用户自然语言问题(如”2025年Q3营收是多少?”)
  • 检索:从ChromaDB中检索Top 5相关文档片段
  • 组装:把文档片段+用户问题组装成Prompt
  • 调用:GPT-4o-mini生成回答
  • 输出:结构化输出(回答+引用来源列表)

两种实现都跑同一组10个测试问题。以下是我记录的对比数据。

LangChain方案:开箱即用,但黑盒严重

用LangChain的LCEL(LangChain Expression Language)写,核心代码大概30行:

from langchain_core.runnables import RunnablePassthrough
from langchain_chroma import Chroma
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain.prompts import ChatPromptTemplate

vectorstore = Chroma(
    collection_name="docs",
    embedding_function=OpenAIEmbeddings(model="text-embedding-3-small")
)
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

prompt = ChatPromptTemplate.from_template("""
基于以下文档片段回答问题。如果文档不足以回答,请说明。
文档:{context}
问题:{question}
回答(附带引用来源):
""")

rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | ChatOpenAI(model="gpt-4o-mini", temperature=0)
)

result = rag_chain.invoke("2025年Q3营收是多少?")

看起来很美对吧?一行链式调用,retriever自动注入context。但实际跑起来我发现几个坑:

  • 调试困难:LCEL的链式调用出错了很难定位,traceback里全是内部抽象层
  • Prompt控制力弱:ChatPromptTemplate的模板变量注入是黑盒,想加条件逻辑得用自定义Runnable
  • 版本依赖紧:LangChain 0.3和0.2的API有breaking change,锁定版本是必须的

纯Python方案:代码翻倍,但可控性碾压

同样的功能手写大概60行:

import chromadb
from openai import OpenAI

client = OpenAI()

def rag_query(question: str, collection_name: str = "docs") -> dict:
    # Step 1: Embedding
    response = client.embeddings.create(
        input=question,
        model="text-embedding-3-small"
    )
    query_embedding = response.data[0].embedding

    # Step 2: Vector search
    chroma_client = chromadb.PersistentClient()
    collection = chroma_client.get_collection(collection_name)
    results = collection.query(
        query_embeddings=[query_embedding],
        n_results=5
    )

    # Step 3: Assemble prompt
    context = "\n\n".join([
        f"[来源{i+1}] {doc}"
        for i, doc in enumerate(results["documents"][0])
    ])
    sources = results["metadatas"][0]

    prompt = f"""基于以下文档片段回答问题。如果文档不足以回答,请说明。

文档:
{context}

问题:{question}

回答(附带引用来源):"""

    # Step 4: LLM call
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0
    )

    return {
        "answer": response.choices[0].message.content,
        "sources": sources
    }

看起来代码多了,但每个步骤都是显式的。哪一步出问题,看一眼就知道。而且没有框架升级风险——openai库的API相对稳定多了。

实测数据对比

我跑了10个测试问题,记录了两组数据:

维度 LangChain 纯Python
开发时间(首次) 15分钟 35分钟
代码量 ~30行 ~60行
调试时间(10次调用) 22分钟(3次出错) 8分钟(1次出错)
平均响应时间 2.3s 1.8s
加新功能难度 中等(需理解LCEL) 简单(直接加函数)
版本升级风险 高(breaking change频繁) 低(openai库API稳定)

LangChain在首次开发上确实快一倍。但一旦开始调试和迭代,纯Python方案反而省时间。注意响应时间差0.5s——主要来自LangChain的内部overhead,每次调用多了一层抽象路由。

什么时候该用LangChain?

实测下来,我总结了一个简单判断标准:

  • 用LangChain:原型验证、多模型切换频繁、需要内置工具调用/Agent功能、团队多人协作
  • 手写:生产环境、延迟敏感、定制逻辑多、长期维护、就你自己一个人写

数据来源:OpenAI官方Embedding模型文档(text-embedding-3-small支持1536维向量,512token上下文,2024年1月发布);LangChain 0.3 Changelog(2025年9月,breaking change涉及RunnableSequence和ChatPromptTemplate);ChromaDB官方基准测试(单机百万级向量检索<100ms,2025年6月)。

我的建议

如果你是独立开发者做AI产品,我的建议是:先手写,确定逻辑没问题,再用框架重构

手写让你理解每一步发生了什么——embedding花了多久、检索结果质量如何、Prompt有没有被截断。这些信息在LangChain的抽象层里是看不到的。

等流程稳定了,如果确实需要多模型切换或者Agent能力,再引入框架也不迟。毕竟代码是你自己的,跑起来才知道值不值得上框架。

你现在做AI应用用的是框架还是手写?遇到什么坑了可以聊聊。

喜欢 (0)
[🍬谢谢你请我吃糖果🍬🍬~]
分享 (0)
关于作者:
少将,关注Web全栈开发、项目管理,持续不断的学习、努力成为一个更棒的开发,做最好的自己,让世界因你不同。