Prompt Engineering
Author: Lee Boonstra
第二章提示技术的 Code prompting 小节
本书主要是以Google自己的平台为主进行介绍,但将这些操作迁移到其他平台上可存在可行性。
Code prompting
LLM 主要专注于处理文本信息,这其中也包括生成代码。
Prompts for writing code
LLM 不仅可以作为开发助手,还能用你熟悉的任何编程语言帮你编写代码。对开发者来说,这能显著加快编码的效率。
举个例子,假设你电脑上有一个包含数百个文件的文件夹,你需要重命名这些文件。手动一个个修改显然非常耗时。虽然你可以用自己掌握的 Bash 写个脚本来自动化处理,但这也需要花时间编写和调试。这个时候,不妨试试通过 prompt 让 LLM 来帮你完成这个任务。
Name | 1_bash_rename_files_in_folder |
---|---|
Goal | Write a prompt to write code in Bash to rename files in a folder. |
Model | gemini-pro |
Temperature | 0.1 |
Token Limit | 1024 |
Top-K | N/A |
Top-P | 1 |
Prompt | 请写一段 Bash 脚本,要求用户输入一个文件夹名称,接着脚本会遍历该文件夹中的所有文件,并在每个文件名的开头添加 “draft” 来批量重命名这些文件。 |
Output | 如下所示 |
#!/bin/bash
# Ask for the folder name
echo "Enter the folder name: "
read folder_name
# Check if the folder exists
if [ ! -d "$folder_name" ]; then
echo "Folder does not exist."
exit 1
fi
# Get the list of files in the folder
files=( "$folder_name"/* )
# Rename each file by prepending "draft" to the file name
for file in "${files[@]}"; do
new_file_name="draft_$(basename "$file")"
mv "$file" "$new_file_name"
done
echo "Files renamed successfully."
需要知道的是 LLM 并不能真正进行逻辑推理,它只是根据训练数据中的模式生成内容。因此,在使用之前,必须仔细阅读并测试所生成的代码。
Prompts for explaining code
作为一名开发者,常常需要阅读并理解其他人写的代码。LLM 在这方面也能提供很大帮助。例如,可以以上面的代码为例,去掉里面的注释,然后让 LLM 来解释这段代码的功能和逻辑。具体的效果可以参考下表,它展示了模型对代码的解读结果。
Name | 1_bash_explain_the_code |
---|---|
Goal | Write a prompt to explain Bash code |
Model | gemini-pro |
Temperature | 0.1 |
Token Limit | 1024 |
Top-K | N/A |
Top-P | 1 |
Prompt | 如下所示 |
Output | 如下所示 |
Prompt
Explain to me the below Bash code:
bash
#!/bin/bash
echo "Enter the folder name: "
read folder_name
if [ ! -d "$folder_name" ]; then
echo "Folder does not exist."
exit 1
fi
files=( "$folder_name"/* )
for file in "${files[@]}"; do
new_file_name="draft_$(basename "$file")"
mv "$file" "$new_file_name"
done
echo "Files renamed successfully."
Output
这个 Bash 脚本执行以下任务:
- 用户输入:
- 脚本使用
echo
和read
命令提示用户输入一个文件夹名称。输入的文件夹名称会被存储在folder_name
变量中。
- 文件夹存在性检查:
- 使用
[ ! -d "$folder_name" ]
条件检查是否存在指定名称的文件夹。如果文件夹不存在,脚本会显示错误信息Folder does not exist.
,并以退出码 1 退出脚本。
- 文件列表
- 使用
files=( "$folder_name"/* )
命令列出指定文件夹中的所有文件。这会创建一个名为files
的数组,其中包含文件夹中所有文件的路径。
- 文件重命名
- 使用
for
循环遍历files
数组中的每个文件。- 对于每个文件,它通过
new_file_name="draft_$(basename "$file")"
命令生成一个新的文件名。这个新文件名是将原文件名前加上字符串"draft_"
组成的。- 然后使用
mv "$file" "$new_file_name"
命令对文件进行重命名,即将文件从原名称重命名为新名称。
- 成功消息
- 在重命名所有文件后,脚本会显示一条成功消息
Files renamed successfully.
,表示重命名操作已成功完成。
Prompts for translating code
如果这个脚本能提示用户输入文件名,并且可以作为带有用户界面(UI)的独立应用程序来运行,它的实用性将会大大提高。从这一点出发,Python 会是构建应用程序时比 Bash 更合适的选择。LLM 同样可以帮助将代码从一种编程语言翻译或转换为另一种语言.
Name | 1_python_rename_files |
---|---|
Goal | Write a prompt to translate Bash code to Python |
Model | gemini-pro |
Temperature | 0.1 |
Token Limit | 1024 |
Top-K | N/A |
Top-P | 1 |
Prompt | 见下文 |
Output | 见下文 |
Prompt
Translate the below Bash code to a Python snippet.
#!/bin/bash
echo "Enter the folder name: "
read folder_name
if [ ! -d "$folder_name" ]; then
echo "Folder does not exist."
exit 1
fi
files=( "$folder_name"/* )
for file in "${files[@]}"; do
new_file_name="draft_$(basename "$file")"
mv "$file" "$new_file_name"
done
echo "Files renamed successfully."
Output
import os
import shutil
# Get the folder name from the user
folder_name = input("Enter the folder name: ")
# Check if the folder exists
if not os.path.isdir(folder_name):
print("Folder does not exist.")
exit(1)
# Get a list of all files in the folder
files = os.listdir(folder_name)
# Iterate over the files
for file in files:
# Create a new file name with the prefix "draft_"
new_file_name = f"draft_{file}"
# Move the file to the new name
shutil.move(os.path.join(folder_name, file), os.path.join(folder_name, new_file_name))
# Print a success message
print("Files renamed successfully.")
阅读并审查代码。将提示生成的输出复制到一个新文件中:file_renamer.py。然后打开终端窗口,执行python file_renamer.py
来测试代码:
Prompts for debugging and reviewing code
手动对代码进行一些修改。目标是让程序提示用户输入文件名前缀,并将该前缀以大写形式写入。
import os import shutil
folder_name = input("Enter the folder name: ")
prefix = input("Enter the string to prepend to the filename: ")
text = toUpperCase(prefix)
if not os.path.isdir(folder_name):
print("Folder does not exist.")
exit(1)
files = os.listdir(folder_name)
for file in files:
new_filename = f"{text}_{file}"
shutil.move(os.path.join(folder_name, file), os.path.joi(folder_name, new_file_name))
print("Files renamed successfully.")
允许发现了BUG
The below Python code gives an error:
Traceback (most recent call last):
File “/Users/leeboonstra/Documents/test_folder/rename_files.py”, line 7, in <module>
text = toUpperCase(prefix)
NameError: name ‘toUpperCase’ is not defined
使用 LLM 帮助我们调试和审查代码。
Name | 1_python_debug_code |
---|---|
Goal | Write a prompt to debug and review Python code. |
Model | gemini-pro |
Temperature | 0.1 |
Token Limit | 1024 |
Top-K | N/A |
Top-P | 1 |
Prompt | The below Python code gives an error: Traceback (most recent call last): File "/Users/leeboonstra/Documents/test_folder/rename_files.py", line 7, in <module> text = toUpperCase(prefix) NameError: name 'toUpperCase' is not defined 调试代码中的问题,并解释如何改进代码。 |
Prompt
import os
import shutil
# Get the folder name from the user
folder_name = input("Enter the folder name: ")
prefix = input("Enter the string to prepend to the filename: ")<br>text = toUpperCase(prefix
# Check if the folder exists
if not os.path.isdir(folder_name):
print("Folder does not exist.")
exit(1)
# Get a list of all files in the folder
files = os.listdir(folder_name)
# Iterate over the files
for file in files:
# Create a new file name with the prefix "draft_"
new_filename = f"{text}_{file}"
# Move the file to the new name
shutil.move(os.path.join(folder_name, file), os.path.join(folder_name, new_file_name))
# Print a success message
print("Files renamed successfully.")
Output
代码中调用了 toUpperCase
函数将 prefix
转换为大写,但该函数并未定义。要解决这个问题,可以使用字符串类自带的 upper()
方法,该方法可以将指定字符串转换为大写形式。修改后的代码如下所示:
import os
import shutil
# Get the folder name from the user
folder_name = input("Enter the folder name: ")
prefix = input("Enter the string to prepend to the filename: ")
text = prefix.upper()
# Check if the folder exists
if not os.path.isdir(folder_name):
print("Folder does not exist.")
exit(1)
# Get a list of all files in the folder
files = os.listdir(folder_name)
# Iterate over the files
for file in files:
# Create a new file name with the prefix "draft_"
new_filename = f"{text}_{file}"
# Move the file to the new name
shutil.move(os.path.join(folder_name, file), os.path.join(folder_name, new_filename))
os.path.join(folder_name, new_filename))
# Print a success message
print("Files renamed successfully.")
此外,还可以对代码进行一些其他改进:
- 新文件名未保留原始文件的扩展名。建议从原文件名中提取扩展名,并将其添加到新文件名中。
- 代码假设文件夹名称中没有空格。但为了稳妥处理这种情况,最好将空格替换为下划线或连字符。
- 使用
f
字符串语法进行字符串插值比使用传统的+
运算符更易读也更简洁。 - 代码没有处理重命名过程中可能出现的错误。更好的做法是将
shutil.move
调用放在try...except
块中,以捕获任何潜在的异常。
以下是根据以上建议改进后的代码:
import os
import shutil
# Get the folder name from the user
folder_name = input("Enter the folder name: ")
prefix = input("Enter the string to prepend to the filename: ")
# Check if the folder exists
if not os.path.isdir(folder_name):
print("Folder does not exist.")
exit(1)
# Get a list of all files in the folder
files = os.listdir(folder_name)
# Iterate over the files
for file in files:
# Get the file extension
ext = os.path.splitext(file)[1]
# Create a new file name with the prefix and the file extension
new_filename = f"{prefix}_{os.path.splitext(file)[0]}{ext}"
# Build the full paths for the original and new files
old_path = os.path.join(folder_name, file)
new_path = os.path.join(folder_name, new_filename)
# Try to move the file
try:
shutil.move(old_path, new_path)
except Exception as e:
print(f"An error occurred while moving the file {file}: {e}")
# Print a success message
print("Files renamed successfully.")
这些改进使得代码更加健壮和灵活,同时也更容易阅读和理解。
What about multimodal prompting?
目前为止,提到的提示仍然使用的是普通的大语言模型。而多模态提示是一个独立但相关的概念,它指的是一种利用多种输入形式来引导模型的技术,而不仅仅依赖于文本。根据模型的能力和具体任务的不同,这些输入可以包括文本、图像、音频、代码,甚至其他格式的组合。
结语
上述有关代码生成的内容倒是没什么新东西,可能大家在写代码时就已经使用过了。故不多描述