" />
文章

LangChain vs 直接 API 调用对比指南

LangChain vs 直接 API 调用对比指南

1. 基础架构对比

系统架构图

graph TB subgraph LangChain架构 A[用户输入] --> B[LangChain Chain] B --> C[Memory系统] B --> D[Tools/Agents] B --> E[LLM接口] E --> F[API调用] C --> B D --> B end subgraph 直接API架构 G[用户输入] --> H[API封装] H --> I[API调用] end

2. 连续对话能力对比

LangChain 连续对话实现

from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
from langchain.chat_models import ChatOpenAI
​
# 初始化对话记忆和模型
memory = ConversationBufferMemory()
llm = ChatOpenAI(temperature=0.7)
conversation = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True
)
​
# 连续对话示例
response1 = conversation.predict(input="你好,我叫小明")
response2 = conversation.predict(input="我刚才说我叫什么?")  # 能够记住上下文

直接 API 连续对话实现

class Conversation:
    def __init__(self):
        self.messages = []
    
    def chat(self, message: str) -> str:
        # 添加用户消息
        self.messages.append({"role": "user", "content": message})
        
        # API 调用
        response = requests.post(
            "API_ENDPOINT",
            headers={"Authorization": f"Bearer {API_KEY}"},
            json={
                "messages": self.messages,
                "temperature": 0.7
            }
        )
        
        # 保存助手回复
        assistant_message = response.json()['choices'][0]['message']
        self.messages.append(assistant_message)
        
        return assistant_message['content']

# 使用示例
conversation = Conversation()
response1 = conversation.chat("你好,我叫小明")
response2 = conversation.chat("我刚才说我叫什么?")

对话流程图

sequenceDiagram participant U as 用户 participant L as LangChain participant M as 记忆系统 participant A as API U->>L: 发送消息1 L->>M: 存储消息 L->>A: API调用 A->>L: 返回响应 L->>M: 存储响应 L->>U: 返回响应 U->>L: 发送消息2 L->>M: 获取历史对话 L->>M: 存储新消息 L->>A: API调用(带历史) A->>L: 返回响应 L->>M: 存储响应 L->>U: 返回响应

3. 插件(Tools)能力对比

LangChain Tools 实现

from langchain.agents import load_tools, initialize_agent
from langchain.agents import AgentType
from langchain.tools import Tool
from langchain.utilities import GoogleSearchAPIWrapper
​
# 加载预定义工具
tools = load_tools(["google-search", "llm-math"])
​
# 自定义工具
def get_weather(location: str) -> str:
    """获取指定位置的天气信息"""
    # 实现天气查询逻辑
    return f"{location}的天气信息"
​
# 创建自定义工具
custom_tool = Tool(
    name="Weather",
    func=get_weather,
    description="获取指定位置的天气信息"
)
​
# 添加到工具列表
tools.append(custom_tool)
​
# 初始化 agent
agent = initialize_agent(
    tools, 
    llm, 
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)
​
# 使用 agent
response = agent.run("北京今天的天气怎么样?顺便帮我计算一下 23 * 45")

直接 API 实现插件功能

class APIWithTools:
    def __init__(self):
        self.tools = {
            "weather": self.get_weather,
            "calculator": self.calculate,
            "search": self.search
        }
    
    def get_weather(self, location: str) -> str:
        # 实现天气查询逻辑
        return f"{location}的天气信息"
    
    def calculate(self, expression: str) -> str:
        # 实现计算逻辑
        return str(eval(expression))
    
    def search(self, query: str) -> str:
        # 实现搜索逻辑
        return f"搜索结果: {query}"
    
    def process_with_tools(self, message: str) -> str:
        # 调用API判断是否需要使用工具
        response = requests.post(
            "API_ENDPOINT",
            json={
                "messages": [{"role": "user", "content": message}],
                "tools": list(self.tools.keys())
            }
        )
        
        # 如果需要使用工具,先执行工具调用
        if "tool_calls" in response.json():
            tool_results = []
            for tool_call in response.json()["tool_calls"]:
                tool_name = tool_call["name"]
                tool_args = tool_call["arguments"]
                result = self.tools[tool_name](**tool_args)
                tool_results.append(result)
            
            # 将工具结果发送给API
            final_response = requests.post(
                "API_ENDPOINT",
                json={
                    "messages": [
                        {"role": "user", "content": message},
                        {"role": "assistant", "content": "工具调用结果:" + str(tool_results)}
                    ]
                }
            )
            return final_response.json()["choices"][0]["message"]["content"]
        
        return response.json()["choices"][0]["message"]["content"]

工具调用流程图

API工具调用

graph TB subgraph 自定义工具调用 I[用户输入] --> J[API判断] J --> K{需要工具?} K -->|是| L[工具执行] L --> M[结果整合] K -->|否| N[直接回复] M --> O[最终响应] N --> O end

LangChain工具调用

graph TB subgraph LangChain工具调用 A[用户输入] --> B[Agent] B --> C{需要工具?} C -->|是| D[工具选择] D --> E[工具执行] E --> F[结果整合] C -->|否| G[直接回复] F --> H[最终响应] G --> H end

4. 记忆系统对比

记忆类型图

graph LR subgraph LangChain记忆系统 A[ConversationBufferMemory] --> B[完整对话历史] C[ConversationBufferWindowMemory] --> D[滑动窗口历史] E[ConversationSummaryMemory] --> F[对话摘要] G[ConversationTokenBufferMemory] --> H[Token限制历史] end subgraph 直接API记忆系统 I[消息数组] --> J[手动管理历史] K[自定义存储] --> L[数据库存储] end

5. 选择建议

功能需求矩阵

graph TB subgraph 需求分析 A[项目需求] --> B{是否需要工具集成?} B -->|是| C[选择LangChain] B -->|否| D{是否需要复杂记忆?} D -->|是| C D -->|否| E{是否是简单对话?} E -->|是| F[选择直接API] E -->|否| C end

6. 注意事项

LangChain 注意点

  1. 学习曲线较陡

  2. 需要理解框架概念

  3. 版本更新可能带来变化

  4. 可能存在性能开销

  5. 工具配置需要额外设置

直接 API 注意点

  1. 需要自行实现功能

  2. 错误处理需要更多代码

  3. 扩展性需要自行设计

  4. 维护成本可能更高

  5. 工具集成需要自行开发

7. 性能对比

响应时间对比

graph LR subgraph LangChain性能 A[请求] --> B[框架处理] B --> C[工具调用] C --> D[API调用] D --> E[响应] E --> F[结果处理] end

graph LR subgraph 直接API性能 G[请求] --> H[API调用] H --> I[响应] end

8. 开发效率对比

开发时间估算

pie title 功能开发时间占比 "基础对话" : 10 "记忆系统" : 25 "工具集成" : 35 "错误处理" : 15 "测试调试" : 15

LangChain 通过提供现成的组件大大减少了开发时间,特别是在实现复杂功能时。而直接 API 调用虽然前期开发较快,但随着功能复杂度增加,开发时间会显著增长。

License:  CC BY 4.0