DLAI-Anthropic-计算机操作笔记-全-
DLAI Anthropic 计算机操作笔记(全)
001:课程介绍
在本节课中,我们将一起学习由吴恩达与Anthropic合作推出的课程《构建计算机操作应用》。本课程将介绍Anthropic模型如何通过理解屏幕截图并生成鼠标点击和键盘输入序列,来实现自动化操作计算机的能力。我们将从基础概念开始,逐步深入到实际应用。
Anthropic近期取得了一项突破,发布了一个能够操作计算机的模型。该模型可以观察计算机屏幕(通常在虚拟机中运行)的截图,并按顺序生成鼠标点击或键盘敲击,以执行特定任务。例如,使用浏览器搜索网页并下载图片。
这种计算机操作能力是通过结合大型语言模型的多种特性构建而成的。这些特性包括模型处理图像(如理解屏幕截图内容)的能力,以及使用工具生成鼠标点击和键盘输入的能力。这些功能被封装在一个迭代的智能体工作流程中,通过在该计算机上执行多次操作来完成复杂任务。
在本课程中,你将学习到这些独立的特性,这些知识即使在不基于计算机操作的应用程序中也非常有用。同时,你也会看到它们如何协同工作以实现计算机操作。Co将向你展示这一切是如何运作的。
在课程中,你将学习如何使用多种模型和功能,它们共同实现了计算机操作。以下是课程的进展安排:
首先,你将了解一些关于Anthropic的背景、愿景以及其模型家族的独特之处。
接着,你将使用API来发起一些基础请求。
然后,课程将引导你进入多模态请求的学习,你将使用模型来分析图像。
之后,你将深入探讨提示工程。Anthropic非常注重通过扎实的提示工程使模型行为更具可预测性。你将学习真正重要的提示技巧。
以下是几种关键的提示技巧:
- 思维链:引导模型展示其推理过程。
- 少样本提示:通过提供少量示例来指导模型。
- 你还有机会使用我们的提示改进工具。
最近,语言模型开始支持超长的输入上下文。例如,Anthropic的模型支持超过20万个输入标记,这相当于500多页文本。
处理长输入的成本可能很高。实际上,在聊天机器人的长对话中,如果你为了持续生成下一个回复而反复处理整个对话历史,那么随着对话的进行和历史记录变长,成本也会增加。
这正好引出了我们的下一个主题:提示缓存。
提示缓存能在多次调用模型之间,保留部分提示处理的结果。这可以显著节省成本和降低延迟。
你还将学习如何使用模型来调用外部工具,并生成结构化输出,例如JSON。
在课程的最后,我们将一起演练一个完整的计算机操作示例,你可以在自己的机器上运行它。
请注意,由于该工具的性质,你需要在计算机的Docker镜像中运行它,而不是直接在DeepLearning.AI的笔记本中运行。
我个人已经尝试过使用Anthropic模型进行计算机操作,发现它非常酷。我认为这项能力将催生许多新的应用,你可以构建一个AI助手来操作计算机,为你执行任务。
这有点像RPA(机器人流程自动化),后者擅长处理重复性任务。但现在,基于大语言模型的工具使得构建这类应用更加容易,且适用性更广。
或者,随着这项技术变得更好,它甚至能处理更灵活、更开放式的任务,逐渐像一个真正的个人助手一样为你做越来越多的事情。
我非常同意这一点,并对它的未来感到非常兴奋。
许多人共同努力创建了这门课程。我要感谢来自Anthropic的Ben Mann、Maggie Vo、Kevin Garside以及计算机操作项目团队。同时,也感谢来自DeepLearning.AI的Jeff Ludwig和Ashmar Gagari。
Anthropic已经构建了许多非常出色的模型,我本人也经常使用它们。Co将在下一个视频中分享这些模型的详细信息。
好的,让我们开始吧。



本节课中,我们一起学习了《构建计算机操作应用》课程的概述。我们了解了Anthropic模型如何通过结合图像理解、工具调用和迭代工作流来实现自动化计算机操作,并预览了课程将涵盖的核心主题,包括API使用、多模态分析、提示工程、长上下文处理、提示缓存以及工具调用。在接下来的课程中,我们将深入探讨这些内容。
002:课程概述 🚀
在本节课中,我们将学习Anthropic在人工智能研究与开发方面的独特方法,了解AI安全、对齐和可解释性的核心原则,并区分Anthropic的模型家族。课程结束时,你将能够解释这些概念,并为后续的实践操作打下基础。

Anthropic的使命与研究重点

上一节我们介绍了课程的整体目标,本节中我们来看看Anthropic这家公司本身。Anthropic是一个独特的人工智能实验室,其研究将安全性置于最前沿。本质上,它致力于构建前沿模型(有时是全球最好的模型),并同时利用这些模型进行尖端研究。
下图的时间线浓缩了这些理念:

Anthropic成立于2021年,你可以看到从那时起直到2024年Claude 3.5 Sonnet发布的一系列模型发布时间线。在时间线底部,你还可以看到同时发布的一些关键研究论文。
虽然这不是一门研究课程,但我想提醒你关注Anthropic网站的研究页面。这是一个很好的资源,可以通过易于理解的形式或完整的研究论文来深入了解我们的研究。
我们重点关注的领域包括:
- 可解释性
- 对齐
- 社会影响
深入理解“对齐”与“可解释性”
接下来,我们特别关注一下“对齐”和“可解释性”这两个核心概念。
对齐科学专注于确保AI系统的行为符合人类的价值观和意图。其核心问题是:我们如何创建能够可靠地追求我们设定的目标和任务的AI系统,即使它们的能力变得越来越强?
可解释性是Anthropic另一个重点研究领域,这个词有点拗口,但它是AI研究中一个非常迷人且关键的方面。可解释性是关于理解大型语言模型内部如何工作的,本质上是对它们进行逆向工程,或者给模型做“MRI”或“脑部扫描”,以便我们能在任何时间点准确理解其内部发生了什么。
如果不理解模型的工作原理,改进模型并确保其安全性将非常困难。如果你感兴趣,我鼓励你阅读我们的一些博客文章,观看关于可解释性的视频,特别是这篇相对易于理解的论文《Scaling Monosemanticity》。我知道这个名字听起来不那么平易近人,但它在阐述一些关键的可解释性研究时,充满了非常酷的图表和可视化。它也是一篇很有趣的读物,包含一些有趣的例子。
Anthropic的模型家族
正如开头提到的,Anthropic不仅是一个专注于安全、对齐和可解释性的研究实验室,我们还发布最先进的大型语言模型。在我们的文档模型页面上,你可以找到我们当前模型的最新列表。像AI领域的一切一样,这个列表更新得非常快,所以它可能看起来和下图不完全一样。

如图所示,Claude 3.5 Sonnet 目前是我们最智能的模型,其次是 Claude 3.5 Haiku。Haiku 能力稍弱,但仍然非常智能,并且速度更快。这是目前提供给你的两个主要选择。
如果我们放大这个模型对比表格,你会看到 Claude 3.5 Sonnet、Claude 3.5 Haiku 以及原始的 Claude 3 系列模型。但两个最新、能力最强的模型是左边的 3.5 Sonnet 和 3.5 Haiku。我们可以看到它们的能力、优势和视觉能力的详细对比。
以下是核心模型的简要对比:
- Claude 3.5 Sonnet:这是我们提供的最智能、能力最强的模型。它支持多语言、多模态(支持图像输入),并支持我们的批量API。需要注意的一点是,它有多个版本,包括最新的升级版 Claude 3.5 Sonnet 2024-10-22。我们将在下一个视频中详细讨论模型字符串,但这是目前最新的 Claude 3.5 Sonnet 版本。它速度很快,但不如 Claude 3.5 Haiku 快。
- Claude 3.5 Haiku:这是我们提供的最快的模型。它在非常快的速度下仍然非常智能,速度比 Claude 3.5 Sonnet 更快,在一些流行基准测试上能力稍弱,并且目前不支持视觉功能。
关于上下文窗口,这两个模型都支持 200,000个令牌 的上下文窗口,最大输出令牌数为 8192。显然,Claude 3.5 Haiku 更便宜、更快,但 Claude 3.5 Sonnet 是最智能的模型。它也是本课程中我们将主要使用的模型,并且价格相当实惠。此外,由于它支持图像输入,目前在计算机使用任务上表现最佳。
在下一个视频中,我们将学习如何使用这些模型并开始发送请求。但我希望你先了解一下这个文档页面,以便随时了解最新模型,并查看这些模型在各种指标上的对比情况。


课程结构与核心主题
以上是对Anthropic的简要介绍:一个创建前沿或尖端模型的前沿研究实验室。这也包含了关于本课程及其大致结构的一点信息。
现在,我们将深入探讨如何使用API,发送我们的第一个简单文本请求,并逐步构建,最终完成计算机操作代理的顶点演示。
本课程将涵盖使用Anthropic API所需了解的一切,包括使用我们的模型,并逐步构建对计算机操作代理工作原理的理解。
那么,什么是计算机操作代理?下面是一个例子。在左侧,你可以看到我正在输入一个提示:“Anthropic在都柏林招聘哪些职位?”(注:右侧演示视频已加速,以便节省时间)。

你可以看到模型正在操作右侧的电脑。它点击、移动鼠标、选择下拉菜单、展开折叠菜单。最终,它找到了Anthropic的招聘页面,按都柏林进行筛选,然后展开两个职位:一个技术项目经理和一个安全审计与合规职位。
这就是我所说的计算机操作代理。你刚才看到的那个代理建立在API的所有基础知识之上。
因此,我们将按顺序讲解以下主题,最终以计算机操作代理演示结束。以下是本课程将涵盖的核心主题列表:
- 基础API请求:该计算机操作代理会向API发送基本请求,如文本提示。它将使用消息格式和各种模型参数。这将是我们接下来要讲的内容。
- 多模态请求:你可能已经注意到,模型使用屏幕截图来决定点击、拖拽或输入的位置。因此,你将学习如何发起涉及图像(包括屏幕截图)的请求。
- 真实世界提示工程:这部分重点在于与像Claude.ai这样的聊天机器人以对话方式交流,与使用API进行可扩展、可重复的提示模板工程之间的巨大差异。
- 提示缓存:这是计算机操作代理采用的一种策略,也是一种很好的节省成本和延迟的措施。
- 工具使用:这使模型能够执行点击、滚动、键入等操作,或其他工具,如连接API、执行bash命令或运行代码。我们可以为模型提供各种工具,模型可以告诉我们它想要执行哪个工具。
- 计算机操作代理实战:在最后,你将看到如何运行刚才看到的计算机操作代理。它结合了我们所涵盖的所有主题,外加一些其他内容。这是一个略有进阶的项目,但它是一个很好的顶点项目,涵盖了使用Anthropic API的所有核心概念。

总结

本节课中,我们一起学习了Anthropic作为一家前沿AI研究实验室的定位,其核心研究重点——对齐与可解释性,并初步了解了其主力模型家族(Claude 3.5 Sonnet 和 Haiku)的特点与区别。我们还预览了整个课程的结构,它将从基础的API调用开始,逐步深入到多模态、提示工程、工具使用,最终构建出一个能够实际操作计算机的智能代理。现在,我们已经为动手实践做好了知识准备,下一节我们将开始发送第一个API请求。
003:API基础


在本节课中,我们将学习如何向Claude API发送请求。你将能够创建自己的API请求,有效地格式化消息以获得最佳AI响应,并控制各种API参数,如系统提示、最大令牌数和停止序列。
环境设置与第一个请求
上一节我们介绍了课程目标,本节中我们来看看如何设置环境并发出第一个API请求。
首先,我们需要安装并导入Anthropic Python SDK。第一步是确保SDK已安装,只需运行 pip install anthropic 即可。安装完成后,我们导入它并实例化一个客户端。
import anthropic
client = anthropic.Anthropic()
现在我们已经有了客户端。下一步是发出我们的第一个请求。我添加了两个代码单元格。第一个只是一个模型名称变量,我们将在整个课程中重复使用这个模型名称。
model_name = "claude-3-5-sonnet-20241022"
接下来是这个较大的代码块。这里最重要的部分是我们如何实际发出一个简单的请求。我们使用客户端变量的 messages.create 方法。
response = client.messages.create(
model=model_name,
max_tokens=100,
messages=[
{
"role": "user",
"content": "写一首关于Anthropic的俳句。"
}
]
)
print(response.content[0].text)
我们运行这些单元格,然后打印 response.content[0].text,看看得到了什么。我们得到了一首关于Anthropic的俳句。
让我们更多地讨论一下返回的响应对象。首先,我们有我们刚刚讨论过的 content。content 是一个列表。如果我们查看第0个元素,我们可以查看它的 text,并看到实际的俳句。我们还有使用的模型。我们有 role。请记住,我们原始消息的 role 是 user,所以这个返回的响应是一个 role 为 assistant 的消息。我们还有 stop_reason,它告诉我们模型停止生成的原因。在这种情况下,它显示 end_turn,这基本上意味着它到达了一个自然的停止点。stop_sequence 是 None。我们稍后会更多地讨论停止序列。然后在 usage 下,我们可以看到输入中涉及的令牌数量,即实际的提示,以及生成的输出令牌数量。
请你自己尝试一下。在这里用任何你想要的提示替换“写一首关于Anthropic的俳句”。
消息列表的格式
上一节我们发出了第一个请求,本节中我们来看看消息列表的具体格式。
SDK的设置方式是,我们传递一个消息列表。这是必需的,同时还需要 max_tokens 和模型名称。到目前为止,这个消息列表只包含了一条 role 设置为 user 的消息。
消息格式的理念是,它允许我们以对话的形式构建我们对Claude的API调用。我们不一定非要那样使用它,目前还没有,但如果我们正在构建任何类型的对话元素或需要保留任何先前的上下文,这通常很有用。
目前,关于消息你需要知道的是,它们需要将 role 设置为 user 或 assistant。
让我们尝试提供一些先前的上下文。假设我们一直在用西班牙语与Claude交谈,我希望Claude继续用西班牙语说话。
response = client.messages.create(
model=model_name,
max_tokens=100,
messages=[
{"role": "user", "content": "Hola, solo háblame en español."},
{"role": "assistant", "content": "¡Claro! Estaré encantado de hablar contigo en español. ¿En qué puedo ayudarte hoy?"},
{"role": "user", "content": "¿Cómo estás?"}
]
)
我更新了消息列表,添加了一些历史记录,其中我有一个用户消息说“你好,只用西班牙语和我说话”,然后我有一个助手消息回复说“好的”,然后我有我的最终用户消息。唯一改变的是这个 role,从 user 到 assistant 再回到 user。我向Claude提供了一些对话历史,然后我最后说“你好吗?”。如果我运行这个,模型将考虑整个对话,然后我们得到一个西班牙语的回复。
这在几种不同的场景中很有用。第一个也许最明显的是在构建对话助手、构建聊天机器人时。
以下是一个利用此消息格式构建的非常简单的聊天机器人实现。
messages = []
while True:
user_input = input("You: ")
if user_input.lower() == "quit":
break
messages.append({"role": "user", "content": user_input})
response = client.messages.create(
model=model_name,
max_tokens=100,
messages=messages
)
assistant_response = response.content[0].text
print(f"Claude: {assistant_response}")
messages.append({"role": "assistant", "content": assistant_response})
我们从一个空的消息列表开始。然后我们有一个 while 循环。我们将永远循环,除非用户输入单词“quit”,这时我们将跳出循环。我们需要提供一个退出机制。但如果他们不输入“quit”,我们会要求用户输入,然后创建一个新的消息字典,role 为 user,content 为用户输入的任何内容。然后我们使用客户端的方法将其发送给模型。然后我们获取助手响应,将其打印出来。然后我们还将该助手消息作为新消息附加到我们的消息列表中。然后我们重复,并在对话的每一轮中不断增长这个列表。我们添加用户消息,获取响应,添加助手消息,然后下次当我们获得新的用户消息时,我们将整个内容发送回模型。
让我们试试看。运行这个。让我们从一些简单的内容开始。“嗨,我是Colt。”我们发送出去。我们得到一个回复。“嗨Colt,我是一个AI助手。很高兴认识你。我能帮你什么吗?”让我们测试一下它是否确实拥有完整的上下文。让我问它“我的名字是什么?”好的,我们发送出去。“你的名字是Colt。正如你之前介绍的那样。”让我们尝试一些更有趣的东西。我请它帮我了解更多关于LLM如何工作的信息。所以它会为我生成一个回复。这个可能有点长,它给了我一些信息。我会跟进“展开第三点”。再次强调,这只是为了演示它自己获取了完整的对话历史。这个消息本身对模型来说没有任何意义,但有了我发送给它的完整对话历史,现在它展开了第三个要点。
这是以消息格式发送消息的一个用例。
另一个用例是我们所说的“预填充”或“把话放进模型的嘴里”。本质上,我们可以使用助手消息来告诉模型“以下是你将开始回应的词语”。我们可以把话放进模型的嘴里。
例如,我让它写一首关于Anthropic的短诗。让我们把它改成别的。写一首关于猪的短诗怎么样?当然。如果我直接运行这个,它可能会告诉我类似“哦,这是一首关于猪的短诗”的内容。但出于某种原因,我真的希望这首诗以“墨水”这个词开头。我坚持这一点。现在,我可以告诉模型“写一首关于猪的诗。你必须以‘墨水’这个词开头。另外,不要给我这个前言,直接开始写诗。”但另一个选择是简单地添加一个以“墨水”开头的助手消息。
response = client.messages.create(
model=model_name,
max_tokens=100,
messages=[
{"role": "user", "content": "写一首关于猪的短诗。"},
{"role": "assistant", "content": "墨水"}
]
)
模型现在将从这个点开始它的回应,“墨水”。然后你可以看到我们得到的补全“墨水,粉红圆润的鼻子,在泥泞的地上快乐地打滚”。需要注意的是,它的回应中不包含“墨水”这个词,因为模型没有生成这个词,是我生成的。但模型通过以“墨水”开头生成了所有这些内容。所以,如果我愿意,我可以将“墨水”这个词与诗的其余部分结合起来。
这就是预填充回应。
控制模型行为的参数
上一节我们了解了消息格式,本节中我们来看看可以通过API传递给模型以控制其行为的一些参数。
第一个我们将介绍的是 max_tokens。我们一直在使用 max_tokens,但还没有讨论它的作用。简而言之,max_tokens 控制Claude在其响应中应生成的最大令牌数。请记住,模型不是以完整的单词或英语单词来思考,而是使用一系列我们称为令牌的单词片段,模型的使用也是根据令牌使用量来计算的。对于Claude,一个令牌大约相当于3.5个英文字符,尽管不同语言可能有所不同。所以这个 max_tokens 参数允许我们设置一个上限。我们可以基本上告诉模型“不要生成超过500个令牌”。或者让我们将其设置为较高的值,比如1000个令牌开始。
response = client.messages.create(
model=model_name,
max_tokens=1000,
messages=[
{"role": "user", "content": "写一篇关于大语言模型的文章。"}
]
)
一个可能会生成大量令牌的提示,因为我要求写一篇文章。这是我们的回复,相当长,看起来是一篇相当不错的文章。
现在,如果我再次尝试,但将 max_tokens 设置为更短的值,比如100个令牌。
response = client.messages.create(
model=model_name,
max_tokens=100,
messages=[
{"role": "user", "content": "写一篇关于大语言模型的文章。"}
]
)
这里会发生的是,模型基本上会在生成过程中被切断,我们只是切断了它,因为我们达到了100个令牌的生成。重要的是,如果我们查看响应对象,我们还会看到嵌套在其中的输出令牌数正好是100。它达到了那个数并停止了,但我们也看到这次的 stop_reason 是 max_tokens。所以模型没有自然停止,因为 stop_reason 设置为 max_tokens,这就是我们知道模型因为我们的 max_tokens 参数而被切断的原因。
所以这并不影响模型的生成方式。我们不是在告诉模型“给我一个简短的回复,写一篇适合100个令牌的完整文章”。相反,我们所做的是告诉模型“写一篇关于大语言模型的文章”,然后我们在100个令牌处切断了它。
那么为什么要使用 max_tokens,或者为什么要将其更改为较低或较高的值呢?一个原因是尝试节省API成本,并通过良好的提示组合设置某种上限。例如,如果你正在制作一个聊天机器人,你可能不希望你的最终用户与聊天机器人进行5000个令牌的对话轮次,你可能更希望这些对话轮次简短并适合聊天窗口。另一个原因是提高速度。输出中涉及的令牌越多,生成所需的时间就越长。
下一个我们将查看的参数称为 stop_sequences。这允许我们做的是提供一个字符串列表,当模型遇到它们时,当模型实际生成它们时,它将停止。所以我们可以告诉模型“一旦你生成了这个词或这个字符或这个短语,就停止”。这给了我们更多的控制,而不是仅仅截断一定数量的令牌。我们可以告诉模型“我们想在这个特定的词上截断你的输出”。
以下是一个我没有使用停止序列的示例。
prompt = "生成一个编号的有序列表,列出如果我想从事大语言模型工作应该学习的技术主题。"
response = client.messages.create(
model=model_name,
max_tokens=300,
messages=[
{"role": "user", "content": prompt}
]
)
我得到了这个不错的编号列表。但它相当长,有12个不同的主题。显然,通过提示,我可以告诉模型“只给我前三个或前五个”。但我将用这个例子来展示。我复制这个并复制它。但这次,我提供 stop_sequences,这是一个列表。
response = client.messages.create(
model=model_name,
max_tokens=300,
messages=[
{"role": "user", "content": prompt}
],
stop_sequences=["4."]
)
它包含字符串。在我的例子中,假设我想在它生成“4.”之后停止。我们再次尝试运行它。你可以看到我们得到了什么。我们得到1,2,3。然后模型继续生成4,然后停止了。请注意,4本身并不包含在输出中。如果我查看响应对象,我们还会看到这次的 stop_reason 设置为 stop_sequence。这是API告诉我们它因为遇到了停止序列而停止。它遇到了哪个停止序列?“4.”。
所以 stop_sequences 是一个列表,我们可以在这里提供任意多个。这是控制模型何时停止输出或何时停止生成的一种方式。当我们学习一些更高级的提示技术时,会看到一些使用案例。
现在,下一个我们将讨论的参数称为 temperature。这个参数用于控制,你可以将其视为生成响应的随机性或创造性。它的范围从0到1,较高的值如1将导致更多样化和更不可预测的响应,措辞上会有变化,而较低的温度接近0将导致更确定性的输出,更倾向于更可能的措辞。
这张图表是我运行的一个小实验的输出。我不建议你运行它,因为它涉及发出数百个API请求,但我通过API要求模型挑选一种动物。我的提示类似于“挑选一种动物。给我一个词。”我用温度为0做了100次。你可以看到,100次中的每一次响应都是“长颈鹿”这个词。现在我又做了一次,但说温度是1。我们仍然得到很多长颈鹿的响应,但我们也得到一些大象、鸭嘴兽、考拉、猎豹等等。我们得到了更多的变化。所以再次强调,温度为0更可能是确定性的,但不能保证;温度为1输出更多样。


以下是一个你可以运行的函数,它将演示这一点。
def generate_planet_name(temperature):
response = client.messages.create(
model=model_name,
max_tokens=10,
messages=[
{"role": "user", "content": "为外星行星生成一个行星名称。用一个词回答。"}
],
temperature=temperature
)
return response.content[0].text
for _ in range(3):
print(generate_planet_name(temperature=0))
for _ in range(3):
print(generate_planet_name(temperature=1))
我要求Claude三次为外星行星生成一个行星名称。我告诉它“用一个词回答”。我用温度为0做三次,用温度为1做三次。让我们看看会发生什么。我执行这个调用函数的单元格。当我使用温度为0时,我连续三次得到相同的行星名称。当我使用温度为1时,我得到Klara、Castrx和Caricx,拼写略有不同。所以我们确实在那里得到了更多的多样性。

关联到计算机使用
上一节我们了解了控制参数,本节中我们将所学内容关联到计算机使用这个核心目标。
现在我们已经看到了发出请求的基础知识。我想将其与计算机使用联系起来。我们将在本课程中学到的一切都以某种方式与使用Claude构建计算机使用代理相关。
以下是我们将在本课程结束时查看的计算机使用快速入门中的一些代码。我想强调几点。我们正在发出一个请求,其中我们提供 max_tokens,我们提供一个消息列表,我们提供一个模型名称,然后还有一些我们稍后会学到的东西。然后我们还使用对话消息格式,正如你在这里看到的,我们有一个消息列表。它在这个仓库或这个文件中更早定义。但我们有一个消息列表,我们将助手响应附加回该列表。所以与我们之前看到的聊天机器人非常相似,当然,要复杂得多。它使用计算机。涉及屏幕截图、工具和一大堆交互,但基本概念相同。我们向模型发送一些消息,然后我们获取助手响应。我们将其附加到我们的消息中。
如果我向上滚动足够高,我们可以看到它全部嵌套在一个 while True 循环中。当然,还有一大堆其他逻辑,但它归结为使用我们的客户端向API发送请求,提供诸如 max_tokens 和 messages 之类的东西,然后随着新响应的返回更新我们的消息列表,并每次提供这个不断更新的、持续增长的消息列表。我们一遍又一遍地这样做,使用我们到目前为止在本视频中学到的所有基础知识。
总结

在本节课中,我们一起学习了如何设置Anthropic Python SDK并发出第一个API请求。我们深入探讨了消息列表的格式及其在构建对话历史和预填充响应中的应用。我们还了解了控制模型行为的关键参数:max_tokens 用于限制响应长度,stop_sequences 用于基于特定内容停止生成,以及 temperature 用于调整响应的随机性和创造性。最后,我们将这些基础知识与构建计算机使用代理的更大目标联系起来,看到了如何在实际应用中使用这些概念。
004:多模态提示与流式响应 🖼️💬

在本节课中,我们将学习如何构建结合图像和文本的多模态提示,并掌握如何处理API返回的流式响应。我们将从基础的消息结构讲起,逐步深入到图像处理和实时数据流。
消息结构回顾
上一节我们介绍了如何向模型发送简单的文本消息。本节中,我们来看看消息内容(content)更灵活的列表结构。
在之前的课程中,我们设置了一个消息列表,其中每条消息的role设为user,content设为一个字符串,例如“讲个笑话”。实际上,将content设置为字符串是以下语法的一种快捷方式:
content = [{"type": "text", "text": "讲个笑话"}]
这里,content被设置为一个包含多个内容块的列表。目前,它只是一个类型为text的单一内容块。当我们仅进行文本提示时,使用字符串的快捷方式更简单。但接下来我们会看到,如果要提供图像,就需要使用内容块列表。
以下是一个包含多个文本块的示例消息:
content = [
{"type": "text", "text": "谁"},
{"type": "text", "text": "创造"},
{"type": "text", "text": "了你?"}
]
所有这些消息块在幕后被组合成一个单一的输入提示。
处理图像输入
现在,我们开始处理图像。我们的Claude模型可以接受图像作为输入。首先,我们需要准备一些图像进行处理。
假设我们运营一家食品配送初创公司,并使用Claude来验证客户的索赔。客户可能会发送截图说:“看,我只收到了一半的订单,要求退款。”我们将使用Claude来分析像下面这样的客户食品图像。

我们从简单的任务开始:让Claude告诉我们这张图片中有多少个餐盒和纸箱。


图像消息结构
包含图像的消息结构如下所示:

如图所示,我们有一个消息列表。其中一条消息的role设为user,content设为一个列表。在这个content列表中,我们有一个新的内容块类型——image块。其结构是:type设为image,source是一个字典,其中type设为base64,media_type设为图像类型(如image/jpeg或image/png),data则包含原始的图像数据。
准备图像数据

回到我们的代码,在创建消息之前,我们需要完成几个步骤来准备图像。
首先,读取图像文件。我们使用路径打开food.png文件。

然后,将图像内容读取为二进制对象。接着,使用base64对二进制数据进行编码。最后,将base64编码的数据转换为字符串。完成这些步骤后,我们就得到了一个很长的base64字符串。
构建并发送图像消息
现在,我们需要将这个包含正确格式图像数据的base64字符串放入一个格式正确的消息中,然后发送给模型。
以下是构建消息的代码:
image_message = {
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": base64_string # 我们之前生成的长字符串
}
}
text_message = {"type": "text", "text": "这张图片中有多少种不同类型的打包餐盒?"}
messages = [
{
"role": "user",
"content": [image_message, text_message]
}
]
我们发送这张装满食物的打包餐盒图片,并询问其中每种类型有多少个。然后,我们将这个消息列表发送给API。
运行后,我们得到了响应:“在这张图片中,有三个带透明盖的矩形塑料餐盒,以及三个白色纸质折叠外卖盒(通常称为中式外卖盒或牡蛎桶)。” 答案是正确的。回顾原图,确实有三个带塑料盖的餐盒和三个纸质外卖盒。
创建辅助函数
反复执行读取图像、转换为base64、编码为UTF-8字符串并添加到格式正确的消息中这些步骤,可能会有些繁琐。因此,创建一个辅助函数是个好主意。


以下是一个名为create_image_message的辅助函数,它整合了我们之前看到的功能:
import base64
import mimetypes
def create_image_message(image_path):
with open(image_path, "rb") as image_file:
binary_data = image_file.read()
base64_bytes = base64.b64encode(binary_data)
base64_string = base64_bytes.decode('utf-8')
mime_type, _ = mimetypes.guess_type(image_path)
image_block = {
"type": "image",
"source": {
"type": "base64",
"media_type": mime_type,
"data": base64_string
}
}
return image_block


这个函数接收图像路径,执行上述步骤,猜测MIME类型,创建格式正确的图像块,然后返回它。
让我们用另一张图片试试。images目录中有一张plant.png的图片,这是一种猪笼草。

我们将使用定义好的函数,并询问模型识别这种植物。

messages = [
{
"role": "user",
"content": [
create_image_message("images/plant.png"),
{"type": "text", "text": "这是什么物种?"}
]
}
]
运行后,我们得到响应:“这看起来是一种猪笼草,属于食虫植物……” 很好。这个辅助函数让事情变得简单了一些。你甚至可以进一步创建一个辅助函数来生成整个消息列表,只需提供图像路径和文本提示即可。
实际用例:文档分析
接下来,我们看一个许多客户正在使用Claude处理的更实际的用例:分析文档。
以这张名为invoice.png的发票为例,它包含大量重要信息。我们可以将其输入Claude,给出清晰的提示,并要求它以结构化数据(如JSON)的形式响应。这样,我们就能在几分钟内将数千张发票转换为JSON并存入数据库。
以下是单个示例的操作:
# 使用辅助函数创建图像消息
image_block = create_image_message("images/invoice.png")
# 构建文本提示
text_prompt = {
"type": "text",
"text": "生成一个代表此发票内容的JSON对象。它应包含所有日期、金额和地址。仅用JSON本身响应。"
}
messages = [{"role": "user", "content": [image_block, text_prompt]}]
response = client.messages.create(model=MODEL_NAME, messages=messages, max_tokens=1024)
print(response.content[0].text)

我们得到了一个JSON响应,包含公司名称、地址、发票信息、账单接收方、物品清单以及总计金额。核对原图,所有这些信息都是准确的。
与识别植物物种相比,这是一个更贴近实际的图像提示用例。
多图像提示

需要说明的是,我们可以在单条消息中提供多张图像。回想一下,我们所有的内容块在输入模型时,本质上都被视为一个提示。因此,我可以在一条用户消息中组合多个图像块和多个文本提示块。content是一个列表,我只需将内容块添加进去,无论其类型是image还是text。
流式响应

本节课我们将涵盖的第二个主题是流式响应。
到目前为止,我们使用client.messages.create的方式效果很好。但如果我给出一个如“写一首诗”这样的提示,你会注意到,我们需要等待整个响应生成完毕才能得到结果。虽然时间不长(可能半秒或一秒),但我们是一次性获得整个生成内容。
当模型的输出较长时(比如用模型写一篇论文),在获得任何内容之前等待的时间会更长。在没有流式传输的情况下,我们需要等到整个输出生成完毕。
使用流式传输,我们可以做一些不同的事情:我们可以在内容生成的同时就获取到内容。这对于面向用户的场景非常有用,因为我们可以开始向用户展示正在生成的响应,而不是等到整个生成完成。
流式传输实际上并不会加快整体生成过程,它只是缩短了“首次令牌时间”,即你看到第一个响应迹象的时间。
代码略有不同,但非常相似:
stream = client.messages.stream(
model=MODEL_NAME,
messages=[{"role": "user", "content": "写一首诗"}],
max_tokens=1024
)
for text in stream.text_stream:
print(text, end="", flush=True)

现在,我们遍历名为stream的对象中的text_stream,并打印出每一段文本。运行后,我们可以看到内容在生成的同时就返回了,而不必一次性等待整个内容生成。我们看到的是小块小块的内容逐个出现。
但再次强调,完成此生成所需的总时间保持不变。我们并没有神奇地比不使用流式传输更快地获得完整结果,我们只是在生成过程中逐步获得了输出的部分内容。
计算机使用示例
最后,我想再次通过我们“计算机使用”快速入门实现中的一个真实示例来结束本节。
这是一个执行多项操作的函数。如果你仔细观察,在突出显示的文本中,我们使用本节课早先讨论过的格式,附加了一个正确格式化的图像。

这些图像是我们提供给模型的屏幕截图。正如我们在介绍本课程计算机使用部分时所见,模型的工作原理是获取屏幕截图、分析截图,然后决定采取操作。因此,我们需要能够向模型提供图像,而我们使用的语法与本节课已经看到的完全相同:我们创建这些图像内容块。
这里的用例比识别植物复杂得多,但语法完全一致。
总结
本节课中,我们一起学习了如何构建多模态提示和处理流式响应。
- 消息结构:我们回顾了消息内容可以是一个内容块列表,这为组合文本和图像提供了灵活性。
- 图像处理:我们学习了如何读取图像文件,将其编码为base64字符串,并构建包含
image类型内容块的消息,以将图像发送给Claude模型。我们还创建了辅助函数来简化这一过程。 - 实际应用:我们探讨了图像提示的实际用例,如分析发票以提取结构化数据。
- 流式响应:我们了解了如何使用
client.messages.stream来获取实时生成的响应,这改善了用户体验,尤其是在生成长文本时。 - 综合应用:我们看到了这些技术如何被集成到更复杂的“计算机使用”场景中,例如通过分析屏幕截图来指导自动化操作。

我们的工具箱正在逐步丰富。接下来,我们将讨论一些更复杂或更贴近现实世界的提示技巧。
005:编写高质量提示词教程 🚀

在本节课中,我们将学习如何构建能获得一致、高质量回复的有效提示词。你将掌握在现实世界中真正重要的、经过验证的提示词技巧,并理解在聊天机器人(如Claude AI)上编写提示词与编写企业级、可重复使用的提示词之间的区别。
从聊天到生产:两种提示词的区别
上一节我们介绍了课程目标,本节中我们来看看编写提示词时面临的核心区别。主要焦点在于区分两种类型的提示词:一种是作为消费者或聊天机器人用户编写的提示词,另一种是大型客户或任何API客户编写的、需要可重复且可靠的提示词。
Anthropic文档中有一个关于提示词工程的章节,包含许多不同的技巧和策略。其中一些确实重要,但有些比另一些更重要。互联网上有很多关于提示词的内容,其中一些可能不太可靠。因此,我们将重点关注那些有实证支持的提示词技巧。

首先,我想展示一个例子来说明什么是消费者提示词,什么是真实世界的企业级提示词。
以下是一个潜在的聊天机器人或消费者提示词的例子,我可能会在Claude AI网站上输入:
help me brainstorm ideas for a talk on AI and education.
如果我满意结果,那就很好。如果不满意,我有无数次机会进行跟进,例如说:“哎呀,实际上你太关注AI了,对教育的关注不够。你能把它改成要点列表吗?你能用Markdown格式吗?”我可以一遍又一遍地跟进,有很大的回旋余地和容错空间。
现在,让我们看一个潜在的企业级提示词。我提前警告你,这个提示词相当长,无法在本视频中详细阅读和讲解。但这就是重点:我想让你看到这些提示词会变得很长、很复杂、有结构。创建这些提示词需要付出很多努力,而不仅仅是像与Claude AI对话那样,想出一个想法,然后再跟进另一个想法。
这是一个处理客户服务通话记录的提示词示例,它会生成JSON摘要。我们可能每小时甚至每分钟都要这样做数千次,例如,如果我们运营一个大型呼叫中心或拥有庞大的客户支持团队。
我们不会逐条讲解这个提示词,但我会留给你,以便你自行查看。这里面有一些东西我们稍后会提到。不过,我想强调的第一点是,对于企业级、可重复的提示词,我们真的应该把它们看作是提示词模板。我们有一个基本保持不变的大型提示词结构,其中包含一个或多个作为变量插入的动态部分。
在这个例子中,它以“分析以下客户服务通话并生成一个JSON对象。这是通话记录:”开始。然后在这一行,我们有一个占位符,实际上会在这里插入真实的通话记录。我们很可能会使用字符串方法动态地完成这个操作,用真实的记录替换这个占位符,然后成千上万次地重复这个过程。因此,我们更多地将其视为一个模板,而不是像考虑Claude AI提示词那样的一次性用例。
核心提示词技巧概览
回到幻灯片,我在这里列出了一些更重要的提示词技巧,并用粗体标出了我认为最重要或比其他任何技巧都更重要的那些。
其中之一是使用提示词模板,我们已经暗示了这个想法。其他技巧包括让Claude思考(也称为思维链),我们稍后会讨论;使用XML结构组织你的提示词,我们刚刚展示的提示词中已经看到了一点,但接下来几分钟我们也会重点讨论;以及使用示例。这些都是有真实数据支持、能证明其重要性的技巧。
现在,我想逐一讲解这些技巧,并尝试构建一个相对真实的提示词。它会变得有点长,提示词确实会包含大量文本和字符串。但我们将一步一步地构建。
我们将通过逐步构建一个更大的、真实世界或企业级的提示词来完成这个任务。我们将使用的想法是一个客户评论分类和情感分析提示词。假设我们经营一家虚构的电子商务公司Acme Company,我们有数百种产品和成千上万的客户评论。我们将使用Claude API来帮助我们理解这些评论的情感以及一些常见的投诉。
如果这是一个假设的评论:“我最近购买了XYZ智能手机。这是一次喜忧参半的体验。”它列出了一些优点和一些缺点。它说:“我期望的问题能少一些。”我希望Claude能够以可重复的方式告诉我,这是一个正面、负面还是中性的评论。并且我希望它能突出一些关键问题和反馈点。
具体来说,为了大规模处理成千上万的评论,我可能希望输出包含一些易于提取和处理的格式。通常,这会是JSON。也许是这样的:一个可重复的对象,总是包含一个情感分数(正面、负面或中性),在名为“sentiment_analysis”的键下有一些分析,然后列出实际的投诉,例如“性能滞后”、“性价比低”、“面部识别不可靠”等等。然后,我可以轻松地为成千上万的评论大规模地执行此操作,存储在数据库中,进行比较,制作图表,无论我想用这个可重复的输出做什么。
逐步构建企业级提示词
现在我们的任务已经定义:我们希望获取客户评论,并将其转换为包含情感分析信息和提取的客户投诉数据的JSON。我们将分部分完成,然后构建整个提示词。
1. 为模型设定角色
我们要讨论的第一个技巧是为模型设定角色。实际上,我对这个技巧的感觉没有那么强烈,所以我们会很快地过一遍。一个有用的做法是,一开始就给模型一个明确的角色和期望。
在这种情况下,它可能看起来像这样:
你是一位专门分析客户评论的AI助手。你的任务是确定给定评论的整体情感,并提取提到的任何具体投诉。请仔细遵循这些说明。
显然,这只是提示词的一部分。但我们正在设定角色或奠定基础,给模型一些关于它应该擅长什么的背景信息。
2. 提供明确的指令
下一步是向模型提供实际的指令。如果我们向上滚动,我们告诉模型“请仔细遵循这些说明”。现在,我们将给它一个非常清晰和直接的、有序的指令列表。
以下是第一个指令:
<instructions>
1. 审阅以下客户反馈:
<review>
{{customer_review}}
</review>
</instructions>
我们正在将其制作成一个提示词模板,我们实际上会在其中插入客户评论。你不必使用这些双花括号,你可以使用任何你想要的变量或占位符来替换。我们喜欢使用双花括号,但这绝对不是必须的。
另外,请注意我在这里使用了XML标签。这也不是必须的,但Claude模型往往与XML标签配合得很好。你可以使用任何语法或任何分隔符来告诉模型:“客户评论从这里开始,到这里结束。”有些客户评论可能很短,只有几句话,但对于一些非常不满或非常热情的客户,我们可能会看到数千个字符。因此,我们想清楚地告诉模型评论的开始和结束位置。
3. 实施“思维链”技巧
接下来要关注的是我们希望模型执行的实际步骤。我们已经提供了上下文并说“我们希望您审阅此客户反馈”。然后我们最终会在这里插入客户反馈。我们希望模型做什么?可能很想简单地说:“生成一个包含情感分数(正面、中性或负面)以及你提取的投诉列表的JSON。”这可能会奏效,在很多情况下很可能有效。
但我想在这里强调的一个提示词技巧是所谓的让Claude思考或思维链。本质上是告诉模型,在它做出决定或某种结论之前,我们希望它“大声思考”并输出一些分析来帮助它做出决定,然后最终做出判断。
以下是一个示例,说明这可能是什么样子。在变量指令的第二部分(另一个长字符串)中,我告诉模型这是你的第二步:
<instructions>
2. 一旦你审阅了客户反馈,请使用以下步骤分析评论:
- 首先,在 <review_breakdown> 标签内展示你的工作。
- 从评论中提取可能与情感相关的关键短语。
- 考虑支持正面、负面和中性情感的论点。
- 确定整体情感并说明你的推理。
- 从实际客户评论中提取投诉。
请彻底分解评论,此部分可以相当长。
</instructions>
这里有几件事我想强调。首先,这一行告诉模型在 <review_breakdown> 标签内展示其工作。再次强调,你不必使用XML,但模型(Claude系列模型)与XML配合良好。因此,一个常见的策略是告诉Claude将其输出的某些部分包含在特定的XML标签中,这样我们就可以告诉它在 <review_breakdown> 标签内进行“大声思考”,与实际分析分开。最终结果我们会告诉它放在某个单独的标签里。
我们告诉模型从提取可能与情感相关的关键短语开始。然后告诉模型考虑支持正面、负面和中性情感的论点。进行整体情感的实际确定并说明其推理。并从实际客户评论中提取投诉。然后我们告诉模型,此部分可以相当长,因为你彻底分解了评论。
现在,这并不是每个提示词都需要的东西。这可能会导致不必要的输出令牌,因为模型在实际生成最终结果或最终JSON分析之前,会生成一大堆“思考”。因此,这不是你需要立即转向的东西,但我在这里展示它,因为它是从模型获得更好结果的更强大技巧之一。
4. 定义最终输出格式
这引出了我们的下一组指令:关于我们想要的最终输出。因此,除了关于“思考”的指令之外,我们将在指令的第三部分告诉模型(记住,我们将所有这些部分组合成一个提示词):
<instructions>
3. 生成一个具有以下确切结构的JSON输出:
{
"sentiment_score": "positive|negative|neutral",
"sentiment_analysis": "详细分析文本...",
"complaints": ["投诉1", "投诉2", ...]
}
将此JSON放在 <json> XML标签内。
</instructions>
我想得到一个情感分数(正面、负面或中性)、一个情感分析(这是更详细的分析)以及一个投诉数组。我希望这在 <json> XML标签内完成。再次强调,不必是XML,但我需要某种简单的方法来提取它。这是响应的核心。如果我成千上万次地重复这样做,我需要一种简单、可重复的方法来获取那个JSON。
最后,我以一些基本提醒结束:
<instructions>
注意:如果没有投诉,请使用空数组 []。
</instructions>
组装完整提示词并测试
现在我们有了提示词的所有部分,让我们把它们组合起来。我将创建一个最终的提示词变量,使用f-string,并动态插入我们提示词的各个部分。
以下是组合后的完整提示词示例(为简洁起见,此处为示意):
你是一位专门分析客户评论的AI助手。你的任务是确定给定评论的整体情感,并提取提到的任何具体投诉。请仔细遵循这些说明。
<instructions>
1. 审阅以下客户反馈:
<review>
{{customer_review}}
</review>
2. 一旦你审阅了客户反馈,请使用以下步骤分析评论:
- 首先,在 <review_breakdown> 标签内展示你的工作。
- 从评论中提取可能与情感相关的关键短语。
- 考虑支持正面、负面和中性情感的论点。
- 确定整体情感并说明你的推理。
- 从实际客户评论中提取投诉。
请彻底分解评论,此部分可以相当长。
3. 生成一个具有以下确切结构的JSON输出:
{
"sentiment_score": "positive|negative|neutral",
"sentiment_analysis": "详细分析文本...",
"complaints": ["投诉1", "投诉2", ...]
}
将此JSON放在 <json> XML标签内。
注意:如果没有投诉,请使用空数组 []。
</instructions>
我的建议不一定是你必须像我这样分成单独的块来写。我只是为了更容易讨论和逐步讲解而将其分解。
现在,让我们看看我们的最终提示词。我已经把它打印出来了。现在我们要做的是编写一个函数,该函数接收一个客户评论,将其插入到这个提示词中,然后发送给Claude,最后提取JSON输出。
以下是一个名为 get_review_sentiment 的简单函数,它使用我们刚刚从小片段组装的最终提示词。它期望我们传入一个客户评论。然后,因为我们使用的是提示词模板,我们将用传入函数的实际客户评论替换我们的小占位符 {{customer_review}}。
然后我们向Claude发送请求。我们构建最终提示词,称之为 prompt,然后将其发送到消息列表中。然后我做两件事:第一件事,只是为了让我们知道它在工作,我打印出模型的整个输出,这允许我们看到思考过程。记住,我们告诉模型执行一些“大声”的思考和分析。然后我们将提取JSON标签之间的内容。我在这里使用正则表达式来帮助我完成这个。我搜索 <json> 开始标签和 </json> 结束标签之间的任何内容。如果你记得,当我们构建这个提示词时,我们告诉模型“生成一个遵循此结构的JSON输出。在JSON XML标签内,放入你的JSON。”我们这样做,然后我们将打印出最终的JSON输出,这才是我们真正想要的。然后,如果由于某种原因我们没有找到它,我们会打印“出现错误或响应中没有情感分析”。
让我们用一个非常简单的评论来试试。我现在就写一个非常简单的。好的,这是一个非常简单的评论:“我爱死我的AcmePhone了。太不可思议了。有点贵。但物有所值。我喜欢它的颜色。”相当正面。
让我们用我们的函数 get_review_sentiment 和我们的第一个评论来运行这个。好的,我来运行这个单元格。我们将看到我们的响应被打印回来。它提取关键短语,进行“大声思考”,这是一些积极的东西,这是一些消极的东西,这是分析,整体情感,投诉,实际上只有一个:“有点贵”。最后,在底部,我们可以看到我们提取的实际JSON。所以情感分数是正面的。这是分析。这是投诉。没有很多投诉,只是“有点贵”。
这是另一个评论,更长一些,更混合一些,列出了更多问题。我们不会一起阅读它,但这可能更接近某人可能写的评论。现在,让我们尝试通过模型运行这个。我将为我们的 review_two 变量运行这个。这次,我们又得到了输出,相当多的输出。它提取了积极短语、消极短语,它自己进行了分析,有点矛盾,是混合的,但它说消极方面超过了积极方面。这也给了我们一种追踪,我们可以理解为什么Claude生成了某个输出,这是让它“大声思考”的另一个优势。然后它提取投诉,最后,它给了我JSON输出,我可以提取并用它做点什么,存储在数据库中,并重复这个过程数万次。
补充技巧:使用示例(少样本提示)
我选择不展示的一个技巧是使用示例,也称为少样本提示,因为它往往会变得非常庞大和冗长。这里的想法是,我们可以在提示词中向模型展示相应的输入和输出作为示例。
以下是一个可能的样子示例。它相当长,在这个例子或这个特定的提示词中不是必需的。但如果你试图让模型做一些它难以完成、不准确或不遵循正确格式的事情,这是首选策略之一。
我们在这里做的是告诉模型:“这里有一些输入和输出的例子,以帮助你理解我们正在寻找的分析类型。”然后我简单地说:“这里有一些在XML标签内的例子。这是第一个例子:这是一个作为输入的客户评论。这是你应该给我的理想输出。”正如你所看到的,它变得相当长,因为在这种情况下理想输出很长。而这只是一个例子。在现实世界中,当你在提示词中提供示例时,你通常希望涵盖许多不同的情况。所以在这种情况下,至少需要一个正面评论、一个负面评论、一个中性评论,也许是一个边缘情况,比如没有评论、评论为空或评论是另一种语言。我们想涵盖我们的基础。因此,编写这些生产级别的提示词真的需要很多工作。
工具推荐:Anthropic控制台的提示词生成器
最后,我们来看看Anthropic控制台的提示词生成器工具。这不是完成本课程所必需的,但这个工具可以帮助你完成编写真实生产级提示词的前75%的工作。


例如,我点击“生成提示词”。也许我需要帮助生成的提示词是一个营销文案生成器,我传入诸如产品描述(要点形式)、可能一张图片、我希望触达的受众以及期望长度等信息。也许我正在尝试写一条推文、一篇博客文章或一则广告。我想要帮助生成营销文案。所以我点击生成。我们将得到一个生成的提示词。它使用了一些流式传输(我们之前介绍过),你可以看到它流式传入。这个提示词,如果我们仔细看,将包含诸如提示词变量之类的东西,我可以在其中插入产品描述、目标受众和期望长度。然后我可以决定使用这个提示词。我可以改进提示词,我也可以向上滚动并实际添加示例,这些示例将被动态添加到提示词中。


这是一个工具,它使编写这些长提示词的初始痛点变得容易得多。它仍然不会按需给你一个完美的提示词,但比从空白页开始要好得多。
总结


本节课中我们一起学习了如何构建有效的企业级提示词。我们探讨了消费者提示词与企业级可重复提示词之间的关键区别,后者通常作为模板使用,包含动态变量。我们介绍了几个核心技巧:为模型设定角色、提供清晰指令、使用XML结构组织提示词、实施“思维链”技巧让模型展示推理过程,以及定义结构化的输出格式(如JSON)。我们还通过构建一个客户评论情感分析提示词的完整示例,演示了如何将这些技巧组合应用。最后,我们了解了使用示例(少样本提示)的威力以及Anthropic控制台的提示词生成器工具如何辅助初始构建。记住,编写生产级提示词需要细致的工作,但遵循这些经过验证的技巧将帮助你获得更一致、可靠的结果。
006:提示缓存


在本节课中,我们将学习如何使用提示缓存功能。这是一种强大的优化技术,可以显著降低API调用成本和延迟,尤其适用于处理长提示或重复性任务的场景。
概述
提示缓存允许我们将提示中保持不变的前缀部分缓存起来,在后续的API调用中重复使用,从而避免重复处理相同的令牌。这可以大幅减少处理时间和费用。
上一节我们介绍了基本的API调用,本节中我们来看看如何通过缓存来优化这些调用。
什么是提示缓存?🤔
提示缓存是一项功能,旨在通过允许从提示共有的特定前缀处恢复处理,来优化API使用。
简而言之,我们可以将那些在多次API调用间保持一致的提示前缀内容缓存起来。这能极大地减少处理时间和成本,尤其适用于重复性任务或重用固定前缀元素的提示。
为了更好地理解其工作原理,我们先来看一些示意图。


左侧是一个假设的提示,用形状表示。这是我们准备发送的请求,初始时没有任何内容被缓存。我们将这个请求发送给API进行处理。假设我们决定缓存发送给API的所有内容。
此时,我们已将第一个请求中的整个提示前缀存储在缓存中。在后续请求中,我们有一个更长的提示。它包含了与第一个请求完全相同的前缀,但后面附加了许多新内容。
现在,API无需再处理整个提示。我们已经缓存了上一轮的前缀。因此,当我发送这个新请求时,将会发生缓存命中。我们将从缓存中读取数据,这意味着我们不必重新处理所有这些令牌。根据令牌数量的多少,这可以为我们节省大量时间。如果我们反复重用这些内容,还能节省大量资金。
然后,我们可以向缓存写入更多内容,并持续这个过程。随着对话的增长,我们可以选择增量地添加到缓存中,或者只缓存提示中某个特别长的部分。
实践:无缓存调用
回到你的笔记本中,我们使用相同的基本设置:导入Anthropic库、设置客户端,并定义模型名称字符串变量。
为了最直观地看到提示缓存的效果,我们将对比使用和不使用缓存的情况。我们将使用一个非常长的提示——整本玛丽·雪莱所著的《弗兰肯斯坦》的文本,该文本保存在一个名为 Frankenstein.txt 的文件中。
第一步是打开这个文件,将其内容读入一个变量,我们称之为 book_content。book_content 将是一个非常长的字符串。
以下是该内容的一小段切片,以便查看书籍的部分内容。
下一步是将整本书连同一些提示(例如“第三章发生了什么?”)一起发送出去。任何与《弗兰肯斯坦》相关的简单提示都可以。所有这些都封装在一个名为 make_uncached_api_call 的函数中。
你会看到函数内部有一些计时逻辑,用于在请求发送前后启动计时器,以计算从发送请求到收到响应之间的时间差。
最后,函数返回整体响应以及时间差。需要明确的是,这个版本完全不使用任何缓存。
高亮显示的行是提供整本书内容(那个巨大的字符串)的地方。注意,它被包裹在 <book_xml> 标签内。这不是必需的,但这是一个很好的方式,用于向模型标示出这个庞大文档的范围。最后是问题“第三章发生了什么?”,它与实际的书籍内容是分开的。这样我们就界定了这本巨著的边界。
接下来是调用这个函数。这行代码调用函数,下一行打印出所花费的时间,再下一行打印出从模型返回的实际内容。
运行这个单元格并等待。这是一个非常长的提示,所以可能需要一段时间。
响应返回了。在这个特定实例中,它花费了 17.77 秒,同样,没有涉及任何缓存。
这是实际的响应内容。坦白说,在这个函数中,响应内容是最不重要的部分。更重要的是关注时间元素以及实际的使用量。
你可以看到处理了相当多的输入令牌:108,000 个输入令牌,接着是 324 个输出令牌(这只是生成过程中使用的令牌数量),以及 0 个缓存创建输入令牌和 0 个缓存读取令牌,因为我们尚未涉及任何缓存。
实践:使用缓存调用
现在,你可以继续学习实际利用我们显式缓存API的缓存版本。
这是一个函数,几乎与上一个函数完全相同,只是它被命名为 make_cached_api_call 而不是 uncached。这里有一个非常重要的新增部分。
在这个提供庞大书籍内容的内容块中,现在有一个 cache_control 属性(或键),其值被设置为一个字典 {"type": "ephemeral"}。任何时候,当你想要设置一个缓存点——即告诉API“我想缓存到此为止的所有输入令牌,以便下次重用”——你都需要这个标签。我们的API会执行此操作。它需要查找这个标签,标签必须存在,API才能知道我们想要写入缓存。
现在,当你第一次运行这个函数时,它仍然需要很长时间。因为我们尚未写入任何缓存,所以不会有任何缓存命中。你可以执行它。同样,由于尚未缓存任何内容,它需要一段时间。
但作为此请求的一部分,直到此 cache_control 点之前处理的输入令牌将被缓存。
运行完成了。这是你可能得到的响应,即模型实际生成的所有内容。但就我们的目的而言,下面这部分是最重要的。
我们看到这次的输入令牌数仅计为 11,输出令牌数为 324,而缓存创建输入令牌数为 108,427。现在已有大量令牌存储在缓存中。
下一步是尝试从缓存中读取。回到你之前运行的 make_cached_api_call 函数。这个 cache_control 标签实际上具有双重作用。
第一次我们的API遇到它时,它将执行到此点的缓存写入,即将所有108,000个令牌写入缓存。
在后续请求中,当它再次遇到这个 cache_control 点时,它将查看是否有任何内容缓存到此点,本质上充当一个读取点。因此,它具有双重目的:既是写入点,也是读取点。
所以,你可以发送完全相同的函数,再次运行相同的函数调用,向API发送完全相同的请求。这次它将充当读取操作。
再次运行这行代码,使用新的变量名 response2 和 duration2。
运行完成后,你可以查看 response2 的 usage 属性,注意到缓存创建输入令牌为 0,因为没有执行任何写入缓存的操作。缓存读取输入令牌为 108,000 个令牌。
与上一轮比较:上一轮缓存创建输入令牌为108,000,缓存读取为0。请求结构完全相同,消息也相同。但这一次,发生了缓存读取。虽然没有写入缓存,但从缓存中进行了大量读取。
如果我们查看 duration2,是 6.2 秒。与完全未缓存的版本(17秒)相比,提示基本相同。这里有一个小区别:这个版本问的是“第三章发生了什么?”,而那个版本问的是“第五章发生了什么?”,但提示的基本长度相同,只是结尾的数字不同。所以是 17.7 秒 对比 6.2 秒。
这还没有考虑成本节省。接下来我们来谈谈这个。
定价与成本节省💰
提示缓存的定价方式非常直接。本质上,写入缓存需要支付少量溢价:缓存写入令牌比常规基础输入令牌贵 25%。
但显著的优点在于缓存读取:从缓存中读取的令牌比未缓存的基础输入令牌便宜 90%。
而实际的输入和输出(任何未缓存的部分以及生成的任何输出)仍然按照标准价格计费。
这意味着,可能没有必要为每条消息缓存所有内容。但是,如果你有一个提示前缀,它在一大批请求中保持不变,那么缓存这个长前缀并重复使用会非常高效且具有成本效益:支付一次 25% 的溢价进行缓存写入,然后在所有后续获得缓存命中的请求中,为这些输入令牌支付减少 90% 的费用。
缓存生命周期与注意事项
关于缓存命中,有一点需要注意:缓存不会永久存在。每个缓存都有一个 5分钟的生命周期(TTL)。目前我们至少支持临时性(ephemeral)缓存。每次从缓存读取时,都会重置这个5分钟的计时器。
因此,这实际上也取决于你的使用场景、你如何使用缓存以及你发送的提示类型。但任何时候,只要你有一个很长、想要节省成本的提示,并且你重用了该提示的很多部分,你就可以使用提示缓存。
提示缓存的一个常见难点是多轮对话缓存。想象你有一个很长的对话,可能是一个涉及《弗兰肯斯坦》这本书的对话,模型收到了整本书的文本,并且围绕它进行了长时间的讨论。这里有一个很长的公共前缀应该被缓存以节省令牌,特别是当对话有几十轮或几百轮且每轮都很长时。
你可以做的是将对话作为一个整体进行缓存。通过设置一个 cache_control 点(记住,它既可以作为写入点——“将此点之前的所有内容写入缓存”,也可以作为读取点——“尝试从缓存读取”),在处理多轮对话时,你可以使用两个 cache_control 点,并随着对话的进行不断向下移动它们,这样你就能始终缓存最新的用户消息,并在倒数第二条用户消息上设置一个 cache_control 点。
为什么要这样做?它是如何工作的?这又回到了其双重目的性。
想象这是一个有数百条消息的非常长的对话。这个 cache_control 点(假设在倒数第二条用户消息上)很可能会从上一轮获得读取命中(因为上一轮它曾是最后一条用户消息,然后我们得到了响应,接着它被写入缓存)。现在它充当读取点,将会发生缓存命中。
然后,在对话的最末尾,这个新的 cache_control 点(在最后一条用户消息上)充当新的写入点,告诉API:“将到此为止的所有内容写入缓存。”
然后你继续这个模式。如果对话增长(正如这个消息列表所示),也是同样的模式:在倒数第二条用户消息上放置一个 cache_control,在最后一条用户消息上放置一个 cache_control。
同样,这告诉API:写入到此点(最后一条消息)的所有内容(这是新的),并从此点(倒数第二条消息)读取所有可能的内容(因为这条“告诉我更多关于火星”的消息,之前曾是最后一条消息)。
你继续这种将这两个 cache_control 点沿着对话向下移动的模式:始终在最后一条用户消息和倒数第二条用户消息上设置,以便持续从最新的缓存中读取,并写入到对话的末尾,以便下次可以从中读取。如此反复进行。
这一点有时会让人困惑,我们的文档中也有说明,当然,这个笔记本里也有。这里我没有发出任何请求,这只是一个你可以参考的消息列表示例。但再次强调,它确实容易让人出错。
与计算机操作的关联💻
最后,将内容联系回计算机操作。这是我们从过去几节课中反复查看的“计算机操作快速入门演示”中的一个小片段。
我只想强调,我们确实使用了缓存控制。cache_control 被设置为 {"type": "ephemeral"},以缓存与模型交互的漫长消息历史,其中包含大量截图(这可能占用相当数量的令牌)。因此,如果这个模型正在执行操作,假设是一个两、三或四分钟的交互,期间它尝试某些操作、进行截图,并且有10张不同的截图以及大量不同的工具调用(我们尚未讨论),那么缓存可以显著减少实际计算机操作使用的时间和成本。
稍后我们将有机会更仔细地查看这段代码。这里主要是向你展示:看,缓存不仅在我们的教学笔记本中是真实的,在实际应用中也同样如此。

总结

本节课中,我们一起学习了提示缓存的核心概念与实践。我们了解到,通过使用 cache_control 参数并设置 {"type": "ephemeral"},可以将长提示中不变的前缀缓存起来。首次调用执行缓存写入(成本增加25%),后续调用则可实现缓存读取(成本降低90%),并能显著降低响应延迟。我们还探讨了在多轮对话中移动缓存点的模式,以及缓存5分钟TTL的特性。这项技术对于处理长上下文、重复性提示或像计算机操作这类包含大量固定内容(如截图历史)的场景,能带来极大的效率和成本优势。
007:工具使用 🛠️


在本节课中,我们将学习Claude模型的核心功能之一:工具使用。我们将了解什么是工具使用,为什么它很重要,并从头到尾学习如何定义自己的工具以及实现基于工具的工作流。
什么是工具使用?
上一节我们介绍了课程概述,本节中我们来看看工具使用的核心概念。
工具使用,也称为函数调用,本质上是扩展Claude模型固有能力的一种方式。我们可以为Claude提供一组外部工具或函数,允许模型在需要时调用它们。更具体地说,模型本身只是请求调用一个工具或函数,而实际的调用和执行则由我们来完成,然后将结果返回给模型。
核心流程可以概括为:
- 模型请求调用工具。
- 我们执行该工具。
- 我们将结果告知模型。
- 模型根据结果继续其任务。
为什么工具使用很重要?

工具使用极大地扩展了Claude模型的应用场景。我们可以将常规的文本或图像提示与对外部函数的调用结合起来。这使得模型能够完成许多其自身无法独立完成的任务,例如:
- 检索动态数据。
- 查询内部数据库。
- 与API交互。
- 执行代码。
- 搜索网络。
- 控制计算机(这是本课程最终目标的基础)。
工具使用的工作流程
为了理解工具使用的具体步骤,我们需要查看其详细的工作流程。




以下是工具使用的基本步骤:
- 定义工具:首先,你需要拥有一组希望提供给模型的工具。
- 格式化工具:其次,你需要以正确的格式(JSON Schema)定义这些工具,并告知模型。
- 处理交互:最后,你需要理解来回交互的流程,以及将工具结果返回给模型的正确格式。
一个简单的示例:客户支持聊天机器人

为了将理论付诸实践,我们将构建一个简单的客户支持聊天机器人示例。我们将使用一个模拟数据库来替代真实数据库,以简化操作。
模拟数据库
我们假设运营一家名为“Acme Corporation”的公司。这个模拟数据库类包含客户和订单信息。

# 示例:模拟数据库结构(非实际代码,仅为说明)
class FakeDatabase:
customers = [
{"customer_id": 1, "username": "john_doe", "email": "john@gmail.com"},
{"customer_id": 2, "username": "priya123", "email": "priya@example.com"}
]
orders = [
{"order_id": 101, "customer_id": 1, "product": "Widget", "status": "shipped"},
{"order_id": 102, "customer_id": 2, "product": "Gadget", "status": "processing"}
]
def get_user(self, key, value):
# 根据邮箱、电话或用户名查找用户
pass
def get_customer_orders(self, customer_id):
# 根据客户ID查找订单
pass
def cancel_order(self, order_id):
# 取消指定订单
pass

定义工具模式
要让Claude使用这些数据库方法,我们需要将它们定义为工具。这需要使用JSON Schema格式来描述每个工具。
以下是get_user工具的JSON Schema定义示例:
{
"name": "get_user",
"description": "根据邮箱、电话或用户名查找用户信息。",
"input_schema": {
"type": "object",
"properties": {
"key": {
"type": "string",
"enum": ["email", "phone", "username"],
"description": "查找依据的字段类型。"
},
"value": {
"type": "string",
"description": "与key对应的具体值,例如邮箱地址。"
}
},
"required": ["key", "value"]
}
}
我们需要为所有四个方法(get_user, get_order_by_id, get_customer_orders, cancel_order)创建类似的模式定义,并将它们放入一个工具列表中。
与模型交互
定义好工具后,我们就可以在调用模型时将其传入。
# 示例:调用模型并传入工具列表
response = client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=1024,
messages=[{"role": "user", "content": "我的用户名是priya123,请帮我查看订单。"}],
tools=tools_list # 这里传入我们定义好的工具列表
)
模型在分析用户请求后,可能会决定调用工具。它的响应中会包含一个tool_use块,指明它想调用哪个工具以及传入什么参数。
执行工具并返回结果
当我们收到模型的工具调用请求后,需要执行相应的函数,并将结果以特定格式返回给模型。
以下是处理工具调用和返回结果的核心逻辑:
# 1. 执行工具调用
def process_tool_call(tool_name, tool_input):
# 根据 tool_name 调用对应的数据库方法,例如 db.get_user(...)
result = call_database_function(tool_name, tool_input)
return result
# 2. 将工具结果返回给模型
# 我们需要在对话历史中添加一条新消息
new_message = {
"role": "user", # 注意:这里是“user”角色
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use_id_from_model, # 必须与模型请求中的ID匹配
"content": tool_execution_result
}
]
}
# 然后将这条消息加入messages列表,再次调用模型
构建完整聊天循环
将以上步骤整合,就形成了一个支持工具调用的完整聊天机器人循环。其核心逻辑是:
- 接收用户输入。
- 将包含所有历史消息和工具列表的请求发送给模型。
- 检查模型响应。如果它想调用工具,则执行工具并将结果作为新消息加入历史。
- 如果模型直接生成文本回复,则将其展示给用户。
- 重复此过程。
连接到计算机使用
工具使用是实现计算机控制的基础。在计算机使用的快速启动实现中,我们导入了一系列计算机操作工具(如点击、移动鼠标、输入等),并将它们作为一个工具集合提供给模型。
其底层机制与我们刚刚构建的客户支持机器人完全相同:
- 模型接收包含
tools参数的请求。 - 模型分析当前屏幕状态(通过图像输入)和用户指令。
- 模型输出
tool_use请求,例如click工具。 - 我们的程序执行这个点击操作。
- 我们将操作结果(例如“点击已完成”)和新屏幕截图返回给模型。
- 模型根据新状态决定下一步操作。
总结

本节课中我们一起学习了Claude模型工具使用的完整流程。我们了解到,工具使用是通过JSON Schema定义外部函数,允许模型在推理过程中请求调用这些函数,并由我们执行后将结果反馈给模型的一种强大机制。我们从解释核心概念开始,通过一个客户支持聊天机器人的示例,逐步实践了定义工具、处理模型请求、执行函数和返回结果的每一步。最后,我们看到这一机制正是实现更复杂的“计算机使用”功能的基石。掌握工具使用,将为你打开利用Claude模型自动化各种任务的大门。
008:7.计算机使用
概述
在本节课中,我们将整合之前学到的所有概念。你将理解基础的智能体架构,并演示Claude的计算机使用能力。你可以按照步骤在自己的计算机上运行这个演示。

课程内容


上一节我们介绍了工具使用和提示缓存等概念。本节中,我们将把这些知识整合到一个具体的用例中:构建一个能够操作计算机的智能体。
在深入之前,你需要知道,运行这个智能体需要在本地计算机上执行几个步骤。这并非本课程的必修部分,而是为有兴趣自行探索的学员提供的演示。
Anthropic在Github上有一个“anthropic-quickstarts”代码库,其中包含一个计算机使用演示。这个演示是一个能让你快速上手的计算机操作智能体实现方案。

以下是运行演示的步骤:
- 克隆代码库。
- 进入计算机使用演示目录。
- 按照README中的说明运行指定命令(该命令假设你已设置好Anthropic API密钥环境变量)。
- 等待服务启动后,在浏览器中访问
localhost:8080。
这个快速启动方案是上手运行计算机操作智能体最快的方式。当然,你也可以修改它。

启动后,界面左侧是一个聊天窗口,你可以向Claude发送消息。右侧是一个容器化的计算机环境,Claude将能与之交互。这是一个简单的Linux机器,底部有各种图标。你可以通过“切换屏幕控制”按钮在手动控制(例如,提前打开Firefox)和交由Claude控制之间切换。
现在,让我们尝试一个简单的例子。输入指令:“查找Anthropic最近关于对齐伪造(alignment faking)的研究论文并为我总结。”
发送指令后,模型开始工作。你会看到左侧显示模型希望使用的工具日志,右侧显示模型在屏幕上的操作。
模型的操作流程如下:
- 搜索“anthropic alignment faking research paper”。
- 点击找到的研究论文。
- 打开PDF文件。
- 使用
curl命令下载该文件。 - 使用bash工具检查下载内容。
- 最终,生成并返回内容摘要。
这个简单的例子展示了从初始指令到最终获得摘要的完整过程。模型以智能体循环的方式,进行了大约10到15轮的消息交互。这是一个非常基础的智能体,其目标明确:查找并总结论文。为了实现目标,模型可以调用多种工具。
这个智能体循环的核心是调用Anthropic API并提供计算机使用工具。它比之前看到的演示更复杂,但其底层原理是一致的。
代码中包含一个长提示词,用于告知模型它正在使用一个虚拟化环境,可以打开Firefox、安装应用、使用各种工具,并告知当前日期等。
进一步查看代码,可以看到一组定义好的工具。这些工具的结构与我们之前讨论的完全相同,只是功能更丰富(特别是计算机工具)。这里还涉及提示缓存技术。
代码中还有一个循环,不断向模型发送消息,直到模型决定任务完成。循环内部包含决定当模型调用工具时该如何处理的逻辑:执行工具,并以正确的工具结果格式回复模型。这些概念我们之前都已涵盖。
在代码库的“tools”文件夹中,包含多个工具定义。我们不会逐一讲解,但可以看看“computer”工具。这个工具的功能包括:键入按键(如字母‘S’或回车键)、移动鼠标、左键单击、右键单击、中键单击、双击,以及最重要的——截取屏幕截图。
整个系统的运行基础依赖于屏幕截图。模型通过请求截图来获取屏幕的当前状态,然后决定将鼠标移动到哪里、在哪里键入或点击。之后,它可能获取另一张截图,并继续此过程。所有决策都基于截图。
当然,代码中还有更多逻辑,例如截图需要被缩放到适合Claude模型处理的最佳分辨率。但归根结底,这只是一个函数:它接收模型的请求(如左键单击、截图、双击或移动鼠标),然后实际执行这些操作(移动鼠标、点击等)。模型本身并不执行工具,就像在简单的聊天机器人示例中一样,模型只是输出一个表示“我想调用这个工具”的代码块。在这里,我们(工程师或开发者)需要实际实现点击、拖拽、截图等操作。模型只是告诉我们它希望执行哪些操作。
让我们放大查看一段日志。模型首先输出一些文本,表示“我将帮助你完成这个任务。让我使用Firefox。”然后它请求一张截图,即输出一个工具调用块,表明它想使用截图工具。接着,我们提供当前状态的截图。模型根据这张截图,判断Firefox图标的位置,并决定将鼠标移动到那里。然后,它输出一个左键单击工具调用块。左键单击后,Firefox打开。这个过程不断重复:获取截图,决定需要在导航栏中键入内容,于是将鼠标移动到导航栏……如此循环,直到最终找到研究论文、下载、总结并给出最终摘要。

如果你不相信这与本课程迄今为止所学的根本原理完全相同,我们可以点击“HTTP交换日志”选项卡。向下滚动,你可以看到整个对话的完整日志。每一轮对话都清晰可见,包括我们的初始指令(用户角色)、助手的响应文本,以及我们熟悉的工具调用块(type: tool_use)。然后,我们作为工程师以工具结果块(type: tool_result)进行回复。工具使用ID必须匹配,正如我们在讲解工具使用时所学到的。
此外,我们还涉及了多模态提示,即提供截图。这里可以看到一个内容块,其类型为image,格式为base64,媒体类型是image/jpeg,后面是数据。这一切看起来应该相对熟悉,只是应用场景略有不同。这个过程不断重复:模型输出一个移动鼠标的工具调用块,然后我们回复对应的工具结果。
因此,这个演示虽然更复杂、更高级,但其底层核心仍然是:以正确的角色和内容类型(图像和文本)发送消息,当然还包括工具使用,以及用正确的工具结果块回复模型,告知其工具执行的结果。其中也运用了我们讲过的提示缓存等技术。可以说,它很好地总结了本课程中几乎所有的主题。
重申一下,这只是一个演示,并非要求你现在就必须去操作。如果你感到好奇或感兴趣,可以在自己的机器上尝试。只需访问快速启动代码库即可。这是一个有趣的实践,你也可以查阅我们的文档和博客,了解如何充分利用计算机使用功能。它作为一个综合性的成果,很好地融合了我们所学的一切。
总结

本节课中,我们一起学习了如何将工具使用、多模态提示、智能体循环等概念整合,构建一个能够操作计算机的智能体。我们通过一个具体的演示,展示了Claude如何通过截图感知环境、调用工具执行操作,并最终完成复杂任务。这标志着我们对Anthropic API核心功能学习的完成。
009:8. 结论 🎯
在本节课中,我们将对使用Anthropic模型家族构建计算机操作应用的学习内容进行总结。
概述
在本课程中,我们学习了如何使用Anthropic模型家族的所有功能。我们看到了如何将这些功能组合起来,以构建像计算机操作这样的应用程序。
课程回顾
上一节我们介绍了构建复杂应用的具体实践,本节中我们来看看整个课程的总结与收获。
以下是本课程涵盖的核心内容要点:
- 掌握了Anthropic模型家族提供的各项功能。
- 理解了如何将这些功能模块进行有效组合。
- 学习了构建实际应用程序(例如计算机操作应用)的方法论。
总结
本节课中我们一起学习了Anthropic模型的核心功能与应用构建方法。我们了解到,通过灵活运用模型提供的各种工具和能力,开发者可以创造出能够执行复杂任务(如模拟计算机操作)的智能应用。这为未来开发更高级的人机交互系统奠定了坚实的基础。


浙公网安备 33010602011771号