通常情况下,LLM 只局限于其已接受过训练的知识和作为上下文提供的额外知识,因此,如果所提供的知识中缺少有用的信息,模型就无法 "绕过去",试图从其他来源中找到该信息。这就是我们需要引入 "代理"(Agent)概念的原因。
代理的核心思想是使用语言模型来选择要采取的一系列行动。在代理中,语言模型被用作推理引擎,以决定采取哪些行动以及行动的顺序。代理可以看作是由语言模型驱动的应用程序,并与搜索引擎、数据库、网站等一系列工具集成。在一个代理中,LLM 是一个推理引擎,它可以根据用户的输入,计划并执行一系列满足请求所需的操作。与传统的人工智能不同,代理可以主动思考并调用工具来逐步完成给定的目标。
上图显示了 LLM 在人工智能代理工作流程中的作用。LLM 会将用户的请求拆分成一系列任务,并根据这些任务的顺序调用(行动)不同的外部工具(工具)。根据从工具中获得的结果(观察),代理将计划下一步行动,然后在满足用户需求后给出最终反馈。让我们通过一个简单的例子来看看如何使用 OpenVINO™ 和 LangChain 实现这一过程。
创建工具
根据 LangChain 的官方教程,首先,我们需要定义一组供代理调用的工具。官方还给出了一个简单的示例,说明如何通过 @tool 装饰器定义一组基本的算术函数:
from langchain_core.tools import tool
@tool
def multiply(first_int: int, second_int: int) -> int:
"""Multiply two integers together."""
return first_int * second_int
我们可以同时创建多个工具,由代理根据用户需求自主选择最合适的工具并获取结果。除了创建自定义工具功能外,LangChain 的一些生态系统合作伙伴还为我们预设了许多实用工具,例如使用维基百科进行关键词搜索,或使用 ChatGPT 服务完成更具挑战性的任务。
创建提示模板
第二步是创建提示模板,在许多 LLM 应用程序中也称为提示工程。其目的是激活 LLM 的计划和行动能力。目前,本地代理最常用的模板包括 "功能调用"、"自我任务 "和 "重新行动"。由于 "功能调用 "功能需要在模型训练过程中启用,因此在此不再赘述。
在 Self-ask 模式中,自问不仅是推理步骤,也是对搜索工具的查询请求,而在 ReAct 模式中,对工具的调用请求紧随推理步骤之后,可以更好地支持搜索以外的更多工具。
在本项目中,以 ReAct 为例,我们可以看到下面的提示模板构建了一个包含思考、行动、观察和最终答案的链条。这个思考过程需要重复多次,直到 LLM 从工具中获得足够的信息来支持它满足用户的要求。
prompt = PromptTemplate.from_template(
"""Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}"""
)
创建 LLM 实例
目前,OpenVINO™已经集成到LangChain的LLM组件之一HuggingFace Pipeline中。开发人员可以通过设置 HuggingFace Pipeline 的后台直接创建基于 OpenVINO 的 LLM 实例,并像 LangChain 中的其他 LLM 实例一样调用它,其中 model_ id 可以是 HuggingFace 模型 ID、本地 PyTorch 或 OpenVINO 模型路径。
ov_llm = HuggingFacePipeline.from_model_id(
model_id=model_path,
task="text-generation",
backend="openvino",
model_kwargs={"device": device.value, "ov_config": ov_config},
pipeline_kwargs={"max_new_tokens": 1024},
)
构建并运行代理
在本示例中,我们使用 "Intel/neural-chat-7b-v3-1 "大型语言模型作为代理。创建 LLM 实例、工具和提示模板后,我们就可以使用 LangChain 中与代理相关的 API 快速构建本地代理服务。
output_parser = ReActSingleInputOutputParser()
agent = create_react_agent(ov_llm, tools, prompt, output_parser=output_parser)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
由于 LangChain 默认的 ReAct 输出解析器无法很好地识别 HuggingFace Pipeline 生成的结果,因此我们需要定义一个新的 custom_output_parser.py 脚本,将 LLM 的原始输出转换为 Action,比如如何匹配工具函数的输入数据。以一个简单的数学运算为例,我们可以看到,在理解了用户的问题后,代理会将其拆分成多个动作,并将多个动作的观察结果进行组合,从而得到最终答案。
Question: Take 3 to the fifth power and multiply that by the sum of twelve and three
Thought: We need to exponentiate 3 to the power of 5, then multiply the result by the sum of 12 and 3
Action: exponentiate
Action Input: base: 3, exponent: 5
Observation: 243
Action: add
Action Input: first_int: 12, second_int: 3
Observation: 15
Action: multiply
Action Input: first_int: 243, second_int: 15
Observation: 3645
Thought: I now know the final answer
Final Answer: 3645
此外,借助 LangChain 中预定义的维基百科工具,我们还可以建立一个维基百科代理工具,如下图所示。这个代理可以通过搜索维基百科获取外部知识。
结论
LLM 不可能无所不能,但它可以足够聪明,为特定任务找到合适的助手。作为人工通用智能(AGI)的入口,代理就像一个智能实体,能像人类一样感知世界、做出决策、与他人互动并执行操作。相信在 OpenVINO™ 的支持下,完全本地化的人工智能代理服务将成为可能。