前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >洞悉LangChain:LangChain工程化设计,从API到智能Agent的全面探索

洞悉LangChain:LangChain工程化设计,从API到智能Agent的全面探索

作者头像
汀丶人工智能
发布2024-07-25 14:48:38
920
发布2024-07-25 14:48:38
举报
文章被收录于专栏:NLP/KG

洞悉LangChain:LangChain工程化设计,从API到智能Agent的全面探索

1. LangChain简介

LangChain 是 2022 年 10 月底,由哈佛大学的 Harrison Chase 发起的基于开源大语言模型的 AI 工程开发框架。当然也可以问一下 AI:

通义千问2.5:LangChain 是一个开源框架,专注于简化开发者利用大型语言模型(LLM)创建应用程序的过程。这些大型语言模型,如GPT-3、GPT-4、LaMDA等,能够处理复杂的语言任务,但直接集成到实际应用中可能具有挑战性。LangChain通过提供一系列工具、组件和接口来解决这一问题,它使得开发者能够更容易地管理与LLM的交互、设计自定义提示策略、构建包含多个逻辑步骤的“链式”工作流,并且能够整合外部API、数据库等资源,从而极大地扩展了模型的功能和应用场景。 核心特点包括:

  • 通用接口:支持多种大型语言模型,便于在不同模型间切换。
  • 提示管理:允许开发者定制和优化向LLM提供的提示,以获得更准确的输出。
  • 链式结构:促进组件间的连接,帮助构建复杂的逻辑流程,实现更智能的应用行为。
  • 外部集成:轻松接入外部数据源和工具,增强模型的实用性和上下文理解能力。
  • 多语言支持:目前支持Python和JavaScript,便于不同背景的开发者使用。

LangChain的应用场景广泛,涵盖聊天机器人、问答系统、文本生成、翻译、代码生成、数据分析等多个领域,为希望利用先进语言AI技术构建创新应用的开发者提供了强大的基础设施。

  1. 作为 AI 工程框架,LangChain 实际是对 LLM 能力的扩展和补充。如果把 LLM 比作人的大脑,LangChain 则是人的躯干和四肢,协助 LLM 完成 “思考” 之外的“脏活累活”。它的能力边界只取决于 LLM 的智力水平和 LangChain 能提供的工具集的丰富程度。
  2. LangChain 提供了 LCEL(LangChain Expression Language)声明式编程语言,降低 AI 工程师的研发成本。
  3. LangChain 提供了 Models、Prompts、Indexes、Memory、Chains、Agents 六大核心抽象,用于构建复杂的 AI 应用,同时保持了良好的扩展能力。

很明显,LLM 作为 LangChain 能力的基础,是了解 LangChain 工程化设计的前提。接下来我们就从最基础的 LLM API 使用谈起,一步步了解 LangChain 的工程化构建过程及其背后的设计理念。

在这里插入图片描述
在这里插入图片描述

2.环境准备

3.设计推演

可插拔架构是一种设计思想,旨在提高系统的灵活性、可维护性和可扩展性。

在软件开发中,可插拔架构强调的是模块化和组件化设计,使得系统中的各个部分(模块、服务、组件)能够独立开发、测试、部署和维护,而不会相互影响。这种设计通常依赖于清晰定义的接口(APIs)和契约,使得组件之间保持低耦合度。具体表现为:

  • 插件化:系统可以通过配置加载不同的插件(模块),每个插件完成特定的功能,新增或移除插件不影响系统核心的运行。
  • 微服务架构:每个服务作为独立的单元存在,可以独立部署和扩展,服务间通过API通信,易于替换和升级。
  • 容器化和Docker:如Docker提供的可插拔存储驱动程序架构,允许用户灵活选择存储解决方案,体现了软件服务的可插拔性。
  • 前端框架中的模块化:如Vue.js等前端框架,支持模块的动态加载和卸载,使得应用可以根据需求加载功能模块,实现“插拔式”的前端架构。

可插拔架构的核心价值在于提升系统的适应性和未来扩展能力,使得系统能够更容易地应对需求变化和技术迭代,同时降低复杂性和故障传播的风险。LangChain 实际上也遵循了可插拔架构的思想

3.1 OpenAI介绍

文本生成模型服务是 OpenAI 提供的最核心的 API 服务,自 ChatGPT 发布后经历过几次版本迭代。

3.1.1 Chat Completion API

当下最新的是 Chat Completion API,是 AI 与 LLM 交互的核心入口。

代码示例参考:

代码语言:javascript
复制
import os
import requests

#API Key
api_key = os.getenv('OPENAI_API_KEY')

#头部信息
headers = {
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {api_key}'
}

#准备数据
data = {
    'model': 'gpt-4',
    'messages': [{'role': 'user', 'content': '什么是图计算?'}],
    'temperature': 0.7
}

#调用API
url = 'https://api.openai.com/v1/chat/completions'
response = requests.post(url, json=data, headers=headers)
answer = response.json()['choices'][0]['message']['content']
print(answer)

代码示例输出:

图计算是一种计算模型,用于处理大规模图形结构的数据,并执行各种复杂的算法和计算。这种计算模型主要用于社交网络分析、Web 搜索、生物信息学、网络路由优化、数据挖掘等领域。图计算模型的核心是将数据表示为图形结构(节点和边),这样可以更好地揭示数据之间的关系和互动。在图计算中,算法通常以迭代的方式运行,每次迭代都会更新图中节点的状态,直到达到某种停止条件。

3.1.2 Completion API

早先的 Completion API 已经在 2023 年 7 月后不再维护,和最新的 Chat Completion API 参数和结果格式有所不同,最明显的是 Prompt 是以纯文本方式传递,而非 Message 格式。

代码语言:javascript
复制
#准备数据
data = {
    'model': 'gpt-3.5-turbo-instruct',
    'prompt': ['什么是图计算?'],
    'max_tokens': 1024
}

#调用API
url = 'https://api.openai.com/v1/completions'
response = requests.post(url, json=data, headers=headers)
answer = response.json()['choices'][0]['text']
print(answer)

除了文本生成服务,OpenAI 也提供了大量的 LLM 的周边服务,以协助 AI 工程构建更复杂的应用能力。如:函数调用、嵌入、微调、多模态等,具体可参考 OpenAI 开发文档的内容。

3.2 Chat 对话模式

自 2022 年 11 月底 ChatGPT 发布以来,AI 的大门才真正地向人类打开,其中给用户留下最深印象的功能,自然是智能对话。OpenAI 的 Chat Completion API 参数支持传入消息历史,可以轻松地实现简单的对话服务。

代码示例参考:

代码语言:javascript
复制
#对话历史
messages = []

def chat_with_ai(message):
    #记录历史
    messages.append({'role': 'user', 'content': message})
    print(f'me: {message}')

    #对话请求
    data = {
        'model': 'gpt-4',
        'messages': messages,
        'temperature': 0.7
    }
    url = 'https://api.openai.com/v1/chat/completions'
    response = requests.post(url, json=data, headers=headers)

    #解析回答
    if response.status_code == 200:
        answer = response.json()['choices'][0]['message']['content']
        messages.append({'role': 'assistant', 'content': answer})
        print(f"ai: {answer}")
    else:
        print(f'Error: {response.status_code}', response.json())

#多轮对话
chat_with_ai('什么是图计算?')
chat_with_ai('刚才我问了什么问题?')

代码示例输出:

me: 什么是图计算? ai: 图计算是一种计算模型,用于处理大规模图形结构数据的计算和分析。在这种计算模型中,数据被表示为图形,其中节点代表实体,边代表实体之间的关系。图计算可以用于解决许多实际问题,如社交网络分析、网络路由、生物信息学等。图计算的主要挑战是如何有效地处理大规模的图形数据,并提供快速的计算和分析结果。 me: 刚才我问了什么问题? ai: 你问的问题是:“什么是图计算?”

3.3 初步封装——SDK

到目前为止,我们还只是用 OpenAI 最原始的 RESTful API 构建 LLM 工程能力,甚至连 OpenAI 提供的 SDK 都未使用。显然这不是一个高效的方式,使用前边安装的 LangChain-OpenAI 集成包langchain-openai可以大大降低代码的开发成本。

代码示例参考:

代码语言:javascript
复制
from langchain_openai import ChatOpenAI

#调用Chat Completion API
llm = ChatOpenAI(model_name='gpt-4')
response = llm.invoke('什么是图计算?')
print(response)

代码示例输出:

content=‘图计算是一种计算模型,主要用于处理图形结构数据的计算和分析。图计算的对象是图,图由节点和边组成,节点代表实体对象,边代表实体对象之间的关系。图计算主要用于解决实体关系复杂、关系密集的问题,如社交网络分析、网络拓扑分析、推荐系统等。图计算的主要任务是通过对图中节点和边的计算,发现和提取出图中隐含的知识和信息。’

3.4 数据抽象-IO

对于文本生成模型服务来说,实际的输入和输出本质上都是字符串,因此直接裸调用 LLM 服务带来的问题是要在输入格式化和输出结果解析上做大量的重复的文本处理工作。LangChain 当然考虑到这一点,提供了 PromptOutputParser 抽象,用户可以根据自己的需要选择具体的实现类型使用。

在这里插入图片描述
在这里插入图片描述

代码示例参考:

代码语言:javascript
复制
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

#创建LLM
llm = ChatOpenAI(model_name='gpt-4')

#创建Prompt
prompt = ChatPromptTemplate.from_template("{question}")

#创建输出解析器
output_parser = StrOutputParser()

#调用LLM
message = prompt.invoke({'question': '什么是图计算?'})
response = llm.invoke(message)
answer = output_parser.invoke(response)
print(answer)

3.5 链——Chain

模型的 IO 组件确实可以减少重复的文本处理工作,但形式上依然不够清晰,这里就引入了 LangChain 中的关键概念:链(Chain)。

3.5.1 HelloWorld

LangChain 的表达式语言(LCEL)通过重载__or__运算符的思路,构建了类似 Unix 管道运算符的设计,实现更简洁的 LLM 调用形式。

代码示例参考:

代码语言:javascript
复制
#创建Chain
chain = prompt | llm | output_parser

#调用Chain
answer = chain.invoke({'question': '什么是图计算?'})
print(answer)

至此,我们终于看到了 LangChain 版的 “HelloWorld”……

3.5.2 RunnablePassthrough

当然,为了简化 Chain 的参数调用格式,也可以借助RunnablePassthrough透传上游参数输入。

代码示例参考:

代码语言:javascript
复制
from langchain_core.runnables import RunnablePassthrough

#创建Chain
chain = {"question": RunnablePassthrough()} | prompt | llm | output_parser

#调用Chain
answer = chain.invoke('什么是图计算?')
print(answer)
3.5.3 DAG

另外,Chain 也可以分叉、合并,组合出更复杂的 DAG 计算图结构。

代码示例参考:

代码语言:javascript
复制
from operator import itemgetter

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

#创建LLM
llm = ChatOpenAI(model_name='gpt-4')

#创建输出解析器
output_parser = StrOutputParser()

#创建Prompt
topic_prompt = ChatPromptTemplate.from_template("生成一种'{input}'的名称")
good_prompt = ChatPromptTemplate.from_template("列举{topic}的好处:")
bad_prompt = ChatPromptTemplate.from_template("列举{topic}的坏处:")
summary_prompt = ChatPromptTemplate.from_messages(
    [
        ("ai", "{topic}"),
        ("human", "好处:\n{good}\n\n坏处:\n{bad}"),
        ("system", "生成最终结论"),
    ]
)

#创建组合Chain
topic_chain = topic_prompt | llm | output_parser | {"topic": RunnablePassthrough()}
goods_chain = good_prompt | llm | output_parser
bads_chain = bad_prompt | llm | output_parser
summary_chain = summary_prompt | llm | output_parser
chain = (
    topic_chain
    | {
        "good": goods_chain,
        "bad": bads_chain,
        "topic": itemgetter("topic"),
    }
    | summary_chain
)

#调用chain
answer = chain.invoke({"input": '常见水果'})
print(answer)

代码示例输出:

苹果是一种营养丰富的水果,具有帮助消化、保护心脏、降低糖尿病风险、强化免疫系统、帮助减肥、保护视力、预防哮喘、抗癌和提升记忆力等多种好处。然而,过度食用或者不适当的食用方式也可能带来一些不利影响,如引发过敏、导致腹泻、对牙齿造成伤害、可能携带农药残留、影响正常饮食和钙质吸收、增加蛀牙风险和引发胃痛等。因此,我们在享受苹果带来的好处的同时,也需要注意适量和正确的食用方式。

通过调用chain.get_graph().print_ascii()可以查看 Chain 的计算图结构。当然,使用 LangSmith 能更清晰的跟踪每一步的计算结果。

Tips:开启 LangSmith 需要申请 LangChain 的 AK,并配置环境变量:

代码语言:javascript
复制
export LANGCHAIN_TRACING_V2="true"  
export LANGCHAIN_API_KEY="<Your-LangChain-AK>"
3.5.4 LangGraph

基于 LCEL 确实能描述比较复杂的 LangChain 计算图结构,但依然有 DAG 天然的设计限制,即不能支持 “循环”。于是 LangChain 社区推出了一个新的项目——LangGraph,期望基于 LangChain 构建支持循环和跨多链的计算图结构,以描述更复杂的,甚至具备自动化属性的 AI 工程应用逻辑,比如智能体应用。其具体使用方式可以参考 LangGraph 文档

LangGraph 声称其设计理念受 Pregel/Beam 的启发,构建支持多步迭代的计算能力

3.6 Memory

通过 Chain,LangChain 相当于以 “工作流” 的形式,将 LLM 与 IO 组件进行了有秩序的连接,从而具备构建复杂 AI 工程流程的能力。而我们都知道 LLM 提供的文本生成服务本身不提供记忆功能,需要用户自己管理对话历史。因此引入 Memory 组件,可以很好地扩展 AI 工程的能力边界。

在这里插入图片描述
在这里插入图片描述
3.6.1 Memory 接口

LangChain 的BaseMemory接口提供了 Memory 的统一抽象(截至 v0.1.12 还是 Beta 版本),提供了多种类型的 Memory 组件的实现,我们选用最简单的ConversationBufferMemory实现类型。

需要注意的是,要将 Memory 组件应用到 Chain 上,需要使用子类LLMChain进行创建 Chain。

代码示例参考:

代码语言:javascript
复制
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, \
    HumanMessagePromptTemplate
from langchain_openai import ChatOpenAI

#创建LLM
llm = ChatOpenAI(model_name='gpt-4')

#创建Prompt
prompt = ChatPromptTemplate.from_messages([
    MessagesPlaceholder(variable_name='chat_history'),
    HumanMessagePromptTemplate.from_template('{question}')
])

#创建Memory
memory = ConversationBufferMemory(memory_key='chat_history',
                                  return_messages=True)
#创建LLMChain
llm_chain = LLMChain(llm=llm, memory=memory, prompt=prompt)

#调用LLMChain
print(llm_chain.predict(question='什么是图计算?'))
print(llm_chain.predict(question='刚才我问了什么问题?'))

代码示例输出:

图计算是一种计算类型,主要处理的数据结构是图。图是由节点(或顶点)和边组成的,节点代表实体,边代表实体之间的关系。在图计算中,主要解决的问题是如何在图的结构上进行有效的计算和分析。 你问的问题是:“什么是图计算?”

这里可以看到,创建带 Memory 功能的 Chain,并不能使用统一的 LCEL 语法。调用LLMChain使用的是 predict 而非 invoke 方法,直接调用 invoke 会返回一个LLMResult类型的结果。因此,LLMChain也不能使用管道运算符接StrOutputParser。这些设计上的问题,个人推测也是目前 Memory 模块还是 Beta 版本的原因之一吧。

3.6.2 History 接口

但是,LangChain 提供了工具类RunnableWithMessageHistory,支持了为 Chain 追加 History 的能力,从某种程度上缓解了上述问题。不过需要指定 Lambda 函数 get_session_history 以区分不同的会话,并需要在调用时通过 config 参数指定具体的会话 ID。

SessionHistory 必须是 History 接口类型BaseChatMessageHistory,用户可以根据需要选择不同的存储实现。这里为了简化,全局只用了一份内存类型的ChatMessageHistory

代码示例参考:

代码语言:javascript
复制
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, \
    HumanMessagePromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_openai import ChatOpenAI

#创建LLM
llm = ChatOpenAI(model_name='gpt-4')

#创建输出解析器
output_parser = StrOutputParser()

#创建Prompt
prompt = ChatPromptTemplate.from_messages([
    MessagesPlaceholder(variable_name="chat_history"),
    HumanMessagePromptTemplate.from_template("{question}")
])

#创建Chain
chain = prompt | llm | output_parser

#添加History
history = ChatMessageHistory()
chain_with_history = RunnableWithMessageHistory(
    chain,
    lambda session_id: history,
    input_messages_key="question",
    history_messages_key="chat_history",
)

#调用Chain
print(chain_with_history.invoke({'question': '什么是图计算?'},
                                config={"configurable": {"session_id": None}}))
print(chain_with_history.invoke({'question': '刚才我问了什么问题?'},
                                config={"configurable": {"session_id": None}}))

调用形式看起来是复杂了一些,不过代码结构相比 Memory 组件更清晰一些,聊胜于无……

3.7 RAG检索增强生成

拥有记忆后,确实扩展了 AI 工程的应用场景。但是在专有领域,LLM 无法学习到所有的专业知识细节,因此在面向专业领域知识的提问时,无法给出可靠准确的回答,甚至会 “胡言乱语”,这种现象称之为 LLM 的 “幻觉”。

检索增强生成(RAG)把信息检索技术和大模型结合起来,将检索出来的文档和提示词一起提供给大模型服务,从而生成更可靠的答案,有效的缓解大模型推理的 “幻觉” 问题。

如果说 LangChain 相当于给 LLM 这个 “大脑” 安装了 “四肢和躯干”,RAG 则是为 LLM 提供了接入“人类知识图书馆” 的能力。

相比提示词工程,RAG 有更丰富的上下文和数据样本,可以不需要用户提供过多的背景描述,即能生成比较符合用户预期的答案。相比于模型微调,RAG 可以提升问答内容的时效性和可靠性,同时在一定程度上保护了业务数据的隐私性。

但由于每次问答都涉及外部系统数据检索,因此 RAG 的响应时延相对较高。另外,引用的外部知识数据会消耗大量的模型 Token 资源。因此,用户需要结合自身的实际应用场景做合适的技术选型。

在这里插入图片描述
在这里插入图片描述

借助 LCEL 提供的RunnableParallel可以清晰描述 RAG 的计算图结构,其中最关键的部分是通过 context 键注入向量存储(Vector Store)的查询器(Retriever)。

代码示例参考:

代码语言:javascript
复制
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores.faiss import FAISS
from langchain_core.documents import Document
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings, ChatOpenAI

#创建LLM
llm = ChatOpenAI(model_name='gpt-4')

#创建Prompt
prompt = ChatPromptTemplate.from_template('基于上下文:{context}\n回答:{input}')

#创建输出解析器
output_parser = StrOutputParser()

#模拟文档
docs = [Document(page_content="图数据库Nebula Graph简介")]

#文档嵌入
splits = RecursiveCharacterTextSplitter().split_documents(docs)
vector_store = FAISS.from_documents(splits, OpenAIEmbeddings())
retriever = vector_store.as_retriever()

#创建Chain
chain_no_context = RunnablePassthrough() | llm | output_parser
chain = (
    {"context": retriever, "input": RunnablePassthrough()}
    | prompt | llm | output_parser
)

#调用Chain
print(chain_no_context.invoke('Nebula Graph介绍'))

代码示例输出:

Nebula图数据库是一款开源的分布式图数据库系统,由中国的石墨烯数据库团队开发。它专为处理大规模图数据而设计,支持高效的存储、查询和分析,适用于社交网络、知识图谱、推荐系统等复杂数据关系的应用场景。Nebula图数据库采用分布式架构,支持水平扩展,提供多语言客户端和查询接口,具备数据持久性、一致性、多版本控制及安全性等特点,是处理复杂图数据的理想选择。

在这里插入图片描述
在这里插入图片描述

结合示例和向量数据库的存取过程,我们简单理解一下 RAG 中关键组件。

  • DocumentLoader:从外部系统检索文档数据。简单起见,示例中直接构造了测试文档对象。实际上 LangChain 提供了文档加载器BaseLoader的接口抽象和大量实现,具体可根据自身需要选择使用。
  • TextSplitter:将文档分割成块,以适应大模型上下文窗口。示例中采用了常用的RecursiveCharacterTextSplitter,其他参考 LangChain 的TextSplitter接口和实现。
  • EmbeddingsModel:文本嵌入模型,提供将文本编码为向量的能力。文档写入和查询匹配前都会先执行文本嵌入编码。示例采用了 OpenAI 的文本嵌入模型服务,其他参考 LangChain 的Embeddings接口和实现。
  • VectorStore:向量存储,提供向量存储和相似性检索(ANN 算法)能力。LangChain 支持的向量存储参考VectorStore接口和实现。示例采用了 Meta 的 Faiss 向量数据库,本地安装方式:pip install faiss-cpu。需要额外提及的是,对于图数据库,可以将相似性搜索问题转化为图遍历问题,并具备更强的知识可解释性。
  • Retriever:向量存储的查询器。一般和 VectorStore 配套实现,通过 as_retriever 方法获取,LangChain 提供的 Retriever 抽象接口是BaseRetriever

3.8 Tool 使用

要构建更强大的 AI 工程应用,只有生成文本这样的 “纸上谈兵” 能力自然是不够的。工具不仅仅是 “肢体” 的延伸,更是为 “大脑” 插上了想象力的 “翅膀”。借助工具,才能让 AI 应用的能力真正具备无限的可能,才能从“认识世界” 走向“改变世界”。

这里不得不提到 OpenAI 的 Chat Completion API 提供的函数调用能力(注意这里不是 Assistant 的函数调用),通过在对话请求内附加 tools 参数描述工具的定义格式(原先的 functions 参数已过期),LLM 会根据提示词推断出需要调用哪些工具,并提供具体的调用参数信息。用户需要根据返回的工具调用信息,自行触发相关工具的回调。下一章内容我们可以看到工具的调用动作可以通过 Agent 自主接管。

为了简化代码实现,我们用 LangChain 的注解 @tool 定义了一个测试用的 “获取指定城市的当前气温” 的工具函数。然后通过bind_tools方法绑定到 LLM 对象即可。需要注意的是这里需要用JsonOutputToolsParser解析结果输出。

代码示例参考:

代码语言:javascript
复制
import random

from langchain_core.output_parsers.openai_tools import JsonOutputToolsParser
from langchain_core.runnables import RunnablePassthrough
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI


#定义Tool
@tool
def get_temperature(city: str) -> int:
    """获取指定城市的当前气温"""
    return random.randint(-20, 50)


#创建LLM
llm = ChatOpenAI(model_name='gpt-4')

#创建JSON输出解析器
output_parser = JsonOutputToolsParser()

#创建Chain
chain = (
    RunnablePassthrough()
    | llm.bind_tools(tools=[get_temperature])
    | output_parser
)

#调用Chain
print(chain.invoke('杭州今天多少度?'))

代码示例输出:

[{‘type’: ‘get_temperature’, ‘args’: {‘city’: ‘杭州’}}]

实际上 LangChain 提供了大量的内置工具和工具库的支持。@tool 只是提供了简洁的工具创建的支持,要定制复杂的工具行为需要自行实现BaseTool工具接口。同时工具库接口BaseToolkit下也有大量的实现,如向量存储、SQL 数据库、GitHub 等等。用户可以根据自身需求选用或自行扩展。

3.9 智能体——Agent

通用人工智能(AGI)将是 AI 的终极形态,几乎已成为业界共识。类比之,构建智能体(Agent)则是 AI 工程应用当下的 “终极形态”。

3.9.1 Agent简介

引用 LangChain 中 Agent 的定义,可以一窥 Agent 与 Chain 的区别。

Agent 的核心思想是使用大型语言模型(LLM)来选择要采取的行动序列。在 Chain 中行动序列是硬编码的,而 Agent 则采用语言模型作为推理引擎来确定以什么样的顺序采取什么样的行动。

Agent 相比 Chain 最典型的特点是 “自治”,它可以通过借助 LLM 专长的推理能力,自动化地决策获取什么样的知识,采取什么样的行动,直到完成用户设定的最终目标。

在这里插入图片描述
在这里插入图片描述

因此,作为一个智能体,需要具备以下核心能力:

  • 规划:借助于 LLM 强大的推理能力,实现任务目标的规划拆解和自我反思。
  • 记忆:具备短期记忆(上下文)和长期记忆(向量存储),以及快速的知识检索能力。
  • 行动:根据拆解的任务需求正确地调用工具以达到任务的目的。
  • 协作:通过与其他智能体交互合作,完成更复杂的任务目标。
3.9.2 构建智能体

我们使用 Agent 继续完成前边 Tool 部分没有完成的例子。这里使用 create_openai_tools_agent 方法创建一个简单的 OpenAI 工具 Agent,AgentExecutor 会自动接管工具调用的动作。如果希望给 Agent 添加记忆能力,依然可以采用前边 Memory 章节提过的 RunnableWithMessageHistory 的方案

代码示例参考:

代码语言:javascript
复制
import random

from langchain.agents import create_openai_tools_agent, \
    AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, \
    HumanMessagePromptTemplate, SystemMessagePromptTemplate
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

#创建LLM
llm = ChatOpenAI()

#定义Tool
@tool
def get_temperature(city: str) -> int:
    """获取指定城市的当前气温"""
    return random.randint(-20, 50)


#创建Agent提示词模板
prompt = ChatPromptTemplate.from_messages([
    SystemMessagePromptTemplate.from_template('You are a helpful assistant'),
    MessagesPlaceholder(variable_name='chat_history', optional=True),
    HumanMessagePromptTemplate.from_template('{input}'),
    MessagesPlaceholder(variable_name='agent_scratchpad')
])

#创建Agent
tools = [get_temperature]
agent = create_openai_tools_agent(llm, tools, prompt=prompt)

#执行Agent
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
print(agent_executor.invoke({'input': '今天杭州多少度?'})['output'])

代码示例输出:

代码语言:javascript
复制
> > Entering new AgentExecutor chain...  
> Invoking: `get_temperature` with `{'city': 'Hangzhou'}`  
> 16 今天杭州的气温是 16 度。
> 
> > Finished chain.  
> 今天杭州的气温是 16 度。

需要补充说明的是,LangChain 提供了 Hub 功能,帮助大家管理共享 Agent 的提示词模板。上述示例代码的 Agent 提示词模板和 hwchase17/openai-tools-agent 的定义等价。

通过代码prompt = hub.pull("hwchase17/openai-tools-agent")可以直接引用创建 prompt。

4.LangChain架构

最后看一下 LangChain 的产品架构。除了本文未介绍的 LangServe——将 Chain 部署为 RESTful 服务,其他不再赘述。

5.进阶LangGraph

LangGraph[https://github.com/langchain-ai/langgraph]

LangGraph是构建在LangChain框架之上的一个高级库,专为开发具备状态、多参与者特性的应用程序而设计,特别是在利用大型语言模型(LLMs)的场景中。它通过引入图数据结构来表示和管理智能体(Agents)及其运行时环境,使得构建复杂的应用逻辑和多步骤交互过程更为直观和高效。

相比于LangChain,LangGraph的主要优势包括:

  • 状态管理能力增强:LangGraph强化了状态管理功能,使智能体能够记住与用户的交互历史,处理更复杂的上下文依赖任务,这对于构建连贯对话体验和个性化服务至关重要。
  • 多智能体协作:它提供了更完善的机制来设计和管理多个智能体之间的协作,这有助于构建更复杂的应用场景,比如多轮对话、任务分配和协同工作,提高了系统的灵活性和可扩展性。
  • 图结构表达:LangGraph采用图论的概念,允许开发者以图形方式组织和表示智能体及其操作,这样的可视化表达有利于理解复杂系统的工作流程,同时也简化了复杂逻辑的构建和维护。
  • 循环机制与动态性:LangGraph引入的循环机制使得智能体的运行时行为更加动态,能够根据运行时条件调整执行路径,增强了应用的适应性和反应能力。
  • 调试与跟踪:结合LangSmith工具,LangGraph提供了更高效的调试和跟踪能力,这对于开发和维护复杂语言模型驱动的应用来说是极大的便利,减少了调试周期,加速了开发进程。
  • 集成与自定义:LangGraph不仅继承了LangChain的组件化和可扩展性,还进一步提供了丰富的集成选项和灵活的自定义方法,使得调用外部函数、工具和适配不同输入输出格式更加便捷。

更多优质内容请关注公号:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。

参考链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 洞悉LangChain:LangChain工程化设计,从API到智能Agent的全面探索
  • 1. LangChain简介
  • 2.环境准备
  • 3.设计推演
    • 3.1 OpenAI介绍
      • 3.1.1 Chat Completion API
      • 3.1.2 Completion API
  • 3.2 Chat 对话模式
    • 3.3 初步封装——SDK
      • 3.4 数据抽象-IO
        • 3.5 链——Chain
          • 3.5.1 HelloWorld
          • 3.5.2 RunnablePassthrough
          • 3.5.3 DAG
          • 3.5.4 LangGraph
        • 3.6 Memory
          • 3.6.1 Memory 接口
          • 3.6.2 History 接口
        • 3.7 RAG检索增强生成
          • 3.8 Tool 使用
            • 3.9 智能体——Agent
              • 3.9.1 Agent简介
              • 3.9.2 构建智能体
          • 4.LangChain架构
          • 5.进阶LangGraph
            • 参考链接
            相关产品与服务
            灰盒安全测试
            腾讯知识图谱(Tencent Knowledge Graph,TKG)是一个集成图数据库、图计算引擎和图可视化分析的一站式平台。支持抽取和融合异构数据,支持千亿级节点关系的存储和计算,支持规则匹配、机器学习、图嵌入等图数据挖掘算法,拥有丰富的图数据渲染和展现的可视化方案。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档