跳到主要内容
LLM 局限性解析与 LangChain 框架初探 | 极客日志
Python AI 算法
LLM 局限性解析与 LangChain 框架初探 综述由AI生成 探讨了大型语言模型(LLM)面临的上下文窗口限制、企业定制需求等局限性,并介绍了 LoRA 微调技术。重点讲解了 LangChain 框架的核心组件,包括提示词模板、LLM 调用、输出解释器、文档加载器(RAG)、向量数据库及 Agent 智能体。通过代码示例展示了如何利用 LangChain 构建检索增强生成应用和自动化任务流程,帮助开发者克服 LLM 原生缺陷,实现更灵活的企业级 AI 应用开发。
Stephaine Walsh 发布于 2025/2/6 更新于 2026/6/4 16 浏览前言
在当今信息爆炸的时代,自然语言处理(NLP)技术的飞速发展为人们提供了前所未有的便利和智能体验。然而,随着大规模预训练语言模型(LLM)的兴起,开发者和消费者们也逐渐发现 LLM 的局限性,并由此诞生了许多解决方案。
本文将探讨 LLM 局限性的来源、影响以及如何使用 LangChain 作为一种解决方案,为克服相关难题。
LLM 的局限性
LLM Tokens 限制
上下文窗口是指模型在处理输入文本时考虑的前后文信息的范围,这个窗口的大小通常以 token 的数量为单位。
这里的 token 可以是一个单词、一个子词或一个字符,具体取决于模型的分词方式。16,385 tokens 可以理解为在与 GPT 开启一次窗口会话时,你可以输入的最大文本量。
GPT-3.5 支持 16,385 tokens,而 GPT-4 取得了显著的进步,支持 128,000 tokens。超过这个限制会导致什么情况呢?可能出现以下问题:
截断或切分:系统可能会选择截断或切分文本以适应模型的要求。这可能导致部分文本信息的丢失,尤其是在截断位置附近的信息。
信息缺失:上下文窗口限制会使模型无法考虑到整个文本的上下文,因此在处理超长文本时,模型可能无法获取一些全局信息,从而影响对整体语境的理解。
性能下降:超过上下文窗口限制可能导致模型在处理任务时性能下降。
简而言之,如果对话记忆超过 tokens 的上限,它将会遗忘之前的对话,并导致响应速度减慢。这是目前 GPT 在需求较为复杂的任务中无法克服的缺陷。
最新的 GPT-4 模型已经支持 128,000 tokens,这是一项显著的进步,相当于一部小说的文本量,也就是说,GPT 可以直接理解一部《哈利波特》的所有内容并回答相关问题。然而,对于企业消费者来说,128,000 tokens 仍然有限,难以满足对大型项目文档分析之类的要求。
企业用户的定制需求
假设我是一个普通用户,那么我可以使用 GPT-4 Turbo(128,000 tokens)解析一本《哈利波特》,然后对这本书的内容进行问答。虽然 GPT 的响应速度会变得很慢,但我仍然可以使用。但如果我是一个企业用户,我需要 LLM 根据我的商品列表进行问答,在不考虑本地部署 LLM 模型的情况下,我很难使用 GPT 之类的模型来实现我的需求。
那么以 GPT 模型为例,假设你需要根据企业内部数据(例如:商品列表信息),让 GPT 进行问答,你会遇到以下问题和挑战:
上下文窗口 tokens 限制:这会限制你将企业信息作为语料输入到 GPT。
语料类型单一:GPT 无法直接解析视频、音频、图片等文件。
数据安全和隐私:如果你的企业数据包含敏感信息,如客户信息、财务数据等,要确保在使用 GPT 时能够有效地保护数据的安全和隐私。
领域特定性:GPT 是在大规模通用文本数据上预训练的,可能对于某些特定领域的企业内部数据理解能力有限。
数据准备:需要对企业内部数据进行预处理,将其转换成适合 GPT 输入的格式。这可能包括分词、标记化和其他数据清理工作,以确保模型能够正确理解和处理数据。
解释性:GPT 等深度学习模型通常被认为是'黑盒'模型,其决策过程难以解释。对于企业决策中需要透明度和解释性的场景,可能需要考虑如何解释模型的输出。
用户反馈和迭代:直接使用 GPT 时,很难修复模型可能存在的偏见或错误,满足用户的定制需求。
问题多样性:GPT 的性能可能会受到问题多样性的影响。在问答任务中,确保模型能够处理各种类型和形式的问题是一个挑战,有时可能需要更多的数据来覆盖不同的情况。
LoRA
基于上面的问题,延伸出一个概念:LoRA —— 大型语言模型的低秩自适应。这个名字挺唬人,但原理很简单。
如上图所示,LoRA 的基本原理是冻结预训练好的模型权重参数,并额外增加一个旁路网络、一个降维矩阵 A、一个升维矩阵 B,用变量 R 来控制降维度。R 越小,整体的参数量就会越小。我们可以使用本地知识库来训练这个旁路网络,这样不仅微调的成本显著降低,而且还能获得和全模型微调类似的效果。
看起来使用 LoRA 微调技术可以满足我们的需求,而且相对于原模型,LoRA 不需要存储优化器数据,所以参数量减少了很多。但即使这样,LoRA 的训练在没有几块 4090 显卡的情况下仍然很困难。
那有没有更轻量级的解决方案呢?——有!
LlamaIndex 和 LangChain 就是其中的佼佼者。
LangChain
我们之前提到了一些更轻量级的解决方案,其中包括 LlamaIndex 和 LangChain。它们的原理和目标都不相同,LlamaIndex 专注于为 Prompt 准备数据,而 LangChain 的功能更为全面和广泛。
现在让我们详细了解一下 LangChain。
LangChain 是什么?
LangChain 是一个由 Python 开发的应用框架,用于帮助开发者利用大语言模型构建应用程序。它提供了一系列的工具和组件,使你能更简单地创建基于大语言模型和聊天模型的应用。使用 LangChain,你能更方便地管理、扩展语言模型的交互,将多个组件链接到一起,并提供额外的资源,如 API 和数据库。
LangChain 能做什么? LangChain 包含一个 Prompt 模板、一个模型输出解释器(OutputParser)和多个指令工具(llm-math、google-search、terminal)。
一个典型的使用场景是,当用户提出问题时,LangChain 会使用 Prompt 模板将问题格式化,然后调用 LLM 模型。模型会根据 Prompt 模板提供的信息返回回答,然后由输出解析器解析输出。如果收到 LLM 模型发出的指令,就执行相应的工具以获取执行结果,再通过 Prompt 向模型请求,直到模型没有下一步指令则返回结果。
那么,既然是面向开发人员的框架,我们就具体看一下 LangChain 能做些什么。我们以 ChatGPT 为例,通过 Python 调用 LangChain。
Prompts 提示词 Prompts 是用于指导模型生成响应的关键词或短语,它们有助于模型理解上下文并生成相关且连贯的基于语言的输出,比如回答问题、完成句子或参与对话。
PromptTemplate 提示词模板 你可以使用此功能自定义一个对话模板,并使用占位符 {} 替换需要动态处理的内容,以确保 LLM 模型能理解对话内容。
例如,假设有一个商品搜索功能,用户输入商品名称,然后 LLM 输出对应商品的信息,这时我们可以定义一个查询商品详情的对话模板,并用占位符 {} 替换需要动态变更的商品名称。
from langchain import PromptTemplate
prompt_template = PromptTemplate.from_template(
"Tell me all about the {goodName}!"
)
prompt_template.format (goodName="MacBook Pro" )
prompt_template.format 对于参数数量没有限制,你可以添加 0 个或多个参数。
此外,prompt_template 还提供了参数校验功能,参数变量将与模板字符串中存在的变量进行比较,如果不匹配,则会引发异常。
ChatPromptTemplate 对话提示模板 langchain.prompts 还支持对话模板的定制,用户可以根据模板的内容进行问答。
from langchain.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_messages([
("system" , "You are a helpful AI bot. Your name is {name}." ),
("human" , "Hello, how are you doing?" ),
("ai" , "I'm doing well, thanks!" ),
("human" , "{user_input}" ),
])
messages = template.format_messages(
name="Bob" ,
user_input="What is your name?"
)
messages
提示词的其他扩展 ChatPromptTemplate.from_messages 还支持复杂对象的构建,例如:你可以传入一个 SystemMessage 对象,在这里配置 LLM 的角色。
langchain.prompts 也支持用户自定义模板,在某些情况下,默认提示模板可能无法满足你的需求。例如,你可能希望创建一个提示模板,其中包含语言模型的特定动态说明。在这种情况下,你可以创建自定义提示模板。
langchain.prompts 支持带例子的提示词模板。有些情况下,我们需要给 LLM 一些例子,让 LLM 模型更好地理解我们的意图。
最后,langchain.prompts 也支持我们将多个提示组合使用(compose),以及将提示词序列号存储(load_prompt)。
LLM 大型语言模型(LLM)是 LangChain 的核心组件。LangChain 不提供自己的 LLM,而是提供了一个标准接口,用于与许多不同的 LLM 进行交互。
直接使用 LLM 模型
import os
os.environ['http_proxy' ] = 'http://127.0.0.1:10809'
os.environ['https_proxy' ] = 'http://127.0.0.1:10809'
from langchain.llms import OpenAI
llm = OpenAI()
llm("给我讲一个笑话" )
llm_result = llm.generate(["给我讲个笑话" , "给我讲个诗词" ]*15 )
llm_result.generations[0 ]
异步调用 LLM 因为 LLM 模型的调用是网络绑定的,异步调用 LLM 可以让程序在等待响应时做更多的事情。
import time
import asyncio
from langchain.llms import OpenAI
def generate_serially ():
llm = OpenAI(temperature=0.9 )
for _ in range (10 ):
resp = llm.generate(["Hello, how are you?" ])
print (resp.generations[0 ][0 ].text)
async def async_generate (llm ):
resp = await llm.agenerate(["Hello, how are you?" ])
print (resp.generations[0 ][0 ].text)
async def generate_concurrently ():
llm = OpenAI(temperature=0.9 )
tasks = [async_generate(llm) for _ in range (10 )]
await asyncio.gather(*tasks)
s = time.perf_counter()
await generate_concurrently()
elapsed = time.perf_counter() - s
print ("\033[1m" + f"Concurrent executed in {elapsed:0.2 f} seconds." + "\033[0m" )
LLM 缓存 LangChain 为 LLM 提供了一个可选的缓存层。这么做的原因有两个:
如果你经常多次请求相同的完成,它可以通过减少你对 LLM 提供程序进行的 API 调用次数来节省你的资金。
它可以减少你对 LLM 调用 API 的次数,来加速你的应用程序。
LangChain LLM 分为基于本地内存的缓存和服务器缓存,下面是两个例子:
import langchain
from langchain.llms import OpenAI
import time
llm = OpenAI(model_name="text-davinci-002" , n=2 , best_of=2 )
from langchain.cache import InMemoryCache
langchain.llm_cache = InMemoryCache()
start_time = time.time()
print (llm.predict("Tell me a joke" ))
end_time = time.time()
elapsed_time = end_time - start_time
print (f"Predict method took {elapsed_time:.4 f} seconds to execute." )
from langchain.cache import SQLiteCache
langchain.llm_cache = SQLiteCache(database_path=".langchain.db" )
start_time = time.time()
print (llm.predict("用中文讲个笑话" ))
end_time = time.time()
elapsed_time = end_time - start_time
print (f"Predict method took {elapsed_time:.4 f} seconds to execute." )
自定义大语言模型 上面我们已经看到了 LangChain 直接调用 OpenAI 接口的示例,下面我们来介绍一下我们如果有自己的大语言模型,该如何接入 LangChain。
ChatGLM 是清华大学团队推出的平民大模型,使用 RTX3090 单卡即可部署,代码库开源,可以作为目前大语言模型的平替。
我们使用 LLMs 模块封装 ChatGLM,请求我们的模型服务,主要重构两个函数:
_call:模型调用的主要逻辑,输入用户字符串,输出模型生成的字符串;
_identifying_params:返回模型的描述信息,通常返回一个字典,字典中包括模型的主要参数;
import time
import logging
import requests
from typing import Optional , List , Dict , Mapping, Any
import langchain
from langchain.llms.base import LLM
from langchain.cache import InMemoryCache
logging.basicConfig(level=logging.INFO)
langchain.llm_cache = InMemoryCache()
class ChatGLM (LLM ):
url = "http://127.0.0.1:8595/chat"
@property
def _llm_type (self ) -> str :
return "chatglm"
def _construct_query (self, prompt: str ) -> Dict :
"""构造请求体
"""
query = {
"human_input" : prompt
}
return query
@classmethod
def _post (cls, url: str ,
query: Dict ) -> Any :
"""POST 请求
"""
_headers = {"Content_Type" : "application/json" }
with requests.session() as sess:
resp = sess.post(url,
json=query,
headers=_headers,
timeout=60 )
return resp
def _call (self, prompt: str ,
stop: Optional [List [str ]] = None ) -> str :
"""_call
"""
query = self ._construct_query(prompt=prompt)
resp = self ._post(url=self .url,
query=query)
if resp.status_code == 200 :
resp_json = resp.json()
predictions = resp_json["response" ]
return predictions
else :
return "请求模型"
@property
def _identifying_params (self ) -> Mapping[str , Any ]:
"""Get the identifying parameters.
"""
_param_dict = {
"url" : self .url
}
return _param_dict
if __name__ == "__main__" :
llm = ChatGLM()
while True :
human_input = input ("Human: " )
begin_time = time.time() * 1000
response = llm(human_input, stop=["you" ])
end_time = time.time() * 1000
used_time = round (end_time - begin_time, 3 )
logging.info(f"chatGLM process time: {used_time} ms" )
print (f"ChatGLM: {response} " )
其他功能和扩展 LLM 序列化: LangChain 提供了一个方便的方法,用于将 LLM 的配置序列化为 JSON 字符串,以便将其保存到磁盘上的文件中。
流式处理响应: 某些 LLM 提供流式处理响应。这意味着,你可以在响应可用时立即开始处理它,而不是等待整个响应返回。在生成响应时向用户显示响应,或在生成响应时处理响应时可以使用此功能。
跟踪 token 使用情况: 通过 langchain.callbacks 的 get_openai_callback,可以获取你的问答使用 tokens 的数量。此外,使用 get_openai_callback 还可以打印出具体的调用链路信息。
FakeListLLM: 可以用于测试的假 LLM 对象。
输出解释器 output_parsers:处理 LLM 输出的文本。你可以用它来格式化输出内容,例如:
LLM 输出英文答案,我们可以用 output_parsers 将其转换成中文。
输出内容包含敏感信息,我们可以将其过滤后输出
需要提取 LLM 回答的内容,做进一步处理时,我们可以用 output_parsers 提取出想要的内容。
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field, validator
from typing import List
model_name = 'text-davinci-003'
temperature = 0.0
model = OpenAI(model_name=model_name, temperature=temperature)
class Joke (BaseModel ):
setup: str = Field(description="question to set up a joke" )
punchline: str = Field(description="answer to resolve the joke" )
@validator('setup' )
def question_ends_with_question_mark (cls, field ):
if field[-1 ] != '?' :
raise ValueError("Badly formed question!" )
return field
parser = PydanticOutputParser(pydantic_object=Joke)
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n" ,
input_variables=["query" ],
partial_variables={"format_instructions" : parser.get_format_instructions()}
)
joke_query = "给我用中文讲个笑话."
_input = prompt.format_prompt(query=joke_query)
output = model(_input .to_string())
parser.parse(output)
文档加载器:检索增强生成(RAG) 当你开发的 LLM 应用需要根据用户特定的数据做交互,而这些数据又不存在于 LLM 模型的训练集时,可以使用 LangChain 的文档加载器(document_loaders),将一段固定内容,或者 csv、pdf 等文件在执行生成传递给 LLM,让 LLM 对文档进行分析,实现简单的文档交互功能。
下面是一段加载文档、分析文档、文档拆分,最后接入 LLM,让 LLM 做文档评估的代码:
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain import OpenAI
from langchain.document_loaders import TextLoader
from langchain.evaluation.qa import QAEvalChain
openai_api_key = "your_api_key_here"
llm = OpenAI(temperature=0 , openai_api_key=openai_api_key)
loader = TextLoader('data/falcon.txt' , encoding="utf-8" )
doc = loader.load()
print (f"You have {len (doc)} document" )
print (f"You have {len (doc[0 ].page_content)} characters in that document" )
text_splitter = RecursiveCharacterTextSplitter(chunk_size=800 , chunk_overlap=400 )
docs = text_splitter.split_documents(doc)
num_total_characters = sum ([len (x.page_content) for x in docs])
print (f"Now you have {len (docs)} documents that have an average of {num_total_characters / len (docs):,.0 f} characters (smaller pieces)" )
embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key)
docsearch = FAISS.from_documents(docs, embeddings)
chain = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff" , retriever=docsearch.as_retriever(), input_key="question" )
question_answers = [
{'question' : "Falcon 是哪个国家研发的" , 'answer' : '阿拉伯联合酋长国' },
{'question' : "爱丁堡大学博士生符尧觉得 Falcon 不会比 LLaMA 好" , 'answer' : '是的' }
]
predictions = chain.apply(question_answers)
predictions
eval_chain = QAEvalChain.from_llm(llm)
graded_outputs = eval_chain.evaluate(question_answers,
predictions,
question_key="question" ,
prediction_key="result" ,
answer_key='answer' )
graded_outputs
向量数据库 这张图是向量数据库的交互逻辑,LangChain 可以对接不同的向量数据库产品,让向量数据库负责数据的检索,对接 LLM 模型,给出更加快速精确的答案。
在上面的 document_loaders 代码中,有一段 from langchain.vectorstores import FAISS 代码,这里的 FAISS 就是一种向量数据库。
那么我们应该如何使用向量数据库呢?以 Chromedb 为例,我们需要做如下几件事:
准备环境: 向量数据库也是数据库,它需要单独安装。pip install chromadb
准备本地数据: Chromedb 支持 doc、txt、pdf 等格式的数据。
将本地数据切片、向量化,然后入库存储: 数据切片工具例如我们上面提到的 RecursiveCharacterTextSplitter,向量化工具有很多,列入 OpenAI 的 text-embedding-ada-002 等。当然,不管是切片工具还是向量化工具,类型是很多种的,需要根据自身需要场景来使用。
配置 LangChain、LLM 和 Chromedb,就可以使用关键字对定制数据进行检索、提问了。
下面是一段使用 LangChain 调用 Chromedb 的示例:
import argparse
import os
from langchain import PromptTemplate
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI, openai
from dotenv import load_dotenv
from langchain.embeddings import HuggingFaceEmbeddings, OpenAIEmbeddings
from langchain.vectorstores import Chroma
from ChatGLM import ChatGLM
load_dotenv("config.env" )
embeddings_model_name = os.environ.get("EMBEDDINGS_MODEL_NAME" )
persist_directory = os.environ.get('PERSIST_DIRECTORY' )
target_source_chunks = int (os.environ.get('TARGET_SOURCE_CHUNKS' , 4 ))
from constants import CHROMA_SETTINGS
if __name__ == '__main__' :
embeddings = HuggingFaceEmbeddings(model_name=embeddings_model_name)
db = Chroma(persist_directory=persist_directory, embedding_function=embeddings, client_settings=CHROMA_SETTINGS)
retriever = db.as_retriever(search_kwargs={"k" : target_source_chunks})
llm = ChatGLM()
prompt_template = """基于以下已知信息,简洁和专业的来回答用户的问题。
如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息",不允许在答案中添加编造成分,答案请使用中文。
已知内容:
{context}
问题:
{question}"""
promptA = PromptTemplate(template=prompt_template, input_variables=["context" , "question" ])
chain_type_kwargs = {"prompt" : promptA}
qa = RetrievalQA.from_chain_type(llm=llm, retriever=retriever, chain_type="stuff" ,
chain_type_kwargs=chain_type_kwargs, return_source_documents=True )
while True :
query = input ("\n请输入问题:" )
if query == "exit" :
break
res = qa(query)
answer, docs = res['result' ], res['source_documents' ]
print ("\n\n> 问题:" )
print (query)
print ("\n> 回答:" )
print (answer)
for document in docs:
print ("\n> " + document.metadata["source" ] + ":" )
Agent 设想这么一种情况,你从朋友那里听说最近有一部叫做《奥本海默》的电影很火,你被吸引力了想去了解一下这部电影,接下来你拿出手机点开搜索引擎搜索'奥本海默'几个关键字,你得到了很多信息,这些信息最终帮助你决定是否去电影院观看这部电影。
现在我们格局大一点,可以将上面的场景描述为:在人类从事一项需要多个步骤的任务时,步骤和步骤之间,或者说动作和动作之间,往往会有一个推理过程。
这个概念是 Shunyu Yao 等人 2022 年提出的,ReAct – 也就是推理和行动,结合 LLMs 模型,我们可以称之为 LLM ReAct 范式,也就是:在大语言模型中结合推理和行动。
LLM ReAct 在 LangChain 中的实践就是 Agent。
LangChain Agent 可以穿插到 LangChain 的执行流程中,运行大体流程:1 用户给出一个任务 (Prompt) -> 2 思考 (Thought) -> 3 行动 (Action) -> 4 观察 (Observation),然后循环执行上述 2-4 的流程,直到大模型认为找到最终答案为止。
我们在文章的一开始将"LangChain 能做什么?"时就说过:'当收到 LLM 模型发出的指令,就执行相应的工具以获取执行结果,再通过 Prompt 向模型请求,直到模型没有下一步指令则返回结果。'这个功能就是通过 Agent 实现。
Agent 的使用 在 LangChain 中,使用 Agent 之前需要定义好工具(BaseTool),并添加描述(description)告知大模型在什么情况下使用这个工具。
基于我们一开始描述的场景,我们来实现这么一个功能:在用户搜索电影相关问题时,让 LLM 调用搜索工具检索信息,然后反馈给用户答案。下面是代码示例:
定义 Agent 工具
import re
from langchain.tools import BaseTool, DuckDuckGoSearchRun
class SearchTool (BaseTool ):
name = "Search"
description = "当问电影相关问题时候,使用这个工具"
return_direct = False
def _run (self, query: str ) -> str :
print ("\n正在调用搜索引擎执行查询:" + query)
search = DuckDuckGoSearchRun()
return search.run(query)
定义结果解析类 from typing import Dict , Union , Any , List
from langchain.output_parsers.json import parse_json_markdown
from langchain.agents.conversational_chat.prompt import FORMAT_INSTRUCTIONS
from langchain.agents import AgentExecutor, AgentOutputParser
from langchain.schema import AgentAction, AgentFinish
class CustomOutputParser (AgentOutputParser ):
def get_format_instructions (self ) -> str :
return FORMAT_INSTRUCTIONS
def parse (self, text: str ) -> Union [AgentAction, AgentFinish]:
print (text)
cleaned_output = text.strip()
action_pattern = r'"action":\s*"([^"]*)"'
action_input_pattern = r'"action_input":\s*"([^"]*)"'
action = re.search(action_pattern, cleaned_output)
action_input = re.search(action_input_pattern, cleaned_output)
if action:
action_value = action.group(1 )
if action_input:
action_input_value = action_input.group(1 )
if action_value and action_input_value:
if action_value == "Final Answer" :
return AgentFinish({"output" : action_input_value}, text)
else :
return AgentAction(action_value, action_input_value, text)
response = parse_json_markdown(text)
action_value = response["action" ]
action_input_value = response["action_input" ]
if action_value == "Final Answer" :
return AgentFinish({"output" : action_input_value}, text)
else :
return AgentAction(action_value, action_input_value, text)
output_parser = CustomOutputParser()
初始化 Agent from langchain.memory import ConversationBufferMemory
from langchain.agents.conversational_chat.base import ConversationalChatAgent
from langchain.agents import AgentExecutor, AgentOutputParser
SYSTEM_MESSAGE_PREFIX = """尽可能用中文回答以下问题。您可以使用以下工具"""
llm = ChatOpenAI(openai_api_key="sk-xxx" , model_name='gpt-3.5-turbo' , request_timeout=60 )
tools = [CalculatorTool(), SearchTool()]
memory = ConversationBufferMemory(memory_key="chat_history" , return_messages=True )
chat_agent = ConversationalChatAgent.from_llm_and_tools(
system_message=SYSTEM_MESSAGE_PREFIX,
llm=llm, tools=tools, memory=memory,
verbose=True ,
output_parser=output_parser
)
agent = AgentExecutor.from_agent_and_tools(
agent=chat_agent, tools=tools, memory=memory, verbose=True ,
max_iterations=3
)
调用 Agent
结果展示
结语与展望 在当前大规模预训练语言模型(LLM)的时代,我们见证了自然语言处理(NLP)技术的飞速发展,为我们带来了前所未有的智能体验。然而,正如我们在本文中所讨论的,LLM 也面临着一些局限性,例如上下文窗口的 tokens 限制、企业用户的定制需求等挑战。
从 GPT-3.5 到 GPT-4 的不断升级,我们看到了 LLM 模型在上下文窗口 tokens 数量上的显著提升,为更复杂的任务提供了更强大的能力。然而,对于企业用户而言,仍然存在一些不容忽视的问题,包括数据安全、领域特定性、解释性等方面的考虑。
在解决这些问题的过程中,我们介绍了 LoRA(大型语言模型的低秩自适应)的概念,以及更轻量级的解决方案 LlamaIndex 和 LangChain。特别是 LangChain,作为一个面向开发者的应用框架,为我们提供了更灵活、全面的工具和组件,使我们能够更轻松地构建基于大语言模型和聊天模型的应用程序。
通过 LangChain,开发者能够更方便地管理和扩展语言模型的交互,将多个组件链接在一起,并通过丰富的资源如 API 和数据库提供更广泛的功能。LangChain 的出现为克服 LLM 的局限性,满足企业用户的定制需求提供了一种创新性的解决方案。
未来,随着技术的不断演进和创新,我们对自然语言处理的期望也将变得更加广阔。LangChain 等工具的应用无疑将在这一领域发挥越来越重要的作用。开发者应关注社区动态,持续学习新的最佳实践,以构建更高效、安全、可控的 AI 应用系统。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online