(点击该图片看本章导学视频)
到目前为止,您已经通过本系列课程看到了如提示之类的核心概念,甚至是称为“提示工程”的整个学科。 您可以与通过使用如 ChatGPT、Office 365、Microsoft Power Platform 等工具结合提示来完成某些工作任务。
为了将这样的体验添加到应用程序中,您需要了解提示、补全等概念并选择要使用的相关库。 这正是您将在本章中学到的内容。
在本章中,您将学习到:
在完成本章的学习,您将能够:
一般来说当您构建应用程序时,它具有某种界面,如下所示:
将其与输入命令的传统应用程序进行比较:
文本生成应用程序有何不同呢?
在文本生成应用程序中,您拥有更大的灵活性,不再局限于一组特定的命令或特定的输入语言。 相反,您可以使用自然语言与应用程序交互。 另一个好处是,因为您已经在与经过大量信息库训练的数据源进行交互,而传统应用程序可能仅限于在数据库中存储的有限内容。
您可以创建很多东西。 例如:
您需要找到一种与 LLMs 结合的方法,通常使用以下两种方法:
有一些比较通用的与 LLMs 整合的 librarys,例如:
还有一些在更高级别的框架运行的 librarys,例如:
Let's see how we can build our first app, what libraries we need, how much is required and so on.
让我们看看如何构建人生中第一个 openai 应用,我们需要哪些libraries,需要多少技能等等。
There are many libraries out there for interacting with OpenAI or Azure OpenAI. It's possible to use numerous programming languages as well like C#, Python, JavaScript, Java and more. We've chosen to use the openai
Python library, so we'll use pip
to install it.
有许多 libraries 可用于与 OpenAI 或 Azure OpenAI 交互。 还可以使用不同的编程语言,如 C#、Python、JavaScript、Java 等。 我们选择使用 openai
Python 库,通过 pip
来安装它。
pip install openai
您需要执行以下步骤:
在 Azure https://azure.microsoft.com/free/ 上创建帐户。
访问 Azure Open AI。 进入到 https://learn.microsoft.com/azure/ai-services/openai/overview#how-do-i-get-access-to-azure-openai 并请求访问权限。
[!注意] 您需要申请访问 Azure Open AI Service 的访问。
安装 Python https://www.python.org/
已创建 Azure OpenAI 服务。 请参阅本指南,了解如何创建资源.
您需要告诉“openai”库要使用什么 API key。 要查找 API key ,请转到创建好的 Azure Open AI Service 中的 "Keys and Endpoint"部分并复制 "Key 1" 值。
复制 Key 后,让我们调用 libraries 使用它。
[!注意] 通过设置环境变量将 API Key 与代码分开是很重要的
- 为您的 API key 中设置
OPENAI_API_KEY
export OPENAI_API_KEY='sk-...'
如果您使用 Azure OpenAI , 请按照以后步骤进行设置
openai.api_type = 'azure'
openai.api_key = os.environ["OPENAI_API_KEY"]
openai.api_version = '2023-05-15'
openai.api_base = os.getenv("API_BASE")
设置相关的补充
api_type
为 azure
. 这告诉 librarys 使用 Azure Open AI 而不是 OpenAI。api_key
, 对应 Azure Portal 中的 API Keyapi_version
, 这是您要使用的 API 版本。 在撰写本文时,最新版本是'2023-05-15'。api_base
, 这是 API 的 endpoint 。 您可以在 Azure Portal 中 API Key 下方找到它。[注意]
os.getenv
是一个读取环境变量的函数。 您可以使用它来读取“OPENAI_API_KEY”和“API_BASE”等环境变量。 在终端中或使用“dotenv”等库设置这些环境变量。
生成文本的方法是使用“Completion”类。 这是一个例子:
prompt = "Complete the following: Once upon a time there was a"
completion = openai.Completion.create(model="davinci-002", prompt=prompt)
print(completion.choices[0].text)
在上面的代码中,我们创建一个 completion 对象并传入我们要使用的模型和提示。 然后我们输出生成的文本。
到目前为止,您已经了解了我们如何使用“Completion”来生成文本。 但还有另一个更适合聊天机器人的类,称为“ChatCompletion”。 这是例子:
import openai
openai.api_key = "sk-..."
completion = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": "Hello world"}])
print(completion.choices[0].message.content)
下一章将详细介绍此功能。
现在我们已经了解了如何设置和配置 openai,是时候构建您的第一个文本生成应用程序了。 请按照下列步骤操作:
创建虚拟环境并安装openai:
python -m venv venv
source venv/bin/activate
pip install openai
[!注意] 如果您使用的是 Windows,请输入
venv\Scripts\activate
而不是source venv/bin/activate
。
[!注意] 转至 https://portal.azure.com/ 找到您的 Azure Open AI Key ,在资源中搜索“Open AI”
并选择“打开 AI 资源”,然后选择
Keys and Endpoint并复制
Key 1` 值。
创建 app.py 文件并添加以下代码:
import openai
openai.api_key = "您的 openai key 或 Azure OpenAI key"
openai.api_type = 'azure'
openai.api_version = '2023-05-15'
openai.api_base = "您的 Azure OpenAI Endpoint"
deployment_name = "部署模型的名字"
# add your completion code
prompt = "Complete the following: Once upon a time there was a"
# make completion
completion = openai.Completion.create(engine= deployment_name, model="davinci-002", prompt=prompt)
# print response
print(completion.choices[0].text)
[!注意] 如果您使用的是 Azure Open AI,则需要将
api_type
设置为azure
,并将api_key
设置为您的 Azure Open AI Key
您应该看到如下所示的输出结果:
very unhappy _____.
Once upon a time there was a very unhappy mermaid.
现在您已经了解了如何使用提示生成文本。 您甚至可以启动并运行一个程序,可以对其进行修改以生成不同类型的文本。
提示可用于各种任务。 例如:
象一下,你家里有食材,你想煮点东西。 为此,你需要一个食谱。 查找食谱的一种方法是使用搜索引擎,或者您可以使用 LLMs 来这样做。
你可以这样写一个提示:
"Show me 5 recipes for a dish with the following ingredients: chicken, potatoes, and carrots. Per recipe, list all the ingredients used"
鉴于上述提示,您可能会得到类似于以下结果:
1. Roasted Chicken and Vegetables:
Ingredients:
- 4 chicken thighs
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 2 tablespoons olive oil
- 2 cloves garlic, minced
- 1 teaspoon dried thyme
- 1 teaspoon dried oregano
- Salt and pepper, to taste
1. Chicken and Potato Stew:
Ingredients:
- 2 tablespoons olive oil
- 1 onion, diced
- 2 cloves garlic, minced
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 teaspoon dried oregano
- 1 teaspoon dried thyme
- 1 cup chicken broth
- Salt and pepper, to taste
1. Chicken and Potato Bake:
Ingredients:
- 2 tablespoons olive oil
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 onion, diced
- 2 cloves garlic, minced
- 1 teaspoon dried oregano
- 1 teaspoon dried thyme
- 1 cup chicken broth
- Salt and pepper, to taste
1. Chicken and Potato Soup:
Ingredients:
- 2 tablespoons olive oil
- 1 onion, diced
- 2 cloves garlic, minced
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 teaspoon dried oregano
- 1 teaspoon dried thyme
- 4 cups chicken broth
- Salt and pepper, to taste
1. Chicken and Potato Hash:
Ingredients:
- 2 tablespoons olive oil
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 onion, diced
- 2 cloves garlic, minced
- 1 teaspoon dried oregano
结果很好,我知道该怎么做菜了。但希望有更进一步的改进是:
针对上述情况,我们添加一个额外的提示:
"Please remove recipes with garlic as I'm allergic and replace it with something else. Also, please produce a shopping list for the recipes, considering I already have chicken, potatoes and carrots at home."
现在你有了一个新的结果,即:
1. Roasted Chicken and Vegetables:
Ingredients:
- 4 chicken thighs
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 2 tablespoons olive oil
- 1 teaspoon dried thyme
- 1 teaspoon dried oregano
- Salt and pepper, to taste
1. Chicken and Potato Stew:
Ingredients:
- 2 tablespoons olive oil
- 1 onion, diced
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 teaspoon dried oregano
- 1 teaspoon dried thyme
- 1 cup chicken broth
- Salt and pepper, to taste
1. Chicken and Potato Bake:
Ingredients:
- 2 tablespoons olive oil
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 onion, diced
- 1 teaspoon dried oregano
- 1 teaspoon dried thyme
- 1 cup chicken broth
- Salt and pepper, to taste
1. Chicken and Potato Soup:
Ingredients:
- 2 tablespoons olive oil
- 1 onion, diced
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 teaspoon dried oregano
- 1 teaspoon dried thyme
- 4 cups chicken broth
- Salt and pepper, to taste
1. Chicken and Potato Hash:
Ingredients:
- 2 tablespoons olive oil
- 2 chicken breasts, cut into cubes
- 2 potatoes, cut into cubes
- 2 carrots, cut into cubes
- 1 onion, diced
- 1 teaspoon dried oregano
Shopping List:
- Olive oil
- Onion
- Thyme
- Oregano
- Salt
- Pepper
That's your five recipes, with no garlic mentioned and you also have a shopping list considering what you already have at home.
这是根据您的购买清单生成你的食谱(不包含大蒜)
根据场景,让我们编写代码来完整代码。为此,请按照下列步骤操作:
使用现有的 app.py 文件作为起点
找到 prompt
变量并将其代码更改为以下内容:
prompt = "Show me 5 recipes for a dish with the following ingredients: chicken, potatoes, and carrots. Per recipe, list all the ingredients used"
运行代码,您应该会看到类似以下内容的输出:
-Chicken Stew with Potatoes and Carrots: 3 tablespoons oil, 1 onion, chopped, 2 cloves garlic, minced, 1 carrot, peeled and chopped, 1 potato, peeled and chopped, 1 bay leaf, 1 thyme sprig, 1/2 teaspoon salt, 1/4 teaspoon black pepper, 1 1/2 cups chicken broth, 1/2 cup dry white wine, 2 tablespoons chopped fresh parsley, 2 tablespoons unsalted butter, 1 1/2 pounds boneless, skinless chicken thighs, cut into 1-inch pieces
-Oven-Roasted Chicken with Potatoes and Carrots: 3 tablespoons extra-virgin olive oil, 1 tablespoon Dijon mustard, 1 tablespoon chopped fresh rosemary, 1 tablespoon chopped fresh thyme, 4 cloves garlic, minced, 1 1/2 pounds small red potatoes, quartered, 1 1/2 pounds carrots, quartered lengthwise, 1/2 teaspoon salt, 1/4 teaspoon black pepper, 1 (4-pound) whole chicken
-Chicken, Potato, and Carrot Casserole: cooking spray, 1 large onion, chopped, 2 cloves garlic, minced, 1 carrot, peeled and shredded, 1 potato, peeled and shredded, 1/2 teaspoon dried thyme leaves, 1/4 teaspoon salt, 1/4 teaspoon black pepper, 2 cups fat-free, low-sodium chicken broth, 1 cup frozen peas, 1/4 cup all-purpose flour, 1 cup 2% reduced-fat milk, 1/4 cup grated Parmesan cheese
-One Pot Chicken and Potato Dinner: 2 tablespoons olive oil, 1 pound boneless, skinless chicken thighs, cut into 1-inch pieces, 1 large onion, chopped, 3 cloves garlic, minced, 1 carrot, peeled and chopped, 1 potato, peeled and chopped, 1 bay leaf, 1 thyme sprig, 1/2 teaspoon salt, 1/4 teaspoon black pepper, 2 cups chicken broth, 1/2 cup dry white wine
-Chicken, Potato, and Carrot Curry: 1 tablespoon vegetable oil, 1 large onion, chopped, 2 cloves garlic, minced, 1 carrot, peeled and chopped, 1 potato, peeled and chopped, 1 teaspoon ground coriander, 1 teaspoon ground cumin, 1/2 teaspoon ground turmeric, 1/2 teaspoon ground ginger, 1/4 teaspoon cayenne pepper, 2 cups chicken broth, 1/2 cup dry white wine, 1 (15-ounce) can chickpeas, drained and rinsed, 1/2 cup raisins, 1/2 cup chopped fresh cilantro
NOTE, your LLM is nondeterministic, so you might get different results every time you run the program.
Great, let's see how we can improve things. To improve things, we want to make sure the code is flexible, so ingredients and number of recipes can be improved and changed.
让我们按以下方式更改代码:
no_recipes = input("No of recipes (for example, 5: ")
ingredients = input("List of ingredients (for example, chicken, potatoes, and carrots: ")
# interpolate the number of recipes into the prompt an ingredients
prompt = f"Show me {no_recipes} recipes for a dish with the following ingredients: {ingredients}. Per recipe, list all the ingredients used"
Taking the code for a test run, could look like this:
No of recipes (for example, 5: 3
List of ingredients (for example, chicken, potatoes, and carrots: milk,strawberries
-Strawberry milk shake: milk, strawberries, sugar, vanilla extract, ice cubes
-Strawberry shortcake: milk, flour, baking powder, sugar, salt, unsalted butter, strawberries, whipped cream
-Strawberry milk: milk, strawberries, sugar, vanilla extract
我们现在有一个能够生成食谱的应用,并且它使用很方便,基于用户的输入和食谱的数量所使用的成分。
为了进一步改进它,添加以下内容:
过滤掉成分。 我们希望能够过滤掉我们不喜欢或过敏的成分。 要完成此更改,我们可以编辑现有提示并在其末尾添加过滤条件,如下所示:
filter = input("Filter (for example, vegetarian, vegan, or gluten-free: ")
prompt = f"Show me {no_recipes} recipes for a dish with the following ingredients: {ingredients}. Per recipe, list all the ingredients used, no {filter}"
Above, we add {filter}
to the end of the prompt and we also capture the filter value from the user.
An example input of running the program can now look like so:
No of recipes (for example, 5: 3
List of ingredients (for example, chicken, potatoes, and carrots: onion,milk
Filter (for example, vegetarian, vegan, or gluten-free: no milk
1. French Onion Soup
Ingredients:
-1 large onion, sliced
-3 cups beef broth
-1 cup milk
-6 slices french bread
-1/4 cup shredded Parmesan cheese
-1 tablespoon butter
-1 teaspoon dried thyme
-1/4 teaspoon salt
-1/4 teaspoon black pepper
Instructions:
2. In a large pot, sauté onions in butter until golden brown.
3. Add beef broth, milk, thyme, salt, and pepper. Bring to a boil.
4. Reduce heat and simmer for 10 minutes.
5. Place french bread slices on soup bowls.
6. Ladle soup over bread.
7. Sprinkle with Parmesan cheese.
8. Onion and Potato Soup
Ingredients:
-1 large onion, chopped
-2 cups potatoes, diced
-3 cups vegetable broth
-1 cup milk
-1/4 teaspoon black pepper
Instructions:
9. In a large pot, sauté onions in butter until golden brown.
10. Add potatoes, vegetable broth, milk, and pepper. Bring to a boil.
11. Reduce heat and simmer for 10 minutes.
12. Serve hot.
13. Creamy Onion Soup
Ingredients:
-1 large onion, chopped
-3 cups vegetable broth
-1 cup milk
-1/4 teaspoon black pepper
-1/4 cup all-purpose flour
-1/2 cup shredded Parmesan cheese
Instructions:
14. In a large pot, sauté onions in butter until golden brown.
15. Add vegetable broth, milk, and pepper. Bring to a boil.
16. Reduce heat and simmer for 10 minutes.
17. In a small bowl, whisk together flour and Parmesan cheese until smooth.
18. Add to soup and simmer for an additional 5 minutes, or until soup has thickened.
正如您所看到的,任何含有牛奶的食谱都已被过滤掉。 但是,如果您患有乳糖不耐症,您可能也想过滤掉含有奶酪的食谱,因此有必要明确一下。
制作购物清单。 我们想根据家里已有的物品制定一份购物清单。
对于此功能,我们可以尝试在一个提示中解决所有问题,也可以将其分成两个提示。 让我们尝试一下后一种方法。 在这里,我们建议添加一个额外的提示,但为了使其起作用,我们需要将前一个提示的结果作为上下文添加到后一个提示中。
找到代码中打印第一个提示结果的部分,并添加以下代码:
old_prompt_result = completion.choices[0].text
prompt = "Produce a shopping list for the generated recipes and please don't include ingredients that I already have."
new_prompt = f"{old_prompt_result} {prompt}"
completion = openai.Completion.create(engine=deployment_name, prompt=new_prompt, max_tokens=1200)
# print response
print("Shopping list:")
print(completion.choices[0].text)
请注意以下事项:
我们通过将第一个提示的结果添加到新提示来构造一个新提示
new_prompt = f"{old_prompt_result} {prompt}"
我们提出一个新的请求,但也考虑到我们在第一个提示中请求的 token 数量,所以这次我们说 max_tokens
是1200。
completion = openai.Completion.create(engine=deployment_name, prompt=new_prompt, max_tokens=1200)
运行代码,结果如下:
No of recipes (for example, 5: 2
List of ingredients (for example, chicken, potatoes, and carrots: apple,flour
Filter (for example, vegetarian, vegan, or gluten-free: sugar
Recipes:
or milk.
-Apple and flour pancakes: 1 cup flour, 1/2 tsp baking powder, 1/2 tsp baking soda, 1/4 tsp salt, 1 tbsp sugar, 1 egg, 1 cup buttermilk or sour milk, 1/4 cup melted butter, 1 Granny Smith apple, peeled and grated
-Apple fritters: 1-1/2 cups flour, 1 tsp baking powder, 1/4 tsp salt, 1/4 tsp baking soda, 1/4 tsp nutmeg, 1/4 tsp cinnamon, 1/4 tsp allspice, 1/4 cup sugar, 1/4 cup vegetable shortening, 1/4 cup milk, 1 egg, 2 cups shredded, peeled apples
Shopping list:
-Flour, baking powder, baking soda, salt, sugar, egg, buttermilk, butter, apple, nutmeg, cinnamon, allspice
到目前为止,我们拥有的是可以运行的代码,但是我们应该做一些调整来进一步改进。 我们应该做的一些事情是:
将 Key 与代码分开,例如 API Key。Key 不属于代码,应存储在安全的位置。 为了将 Key 与代码分开,我们可以使用环境变量和像python-dotenv
这样的 libraries 从文件中加载它们。 代码如下:
创建一个包含以下内容的 .env
文件:
OPENAI_API_KEY=sk-...
Note, for Azure, you need to set the following environment variables:
OPENAI_API_TYPE=azure
OPENAI_API_VERSION=2023-05-15
OPENAI_API_BASE=<replace>
In code, you would load the environment variables like so:
from dotenv import load_dotenv
load_dotenv()
openai.api_key = os.environ["OPENAI_API_KEY"]
关于 token 长度。 我们应该考虑需要多少 token 来生成我们想要的文本。 token 需要花钱,因此在可能的情况下,我们应该尽量节约使用 token 的数量。 例如,我们可以对提示进行调整,以便我们可以使用更少的 token
要更改使用的 token,您可以使用 max_tokens
参数。 例如,如果您想使用 100 个 token,您可以这样做:
completion = openai.Completion.create(model="davinci-002", prompt=prompt, max_tokens=100)
进行 temperature 调整试验。 temperature 是我们到目前为止还没有提到的东西,但它是我们的程序如何执行的重要元素。 temperature 值越高,输出就越随机。 相反, temperature 值越低,输出就越可预测。 考虑一下您是否希望输出有所变化。
要改变 temperature ,您可以使用 `temperature` 参数。 例如,如果您想使用 0.5 的 temperature ,您可以这样做:
```python
completion = openai.Completion.create(model="davinci-002", prompt=prompt, temperature=0.5)
```
请注意,越接近 1.0,输出的变化就越多。
对于此作业,选择要构建的内容。
以下是一些建议:
下面是一个基础提示,看看如何使用它并根据自己的喜好进行调整。
- "You're an expert on the Python language
Suggest a beginner lesson for Python in the following format:
Format:
- concepts:
- brief explanation of the lesson:
- exercise in code with solutions"
以下是您可能会使用的一些提示:
- "You are Abe Lincoln, tell me about yourself in 3 sentences, and respond using grammar and words like Abe would have used"
- "You are Abe Lincoln, respond using grammar and words like Abe would have used:
Tell me about your greatest accomplishments, in 300 words:"
temperature 有什么作用?
A: 1
完成作业时,尝试改变 temperature ,尝试将其设置为 0、0.5 和 1。请记住,0 是变化最少的,1 是变化最多的,看看什么值最适合您的应用?
想要了解有关创建文本生成应用的更多信息? 转至进阶学习的页面 查找有关此主章节的其他学习资源。
前往第七章,我们将学习构建聊天应用程序