别再死磕OpenAI API Key了!用LangChain 0.1.x 轻松接入本地ChatGLM3或智谱GLM-4
·
解放生产力:LangChain 0.1.x 本地模型与智谱GLM-4的无缝接入指南
当你在GitHub上发现一个令人兴奋的AI项目,正准备大展拳脚时,却看到这样的代码片段:
os.environ["OPENAI_API_KEY"] = "sk-..."
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4")
这种OpenAI API依赖不仅增加了开发成本,还可能因为网络限制让项目陷入停滞。本文将带你突破这一瓶颈,实现从"API Key奴隶"到"本地模型主人"的转变。
1. 为什么需要摆脱OpenAI API依赖
在当前的AI开发环境中,过度依赖单一商业API会带来三大核心问题:
- 成本不可控 :按token计费的模式在长期运行中可能产生巨额费用
- 网络限制 :部分地区访问稳定性差,影响开发效率
- 数据隐私 :敏感业务数据需要留在本地环境
本地模型与国产大模型的崛起 为解决这些问题提供了新选择。以ChatGLM3-6B为代表的本地可部署模型,以及智谱AI的GLM-4等国产大模型,正在性能上快速追赶国际领先水平。
提示:根据实际测试,ChatGLM3-6B在中文任务上的表现已接近GPT-3.5水平,而GLM-4在部分专业领域甚至超越了GPT-4的中文能力。
2. LangChain的模块化设计哲学
LangChain之所以能成为大模型应用开发的事实标准,其核心在于优秀的抽象设计。理解这一点是进行自定义扩展的关键。
2.1 LLM基类的核心方法
LangChain中的 LLM 基类主要定义了以下必须实现的方法:
| 方法名 | 作用 | 是否必须 |
|---|---|---|
_call |
核心推理逻辑 | 是 |
_llm_type |
标识模型类型 | 是 |
_identifying_params |
返回模型参数 | 否 |
from langchain.llms.base import LLM
from typing import Optional, List
class CustomLLM(LLM):
def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
# 实现你的模型调用逻辑
return "模型响应"
@property
def _llm_type(self) -> str:
return "custom"
2.2 ChatOpenAI类的特殊设计
与基础LLM类不同, ChatOpenAI 还包含了对话特有的功能:
- 消息历史管理
- 角色系统(user/assistant)
- 更复杂的参数控制
from langchain_openai import ChatOpenAI
class CustomChat(ChatOpenAI):
def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
# 重写调用逻辑
messages = [{"role": "user", "content": prompt}]
return self.custom_completion(messages)
3. 实战:ChatGLM3本地模型集成
3.1 环境准备与模型加载
首先确保已安装必要依赖:
pip install langchain==0.1.x transformers torch
本地模型加载的核心代码:
from transformers import AutoTokenizer, AutoModel
import torch
class ChatGLM3Loader:
def __init__(self, model_path: str, quantize: bool = False):
self.tokenizer = AutoTokenizer.from_pretrained(
model_path, trust_remote_code=True
)
self.model = AutoModel.from_pretrained(
model_path, trust_remote_code=True
).half()
if quantize:
self.model = self.model.quantize(8)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
self.model = self.model.to(device)
self.model.eval()
3.2 完整LangChain集成方案
将本地模型封装为LangChain兼容的LLM类:
from langchain.llms.base import LLM
from langchain.llms.utils import enforce_stop_tokens
class ChatGLM3_LLM(LLM):
def __init__(self, model_path: str, quantize: bool = False):
super().__init__()
self.loader = ChatGLM3Loader(model_path, quantize)
self.history = []
def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
response, self.history = self.loader.model.chat(
self.loader.tokenizer,
prompt,
history=self.history,
max_length=8192,
temperature=0.7
)
if stop:
response = enforce_stop_tokens(response, stop)
return response
@property
def _llm_type(self) -> str:
return "chatglm3"
4. 智谱GLM-4 API的高效接入
4.1 API密钥配置与初始化
首先安装官方SDK:
pip install zhipuai
创建自定义LLM类:
from langchain.llms.base import LLM
from typing import Optional, List
class GLM4_LLM(LLM):
def __init__(self, api_key: str):
super().__init__()
self.api_key = api_key
def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
from zhipuai import ZhipuAI
client = ZhipuAI(api_key=self.api_key)
response = client.chat.completions.create(
model="glm-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
result = response.choices[0].message.content
if stop:
result = enforce_stop_tokens(result, stop)
return result
@property
def _llm_type(self) -> str:
return "glm4"
4.2 高级功能扩展
智谱API支持更多专业参数:
response = client.chat.completions.create(
model="glm-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
top_p=0.9,
max_tokens=1024,
tools=[...], # 函数调用支持
tool_choice="auto"
)
5. 项目迁移实战技巧
5.1 最小化修改原则
当接手一个基于OpenAI的项目时,遵循以下步骤进行迁移:
- 定位LLM初始化代码 :通常集中在配置模块或工厂类中
- 创建替换类 :根据项目需求选择继承
LLM或ChatOpenAI - 保持接口一致 :确保输入输出格式与原有代码兼容
- 逐步替换测试 :先替换非核心功能,验证通过后再全面迁移
5.2 常见问题解决方案
问题1 :项目使用了 ChatOpenAI 特有的方法
# 原项目代码
messages = [{"role": "system", "content": "你是一个助手"}]
llm.predict_messages(messages)
# 解决方案
class CustomChat(ChatOpenAI):
def predict_messages(self, messages):
# 实现自定义逻辑
return self._call(messages[-1]["content"])
问题2 :需要支持流式输出
def _stream(self, prompt: str, stop: Optional[List[str]] = None):
# 实现流式响应逻辑
for chunk in self.model.stream_chat(...):
yield chunk
在实际项目中,最耗时的往往不是技术实现,而是对原有代码架构的理解。建议先从简单的示例项目开始练习,逐步掌握迁移模式。
更多推荐


所有评论(0)