本章内容概览
- 使用预训练大型语言模型进行文本、图像、语音和代码生成少样本(few-shot)、单样本(one-shot)和零样本(zero-shot)提示技术使用 LangChain 创建零样本个人助理生成式 AI 的局限性与伦理问题
预训练大型语言模型(LLM)的兴起彻底改变了自然语言处理(NLP)和生成任务领域。以 OpenAI 的 GPT 系列为代表,这些模型展现了生成逼真文本、图像、语音甚至代码的强大能力。高效利用预训练 LLM 意义重大:它使我们无需庞大资源来开发和训练模型即可部署先进的 AI 功能;同时,深入理解这些模型也为创新应用奠定基础,推动各行各业的发展。
在 AI 越来越主导世界的今天,掌握预训练 LLM 的集成与定制,成为数字时代创新和成功的关键竞争优势。随着 AI 的不断演进,灵活运用这些复杂模型尤为重要。
通常,这些模型通过浏览器界面操作,且不同 LLM 之间相互独立,界面各异。每个模型各有所长,浏览器界面限制了我们充分发挥单个模型潜力的能力。而借助 Python 等编程语言,尤其是 LangChain 库,可以带来显著优势:
- Python 在与 LLM 交互时,极大增强了工作流和流程的自动化能力。Python 脚本可以自主运行,无需人工干预,适合需要处理大量数据的企业。例如,Python 脚本可自动调用 LLM 生成月度报告,综合数据洞察,并通过邮件或数据库分发结果。Python 相较浏览器界面,提供更高的定制性和控制力,支持实现条件逻辑、多请求循环处理、异常管理等复杂需求。这种灵活性对满足特定业务目标或研究需求至关重要。Python 丰富的库生态便于将 LLM 集成到现有软件系统中。LangChain 库便是其中典范,扩展了 Python 与 LLM 的结合能力。它支持多模型组合,或将 LLM 与如 Wikipedia API、Wolfram Alpha API 等服务集成(后续章节详述)。这种“链式”集成能力能构建复杂多步骤的 AI 系统,使各任务由最合适的模型或服务负责,提升性能与准确度。
因此,本章首先介绍如何使用 OpenAI API 结合 Python 编程生成文本、图像、语音及代码内容;同时讲解少样本、单样本与零样本生成的区别——少样本提示是给模型多个示例帮助理解任务,单样本和零样本则分别是一个示例或无示例。
现代 LLM(如 ChatGPT)训练数据截止几个月前,无法提供最新或实时信息(如天气、航班状态、股价等)。你将学习如何借助 LangChain,将 LLM 与 Wolfram Alpha、Wikipedia API 结合,打造零样本全能个人助理。
尽管 LLM 功能强大,但它们并不具备真正的内容理解,可能出现逻辑错误、事实不准或难以把握复杂概念和细微差别。此外,模型的快速发展与广泛应用也带来了诸多伦理问题,如偏见、虚假信息、隐私和版权等。这些挑战需审慎对待,并采取积极措施,确保 LLM 的开发与应用符合伦理标准和社会价值。
16.1 使用 OpenAI API 进行内容生成
虽然还有其他大型语言模型(LLM),如 Meta 的 LLAMA 和 Google 的 Gemini,但本章以 OpenAI 的 GPT 系列为主要示例,因为其最为知名和广泛应用。
OpenAI 允许你使用 LLM 生成各种内容,如文本、图像、音频和代码。你可以通过网页浏览器或 API 访问其服务。本章重点介绍通过 API 使用 Python 程序与 LLM 交互进行内容生成的方式,原因在于前文提到 Python 与 LLM 交互的诸多优势。
你需要具备 OpenAI API 密钥才能运行本章中的程序。我假设你已在第15章获得密钥,若尚未获取,请返回第15章查看详细指导。
本节主要聚焦文本生成,同时也会给出代码、图像和语音生成的示例。
本章涉及多个新的 Python 库,安装命令如下,可在你电脑上的 Jupyter Notebook 新单元中运行:
!pip install --upgrade openai langchain_openai langchain!pip install wolframalpha langchainhub!pip install --upgrade --quiet wikipedia
根据屏幕提示完成安装。
16.1.1 使用 OpenAI API 进行文本生成任务
你可以为多种用途生成文本,比如问答、文本摘要和创意写作。
当你向 OpenAI GPT 提问时,请注意所有 LLM(包括 OpenAI GPT)均基于自动网络爬取的历史数据训练。截至目前,GPT-4 的训练数据截止到2023年12月(有三个月延迟),而 GPT-3.5 的训练数据截止至2021年9月。
先来用 GPT 询问一个历史事实问题,以下代码在新单元中输入执行:
from openai import OpenAIopenai_api_key = "在这里填写你的实际 OpenAI API 密钥" # ①client = OpenAI(api_key=openai_api_key) # ②completion = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": '''You are a helpful assistant, knowledgeable about recent facts.'''}, {"role": "user", "content": '''Who won the Nobel Prize in Economics in 2000?'''} ])print(completion.choices[0].message.content)
① 填写你的 OpenAI API 密钥
② 实例化 OpenAI() 类,命名为 client
③ 设定系统角色,指明助理身份
④ 用户发出问题
务必将你的 OpenAI API 密钥填写到代码中。我们首先实例化 OpenAI() 类并命名为 client。在 chat.completions.create() 方法中,指定模型为 gpt-3.5-turbo。官网 platform.openai.com/docs/models 提供了可用模型列表。你可以选择 gpt-4 或 gpt-3.5-turbo 进行文本生成,前者效果更佳但成本较高,本书示例多用后者,简单任务表现同样优秀。
messages 参数是一个消息列表,每条消息包含角色(“system”、“user”或“assistant”)和内容。system 消息设定助理行为;若无,则默认为“乐于助人的助手”。user 消息为用户询问或评论。上例中,用户询问:“谁获得了2000年诺贝尔经济学奖?”
返回结果:
2000年诺贝尔经济学奖授予了 James J. Heckman 和 Daniel L. McFadden,以表彰他们在微观计量经济学和微观经济理论方面的贡献。
OpenAI 给出了正确答案。
你还可以让模型写短文。例如,要求它写一篇关于自我激励重要性的短文:
completion = client.chat.completions.create( model="gpt-3.5-turbo", n=1, messages=[ {"role": "system", "content": '''You are a helpful assistant, capable of writing essays.'''}, {"role": "user", "content": '''Write a short essay on the importance of self-motivation.'''} ])print(completion.choices[0].message.content)
参数 n=1 表示生成一条回复,想要多条可调整 n。默认 n=1。
输出示例(仅摘录开头):
自我激励是实现成功和个人成长的关键因素,贯穿生活各方面。它是驱动我们行动、决策和目标的动力,推动我们克服道路上的障碍和挑战。
自我激励的主要益处之一是帮助个人主动掌控生活……
这篇短文共六段,全文可访问本书 GitHub 仓库(github.com/markhliu/DG…)。可以看到写作连贯、切题且语法无误。
你甚至可以让 GPT 给你讲个笑话:
completion = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": '''You are a helpful assistant, capable of telling jokes.'''}, {"role": "user", "content": '''Tell me a math joke.'''} ])print(completion.choices[0].message.content)
示例回复:
为什么等号那么谦虚?因为它知道自己不比任何人多,也不比任何人少!
你还能和助手进行上下文连续的对话。消息参数会自动包含对话历史。例如,在上面讲笑话的代码执行后,若运行:
completion = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "user", "content": '''Haha, that's funny! Tell me another one.'''} ])print(completion.choices[0].message.content)
你会收到类似回复:
当然!为什么数学书很难过?因为它有太多问题。
这里用户的提问“哈哈,很好笑!再讲一个。”只有结合之前请求数学笑话的上下文才有意义。
其他文本生成能力还包括文本摘要和分类,后续章节将展示相关示例。
16.1.2 使用 OpenAI API 生成代码
Codex 专门设计用于理解和生成代码,支持多种编程语言,并能将自然语言描述转换为代码。Codex 现已集成到 OpenAI 的 GPT 系列中。
接下来,我们让 OpenAI GPT 生成一个绘制正弦曲线的 Python 程序:
completion = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": '''You are a helpful assistant, capable of generating Python programs.'''}, {"role": "user", "content": '''Write a Python program to plot a sine graph.'''} ])print(completion.choices[0].message.content)
请注意,ChatGPT 使用的是 GPT-3.5-Turbo 模型,既负责对话交互,也负责代码生成任务,OpenAI 并未单独提供仅用于代码生成的 Codex 模型。
生成的代码如下:
import matplotlib.pyplot as pltimport numpy as np# 生成从0到2π的x值x = np.linspace(0, 2*np.pi, 100)# 计算正弦函数的y值y = np.sin(x)# 绘制正弦曲线plt.figure()plt.plot(x, y)plt.title('Sine Graph')plt.xlabel('x')plt.ylabel('sin(x)')plt.grid(True)plt.show()
你可以在安装了 matplotlib 库的 Python 环境中运行此程序,以可视化正弦曲线。
如果你将生成的 Python 程序复制粘贴到 Jupyter Notebook 的一个单元格中运行,将会看到类似图16.1的图像。
图16.1 使用 OpenAI GPT-3.5 生成绘制正弦曲线的 Python 代码。我们通过文本描述“Write a Python program to plot a sine graph”请求模型生成 Python 程序,然后运行该程序绘制出图像。
大型语言模型不仅提供了 Python 代码,还提示你需要在安装了 matplotlib 库的 Python 环境中运行代码。
16.1.3 使用 OpenAI DALL·E 2 进行图像生成
DALL·E 2 是 OpenAI 开发的 AI 模型,专门用于根据文本描述生成图像。它是原始 DALL·E 模型的升级版本,在视觉内容生成领域具有重要进展。
DALL·E 2 使用与第15章讨论的类似的扩散模型,从随机像素开始,逐步细化成与输入文本相符的连贯图像。相比原始 DALL·E,DALL·E 2 生成的图像质量更高,且对文本描述的表现更准确细致。
将 DALL·E 2 集成进 OpenAI GPT 系列,使我们不仅能生成文本,还能基于文本提示生成图像。接下来,我们请求 DALL·E 2 创建一张“有人在河岸钓鱼”的图像:
response = client.images.generate( model="dall-e-2", prompt="someone fishing at the river bank", size="512x512", quality="standard", n=1,)image_url = response.data[0].urlprint(image_url)
该代码块会生成一个 URL,点击该 URL 可查看一张类似图16.2的图像。
16.1.4 使用 OpenAI API 进行语音生成
文本转语音(TTS)是一项将书面文本转换成语音的技术。TTS 通过多模态 Transformer 训练,输入是文本,输出是音频格式。在 ChatGPT 的应用中,集成 TTS 功能意味着大型语言模型不仅能生成文本回答,还能将其朗读出来。下面示例演示如何调用 OpenAI API 将一段短文本转换为语音:
response = client.audio.speech.create( model="tts-1-hd", voice="shimmer", input='''This is an audio file generated by OpenAI's text to speech AI model.''')response.stream_to_file("files/speech.mp3")
执行以上代码后,电脑上会保存一个名为 speech.mp3 的文件,你可以播放它。官方文档(platform.openai.com/docs/guides…)提供了多种声音选项,此处我们选择了“shimmer”,其他选项包括 “alloy”、“echo”等。
16.2 LangChain 简介
LangChain 是一个专为 Python 设计的库,旨在简化大型语言模型(LLM)在各类应用中的使用。它提供了一套工具和抽象层,帮助开发者更轻松地构建、部署和管理基于 GPT-3、GPT-4 及类似模型的应用。
LangChain 屏蔽了与不同 LLM 和应用交互的复杂细节,使开发者能专注于业务逻辑开发,而无需担心底层模型差异。它非常适合构建“无所不知”的智能代理,将 LLM 与可提供实时信息或最新事实的工具(如 Wolfram Alpha 和 Wikipedia)串联起来。其模块化架构支持灵活集成不同组件,充分发挥各类模型和服务的优势。
16.2.1 为什么需要 LangChain
假设你的目标是构建一个零样本(zero-shot)无所不知智能代理,使其能生成多种内容、检索实时信息并回答事实性问题。你希望代理能自动根据任务选择正确的信息来源,无需明确告诉它如何操作。LangChain 就是解决这一需求的合适工具。
在本项目中,你将学习使用 LangChain 将 LLM 与 Wolfram Alpha 和 Wikipedia API 结合,打造零样本无所不知智能代理。Wolfram Alpha 擅长科学计算和实时信息检索,Wikipedia 擅长提供历史与近期事件和事实信息。
LangChain 让我们创建的代理能利用多个工具回答问题:代理首先理解查询意图,然后决定使用哪个工具获取答案。
为了证明即使最先进的 LLM 也不具备这些能力,我们问它2024年奥斯卡最佳男演员是谁:
completion = client.chat.completions.create( model="gpt-4", messages=[ {"role": "system", "content": '''You are a helpful assistant, knowledgeable about recent facts.'''}, {"role": "user", "content": '''Who won the Best Actor Award in 2024 Academy Awards?'''} ])print(completion.choices[0].message.content)
输出为:
抱歉,我无法提供实时信息或预测未来事件,如2024年奥斯卡颁奖情况。建议你在颁奖日期临近时查阅可靠新闻或权威渠道以获取最新信息。
我在2024年3月17日进行此查询,GPT-4 无法回答该问题。如果你现在尝试,模型或许因更新了更近期数据而能给出正确答案。如果是这样,请改问几天前的事件,通常会得到类似上述的回应。
因此,我们用 LangChain 将 LLM 与 Wolfram Alpha 和 Wikipedia API 串联起来。Wolfram Alpha 擅长科学运算和实时信息检索,Wikipedia 以提供历史与最新事实著称。
16.2.2 在 LangChain 中使用 OpenAI API
你在本章早些时候安装的 langchain-openai 库,可以让你用极少的提示词工程与 OpenAI GPT 交互,只需用简洁的英文告诉模型想做什么。
下面示例演示如何让代理纠正文本中的语法错误:
from langchain_openai import OpenAIllm = OpenAI(openai_api_key=openai_api_key)prompt = """Correct the grammar errors in the text:i had went to stor buy phone. No good. returned get new phone."""res = llm.invoke(prompt)print(res)
输出为:
I went to the store to buy a phone, but it was no good. I returned it and got a new phone.
注意这里我们未做任何复杂的提示词工程,也未指定具体模型。LangChain 会基于任务需求及成本、延迟、性能等因素,自动选择最合适的模型,并自动格式化请求以适配该模型。前面示例仅用简洁英语指示代理纠正文本语法,返回了语法正确的文本。
另一个例子,我们问代理肯塔基州的首府是哪座城市:
prompt = """What is the capital city of the state of Kentucky?"""res = llm.invoke(prompt)print(res)
输出:
The capital city of Kentucky is Frankfort.
正确告知我们肯塔基州首府是弗兰克福特。
16.2.3 零样本(zero-shot)、单样本(one-shot)和少样本(few-shot)提示
少样本、单样本和零样本提示指的是向 LLM 提供示例或指令的不同方式,旨在引导模型生成更准确或相关的回复。
- 零样本提示:只给模型任务描述或问题,不提供示例。模型凭借已有知识和理解生成答案。单样本提示:给模型一个示例,说明任务要求。少样本提示:提供多个示例,帮助模型更好理解任务模式或规则,提升准确度。
迄今为止,你与 OpenAI GPT 的交互均属于零样本提示,因为未向模型提供示例。
下面示范一个少样本提示例子,进行情感分析任务:判断一句话是正面还是负面情绪。我们给出多个示例:
prompt = """The movie is awesome! // PositiveIt is so bad! // NegativeWow, the movie was incredible! // PositiveHow horrible the movie is! //"""res = llm.invoke(prompt)print(res)
输出:
Negative
提示中,我们给了三个例子,其中两句为正面,一句为负面。接着让模型判断“How horrible the movie is!”的情绪,模型正确判断为负面。
这里用“//”分隔句子和情绪标签,你也可以用“->”等符号,只要保持一致即可。
下面是单样本提示例子:
prompt = """Car -> DriverPlane ->"""res = llm.invoke(prompt)print(res)
输出:
Pilot
给出一个例子后,实际上是问模型“驾驶汽车的人称为什么,驾驶飞机的人称为什么?”模型正确回答“Pilot”。
练习16.1
假设你想问模型“花园对应园丁,就像厨房对应厨师一样”的类比关系。请用单样本提示获取答案。
最后是零样本提示例子:
prompt = """Is the tone in the sentence "Today is a great day for me" positive, negative, or neutral?"""res = llm.invoke(prompt)print(res)
输出:
Positive
这里提示中未提供任何示例,只用简洁英文指示模型判断该句子语气是正面、负面还是中性。
16.3 使用 LangChain 创建零样本无所不知智能代理
本节你将学习如何在 LangChain 中创建一个零样本无所不知智能代理。你会使用 OpenAI GPT 生成各种内容,如文本、图像和代码。为弥补大型语言模型无法提供实时信息的不足,你还将学习如何将 Wolfram Alpha 和 Wikipedia API 添加到代理的工具箱中。
Wolfram Alpha 是一款专注于在线处理事实查询的计算知识引擎,擅长数值与计算任务,尤其是在科学和技术领域。通过集成 Wolfram Alpha API,智能代理几乎能够回答各类学科的任何问题。当 Wolfram Alpha 无法提供答案时,我们将使用 Wikipedia 作为辅助,针对特定主题的事实性问题提供信息来源。
图16.3 展示了本节构建零样本无所不知智能代理的步骤流程图。
具体来说,我们首先将在 LangChain 中创建一个只使用一个工具——Wolfram Alpha API 的智能代理,用于回答与实时信息和最新事实相关的问题。随后,我们将把 Wikipedia API 添加到工具箱中,作为查询最新事实问题时的备选方案。接着,我们会添加利用 OpenAI API 的各种工具,比如文本摘要器、笑话讲述者和情感分类器。最后,还会加入图像和代码生成的功能。
16.3.1 申请 Wolfram Alpha API 密钥
Wolfram Alpha 每月提供最多 2000 次非商业用途的免费 API 调用。要获取 API 密钥,首先访问 account.wolfram.com/login/creat…,完成注册账户的步骤。
Wolfram 账户本身仅提供浏览器访问权限,你还需要在 products.wolframalpha.com/api/ 申请 API 密钥。进入页面后,点击左下角的“Get API Access”按钮。弹出一个小对话框,填写“Name”和“Description”字段,从下拉菜单中选择“Simple API”,然后点击“Submit”,如图16.4所示。
之后,你的 AppID 会出现在新窗口中。复制该 API 密钥并保存到文件以备后续使用。
以下示例演示如何使用 Wolfram Alpha API 进行数学运算:
import osos.environ['WOLFRAM_ALPHA_APPID'] = "你的 Wolfram Alpha AppID"from langchain_community.utilities.wolfram_alpha import WolframAlphaAPIWrapperwolfram = WolframAlphaAPIWrapper()res = wolfram.run("how much is 23*55+123?")print(res)
输出结果为:
Assumption: 23×55 + 123Answer: 1388
Wolfram Alpha API 给出了正确答案。
我们还会加入 Wikipedia API 来回答各类话题。如果你已经在电脑上安装了 Wikipedia 库,则无需申请 API 密钥。以下是 LangChain 库中调用 Wikipedia API 的示例:
from langchain.tools import WikipediaQueryRunfrom langchain_community.utilities import WikipediaAPIWrapperwikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())res = wikipedia.run("University of Kentucky")print(res)
输出示例:
Page: University of KentuckySummary: The University of Kentucky (UK, UKY, or U of K) is a publicland-grant research university in Lexington, Kentucky. Founded in 1865 byJohn Bryan Bowman as the Agricultural and Mechanical College of Kentucky,the university is one of the state's two land-grant universities (theother being Kentucky State University)…
为了简洁起见,此处省略了大部分输出内容。
16.3.2 在 LangChain 中创建智能代理
接下来,我们将在 LangChain 中创建一个仅包含 Wolfram Alpha API 的智能代理。此处“代理”指的是通过自然语言交互,设计用于处理特定任务或流程的独立实体。随后我们会逐步向链中添加更多工具,使代理能够处理更多任务。
代码清单16.2 创建 LangChain 代理:
import osos.environ['OPENAI_API_KEY'] = openai_api_keyfrom langchain.agents import load_toolsfrom langchain_openai import ChatOpenAIfrom langchain import hubfrom langchain.agents import AgentExecutor, create_react_agentfrom langchain_openai import OpenAIprompt = hub.pull("hwchase17/react")llm = ChatOpenAI(model_name='gpt-3.5-turbo') # ①tool_names = ["wolfram-alpha"]tools = load_tools(tool_names, llm=llm) # ②agent = create_react_agent(llm, tools, prompt)agent_executor = AgentExecutor(agent=agent, tools=tools, handle_parsing_errors=True, verbose=True) # ③res = agent_executor.invoke({"input": """What is the temperature in Lexington, Kentucky now?"""}) # ④print(res["output"])
① 定义所用大型语言模型(LLM)
② 将 Wolfram Alpha 加入工具箱
③ 创建代理并初始化执行器
④ 向代理提问
LangChain 中的 hwchase17/react
指的是一种特定的 ReAct 代理配置。ReAct(Reactive Action)是 LangChain 中的一个框架,旨在优化语言模型与其他工具的结合,提升解决复杂任务的能力。详情见:python.langchain.com/docs/how_to…。
创建代理时需要指定代理可用的工具,上例中仅使用 Wolfram Alpha API。
示例提问肯塔基州列克星敦当前温度,输出如下:
> Entering new AgentExecutor chain...I should use Wolfram Alpha to find the current temperature in Lexington, Kentucky.Action: wolfram_alphaAction Input: temperature in Lexington, KentuckyAssumption: temperature | Lexington, KentuckyAnswer: 44 °F (wind chill: 41 °F) (27 minutes ago)I now know the current temperature in Lexington, Kentucky.Final Answer: The temperature in Lexington, Kentucky is 44 °F with a wind chill of 41 °F.> Finished chain.The temperature in Lexington, Kentucky is 44 °F with a wind chill of 41 °F.
输出不仅展示了最终答案(44 华氏度,体感温度41华氏度),还展示了思考链,表明答案来自 Wolfram Alpha。
我们也可以把 Wikipedia 加入工具箱:
tool_names += ["wikipedia"]tools = load_tools(tool_names, llm=llm)agent = create_react_agent(llm, tools, prompt)agent_executor = AgentExecutor(agent=agent, tools=tools, handle_parsing_errors=True, verbose=True)res = agent_executor.invoke({"input": """Who won the Best Actor Award in 2024 Academy Awards?"""})print(res["output"])
我询问2024年奥斯卡最佳男演员归属,代理使用 Wikipedia 找到正确答案:
I need to find information about the winner of the Best Actor Award at the 2024 Academy Awards.Action: wikipediaAction Input: 2024 Academy Awards Best Actor…Cillian Murphy won the Best Actor Award at the 2024 Academy Awards for his performance in Oppenheimer.
代理首先决定用 Wikipedia 作为工具搜索,查询多条 Wikipedia 来源后,给出正确答案。
接下来,你将学习如何向代理的工具箱添加更多 OpenAI GPT 工具。
16.3.3 使用 OpenAI GPT 向代理添加工具
我们首先添加一个文本摘要工具,让代理能够对文本进行总结。
代码清单16.3 向代理工具箱添加文本摘要器:
from langchain.agents import Toolfrom langchain.prompts import PromptTemplatefrom langchain.chains import LLMChaintemp = PromptTemplate(input_variables=["text"], # ① template="Write a one sentence summary of the following text: {text}")summarizer = LLMChain(llm=llm, prompt=temp) # ②sum_tool = Tool.from_function( func=summarizer.run, name="Text Summarizer", description="A tool for summarizing texts") # ③tools += [sum_tool]agent = create_react_agent(llm, tools, prompt) # ④agent_executor = AgentExecutor(agent=agent, tools=tools, handle_parsing_errors=True, verbose=True)res = agent_executor.invoke({"input": '''Write a one sentence summary of the following text:The University of Kentucky's Master of Science in Finance (MSF) degree prepares students for a professional career in the finance and banking industries. The program is designed to provide rigorous and focused training in finance, broaden opportunities in your career, and sharpened skills for the fast-changing and competitive world of modern finance.'''})print(res["output"])
① 定义模板
② 定义摘要函数
③ 将摘要器添加为工具
④ 使用更新后的工具箱重新定义代理
我们首先提供了一个摘要模板,然后定义了摘要函数并将其添加到工具箱,最后使用更新后的工具箱重新创建代理,并要求代理用一句话总结示例文本。确保你的提示格式符合模板描述,这样代理才能正确识别使用哪个工具。
代码运行输出:
> Entering new AgentExecutor chain...I need to summarize the text provided.Action: Summarizer…> Finished chain.The University of Kentucky's MSF program offers specialized training in finance to prepare students for successful careers in the finance and banking industries.
代理选择了摘要工具执行任务,因为输入匹配了摘要器函数中描述的模板。我们输入了两句较长的文本,代理输出了简洁的一句话摘要。
你可以添加任意多的工具。例如,添加一个讲笑话的工具:
temp = PromptTemplate(input_variables=["text"], template="Tell a joke on the following subject: {subject}")joke_teller = LLMChain(llm=llm, prompt=temp)tools += [Tool.from_function(name='Joke Teller', func=joke_teller.run, description='A tool for telling jokes')]agent = create_react_agent(llm, tools, prompt)agent_executor = AgentExecutor(agent=agent, tools=tools, handle_parsing_errors=True, verbose=True)res = agent_executor.invoke({"input": '''Tell a joke on the following subject: coding'''})print(res["output"])
输出示例:
> Entering new AgentExecutor chain...I should use the Joke Teller tool to find a coding-related joke.Action: Joke TellerAction Input: codingObservation: Why was the JavaScript developer sad?Because he didn't know how to "null" his feelings.Thought:That joke was funny!Final Answer: Why was the JavaScript developer sad? Because he didn't know how to "null" his feelings.> Finished chain.Why was the JavaScript developer sad? Because he didn't know how to "null" his feelings.
我们要求代理讲一个关于编程的笑话,代理识别“Joke Teller”为相应工具,输出了一个与编程相关的笑话。
练习16.2
向代理工具箱添加一个情感分析工具,命名为 Sentiment Classifier。然后让代理对文本“This movie is so-so”进行正面、负面或中性分类。
16.3.4 添加代码和图像生成工具
你可以在 LangChain 中为工具箱添加各种工具,详情请参考:python.langchain.com/docs/how_to…。接下来,我们添加代码和图像生成工具。
添加代码生成工具示例如下:
temp = PromptTemplate(input_variables=["text"], template='''Write a Python program based on the description in the following text: {text}''')code_generator = LLMChain(llm=llm, prompt=temp)tools += [Tool.from_function(name='Code Generator', func=code_generator.run, description='A tool to generate code')]agent = create_react_agent(llm, tools, prompt)agent_executor = AgentExecutor(agent=agent, tools=tools, handle_parsing_errors=True, verbose=True)res = agent_executor.invoke({"input": '''Write a Python program based on the description in the following text: write a python program to plot a sine curve and a cosine curvein the same graph. The sine curve is in solid line and the cosinecurve is in dashed line. Add a legend to the graph. Set the x-axis range to -5 to 5. The title should be "Comparing sine and cosine curves."'''})print(res["output"])
输出示例:
> Entering new AgentExecutor chain...I should use the Code Generator tool to generate the Python program based on the given description.Action: Code GeneratorAction Input: Write a Python program to plot a sine curve and a cosine curve in the same graph. The sine curve is in solid line and the cosine curve is in dashed line. Add a legend to the graph. Set the x-axis range to -5 to 5. The title should be "Comparing sine and cosine curves."Observation: import matplotlib.pyplot as pltimport numpy as npx = np.linspace(-5, 5, 100)y1 = np.sin(x)y2 = np.cos(x)plt.plot(x, y1, label='Sine Curve', linestyle='solid')plt.plot(x, y2, label='Cosine Curve', linestyle='dashed')plt.legend()plt.title('Comparing Sine and Cosine Curves')plt.xlim(-5, 5)plt.show()Thought:The Python program has been successfully generated to plot the sine and cosine curves. I now know the final answer.Final Answer: The Python program to plot a sine curve and a cosine curve in the same graph with the specified requirements has been generated.> Finished chain.The Python program to plot a sine curve and a cosine curve in the same graph with the specified requirements has been generated.
将生成的代码粘贴到 Jupyter Notebook 单元格运行,你会看到类似图16.5的图像。
图16.5 在 LangChain 中添加生成 Python 代码的工具。该工具随后生成了用于在同一图中绘制正弦曲线和余弦曲线的代码,并带有图例和线条样式。
要添加图像生成器,可以按如下方式操作:
from langchain_community.utilities.dalle_image_generator import DallEAPIWrapperfrom langchain.prompts import PromptTemplatefrom langchain.chains import LLMChainfrom langchain.agents import Tool, create_react_agent, AgentExecutortemp = PromptTemplate(input_variables=["text"], template="Create an image base on the following text: {text}")grapher = LLMChain(llm=llm, prompt=temp)tools += [Tool.from_function(name='Text to image', func=grapher.run, description='A tool for text to image')]agent = create_react_agent(llm, tools, prompt)agent_executor = AgentExecutor(agent=agent, tools=tools, handle_parsing_errors=True, verbose=True)image_url = DallEAPIWrapper().run(agent_executor.invoke({"input": '''Create an image base on the following text: a horse grazes on the grassland.'''})["output"])print(image_url)
输出是一个 URL,你可以通过它查看和下载生成的图像。我们让代理根据文本“a horse grazes on the grassland”创建了一张图片。该图片示例如图16.6所示。
至此,你已经学会了如何在 LangChain 中创建一个零样本无所不知的智能代理。你可以根据代理需要完成的任务,继续往工具箱中添加更多工具。
16.4 大型语言模型的局限性与伦理问题
OpenAI 的 GPT 系列等大型语言模型(LLM)在自然语言处理和生成式 AI 领域取得了显著进展。尽管其能力令人印象深刻,这些模型仍存在不少局限。理解这些限制对于充分发挥其优势和有效规避潜在风险至关重要。
同时,随着这些模型的快速发展和广泛应用,也引发了诸多伦理问题,如偏见、不准确、隐私泄露和版权侵权等。这些问题需要审慎对待并采取积极措施,确保 LLM 的开发和部署符合伦理标准和社会价值观。
本节将探讨 LLM 的局限性,分析这些问题为何持续存在,并通过典型失败案例强调解决这些挑战的重要性。我们还将审视与 LLM 相关的主要伦理关注,并提出相应的缓解途径。
16.4.1 LLM 的局限性
LLM 的根本局限之一是缺乏真正的理解和推理能力。虽然它们能生成连贯且上下文相关的回答,但并不具备对内容的内在理解。这可能导致逻辑错误、事实不准确,以及无法准确把握复杂概念或细微差别。
这种问题在 LLM 出现的许多严重错误中表现得淋漓尽致。《Smart Until It’s Dumb》一书收录了 GPT-3 和 ChatGPT 许多有趣的错误案例。例如,问题是:“Mrs. March 给母亲喝茶和粥,同时她像对待自己的孩子一样温柔地为小宝宝穿衣。谁是宝宝的母亲?”GPT-3 的回答是 Mrs. March。
公平地说,随着 LLM 快速发展,很多此类错误逐渐被修正,但 LLM 仍会犯一些低级错误。2023年6月,David Johnston 在 LinkedIn 上发表文章(www.linkedin.com/pulse/intel…),测试了 LLM 解决人类轻松能答出的一些问题的能力。包括 GPT-4 在内的模型在测试中表现挣扎。其中一道题目是:请说出一种动物,其名称的字母数等于它的腿数减去尾巴数。
截至目前,这个错误仍未被纠正。图16.7 是我通过浏览器界面提问时,GPT-4 给出的答案截图。
16.4.2 大型语言模型的伦理问题
其中一个最紧迫的伦理问题是,LLM 可能会延续并放大其训练数据中的偏见。由于这些模型从大量通常由人类生成的内容构建的数据集中学习,它们可能继承与性别、种族、民族及其他社会因素相关的偏见,导致输出结果带有偏见,强化刻板印象和歧视。
为减轻偏见,必须采用多样且包容性的训练数据集,实施偏见检测和校正算法,并确保模型开发和评估过程的透明度。尤其需要在行业内建立合作,制定偏见缓解的标准,推动负责任的人工智能发展。
然而,也应避免过度纠正。一个反例是谷歌的 Gemini 在图像生成中试图纠正刻板印象时,错误地将有色人种包含进纳粹时期德国士兵的群体中。
另一个关注点是 LLM 可能被用于制造和传播错误信息和操控内容。LLM 能生成逼真且具有说服力的文本,这种能力可能被滥用来制作虚假信息、宣传或操控内容,给公共舆论、民主制度和信息信任带来严重风险。
对此的解决方案是开发健全的内容审核系统。制定负责任使用指南,促进 AI 开发者、政策制定者和媒体机构之间的合作,是对抗错误信息的关键举措。
第三个关注点涉及隐私。用于训练 LLM 的庞大数据量引发隐私担忧,模型输出可能无意中泄露敏感信息。此外,LLM 也可能被用于网络攻击或绕过安全措施,带来重大安全风险。
此外,训练 LLM 所用的数据大多未经授权收集。支持者认为,LLM 的训练属于“转化性”使用:模型不仅是简单复述数据,而是用数据生成新的原创内容。此类转化可能符合“合理使用”原则,即在未经许可情况下有限度使用受版权保护材料,只要用途中加入了新的表达或意义。反对者则认为,LLM 大规模未经许可地训练于受版权保护文本,超出了合理使用的范畴。训练过程中大量直接摄取未经过转化的版权材料,可能构成侵权。对此争议仍在持续。现行版权法并非针对生成式 AI 设计,导致法律在适用于 LLM 等技术时存在模糊之处。相关争议可能需要立法和司法机构介入,制定明确指南,确保各方利益公平。
围绕 LLM 的伦理问题多层且复杂,需要综合施策。AI 研究者、开发者和政策制定者的协作对于制定伦理准则和框架,指导这些强大模型的负责任开发与应用至关重要。随着我们继续挖掘 LLM 的潜力,伦理考量必须始终置于首位,确保 AI 发展与社会价值观和人类福祉和谐共进。
总结
少样本提示(few-shot prompting)是指给大型语言模型(LLM)提供多个示例,帮助其理解任务;而单样本提示(one-shot)和零样本提示(zero-shot)则分别指提供一个示例或不提供示例。
LangChain 是一个 Python 库,旨在简化 LLM 在各类应用中的使用。它屏蔽了与不同 LLM 和应用交互的复杂细节,使智能代理能够根据任务自动选择工具箱中合适的工具,无需明确指示如何操作。
现代预训练的 LLM,如 OpenAI 的 GPT 系列,能够生成多种格式的内容,包括文本、图像、音频和代码。
尽管取得了令人瞩目的成就,LLM 仍缺乏对内容的真实理解和推理能力。这些局限可能导致逻辑错误、事实不准确以及无法把握复杂概念或细微差别。此外,模型的快速发展和广泛应用也带来了诸多伦理问题,如偏见、虚假信息、隐私泄露和版权侵权等。这些问题需要谨慎对待并采取积极措施,确保 LLM 的开发与应用符合伦理标准和社会价值。