正如你所知,ChatGPT将颠覆简单的程序员。因此,我尝试了一下完全使用ChatGPT开发云应用的情况。( 实际上我使用了带有GPT-4模式的ChatGPT Plus。)
总结
ChatGPT对于加速我们在开始阶段的开发速度非常有用。但是,当我们无法充分使用ChatGPT(实际上不仅仅是ChatGPT还包括其他的AI)时,GIGO(垃圾进垃圾出)定律是真实的。这取决于我们如何充分利用ChatGPT。
前提条件
这一次,我创建了几个代码来爬取Amazon产品页面。但是,Amazon禁止了爬取,我在开始之前没有注意到这一点。
概观
我向ChatGPT发送了以下消息(用日语),这对于人力开发人员来说也显得太粗糙了:)
你是一名软件工程师,需要创建一个应用程序,可以通知特定产品的价格将要变化,并通知我。
# 规格说明。
1. 在开发中使用以下技术。
1) 处理:Python
A) 从数据库中读取产品代码并访问Amazon产品页。
B) 从产品页检索价格并将其与上一价格进行比较。
C) 如果价格低于上一个价格,请在Slack上通知。
2) 数据库:MySQL
DB中存储以下内容。
A) 产品代码
B) 产品价格(先前价格)
3) 价格更改时的通知目的地:Slack
2. 该应用程序应为在AWS EC2上运行的独立应用程序。
3.该程序将每小时启动一次。
# 交付成果
1. 数据库建立DDL。
2. Python程序。
3. 用于在EC2上构建它们的CloudFormation模板。
输出代码应为可复制格式。
简单的应用程序结构如下。
ChatGPT的答复
有几个小错误在我进行了审查后,ChatGPT帮我进行了纠正,但几乎是这个结果。乍一看,这似乎是正确的,甚至有点可怕。并且还可以生成CloudFormation (CFn)模板,这使我感到惊讶。
(底部包含所需的通信详细信息。)
DDL:
CREATE TABLE `product_price` (
`product_code` varchar(50) NOT NULL,
`price` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`product_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Python代码(现在已禁止Amazon页面爬取,因此我删除了相关代码)
import os
import boto3
import requests
from bs4 import BeautifulSoup
import pymysql
import logging
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
region_name = os.environ["AWS_REGION"]
ssm = boto3.client("ssm", region_name=region_name)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Database connection information
DB_ENDPOINT = ssm.get_parameter(Name='/cgpt-amazon-price-alert/db-endpoint', WithDecryption=True)['Parameter']['Value']
DB_USER = ssm.get_parameter(Name='/cgpt-amazon-price-alert/db-user', WithDecryption=True)['Parameter']['Value']
DB_PASSWORD = ssm.get_parameter(Name='/cgpt-amazon-price-alert/db-password', WithDecryption=True)['Parameter']['Value']
DB_NAME = ssm.get_parameter(Name='/cgpt-amazon-price-alert/db-name', WithDecryption=True)['Parameter']['Value']
# Slack Bot connection information
SLACK_BOT_TOKEN = ssm.get_parameter(Name='/cgpt-amazon-price-alert/slack-bot-token', WithDecryption=True)['Parameter']['Value']
SLACK_CHANNEL = ssm.get_parameter(Name='/cgpt-amazon-price-alert/slack-channel', WithDecryption=True)['Parameter']['Value']
# Database connection
conn = pymysql.connect(host=DB_ENDPOINT, user=DB_USER, password=DB_PASSWORD, database=DB_NAME)
# Slack Notify
def notify_slack(message):
try:
client = WebClient(token=SLACK_BOT_TOKEN)
response = client.chat_postMessage(channel=SLACK_CHANNEL, text=message)
except SlackApiError as e:
logger.error("Error sending message: {}".format(e.response['error']))
def get_price(url):
### Deleted because scraping Amazon website is prohibited now. ###
def main():
# Get product information from Database
cursor = conn.cursor()
cursor.execute("SELECT product_code, price FROM product_price")
rows = cursor.fetchall()
# Get Amazon product price and compare with previous one.
for row in rows:
# Get the price from Amazon
product_code, previous_price = row
url = f"https://www.amazon.co.jp/dp/{product_code}"
current_price = get_price(url)
# Comparing with previous price
if current_price < previous_price:
message = f"Product {product_code} price was lower than before. Previous price: {previous_price} Yen, Current price: {current_price} Yen"
notify_slack(message)
# Update DB product information.
cursor.execute("UPDATE products SET price=%s WHERE product_code=%s", (current_price, product_code))
conn.commit()
if __name__ == "__main__":
main()
SSM的必要密钥注册:
aws ssm put-parameter \
--name "/cgpt-amazon-price-alert/db-endpoint" \
--value "your_db_endpoint" \
--type "SecureString"
aws ssm put-parameter \
--name "/cgpt-amazon-price-alert/db-user" \
--value "your_db_username" \
--type "SecureString"
aws ssm put-parameter \
--name "/cgpt-amazon-price-alert/db-password" \
--value "your_db_password" \
--type "SecureString"
aws ssm put-parameter \
--name "/cgpt-amazon-price-alert/db-name" \
--value "your_db_name" \
--type "SecureString"
aws ssm put-parameter \
--name "/cgpt-amazon-price-alert/slack-bot-token" \
--value "your_slack_bot_token" \
--type "SecureString"
aws ssm put-parameter \
--name "/cgpt-amazon-price-alert/slack-channel" \
--value "your_slack_channel" \
--type "SecureString"
CloudFormation模板:
---
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: "VPC ID"
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: "Subnet ID"
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Metadata:
AWS::CloudFormation::Init:
config:
commands:
01_install_mysql:
command: |
amazon-linux-extras install -y epel
yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
yum --nogpgcheck install -y mysql-community-server
systemctl start mysqld
systemctl enable mysqld
02_generate_password:
command: |
echo $(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}') > /tmp/mysql_root_password
03_install_slack_sdk:
command: |
yum install -y python3-pip
pip3 install slack-sdk
04_install_beautifulsoup4:
command: |
pip3 install beautifulsoup4
05_install_lxml:
command: |
pip3 install lxml
06_install_requests:
command: |
pip3 install requests
services:
sysvinit:
mysqld:
enabled: true
ensureRunning: true
Properties:
ImageId: ami-05b5badc2f7ddd88d
InstanceType: t3.micro # Instance Type
KeyName: cgpt-amazon-price-alert-key # Keypair name for connection to EC2 instance.
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo "export AWS_REGION=${AWS::Region}" >> /etc/profile.d/aws_region.sh
chmod +x /etc/profile.d/aws_region.sh
source /etc/profile.d/aws_region.sh
/opt/aws/bin/cfn-init --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region}
yum update -y
yum install -y python3
pip3 install boto3
pip3 install pymysql
pip3 install slack-sdk
mkdir /app
touch /app/check_price.py
touch /var/log/check_price.log
chown ec2-user:ec2-user /var/log/check_price.log
echo '*/1 * * * * ec2-user /usr/bin/python3 /app/check_price.py' > /etc/cron.d/check_price-cron
IamInstanceProfile: !Ref InstanceProfile
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: 0
GroupSet:
- !Ref InstanceSecurityGroup
SubnetId: !Ref SubnetId
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow SSH access
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref InstanceRole
InstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: SSMParameterAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ssm:GetParameter
Resource: "*"
我使用ChatGPT准备MySQL DB初始化所需的时间比较长,因此我使用ChatGPT创建了shell脚本。(实际上以下代码有一些不安全的部分"密码直接输入",最好不要使用。)
#!/bin/bash
# Variables
initial_password="your_initial_password"
new_password="your_new_password"
# Log in to MySQL and execute commands
mysql -u root -p"${initial_password}" <<EOF
-- Change the initial password
ALTER USER 'root'@'localhost' IDENTIFIED BY '${new_password}';
-- Create the amazonprice database
CREATE DATABASE amazonprice;
-- Use the amazonprice databse
USE amazonprice;
-- Create the product_price table
CREATE TABLE product_price (
product_code VARCHAR(50) NOT NULL,
price DECIMAL(10,2) DEFAULT NULL,
PRIMARY KEY (product_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Insert sample data into the product_price table
INSERT INTO product_price (product_code, price) VALUES ('your_price_code', 1000.00);
EOF
它们的执行过程:
chmod +x setup_mysql.sh
./setup_mysql.sh
结论
如我在开头所提到的,这似乎是一个非常强大的服务,可以增加开发的初始速度。然而,如果你试图做比提高初始速度更多的事情,那么将会花费很多时间,所以现在,我认为最好在开发的早期使用它。
需要注意的是,代码完成了很多我想要指出的内容,例如在UserData中挖掘根目录中的文件夹,只有root可以访问它,或异常处理等等。我没有用它来得到报酬。
(附录)我需要与ChatGPT多次通信的内容
开始时我提到的第一条消息中有几个不完整的部分。因此,我多次与ChatGPT进行沟通以提高质量。
总的来说,我与ChatGPT的通信达到了40到50次。
以下是我多次交流的主要部分。
- 像DB_ENDPOINT这样的值被定义在环境变量中。 →改进以从SSM获取它们。
- CFT(CloudFormation Template)中有关所需库的安装描述不够详细。
- VPC / Subnet等没有被描述,因此无法生成CFn堆栈。
- 多次通信后,之前的修改点下降了。 我不想做到这样类似于人:)
- MySQL安装未包含在CFn模板中。
- 存在"Userdata"中未列出Metadata的问题,因此未执行Metadata部分。
- MySQL安装中有几个错误,包括GPG密钥错误。
- 缺少访问AWS资源的区域规范和附加到EC2的IAM角色设置。
- 即使Amazon有反爬虫措施,ChatGPT也提供了爬虫代码。(在这种情况下,我没有修改代码来使用Amazon API,但是如果我明确指定要使用AmazonAPI,ChatGPT可以生成它。)