至此,我们已经构建了 GenAISys 的核心框架。我们拥有了一个响应灵敏的小型 ChatGPT 式交互界面,超越了传统一对一的协同助手模式,创造了一个协作型多用户环境,AI 代理积极参与讨论。我们通过集成 RAG 技术,赋予 AI 代理访问 Pinecone 索引的能力,该索引能管理指令场景和数据。最终,我们构建了一个灵活的 GenAISys,使用户在协作会议中可自由开启或关闭 AI 代理。简而言之,我们打造的是一个以人为中心、辅助人类团队的 AI 系统,而非用机器智能替代人类。
然而,尽管具备以人为本的设计,全球跨大陆供应链的指数级增长以及每天海量的商品、服务和数字内容流通,依然需要高度自动化。举例来说,无法指望 Meta、X 或 LinkedIn 等社交媒体平台每天依靠数百万员工来审核数十亿条消息(包括图片、音频和视频文件);同样,亚马逊等公司也无法仅靠人工管理数百万在线交易和实体配送。自动化对提升人类决策和推理能力至关重要,尤其是在大规模关键任务中。因此,本章将通过为 GenAISys 增加多模态功能和推理能力来应对跨领域自动化的挑战。我们将实现图像生成与分析,并开始集成机器学习,目标是在 GenAISys 中构建一个全新的自主智能 AI 层。
我们将从概述即将集成的功能开始。随着 GenAISys 应用范围的拓展,我们将引入链式思维(Chain-of-Thought,CoT)推理过程,来有效编排和管理复杂任务。随后,纳入计算机视觉能力,包括使用 DALL·E 构建图像生成函数,以及利用 GPT-4o 实现图像分析功能。接着,我们将添加音频交互功能,支持语音对话:利用语音转文本(STT)作为输入提示,文本转语音(TTS)作为响应输出。最后,我们将在 GenAISys 中引入决策树分类器作为机器学习终端,用于活动预测。至本章末,我们将成功扩展 GenAISys,使其成为一个完全互动的多模态推理平台,能够应对复杂的跨领域用例。
本章涵盖内容包括:
- GenAISys 额外功能的架构设计
- 实现图像文件处理控件(widget)
- 实现支持语音对话的控件
- 利用 DALL·E 进行图像生成
- 利用 GPT-4o 实现图像分析
- 构建基于决策树分类器的机器学习终端
- 实现链式思维(CoT)推理
让我们先从设计一个增强版的 GenAISys 界面开始,赋予其更多 AI 能力。
增强事件驱动的 GenAISys 界面
到目前为止,我们开发的 GenAISys 框架是事件驱动的,由用户输入(人类或系统产生)激活,触发特定的 AI 代理功能。本章中,我们将通过添加以下新功能来扩展 GenAISys:
- 语音交互,使用户能够通过语音管理 GenAISys
- 使用决策树分类器构建新的机器学习终端,用于预测任务
- 多模态功能,包括利用 DALL·E 进行图像生成以及使用 GPT-4o 进行图像分析
- 链式思维(CoT)推理协调器,用于协调复杂且具自我反思能力的指令场景
让我们先来看看图5.1所示的扩展后 GenAISys 架构:
该图(是上一章图4.1的扩展版)突出了我们将集成到 GenAISys 中的新功能:
- I1 – AI 控制器:增强了链式思维(CoT)推理能力,支持按需自动执行任务序列,并集成了用于管理语音交互的控件(widget)
- I2 – 多用户聊天机器人:保持与前几章设计完全一致
- F1 – 生成式 AI 模型:扩展以支持多模态任务
- F2 – 记忆保持:保持不变,延续之前章节的设计
- F3 – 模块化 RAG:保持不变,延续之前章节的设计
- F4 – 多功能能力:新增音频和图像处理功能,包括用于预测的决策树分类器
提醒:
我们故意没有用箭头来展示 GenAISys 架构的主要组件,这是为了传达一个核心理念——模块化和架构灵活性。此图不是一张死板的蓝图,而是一套概念性工具包。它展示了你可以使用的强大组件——I1(AI 控制器)、I2(多用户聊天机器人)、F1(生成式 AI 模型)、F2(记忆保持)、F3(模块化 RAG)以及 F4(多功能能力)——作为独立且可互操作的模块。
我们在第4章构建的 GenAISys 功能基础上进行扩展,添加新层次而非替换已有组件,重点是功能增强与无缝集成。下图展示了一个高层流程图,说明了这些新增功能如何整合进现有 GenAISys 架构:
以下附加功能将集成到我们现有的 GenAISys 界面中:
- 启动(Start):初始化两个新控件——一个用于文本转语音(TTS)功能,另一个用于处理图像文件
- 用户输入(User Input):现支持可选的语音输入功能,用户可根据需要开启
- 生成机器人及其响应(Generate Bot 和 Generate Bot Response):这两个流程直接连接到现有的 VBox 界面,AI 代理使用链式思维(CoT)逻辑时,能清晰展示推理步骤
为实现上述扩展功能,我们将开发以下关键特性:
- 语音识别与合成(STT 和 TTS):集成谷歌文本转语音库(gTTS)
- 机器学习终端:实现基于决策树分类器的预测能力
- 图像生成与分析:由 OpenAI 的 DALL·E 和 GPT-4o 模型驱动
- 链式思维(CoT)推理:协调任务、功能和扩展,为 GenAISys 提供明确的机器推理能力(非人类推理)
尽管增加了多个新功能(包括推理功能 CoT),本章仅引入了一个新的依赖包 gTTS,以尽量降低复杂度。我们主要关注于构建一个可靠且依赖管理优化的架构。
接下来,让我们先了解更新后的 IPython 界面元素以及 AI 代理的增强部分。
IPython 界面与 AI 代理的增强
我们构建的 GenAISys 架构现在可视为由三个相互连接的层次组成,如图5.3所示。这些增强模糊了编排、控制和代理功能之间的界限,因为这些角色现分布在多个层次中:
- 第一层(IPython 界面)通过事件驱动的控件管理用户和系统输入,根据用户交互(输入框和复选框)编排任务。
- 第二层(AI 代理)控制生成式 AI 模型(本例中为 OpenAI 模型),并能够触发链式思维(CoT)推理序列。
- 第三层(函数与代理)包含由 AI 代理触发的函数。值得注意的是,CoT 函数本身也作为一个代理,能够根据需要编排生成式 AI 任务、机器学习以及其他附加功能。
这个高层架构整合了编排器、控制器和代理,每个部分都细分为具体的 Python 功能。让我们先从功能角度探讨第一层——IPython 界面。
第一层:IPython 界面
IPython 界面现新增了三个功能(在图5.4中以黄色高亮显示):语音控件、文件处理控件,以及由用户输入和 AI 代理活动触发的专用推理界面。这些增强使界面总共包含六个交互控件和功能。
让我们逐个介绍各个控件和功能:
-
用户选择(User selection)保持第4章的设计,是 GenAISys 协作设计的核心,未作改动。
-
用户输入(User input)同样沿用第4章设计,依然是捕获用户提示的关键控件。
-
AI 代理(AI agent)如第4章所述,负责激活或停用生成式 AI 代理(chat_with_gpt)。
-
语音控件(Voice widget)支持基于语音的交互,包括语音转文本(STT)和文本转语音(TTS)。STT 使用内置且免费的功能:
- Windows:按下 Windows键 + H
- macOS:在键盘设置中启用“听写”,并设置自定义快捷键
TTS 使用 gTTS 服务,通过一个默认值为 False 的复选框控制:
tts_checkbox = Checkbox(
value=False,
description='Voice Output',
layout=Layout(width='20%')
)
如果 AI 代理复选框被勾选,则调用 TTS 功能:
if agent_checkbox.value:
...
if tts_checkbox.value:
text_to_speech(response)
生成的 MP3 文件(response.mp3)会在 update_display() 函数中自动播放:
def update_display():
...
if os.path.exists("/content/response.mp3"):
display(Audio("/content/response.mp3", autoplay=True))
!rm /content/response.mp3
- 文件控件(Files widget)是一个新控件,用于管理文件,展示由生成式 AI 模型(DALL·E)生成并保存的图像。该控件通过一个默认值为 False 的复选框控制:
files_checkbox = Checkbox(
value=False,
description='Files',
layout=Layout(width='20%')
)
如果存在图像文件且复选框被选中,则通过 Python 图像库(PIL)显示图像:
if os.path.exists("/content/c_image.png") and files_checkbox.value == True:
original_image = PILImage.open("/content/c_image.png")
new_size = (original_image.width // 2, original_image.height // 2)
resized_image = original_image.resize(new_size)
display(resized_image)
- 推理激活控件(Reasoning activated)是 GenAISys 的另一个新控件。用户输入将触发 AI 代理中的事件,进而触发链式思维(CoT)推理过程。推理界面会实时显示 CoT 的思考过程。推理输出控件在会话开始时创建:
reasoning_output = Output(
layout=Layout(border="1px solid black", padding="10px",
margin="10px", width="100%")
)
该控件接收 CoT 过程的输出,并在 update_display() 函数中持续显示:
def update_display():
...
display(reasoning_output)
...
- VBox 界面现包含所有交互控件,包括新添加的 TTS 和文件控件:
if conversation_active:
display(
VBox(
[user_selector, input_box, agent_checkbox,
tts_checkbox, files_checkbox],
layout=Layout(display='flex', flex_flow='column',
align_items='flex-start', width='100%')
)
)
- 考虑到 AI 代理响应的长度和复杂度(尤其是在 CoT 过程中),我们引入了 Markdown 格式化增强功能。
update_display()函数现在会清晰格式化每条记录,调用专门的格式化函数:
def update_display():
clear_output(wait=True)
for entry in user_histories[active_user]:
formatted_entry = format_entry(entry)
display(Markdown(formatted_entry))
format_entry(entry)函数格式化用户(蓝色)和助手(绿色)的回复,确保可读性:
def format_entry(entry):
"""格式化条目内容以供 Markdown 显示"""
if entry['role'] == 'user':
formatted_content = format_json_as_markdown(entry['content']) \
if isinstance(entry['content'], (dict, list)) else entry['content']
formatted_content = formatted_content.replace("\n", "<br>")
return f"**<span style='color: blue;'>{active_user}:</span>** {formatted_content}"
elif entry['role'] == 'assistant':
formatted_content = format_json_as_markdown(entry['content'])
return f"**<span style='color: green;'>Agent:</span>** {formatted_content}"
这个设计强调 IPython 界面(第一层)纯粹负责编排用户交互,并触发底层功能层和代理层。这种架构确保你能灵活调用函数和代理,甚至无需用户界面。
了解完 IPython 界面后,接下来让我们探索第二层——AI 代理的增强功能。
第二层:AI 代理
第一层 IPython 界面调用的 AI 代理依旧是 chat_with_gpt 函数,进一步强化了 GenAISys 的对话特性。随着推理能力的引入,AI 代理之间也可以直接展开对话。
chat_with_gpt 函数经过扩展,新增了若干功能。必要时可回顾第4章中描述的核心功能。
让我们来看 AI 代理新增的改进:
- 函数开始处引入了
continue_functions=True,确保一次仅执行一个请求的任务。 - 在检测到用户消息中含有 “Pinecone” 关键词、触发 Pinecone 查询流程后,将
continue_functions设为False,避免额外的任务被无意执行。 - 在满足特定条件时,调用新的函数
reason.chain_of_thought_reasoning(稍后“链式思维推理”章节会详细介绍):
if "Use reasoning" in user_message and "customer" in user_message and "activities" in user_message and continue_functions == True:
该条件保证推理功能只在初次用户查询时调用。此过程中,还会下载示例的客户活动文件:
initial_query = user_message
download("Chapter05","customer_activities.csv")
reasoning_steps = reason.chain_of_thought_reasoning(initial_query)
本章示例用例展示了团队如何自动访问和查询定期更新的客户活动数据源。示例文件包含1万条历史客户活动记录,包括客户ID、地点、活动类型和活动评级。
决策树分类器稍后会利用该数据集,在链式思维(CoT)推理函数中预测最受欢迎的客户活动。响应生成后,将结果赋值给输出变量,并将 continue_functions 设为 False:
aug_output = reasoning_steps
continue_functions = False
我们将在“图像生成与分析”部分实现的新函数 reason.generate_image 也已集成。调用方式如下:
prompt = user_message
image_url = reason.generate_image(prompt, model="dall-e-3",
size="1024x1024", quality="standard", n=1)
生成的图片 URL 会返回,图像随后被下载并保存在本地,供展示或进一步处理:
# 本地保存图片
save_path = "c_image.png"
image_data = requests.get(image_url).content
with open(save_path, "wb") as file:
file.write(image_data)
随后,一条相应的消息会添加到输出中,同时将 continue_functions 设为 False:
aug_output = "Image created"
continue_functions = False
之前名为 openai_api.make_openai_api_call 的函数现改名为 reason.make_openai_api_call。其功能与第4章相同,但现在作为 GenAISys 推理库的一部分。
内存管理部分中,if user_memory…else 结构根据 user_memory 和 continue_functions 标志的状态进行了更新,显式判断二者:
if user_memory == False and continue_functions == True:
...
if user_memory == True and continue_functions == True:
...
因此,AI 代理充当中间编排者的角色,调用并管理底层函数的执行,而不直接执行它们。Pinecone 接口仍然是顶层,负责调用 AI 代理,AI 代理再与第三层的具体功能交互。
第三层:功能层
在这一层,我们重点关注为支持通过链式思维(CoT)认知代理实现高级推理而引入的新功能。Pinecone索引和标准OpenAI调用保持第4章中的实现不变。本章的主要新增功能包括:
- 利用DALL-E和GPT-4o分别实现的图像生成与分析
- 引入能够编排任务的认知代理——链式思维(CoT)推理
- 通过gTTS实现的语音交互能力
- 利用决策树分类器的机器学习端点
我们将在本章接下来的各节详细探讨这些功能,具体如下:
- 在“环境搭建”部分,详细介绍gTTS和机器学习的环境配置与初始化
- “图像生成与分析”部分涵盖图像相关功能
- “链式思维推理”部分搭建推理编排逻辑
到本章结束时,我们增强的三层GenAISys框架将具备这些强大的新能力,并将在后续章节继续扩展。现在,让我们从环境搭建开始,深入了解这些增强功能。
环境搭建
本节将对之前搭建的环境进行增强、扩展和重组,以完成 GenAISys 框架的最终构建。这些调整对于后续章节中的用例至关重要。请打开 GitHub 上 Chapter05 目录下的 Multimodal_reasoning_with_Chain_of_Thought.ipynb 笔记本(链接:github.com/Denis2054/B…)。
关于包的安装,笔记本中“环境搭建”部分与上一章节(Event-driven_GenAISys_framework.ipynb)基本相同,仅新增了 Google 文字转语音(gTTS)包。
不过,为支持链式思维(CoT)生成式AI推理功能,我们对环境进行了若干重要更新。下面逐项介绍这些更新,先从 OpenAI 部分开始。
OpenAI
前两份下载的文件与前几章保持一致。但第三和第四份文件是新增的,用以支持高级功能:
from grequests import download
download("commons","requirements01.py")
download("commons","openai_setup.py")
download("commons","reason.py")
download("commons","machine_learning.py")
reason.py 现在包含了之前章节中构建的生成式AI库函数,以及本章新增的函数。主要功能及其状态如下:
-
make_openai_api_call(input, mrole, mcontent, user_role)是通用的 OpenAI API 调用函数,已在第1章“环境搭建”部分描述。现在改为从reason导入:from reason import make_openai_api_call -
image_analysis是图像分析功能,可描述图像或以图像为起点生成故事等内容。该功能详见本章“图像生成与分析”部分。 -
generate_image是用 DALL-E 生成图像的新函数,详见本章“图像生成与分析”部分。 -
chain_of_thought_reasoning是我们正在构建的 GenAISys 新增的链式思维(CoT)逻辑函数,具体实现见本章“链式思维推理”部分。它可调用其他库中的函数,如机器学习库。
machine_learning.py 文件将包含一个名为 ml_agent 的决策树分类器函数,该函数接收两个参数:
ml_agent(feature1_value, feature2_column)
在我们的示例中,feature1_value 表示客户所在地,feature2_column 表示客户活动。该分类器基于历史数据预测特定地点最受欢迎的客户活动。
导入 ml_agent 的方式如下:
import os
import machine_learning
from machine_learning import ml_agent
其他 OpenAI 设置子部分,包括包安装和 API Key 初始化,与前几章保持一致。接下来,我们将初始化这些新功能。
初始化 gTTS、机器学习和链式思维(CoT)
我们将初始化以下新功能:
gTTS 使用命令 !pip install gTTS==2.5.4 安装,这是一个开源且免费的文本转语音(TTS)库,非常适合原型开发,详见:pypi.org/project/gTT… 。gTTS 依赖命令行库 click。笔记本的第一个单元格通过设置 use_gtts = True 来决定是否启用 gTTS:
use_gtts = True # 如果为 True,则在 Google Colab 中启用 Google TTS;否则禁用
第二个单元格会检测并设置正确版本的 click(如果 use_gtts 为 True)。如果需要更新,会在笔记本输出中显示清晰提示,要求你手动重启运行环境。重启后,点击“Run All”继续执行。代码会在版本更新时显示 HTML 格式的重启提示信息:
import importlib.metadata
from IPython.display import display, HTML
# ... 定义 required_click_version、current_click_version 和 html_message ...
if current_click_version != required_click_version:
# --- 在此处添加卸载和安装 'click' 的命令 ---
# 例如: !pip uninstall -y click
# 例如: !pip install click==8.1.8
display(HTML(html_message)) # 显示提示重启的消息
raise SystemExit("Please restart the Colab runtime to apply changes.")
else:
print(f"--- ‘click’ 已经是正确版本 ({required_click_version}),无需操作。---")
如果 use_gtts 设置为 True,安装 gTTS 并定义文本转语音函数:
if use_gtts:
!pip install gTTS==2.5.4
from gtts import gTTS
from IPython.display import Audio
def text_to_speech(text):
# 将文本转换为语音并保存为 MP3 文件
if use_gtts:
if not isinstance(text, str):
text = str(text) # 确保文本为字符串类型而非列表
tts = gTTS(text)
tts.save("response.mp3")
当 AI 代理返回响应时,该函数将在 IPython 接口中被调用,具体见前文“Layer 1: IPython interface”部分。
ml_agent 算法端点从 machine_learning.py 中导入:
import os
import machine_learning
from machine_learning import ml_agent
该决策树分类器函数将基于历史数据预测受欢迎的客户活动,增强 GenAISys 的预测能力。
链式思维(CoT)推理框架从 reason.py 中导入:
import os
import reason
from reason import chain_of_thought_reasoning
Pinecone 的安装、初始化及查询按第3、4章说明进行定义。需要时请复习相关章节,因为我们将复用之前开发的函数。
现在,我们已准备好构建图像生成与分析功能。
图像生成与分析
本节将首先利用 OpenAI 的 DALL-E 模型创建一个灵活的图像生成函数。随后,我们将构建一个图像分析函数。目标是在保持 GenAISys 响应式、事件驱动功能的同时,增强其计算机视觉能力,如图 5.6 所示:
前述图示是我们在第四章初步构建架构的进化版本。它新增了多项功能:语音(语音激活)特性的启用、图像文件管理、增强的显示功能,以及通过链式思维(CoT)实现的推理功能。本节重点将放在将计算机视觉能力与增强的显示功能集成并展示上。
图像生成与分析流程设计得非常灵活:
-
图像生成或分析无需强制选择或显式激活控件。如果某个用例需要,我们可以轻松添加标有“图像生成”或“图像分析”的显式控件。然而,我们在这里采用的方法刻意保持灵活性,为集成到更复杂的自动化推理流程(如CoT)奠定基础。
-
“文件”复选框控件有两个不同的用途:
- 如果未勾选,DALL-E 会生成图像并保存到文件,但不会显示。这允许图像在后台静默生成,供后续使用或存储。
- 如果勾选,生成或分析后的图像将显示在用户界面中,如图 5.7 所示。
AI 会话代理会基于用户提示自动激活图像生成或分析功能。这些视觉能力还能触发自动推理流程,使系统能够无缝执行复杂的CoT任务。
请注意,图像文件只有在“文件”控件被勾选时才会显示。接下来,我们将深入介绍这些视觉功能是如何集成到 GenAISys 界面中的,特别演示当“文件”复选框被激活(勾选)时的场景,如图 5.7 所示:
当“文件”复选框被选中时,DALL-E 根据用户提示生成的图像将会被立即显示,如图 5.8 所示:
如果“文件”选项未被选中,图像会被生成并保存,但不会显示。类似地,图像显示功能也适用于分析从外部来源下载的图像。当“文件”复选框未选中时,图像分析会运行,但不会在界面上显示图像。现在我们准备详细查看图像生成函数的实现细节。
图像生成
图像生成函数位于 commons 目录下的自定义生成式 AI 库 reason.py 中。该函数可以由用户提示或链式思维(CoT)框架触发。函数名为 generate_image,它接受五个参数:
def generate_image(
prompt, model="dall-e-3", size="1024x1024", quality="standard", n=1
):
五个参数说明如下:
- prompt:用户或系统提供的与图像相关的查询内容。
- model:使用的 OpenAI 模型,此处默认值为
dall-e-3。 - size:图像尺寸,默认是
1024x1024。 - quality:图像质量,默认是
standard,相较于更高质量的hd选项,成本更低。 - n:生成图像的数量,默认生成 1 张。
该函数返回生成图像的 URL。代码首先初始化 OpenAI 客户端:
def generate_image(
prompt, model="dall-e-3", size="1024x1024", quality="standard", n=1
):
# 初始化 OpenAI 客户端
client = OpenAI()
然后通过 OpenAI API 调用 DALL-E 模型,传入指定参数:
# 使用 OpenAI API 生成图像
response = client.images.generate(
model=model,
prompt=prompt,
size=size,
quality=quality,
n=n,
)
这些参数在第一章“设置环境”部分有详细说明。
定义好内容、消息和参数后,调用 OpenAI API:
# 发起 API 请求
response = client.chat.completions.create(
model=model,
messages=messages,
**params # 解包参数字典
)
从响应中提取图像 URL 并返回:
# 从响应中提取并返回图像 URL
return response.data[0].url
图像生成或获取完成后,我们可以根据需求选择显示或分析该图像。
图像分析
图像分析函数也位于 commons 目录下的自定义生成式 AI 库 reason.py 中。该函数名为 image_analysis,定义如下,接收三个参数:
def image_analysis(image_path_or_url, query_text, model="gpt-4o"):
三个参数说明如下:
image_path_or_url(字符串):本地图片文件路径或图片的 URL。query_text(字符串):用户或系统提供的与图片相关的查询文本。model(字符串):使用的 OpenAI 模型,此处默认是具备视觉能力(生成与分析)的gpt-4o。
函数首先用提供的查询文本初始化调用 API 所需的内容结构:
# 使用查询文本初始化内容列表
content = [{"type": "text", "text": query_text}]
接着函数判断传入的是 URL 还是本地文件:
if image_path_or_url.startswith(("http://", "https://")):
# 是 URL,加入内容列表
content.append({"type": "image_url", "image_url": {"url": image_path_or_url}})
else:
# 是本地文件,读取并进行 Base64 编码
with open(image_path_or_url, "rb") as image_file:
image_data = base64.b64encode(image_file.read()).decode('utf-8')
如果是 URL,则直接添加;如果是本地文件,则编码成 Base64 并转成 UTF-8 字符串格式,这样便于在基于文本的系统(如 JSON 或 HTML)中嵌入图片数据。随后创建一个数据 URL 并添加到内容列表:
# 创建图片数据 URL
data_url = f"data:image/png;base64,{image_data}"
content.append({"type": "image_url", "image_url": {"url": data_url}})
接下来基于上下文(包含查询信息和图片内容)创建 OpenAI 消息对象:
# 创建消息对象
messages = [{"role": "user", "content": content}]
API 调用使用一组标准参数,详情见第一章“设置环境”部分:
# 定义参数
params = {
"max_tokens": 300,
"temperature": 0,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
}
内容、消息和参数定义完成后,调用 OpenAI API:
# 发起 API 请求
response = client.chat.completions.create(
model=model,
messages=messages,
**params # 解包参数字典
)
为了方便后续集成(特别是在第六章结合 Pinecone 做 RAG 时),将响应结果保存为文本文件,以便后续调用和检索:
# 保存结果到文件
with open("image_text.txt", "w") as file:
file.write(response.choices[0].message.content)
函数返回 API 返回的文本内容:
return response.choices[0].message.content
这个 image_analysis 函数也会被本章后面构建的链式思维(CoT)推理流程调用,其中 query_text 会动态生成并传入函数:
response = image_analysis(image_url, query_text)
至此,我们已将计算机视觉组件完整集成到 GenAISys 中。拥有这些能力后,接下来我们将构建 CoT 推理流程。
链式思维推理(CoT)
全球市场的指数级加速导致每天在社交媒体、电商平台、生产线和 SaaS 平台等产生数十亿个微任务。没有强大的自动化支持,实时应对这些需求几乎不可能。速度和效率成为关键,任务必须实时或近实时执行。近期的 AI 进展极大地帮助我们适应了这种市场范式,必须在越来越短的时间内处理更多任务。然而,随着 AI 功能数量和范围的不断扩大,用户在复杂场景下与协同助手的交互变得愈发复杂,开发团队也面临如何构建一个既包含所需功能又有清晰直观操作序列的 GenAISys 的挑战。
本节通过实现链式思维推理(CoT)来应对这些挑战。CoT 推理将复杂任务拆分为更小、更易管理的步骤,每一步的输出成为下一步的输入。这种流程模拟了(而非替代)人类的思维过程,减少用户的认知负担,使其能专注于决策。此外,CoT 推理让 AI 代理的内部思考过程透明化,实时解释每一步推理。
本节目标是基于我们开发的灵活交互式 GenAISys 框架,使用 Python 构建 CoT 推理流程。具体应用包括:模拟在线旅游平台的客户偏好分析,生成活动创意建议,利用 DALL-E 生成图像,并基于图像通过 GPT-4o 创作故事叙述。
乍一看,CoT 认知代理似乎与传统软件开发中的函数序列相似。为此,先澄清两者的重要区别:
GenAISys 中的 CoT 与传统软件序列的区别
- 传统的非 AI 或 AI 函数序列由一系列独立执行的步骤组成,采用“黑盒模型”,前一步的输出作为下一步的静态输入。
- CoT 推理过程模拟人类思维,步骤间存在逻辑递进,每一步都基于前一步的输出。我们将在实现 CoT 时看到 GenAISys 的“思考过程”通过交互界面实时展现,整个过程透明且易于解释,可随时观察和独立调试任意步骤。
CoT 的另一个关键特性是其中间推理:
- CoT 中的步骤虽然依赖前一步,但并非所有步骤都是静态的。例如,DALL·E 生成的图像是全新创造的,而非数据库检索结果,这依赖于生成式 AI 模型,而非预设内容。
- 过程中的下一步也不是预先生成的固定内容。例如 DALL-E 生成图像后,我们会让 GPT-4o 根据输入即兴创作故事,或者仅简单描述图像,无需改变或微调模型。
CoT 推理实现了更贴近人类思维模式的认知对齐。人类解决问题时,会将整体问题拆解成更小的部分,逐个处理,再汇总中间结论以达成整体解决方案。本章构建的 CoT 框架让 GenAISys 更加直观且富有创造力,模拟(而非替代)人类的解决问题方式。在后续章节(尤其第 6 章)我们将进一步扩展和完善 CoT 推理功能。
总结来看,CoT 包含任务序列,但比传统的非 AI 或 AI 序列更灵活、更具创造性。接下来,我们将定义 CoT 推理的认知流程。
链式思维推理(CoT)的认知流程
我们将不使用传统的“流程图”一词,而采用“认知流程”来描述正在实现的 CoT 过程。这个术语强调了 AI 代理具备的人类般的推理和动态问题解决能力,明显区别于经典的软件流程图。传统的流程图只是展示函数执行的顺序;而推理型的 CoT 认知流程则映射了 AI 代理从一步思考到下一步的逻辑进展,展现了 AI 如何模拟人类的推理过程。
首先,我们来看将在 Python 中实现的认知流程,该流程在图 5.9 中进行了可视化展示。我们使用的 Python 函数位于 commons 目录下的 reason.py 文件中,具体细节请参考本章“设置环境”部分的 OpenAI 小节。
我们 CoT 推理过程的认知流程由五个主要阶段组成,由 chain_of_thought_reasoning() 函数协调执行。这个流程从“开始”阶段启动。
开始(Start)
CoT 推理过程从接收 AI 代理提供的输入文本开始。AI 代理分析用户输入,然后触发 CoT 函数(如前文“第二层:AI 代理”部分所述)。在 CoT 函数开始时,会初始化两个关键内容:推理记忆(steps = [])被初始化,同时在 IPython 交互界面中激活推理显示控件:
steps = []
# 在界面中显示 reasoning_output 控件
display(reasoning_output)
display(reasoning_output) 会触发显示控件,实现 IPython 界面的实时更新,确保 CoT 过程的透明度和易于用户理解。
第一步:机器学习基线(ML-baseline)
第一步激活机器学习端点(machine_learning.ml_agent()),使用决策树分类器动态分析客户数据并预测感兴趣的活动。该函数以位置(例如 “Rome”)和目标列 “ACTIVITY” 作为预测参数:
# 第一步:分析客户数据库并进行预测
steps.append("Process: Performing machine learning analysis of the customer database. \n")
with reasoning_output:
reasoning_output.clear_output(wait=True)
print(steps[-1]) # 打印当前步骤
time.sleep(2) # 模拟处理时间
result_ml = machine_learning.ml_agent("Rome", "ACTIVITY")
steps.append(f"Machine learning analysis result: {result_ml}")
这段代码的执行模式在每个推理步骤都会重复:
- 以注释形式说明当前步骤,例如:
# Step 1: Analysis of the customer database and prediction steps.append(...)将当前步骤描述添加到推理内存列表中with reasoning_output:启动显示控件的代码块reasoning_output.clear_output(wait=True)清空控件内容print(steps[-1])打印最新的步骤time.sleep(2)模拟两秒的处理时间- 调用
ml_agent执行机器学习预测 - 将预测结果追加到步骤列表
机器学习的输出(预测罗马地区客户最喜爱的活动)将作为下一步的输入,用于提出创意活动建议。
决策树分类器简介
决策树分类器适合此任务,因为它通过基于特征值将数据划分成树形结构进行预测。它递归地选择最优分裂特征,直到满足停止条件(如最大深度或叶子节点最小样本数)。每一步都将可能性缩小,最终得到一个预测结果。
运行决策树需要导入处理数据和训练模型的库,并禁用警告避免输出混乱:
import pandas as pd
import random
from sklearn.preprocessing import LabelEncoder # 编码类别变量
from sklearn.tree import DecisionTreeClassifier # 训练决策树模型
import warnings
warnings.simplefilter(action='ignore', category=UserWarning)
定义决策树分类器函数 ml_agent(),包含两个参数:
def ml_agent(feature1_value, feature2_column):
参数说明:
feature1_value:需要预测活动的地点值feature2_column:目标列,例为"ACTIVITY"
函数首先加载客户活动数据集:
df = pd.read_csv("customer_activities.csv")
接着对类别变量 LOCATION 和 ACTIVITY 进行编码:
le_location = LabelEncoder()
le_activity = LabelEncoder()
df["LOCATION_ENCODED"] = le_location.fit_transform(df["LOCATION"])
df["ACTIVITY_ENCODED"] = le_activity.fit_transform(df["ACTIVITY"])
若未提供具体地点,则默认选取出现频率最高的地点:
if not feature1_value.strip():
feature1_value = df["LOCATION"].mode()[0]
准备特征(X)和目标变量(y):
X = df[["LOCATION_ENCODED"]]
y = df["ACTIVITY_ENCODED"]
训练决策树模型:
model = DecisionTreeClassifier(random_state=42)
model.fit(X, y)
设置 random_state=42 确保每次运行结果一致。然后将输入地点编码为整数:
feature1_encoded = le_location.transform([feature1_value])[0]
使用训练好的模型预测活动类别,并还原为原始标签:
predicted_activity_encoded = model.predict([[feature1_encoded]])[0]
predicted_activity = le_activity.inverse_transform([predicted_activity_encoded])[0]
构造客户描述性输出:
text = (f"The customers liked the {predicted_activity} because it reminded them of how "
f"our democracies were born and how it works today. "
f"They would like more activities during their trips that provide insights into "
f"the past to understand our lives.")
将描述性文本返回给 CoT 函数:
return text
调用决策树分类器示例:
result_ml = ml_agent("", "ACTIVITY")
print(result_ml)
预期输出:
Machine learning analysis result: The customers liked the Forum of Rome because it reminded them of how our democracies were born and how it works today. They would like more activities during their trips that provide insights into the past to understand our lives.
接下来,我们将用该步骤的输出建议活动。
步骤二:建议活动
此步骤遵循与步骤一相同的逻辑和结构。该过程的名称如下:
steps.append("Process: Searching for activities that fit the customer needs. \n")
步骤一的输出结果(result_ml)成为发送给 GPT-4o 的指令的一部分,用于增强输入上下文。组合后的查询(umessage)如下:
umessage = (
"What activities could you suggest to provide more activities and excitement in holiday trips."
+ result_ml
)
此时,指令专门针对我们以旅游为重点的领域进行了定制。在第六章中,我们将把这些指令发展成动态的基于事件的变量。这里,我们继续使用之前章节中构建的 GenAISys OpenAI API 调用:
mrole = "system"
mcontent = (
"You are an assistant that explains your reasoning step by step before providing the answer. "
"Use structured steps to break down the query."
)
user_role = "user"
task_response = make_openai_api_call(umessage, mrole, mcontent, user_role)
从 GPT-4o 获得的输出(task_response)将作为下一步(步骤三)的输入。追加和展示推理步骤的方法与步骤一保持一致。
步骤三:生成图像
此步骤以从上一步(task_response)获得的详细建议作为提示,直接传递给 DALL-E 的图像生成函数。其结构和逻辑与前几步一致,但现在聚焦于生成图像:
prompt = task_response
image_url = generate_image(prompt)
图像生成后,会被下载并本地保存为 c_image.png。如果“Files”控件被选中,这个图像文件将通过 IPython 界面显示,如“层 1:IPython 界面”部分所述:
save_path = "c_image.png"
image_data = requests.get(image_url).content
with open(save_path, "wb") as file:
file.write(image_data)
steps.append(f"Image saved as {save_path}")
图像生成并保存后,CoT 过程将进入对新生成图像的分析阶段。
步骤四:分析图像
此分析步骤的输入是步骤三生成的图像 URL,存储在 image_url 变量中。如前所述,本笔记本中查询文本设置为通用但旅游相关的请求,后续章节中该查询文本将变得更具事件驱动性和动态性。
为了分析图像,我们指示生成式 AI 模型根据生成的图像创作一个引人入胜的故事:
query_text = "Providing an engaging story based on the generated image"
封装指令的代码与之前步骤相同。CoT 函数现在调用了先前在“图像生成与分析”部分介绍的 image_analysis 函数:
response = image_analysis(image_url, query_text)
函数输出存储于 response 变量中,并保存至 image_text.txt 文件以供后续使用。至此,CoT 推理步骤完成。
结束
完成所有推理任务后,CoT 函数通过清空并更新 IPython 显示来标志过程结束:
# 清空输出并通知完成
with reasoning_output:
reasoning_output.clear_output(wait=True)
print("All steps completed!")
return steps
接下来由 IPython 界面接管。现在,让我们从用户的角度运行 CoT 流程。
从用户视角运行CoT推理
本节将无缝运行我们从本书开篇以来一直构建的复杂GenAISys。一个简单的提示词即可触发整个CoT流程。
我们将模拟用户激活GenAISys的推理能力,以获得针对在线旅行社的全面创意。具体来说,目标是预测客户偏好的活动,生成吸引人的图像,并创作故事叙述来唤起客户的情景记忆。这些情景记忆可能是现实中的经历,也可能是对某地旅行和参与特定活动的梦想。
要运行此场景,请确保勾选“AI Agent”和“Files”复选框,并仔细输入以下提示语:
“Use reasoning to suggest customer activities.”
提示中的关键词“Use”、“reasoning”、“customer”和“activities”将被AI代理识别并触发本章构建的CoT流程。或者,我们也可以实现下拉菜单,或在Pinecone索引中执行相似度搜索以检索特定的指令场景。STT语音输入也可用。但本章我们采用键入的关键词提示,以清晰演示CoT过程。
在第7章中,我们将构建一个中央关键词注册表和一个调度器,以进一步优化AI代理的决策过程。
用户按下回车键后,我们只需静待结果,就像使用在线ChatGPT类协同助手一样。第一个流程是分析客户数据,找出基于每日数据排名最高的活动,如图所示。
整个过程完成后,决策树分类器返回结果:
“机器学习分析结果:客户喜欢罗马论坛,因为它让他们想起了……”
下一阶段是搜索符合客户偏好的合适活动:
GPT-4o 的创意输出提供了结构化的步骤,用于提升线上产品的内容:
Activity suggestions: To enhance holiday trips with more activities, especially focusing on cultural experiences, we can consider a variety of options. Here's a structured approach to brainstorming and suggesting activities:
…### Step 3: Suggest Activities
1.
Historical Tours and Sites
:
-
Athens, Greece
: Visit the Acropolis and the Agora, where democracy was born. Include guided tours that explain the significance of these sites.
-
Philadelphia, USA
: Explore Independence Hall and the Liberty Bell, focusing on the birth of modern democracy.
-
Westminster, UK
: Tour the Houses of Parliament and learn about the evolution of the British democratic system…
接下来,CoT 指示 DALL-E 根据这些建议的活动生成一幅吸引人的图像:
由于选中了“Files”复选框,生成的图像会被显示出来。这个图像相当有创意,每次运行时都会有所不同:
在这个例子中,图像中包含了诸如“…对历史及其对现代生活影响的理解。”等文字,完美契合了我们的请求。
请注意,由于上下文的变化以及生成式 AI 模型(如 GPT-4o)的随机性(概率性),每次运行可能会产生不同的结果。
接下来的过程是请 GPT-4o 创作一个叙述,用于讲故事式的推广,借助于对过去真实经历或想象旅行的情景记忆:
GPT-4o 生成的叙述输出如图所示,具有示范性,且如前所述,每次可能有所不同:
…Story response: In the bustling town of New Haven, a place where history and technology intertwined, a young historian named Clara discovered an ancient artifact that would change everything. The artifact, a mysterious tablet, was said to hold the secrets of the past, capable of bringing historical figures to life through augmented reality…
一旦 CoT 序列结束,GenAISys 会保持其推理状态,等待新的独立提示或进一步的 CoT 运行:
笔记本中的“加载并显示对话历史”和“加载并总结对话历史”部分使用了第4章中详细介绍的相同功能。
我们现已成功构建了一个具备定制功能的小规模类ChatGPT GenAISys系统,包括多用户支持、领域专属的RAG以及量身定制的CoT能力。在接下来的章节中,我们将把这个GenAISys框架应用到多个实际业务领域。
总结
本章完成了GenAISys的基础框架搭建,该框架由三层组成:
- 第一层是IPython交互界面,充当协调器角色。该层新增了语音功能、文件展示和CoT功能,除此之外还包括用户输入、用户选择和AI代理小部件。
- 第二层是AI代理协调器,由用户提示触发。这里展示了GenAISys中协调与控制功能的界限有所模糊,这得益于这些组件的交互特性。AI代理在Pinecone索引(用于查询)和OpenAI API代理(用于生成任务,如内容和图像生成)之间分配任务。AI代理还可以触发CoT流程,我们将在后续章节进一步增强其能力。
- 第三层包含GenAISys的核心功能,由GPT-4o和DALL-E驱动的AI工作者组成。本章引入了DALL-E进行图像生成,并利用GPT-4o对这些图像进行富有洞察力的解读。此外,我们还实现了决策树分类器来预测客户活动,将机器学习能力融入GenAISys中。
引入CoT功能标志着我们从终端用户角度迈出了创建无缝推理能力的第一步。复杂任务需要能够模拟人类推理的高级AI系统。因此,在下一章,我们将进一步拓展GenAISys的推理能力以及其他功能。