AI Agents实战——驾驭大型语言模型的力量

121 阅读29分钟

本章内容包括:

  • 理解大型语言模型(LLMs)的基础知识
  • 连接并使用OpenAI API
  • 使用LM Studio探索和使用开源LLM
  • 通过提示工程(Prompt Engineering)进行LLM提示
  • 根据具体需求选择最适合的LLM

“大型语言模型”(LLMs)这一术语现在已经成为一种广泛使用的人工智能描述词。这些LLM是通过生成预训练变换器(GPT)开发的。虽然其他架构也能驱动LLM,但GPT架构目前是最成功的。

LLM和GPT是生成模型,这意味着它们的训练目标是生成内容,而非预测或分类内容。为了进一步说明这一点,可以参考图2.1,该图展示了生成模型和预测/分类模型的区别。生成模型从输入中创造内容,而预测和分类模型则对其进行分类。

image.png

我们可以通过LLM的组成部分进一步定义它,如图2.2所示。在这个图示中,数据代表了用于训练模型的内容,而架构是模型本身的一个属性,例如模型的参数数量或大小。模型还会针对特定的使用案例进行进一步训练,包括聊天、补全或指令等。最后,微调是对模型的一个功能,它通过优化输入数据和模型训练,使其更好地匹配特定的使用案例或领域。

image.png

GPT的变换器架构(这是LLMs的一种特定架构)使得模型能够扩展到数十亿的参数规模。这要求这些大型模型必须在数TB的文档上进行训练,以构建基础。在此基础上,这些模型将通过各种方法进行进一步训练,以实现模型的预期用途。

例如,ChatGPT首先有效地在公共互联网数据上进行训练,然后使用多种训练策略进行微调。最终的微调训练通过一种名为“强化学习与人类反馈”(RLHF)的高级形式完成。这产生了一个名为聊天补全的模型用例。

聊天补全的LLM旨在通过迭代和优化不断改进——换句话说,就是通过聊天来提升。这些模型也经过基准测试,在任务完成、推理和规划方面表现最佳,使得它们非常适合构建代理和助手。补全模型则专门设计为仅在输入文本上提供生成的内容,因此它们不会从迭代中受益。

在本书中,我们将重点关注名为聊天补全模型的LLM类别,这也是我们构建强大代理的旅程的基础。当然,这并不排除你尝试其他模型形式来构建你的代理,但你可能需要显著修改提供的代码示例,以支持其他模型形式。

在本章后面,我们将进一步揭示LLM和GPT的更多细节,特别是当我们研究如何在本地运行开源LLM时。在接下来的部分,我们将探讨如何通过OpenAI的不断发展标准连接到LLM。

2.1 掌握OpenAI API

许多AI代理和助手项目使用OpenAI API SDK连接到LLM。虽然这不是标准,但现在描述连接的基本概念遵循OpenAI的模式。因此,我们必须理解使用OpenAI SDK连接LLM的核心概念。

本章将探讨如何通过OpenAI Python SDK/包连接到LLM模型。我们将讨论如何连接到GPT-4模型、模型响应、计算令牌以及如何定义一致的消息。接下来的子部分将介绍如何使用OpenAI。

2.1.1 连接到聊天补全模型

要完成本节及后续章节的练习,你必须设置一个Python开发环境并获得LLM的访问权限。附录A会指导你如何设置OpenAI账户并访问GPT-4或其他模型。附录B展示了如何使用Visual Studio Code(VS Code)设置Python开发环境,包括安装所需的扩展。如果你想跟随情境进行操作,请查阅这些章节。

首先,在VS Code中打开chapter_2文件夹中的源代码,并创建一个新的Python虚拟环境。如果需要帮助,请参考附录B。

然后,使用以下命令安装OpenAI和Python dot环境包。这将把所需的包安装到虚拟环境中。

命令 2.1 pip 安装

pip install openai python-dotenv

接下来,打开VS Code中的connecting.py文件,并检查命令 2.2 中显示的代码。请确保将模型名称设置为合适的名称——例如,gpt-4。在写作时,gpt-4-1106-preview用于表示GPT-4 Turbo。

命令 2.2 connecting.py

import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()                           #1
api_key = os.getenv('OPENAI_API_KEY')
if not api_key:                             #2
    raise ValueError("No API key found. Please check your .env file.")
client = OpenAI(api_key=api_key)                        #3

def ask_chatgpt(user_message):
    response = client.chat.completions.create(      #4
        model="gpt-4-1106-preview",
        messages=[{"role": "system",
 "content": "You are a helpful assistant."},
        {"role": "user", "content": user_message}],
        temperature=0.7,
        )
    return response.choices[0].message.content     #5

user = "What is the capital of France?"
response = ask_chatgpt(user)                #6
print(response)
#1 加载存储在.env文件中的机密
#2 检查API密钥是否已设置
#3 使用密钥创建客户端
#4 使用create函数生成响应
#5 返回响应的内容
#6 执行请求并返回响应

这里发生了很多事情,所以让我们按部分分解,从加载环境变量开始。在chapter_2文件夹中还有一个名为.env的文件,里面包含了环境变量。通过调用load_dotenv函数,这些变量会自动设置。

你必须在.env文件中设置你的OpenAI API密钥,如下所示。再次参考附录A了解如何获取密钥和找到模型名称。

命令 2.3 .env

OPENAI_API_KEY='your-openai-api-key'

设置好密钥后,可以按F5键或从VS Code菜单中选择“运行 > 开始调试”来调试文件。这将运行代码,你应该会看到类似于“法国的首都是巴黎”这样的输出。

记住,生成模型的响应依赖于概率。在这种情况下,模型可能会给出一个正确且一致的答案。

你可以通过调整请求的温度来玩转这些概率。如果你希望模型更一致,可以将温度设置为0;如果希望模型产生更多变异,则可以将温度调高。我们将在下一部分进一步探讨如何设置温度。

2.1.2 理解请求和响应

深入了解聊天补全请求和响应的特性是很有帮助的。我们将首先关注请求,如下所示。请求封装了预定的模型、消息以及温度。

命令 2.4 聊天补全请求

response = client.chat.completions.create(
    model="gpt-4-1106-preview",                 #1
    messages=[{"role": "system", 
"content": "You are a helpful assistant."},                     #2
              {"role": "user", "content": user_message}],      #3
    temperature=0.7,     #4
    )

#1 用于响应请求的模型或部署 #2 系统角色消息 #3 用户角色消息 #4 请求的温度或变异性

在请求中,消息块描述了请求中使用的一组消息和角色。聊天补全模型的消息可以通过三种角色来定义:

  • 系统角色:描述请求规则和指导方针的消息。通常可以用来描述LLM在请求中扮演的角色。
  • 用户角色:代表并包含用户的消息。
  • 助手角色:可以用于捕获LLM之前响应的消息历史。如果没有历史记录,它也可以注入消息历史。

在单一请求中发送的消息可以封装整个对话,如以下列表中的JSON所示。

命令 2.5 带有历史记录的消息

[    {        "role": "system",        "content": "You are a helpful assistant."    },    {        "role": "user",        "content": "What is the capital of France?"    },    {        "role": "assistant",        "content": "The capital of France is Paris."    },    {        "role": "user",        "content": "What is an interesting fact of Paris."    }]

你可以通过在VS Code中打开message_history.py文件并按F5键进行调试来查看这一点。运行文件后,请确保检查输出。然后,再尝试运行该示例几次,看看结果如何变化。

由于温度设置为0.7,结果会随着每次运行而变化。将温度减少到0后,再运行message_history.py示例几次。保持温度为0将会每次显示相同或相似的结果。

请求的温度设置通常取决于你特定的使用案例。有时,你可能希望限制响应的随机性(随机性)。将温度减少到0会得到一致的结果。同样,温度为1.0时会产生响应中的最大变异性。

接下来,我们还希望了解每个请求返回的信息。下一个命令显示了响应的输出格式。你可以通过在VS Code中运行message_history.py文件来查看此输出。

命令 2.6 聊天补全响应

{
    "id": "chatcmpl-8WWL23up3IRfK1nrDFQ3EHQfhx0U6",
    "choices": [                                      #1
        {
            "finish_reason": "stop",
            "index": 0,
            "message": {
                "content": "… omitted",
                "role": "assistant",       #2
                "function_call": null,
                "tool_calls": null
            },
            "logprobs": null
        }
    ],
    "created": 1702761496,
    "model": "gpt-4-1106-preview",     #3
    "object": "chat.completion",
    "system_fingerprint": "fp_3905aa4f79",
    "usage": {
        "completion_tokens": 78,     #4
        "prompt_tokens": 48,         #4
        "total_tokens": 126          #4
    }
}

#1 模型可能返回多个响应。 #2 在助手角色中返回的响应 #3 指示所使用的模型 #4 计算输入(提示)和输出(补全)令牌的数量

追踪输入令牌(用于提示的令牌)和输出令牌(通过补全返回的令牌)的数量可能会很有帮助。有时,减少令牌数量非常重要。通常,令牌数量越少,LLM交互的成本越低,响应速度越快,结果也会更一致、更好。

这涵盖了连接LLM并返回响应的基础知识。在本书中,我们将回顾并扩展与LLM交互的方式。接下来,我们将探讨如何加载和使用开源LLM。

2.2 使用LM Studio探索开源LLM

商业LLM,如OpenAI的GPT-4,是学习如何使用现代AI和构建代理的一个极好的起点。然而,商业代理是一个外部资源,既有成本,又降低了数据隐私性和安全性,还带来了依赖性。其他外部因素可能会进一步使这些问题复杂化。

毫不奇怪,构建与之相媲美的开源LLM的竞争越来越激烈。因此,现在有一些开源LLM可能足够应对许多任务和代理系统。仅仅在一年内,工具方面的进步已经如此显著,以至于如今在本地托管LLM变得非常容易,我们将在下一节中看到这一点。

2.2.1 安装和运行LM Studio

LM Studio是一个免费的下载工具,支持在Windows、Mac和Linux上本地下载和托管LLM及其他模型。该软件易于使用,提供了一些有用的功能,帮助你快速入门。以下是下载和设置LM Studio的快速步骤总结:

  1. lmstudio.ai/下载LM Studio。
  2. 下载后,根据你的操作系统安装软件。需要注意的是,某些版本的LM Studio可能处于测试版,可能需要安装额外的工具或库。
  3. 启动软件。

图2.3展示了运行中的LM Studio窗口。在这里,你可以查看当前的热门模型列表,搜索其他模型,甚至进行下载。首页内容可以帮助你了解顶级模型的详细信息和规格。

image.png

LM Studio的一个吸引人的特点是它能够分析你的硬件,并将其与给定模型的要求进行匹配。软件会告诉你在你的系统上运行某个模型的效果如何。这可以在选择实验的模型时节省大量时间。

输入一些文本来搜索模型,然后点击“Go”按钮。你将被带到搜索页面界面,如图2.4所示。在这个页面上,你可以看到所有的模型变体和其他规格,比如上下文令牌的大小。点击“兼容性猜测”按钮后,软件甚至会告诉你该模型是否能在你的系统上运行。

image.png

点击下载任何能够在你的系统上运行的模型。你可能想要选择专为聊天补全设计的模型,但如果你的系统有限,使用现有的资源也没问题。此外,如果你不确定该使用哪个模型,可以先下载并尝试。LM Studio是一个很好的探索和实验多种模型的工具。

下载模型后,你可以在聊天页面加载并运行该模型,或者在服务器页面作为服务器运行。如图2.5所示,展示了在聊天页面加载和运行模型的过程。如果你有GPU,还可以看到启用和使用GPU的选项。

image.png

要加载并运行模型,打开页面顶部中间的下拉菜单,选择已下载的模型。进度条会显示模型加载的过程,当模型准备好后,你就可以开始在UI中输入内容了。

如果检测到GPU,软件还允许你使用部分或全部GPU来进行模型推理。GPU通常能在某些情况下加速模型的响应时间。你可以通过查看页面底部的性能状态,了解添加GPU后如何影响模型的性能,如图2.5所示。

与模型进行对话,并使用或尝试不同的提示,可以帮助你判断某个模型是否适合你的特定使用案例。一个更系统化的方法是使用提示流工具来评估提示和LLM。在第9章中,我们将介绍如何使用提示流。

LM Studio还允许在服务器上运行模型,并使用OpenAI包进行访问。我们将在下一节中看到如何使用服务器功能并为模型提供服务。

2.2.2 使用LM Studio本地托管LLM

使用LM Studio在本地作为服务器运行LLM非常简单。只需打开服务器页面,加载模型,然后点击“启动服务器”按钮,如图2.6所示。从那里,你可以复制并粘贴任何示例来连接到你的模型。

image.png

你可以通过在VS Code中打开chapter_2/lmstudio_server.py文件来查看Python代码示例。代码也在这里以命令2.7的形式展示。然后,在VS Code调试器中运行代码(按F5键)。

命令 2.7 lmstudio_server.py

from openai import OpenAI

client = OpenAI(base_url="http://localhost:1234/v1", api_key="not-needed")

completion = client.chat.completions.create(
  model="local-model",                           #1
  messages=[
    {"role": "system", "content": "Always answer in rhymes."},
    {"role": "user", "content": "Introduce yourself."}       #2
  ],
  temperature=0.7,
)

print(completion.choices[0].message)      #3

#1 当前未使用;可以是任何内容

#2 随意更改消息内容

#3 默认代码输出整个消息

如果在连接到服务器时遇到问题或遇到其他问题,请确保你的服务器模型设置与模型类型匹配。例如,在之前的图2.6中,加载的模型与服务器设置不同。图2.7展示了修正后的设置。

image.png

现在,你可以使用本地托管的LLM或商业模型来构建、测试,甚至可能运行你的代理。接下来的部分将探讨如何更有效地使用提示工程来构建提示。

2.3 使用提示工程提示LLM

为LLM定义的提示是请求中用于获取更好响应输出的消息内容。提示工程是一个新兴领域,旨在为构建提示提供一种结构化的方法。不幸的是,提示构建并不是一个成熟的科学,目前已定义的提示工程方法种类繁多,且不断增长。

幸运的是,像OpenAI这样的组织已经开始记录一套通用的策略,如图2.8所示。这些策略涵盖了各种战术,其中一些需要额外的基础设施和考虑因素。因此,涉及更高级概念的提示工程策略将在后续章节中详细讨论。

image.png

图2.8中的每个策略都展开为战术,进一步细化特定的提示工程方法。本章将探讨基础的“写清晰指令”策略。图2.9详细展示了这一策略的战术,并为每个战术提供了示例。我们将在接下来的部分中通过代码示范来运行这些示例。

image.png

“写清晰指令”策略是关于在提问时要小心且具体。要求LLM执行一个任务与要求一个人完成同样的任务没有什么区别。通常,你可以在请求中指定更多与任务相关的信息和背景,响应会更好。

这个策略已被拆解为可以应用于提示的具体战术。为了理解如何使用这些战术,章节2的源代码文件夹中有一个代码示范(prompt_engineering.py),其中包含了各种提示的示例。

打开VS Code中的prompt_engineering.py文件,如命令2.8所示。该代码首先加载提示文件夹中的所有JSON Lines文件。然后,它将文件列表显示为选择项,并允许用户选择一个提示选项。选择选项后,提示将被提交给LLM,响应将被打印出来。

命令 2.8 prompt_engineering.py (main())

def main():
    directory = "prompts"
    text_files = list_text_files_in_directory(directory)    #1

    if not text_files:
        print("No text files found in the directory.")
        return

    def print_available():                                     #2
        print("Available prompt tactics:")
        for i, filename in enumerate(text_files, start=1):
            print(f"{i}. {filename}")

    while True:
        try:
            print_available()                   #2              
            choice = int(input("Enter … 0 to exit): "))           #3
            if choice == 0:
                break
            elif 1 <= choice <= len(text_files):
                selected_file = text_files[choice - 1]
                file_path = os.path.join(directory, selected_file)
                prompts = load_and_parse_json_file(file_path)    #4
                print(f"Running prompts for {selected_file}")
                for i, prompt in enumerate(prompts):
                    print(f"PROMPT {i+1} --------------------")
                    print(prompt)
                    print(f"REPLY ---------------------------")
                    print(prompt_llm(prompt))                      #5
            else:
                print("Invalid choice. Please enter a valid number.")
        except ValueError:
            print("Invalid input. Please enter a number.")
#1 收集给定文件夹中的所有文件
#2 打印文件列表作为选择项
#3 输入用户的选择
#4 加载提示并将其解析为消息
#5 将提示提交给OpenAI LLM

在代码列表中注释掉的部分展示了如何连接到本地LLM。这将允许你探索同样应用于本地运行的开源LLM的提示工程战术。默认情况下,这个示例使用的是我们在第2.1.1节中之前配置的OpenAI模型。如果你之前没有完成该部分,请在运行本示例之前返回并完成它。

图2.10展示了运行提示工程战术测试器(prompt_engineering.py文件)时的输出。当你运行测试器时,你可以输入要测试的战术值,并观察它的执行过程。

image.png

在接下来的章节中,我们将更详细地探讨每个提示战术,并检查各种示例。

2.3.1 创建详细查询

这个战术的基本前提是提供尽可能多的细节,但也要小心不要提供无关的细节。以下列出了用于探索此战术的JSON Lines文件示例。

命令 2.9 detailed_queries.jsonl

[                        #1
    {
        "role": "system",
        "content": "You are a helpful assistant."
    },
    {
        "role": "user",
        "content": "What is an agent?"      #2
    }
]
[
    {
        "role": "system",
        "content": "You are a helpful assistant."
    },
    {
        "role": "user",
        "content": """
What is a GPT Agent? 
Please give me 3 examples of a GPT agent
"""                                        #3
    }
]

#1 第一个示例没有使用详细查询。

#2 首先问LLM一个非常宽泛的问题。

#3 问一个更具体的问题,并要求提供示例。

这个示例展示了使用详细查询与不使用详细查询之间的区别。它还进一步要求提供示例。记住,你在提示中提供的相关性和背景越多,整体响应会越好。要求提供示例是强制建立问题与预期输出之间关系的另一种方式。

2.3.2 采用角色

采用角色可以为LLM定义一个全面的背景或一组规则。LLM可以使用该背景和/或规则来框定后续的所有输出响应。这是一个有力的战术,并且我们将在本书中广泛使用。

命令 2.10 adopting_personas.jsonl展示了使用两种角色来回答同一个问题的示例。这可以是一种有趣的技术,用于探索各种新颖的应用场景,从获取人口统计反馈到专注于特定任务,甚至进行“橡胶鸭调试”。

GPT 橡胶鸭调试

橡胶鸭调试是一种解决问题的技巧,在这种技巧中,个人将问题向一个无生命的物体(如橡胶鸭)解释,以理解或找到解决方案。此方法在编程和调试中非常常见,因为大声阐述问题通常有助于澄清问题,并可能带来新的见解或解决方案。

GPT橡胶鸭调试使用相同的技巧,但我们使用的是LLM,而不是无生命的物体。通过为LLM提供一个特定领域的角色,您可以进一步扩展这一策略。

[
    {
        "role": "system",
        "content": """
You are a 20 year old female who attends college 
in computer science. Answer all your replies as 
a junior programmer.
"""                         #1
    },
    {
        "role": "user",
        "content": "What is the best subject to study."
    }
]
[
    {
        "role": "system",
        "content": """
You are a 38 year old male registered nurse. 
Answer all replies as a medical professional.
"""                                             #2
    },
    {
        "role": "user",
        "content": "What is the best subject to study."
    }
]

#1 第一个角色

#2 第二个角色

代理档案的核心元素之一是角色。我们将使用各种角色来帮助代理完成任务。当你运行这个战术时,特别注意LLM输出响应的方式。

2.3.3 使用分隔符

分隔符是一种有效的方式,用来隔离并让LLM专注于消息的某个部分。这个战术通常与其他战术结合使用,但也可以独立有效地工作。以下列出了两个示例,但描述分隔符的方法有很多种,从XML标签到使用Markdown等。

命令 2.11 using_delimiters.jsonl

[
    {
        "role": "system",
        "content": """
Summarize the text delimited by triple quotes 
with a haiku.
"""               #1
    },
    {
        "role": "user",
        "content": "A gold chain is cool '''but a silver chain is better'''"
    }
]
[
    {
        "role": "system",
        "content": """
You will be provided with a pair of statements 
(delimited with XML tags) about the same topic. 
First summarize the arguments of each statement. 
Then indicate which of them makes a better statement
 and explain why.
"""                        #2
    },
    {
        "role": "user",
        "content": """
<statement>gold chains are cool</statement>
<statement>silver chains are better</statement>
"""
    }
]

#1 分隔符由字符类型和重复次数定义。

#2 分隔符由XML标准定义。

运行此战术时,请注意LLM在输出响应时关注文本的哪些部分。此战术对描述信息的层级结构或其他关系模式非常有帮助。

2.3.4 指定步骤

指定步骤是另一个强大的战术,具有广泛的用途,包括在代理中,如命令2.12所示。它在为复杂的多步骤任务开发提示或代理档案时特别有用。你可以指定步骤,将这些复杂的提示分解为LLM可以跟随的逐步过程。反过来,这些步骤可以引导LLM通过多个交互,在更长的对话中进行多次迭代。

命令 2.12 specifying_steps.jsonl

[
    {
        "role": "system",
        "content": """
Use the following step-by-step instructions to respond to user inputs.
Step 1 - The user will provide you with text in triple single quotes. 
Summarize this text in one sentence with a prefix that says 'Summary: '.
Step 2 - Translate the summary from Step 1 into Spanish, 
with a prefix that says 'Translation: '.
"""                                          #1
    },
    {
        "role": "user",
        "content": "'''I am hungry and would like to order an appetizer.'''"
    }
]
[
    {
        "role": "system",
        "content": """
Use the following step-by-step instructions to respond to user inputs.
Step 1 - The user will provide you with text. Answer any questions in 
the text in one sentence with a prefix that says 'Answer: '.

Step 2 - Translate the Answer from Step 1 into a dad joke,
 with a prefix that says 'Dad Joke: '."""                      #2
    },
    {
        "role": "user",
        "content": "What is the tallest structure in Paris?"
    }
]

#1 注意使用分隔符的战术。

#2 步骤可以是完全不同的操作。

2.3.5 提供示例

提供示例是指导LLM生成期望输出的一个很好的方式。提供示例有多种方式,可以通过系统消息/提示来强调一般输出。以下示例中,示例作为最后一个LLM助手的回复被添加,前提是“教我Python”。

命令 2.13 providing_examples.jsonl

[
    {
        "role": "system",
        "content": """
Answer all replies in a consistent style that follows the format, 
length and style of your previous responses.
Example:
  user:
       Teach me about Python.
  assistant:                                                #1
       Python is a programming language developed in 1989
 by Guido van Rossum.

  Future replies:
       The response was only a sentence so limit
 all future replies to a single sentence.
"""                                           #2
    },
    {
        "role": "user",
        "content": "Teach me about Java."
    }
]

#1 将示例输出作为“之前的”助手回复注入

#2 添加输出限制战术,以限制输出的大小并与示例匹配

提供示例还可以用于请求从复杂任务系列中生成的特定输出格式。例如,要求LLM生成与示例输出匹配的代码就是一个极好的应用示例。我们将在本书中广泛应用这一战术,但也有其他方法可以指导输出。

2.3.6 指定输出长度

指定输出长度的战术不仅可以限制令牌数量,还可以引导输出到所需的格式。命令 2.14展示了使用两种不同技术的示例。第一个将输出限制为10个单词以内,这可以使响应更加简洁并具有方向性,对于某些使用场景是非常可取的。第二个示例演示了将输出限制为简洁的要点集。这种方法可以帮助缩小输出范围并保持答案简短。更简洁的答案通常意味着输出更专注,填充内容更少。

命令 2.14 specifying_output_length.jsonl

[
    {
        "role": "system",
        "content": """
Summarize all replies into 10 or fewer words.
"""                                               #1
    },
    {
        "role": "user",
        "content": "Please tell me an exciting fact about Paris?"
    }
]
[
    {
        "role": "system",
        "content": """
Summarize all replies into 3 bullet points.
"""                                           #2
    },
    {
        "role": "user",
        "content": "Please tell me an exciting fact about Paris?"
    }
]

#1 限制输出使答案更加简洁。

#2 将答案限制为简短的要点集。

保持答案简短在开发多代理系统时可以带来额外的好处。任何与其他代理交互的代理系统都可以从更简洁和集中的回复中受益。它有助于让LLM更加专注,减少嘈杂的沟通。

务必运行本策略所有提示战术的示例。如前所述,我们将在后续章节中介绍其他提示工程策略和战术。本章的最后,我们将探讨如何为你的使用案例选择最佳LLM。

2.4 为你的特定需求选择最佳LLM

虽然成为一个成功的AI代理构建者不需要深入理解LLM,但能够评估LLM的规格是非常有帮助的。就像计算机用户不需要知道如何构建处理器就能理解不同处理器型号之间的差异一样,这一类比同样适用于LLM,虽然标准可能不同,但仍然依赖于一些主要的考虑因素。

通过我们之前的讨论和对LM Studio的了解,我们可以提取出一些在考虑LLM时对我们至关重要的基本标准。图2.11解释了定义一个LLM值得考虑用于创建GPT代理或任何LLM任务的基本标准。

image.png

为了构建AI代理,我们需要根据任务相关的标准来考虑这些因素。模型的上下文大小和速度可以视为第六和第七个标准,但通常它们被视为模型部署架构和基础设施的变化。考虑LLM时的第八个标准是成本,但这取决于许多其他因素。以下是这些标准如何与构建AI代理相关的总结:

  • 模型性能:你通常需要了解LLM在给定任务集上的表现。例如,如果你正在构建一个专门用于编码的代理,那么一个在代码上表现良好的LLM将是必不可少的。
  • 模型参数(大小) :模型的大小通常是推理性能和模型响应能力的一个很好的指示。然而,模型的大小也会决定你的硬件要求。如果你计划使用自己本地托管的模型,模型的大小也将主要决定你所需的计算机和GPU。幸运的是,我们看到有许多小型、高效的开源模型被定期发布。
  • 使用案例(模型类型) :模型类型有多种变体。聊天补全模型,如ChatGPT,适合迭代和推理问题,而诸如补全、问答和指令类型的模型则更与特定任务相关。对于代理应用,尤其是需要迭代的代理应用,聊天补全模型是必不可少的。
  • 训练输入:了解用于训练模型的内容通常会决定模型的领域。虽然通用模型可以有效地应用于各种任务,但更具体或经过微调的模型可能对某个领域更相关。如果是一个领域特定的代理,较小且经过微调的模型可能与GPT-4等大型模型一样,甚至表现更好。
  • 训练方法:虽然这可能不太重要,但了解模型训练方法是有帮助的。模型的训练方式可能会影响它的泛化、推理和规划能力。这对于规划代理至关重要,但对于任务更特定的助手来说可能不那么重要。
  • 上下文令牌大小:模型的上下文大小更具体地与模型架构和类型相关。它决定了模型能够保持的上下文或记忆的大小。小于4,000个令牌的上下文窗口通常足以处理简单任务。然而,当使用多个代理进行任务协作时,较大的上下文窗口是必不可少的。模型通常会根据上下文窗口的大小进行部署。
  • 模型速度(模型部署) :模型的速度由其推理速度(即模型对请求的响应速度)决定,这又受到其运行基础设施的影响。如果你的代理不直接与用户互动,实时速度可能不是必需的。另一方面,实时互动的LLM代理需要尽可能快。对于商业模型,速度将由提供商确定并支持。而对于那些希望自行运行LLM的人来说,基础设施将决定模型的速度。
  • 模型成本(项目预算) :成本通常由项目决定。无论是学习构建代理,还是实施企业软件,成本始终是一个考虑因素。在运行自己的LLM与使用商业API之间,存在一个显著的权衡。

在选择基于哪个模型构建生产代理系统时,有很多因素需要考虑。然而,选择并使用单一模型通常对于研究和学习来说是最好的。如果你是LLM和代理的新手,你可能会选择像GPT-4 Turbo这样的商业选项。除非另有说明,本书中的工作将依赖于GPT-4 Turbo。

随着时间的推移,模型无疑会被更好的模型所取代。所以你可能需要升级或更换模型。为了做到这一点,你必须理解你所使用的LLM和代理的性能指标。幸运的是,在第9章中,我们将探讨如何通过提示流来评估LLM、提示和代理档案。

2.5 练习

通过以下练习帮助你更好地理解本章内容:

练习 1 — 使用不同的LLM

  • 目标:使用connecting.py代码示例连接到来自OpenAI或其他提供商的不同LLM。

  • 任务

    1. 修改connecting.py以连接到不同的LLM。
    2. 选择一个来自OpenAI或其他提供商的LLM。
    3. 更新代码中的API密钥和端点。
    4. 执行修改后的代码并验证响应。

练习 2 — 探索提示工程战术

  • 目标:探索各种提示工程战术,并为每个战术创建变体。

  • 任务

    1. 回顾本章中涉及的提示工程战术。
    2. 为每个战术编写变体,尝试不同的措辞和结构。
    3. 使用LLM测试这些变体,观察不同的结果。
    4. 记录结果,并分析每种变体的有效性。

练习 3 — 使用LM Studio下载并运行LLM

  • 目标:使用LM Studio下载一个LLM,并将其与提示工程战术结合。

  • 任务

    1. 在你的机器上安装LM Studio。
    2. 使用LM Studio下载一个LLM。
    3. 使用LM Studio托管该模型。
    4. 编写Python代码以连接到托管的模型。
    5. 将提示工程战术示例与托管的模型集成。

练习 4 — 比较商业LLM与开源LLM

  • 目标:比较商业LLM(如GPT-4 Turbo)与开源模型在使用提示工程示例时的表现。

  • 任务

    1. 使用GPT-4 Turbo实现提示工程示例。
    2. 使用开源LLM重复该实现。
    3. 根据响应准确性、一致性和速度等标准评估这些模型。
    4. 记录评估过程,并总结结果。

练习 5 — LLM的托管替代方案

  • 目标:对比和比较LLM托管的替代方案与使用商业模型的情况。

  • 任务

    1. 研究LLM的不同托管选项(例如本地服务器、云服务)。
    2. 评估每个托管选项的优缺点。
    3. 在成本、性能和易用性方面将这些选项与使用商业模型进行比较。
    4. 撰写报告,概述比较结果,并根据特定用例推荐最佳方法。

总结

  • LLM使用一种称为生成预训练变换器(GPTs)的架构。
  • 生成模型(如LLM和GPT)不同于预测/分类模型,它们通过学习如何表示数据,而不仅仅是对数据进行分类。
  • LLM是数据、架构和针对特定使用案例的训练(称为微调)的集合。
  • OpenAI API SDK可以用来连接到LLM模型(如GPT-4),并且可以用来消费开源LLM。
  • 你可以快速设置Python环境并安装必要的包来进行LLM集成。
  • LLM可以处理各种请求,并生成独特的响应,这些响应可以用来增强与LLM集成相关的编程技能。
  • 开源LLM是商业模型的替代方案,可以通过LM Studio等工具本地托管。
  • 提示工程是一系列技巧,有助于制定更有效的提示,从而改善LLM的响应。
  • LLM可以用于驱动代理和助手,从简单的聊天机器人到完全自主的工作者。
  • 为特定需求选择最合适的LLM取决于性能、参数、使用案例、训练输入和其他标准。
  • 在本地运行LLM需要一系列技能,从设置GPU到理解各种配置选项。