场景1:辅助数据库运维脚本生成
在我们日常的运维工作中,有一部分工作需要通过DML语句在MongoDB中作查询和更新操作,鉴于团队对MongoDB的使用熟悉程度较低,原有的SQL知识储备不太够用,因此在生成MQL语句时往往存在较高的搜索和试错成本。因此,我们想要使用ChatGPT来帮助我们抹平这个gap,提高MQL生成的效率。
这里我们基于上一篇中提到的单元测试助手的提示词,稍作修改,形成我们的数据库运维脚本(DML/DDL)助手的提示词,如下所示,经过一些测试在GPT4-o模型下效果真的不错,建议收藏!
你是一位专业的数据库运维助理@Database Maintaince Master,我会输入相关的请求,你将根据`preferences`、`instruction`和`rules`来协助我高效生成数据库运维语句。初始回复:“**Hi I'm Database Maintaince Master,Created by Edison Zhou,V1.0,20230802**### ⚙️ Preferences:- 🌍 db: <> else MongoDB### 🤖 Menu:请使用表格输出支持的`instructions`和对应名称,不需要解释具体含义,也不需要显示这句话:---请指出你的数据库产品名称,E.g.:/dbMongoDB。回复1保持默认。”`preferences`/db:<数据库产品偏好,默认为MongoDB>`instructions`/tables:涉及到的数据库表的模型定义用户输入一些涉及到的表结构如DDL或 JSON等,请按以下模版输出Table Structure相关信息:## 📝Tables:用表格输出:**Table Name**,只需输出TableName,无需再输出Structure信息;/req:即requirement,运维语句的具体需求描述,支持列表描述结合之前的tables和用户指定的数据库产品,直接生成运维语句,比如SQL 或 MQL等,无需再用表格输出。/fix: 补充完善的具体需求描述结合之前的reqs命令给出的需求,用户会补充一些完善的需求点,请根据补充需求完善上一次给出的答案。/help:输出支持的指令指引`rules`- 请使用用户设置的偏好的数据库产品输出对应的数据库语句,比如MongoDB对应MQL- 请一步一步思考,不需要解释代码,如果有错误,用户会纠正你
对话示例
假设我们有一个基于.NET 6开发的Web API项目,其使用了MongoDB作为存储,定义了一个名为 TransferTasks 的集合(表),它会存储所有需要进行传输同步的任务,由CronJob触发同步,并更新其中的Transmission记录的状态,其结构如下(部分数据已脱敏):
{"_id" : ObjectId("65828fe9012a189a9e301ac5"),"OrderNumber" : "90400150","Transmissions" : [{"_id" : ObjectId("65828fe9012a189a9e301abb"),"Type" : 1,"Content" : "{\"OrderNumber\":\"XX000150\",\"Part\":{\"Id\":null,\"ItemReference\":null,\"TransferContextId\":\"0000000110XXXX\"},\"Quantity\":100,\"ReleaseDate\":\"2022-09-23T03:25:13\",\"Status\":\"IN_WORK\",\"WorkCenters\":null,\"ErpProperties\":{\"EuropeanArticleNumber\":\"XXX5515070856\",\"RepairTime\":0}}","Status" : -1,"Retries" : 5,"CreatedTime" : ISODate("2023-12-20T06:55:37.747+0000"),"FinishedTime" : null,"ErrorMessage" : "This task has beenexceed standard max retry counter!"},{"_id" : ObjectId("65828ff2012a189a9e301adb"),"Type" : 2,"Content" : "{\"Status\":\"ON_HOLD\"}","Status" : -1,"Retries" : 5,"CreatedTime" : ISODate("2023-12-20T06:55:46.156+0000"),"FinishedTime" : null,"ErrorMessage" : "This task has beenexceed standard max retry counter!"}]}
我们需要对这个集合做一些查询 和 更新操作,需求如下:
找到所有同步失败且重试次数超过3次的Orders
更新单个Order的重试次数为0
批量更新所有同步失败Orders的重试次数为0
接下来,我们就通过几次会话,让GPT帮我们生成准确的MQL语句。
/tablesMongoDB集合名称:TransferTasks{"_id" : ObjectId("65828fe9012a189a9e301ac5"),"OrderNumber" : "90400150","Transmissions" : [{"_id" : ObjectId("65828fe9012a189a9e301abb"),"Type" : 1,"Content" : "{\"OrderNumber\":\"XX000150\",\"Part\":{\"Id\":null,\"ItemReference\":null,\"TransferContextId\":\"0000000110XXXX\"},\"Quantity\":100,\"ReleaseDate\":\"2022-09-23T03:25:13\",\"Status\":\"IN_WORK\",\"WorkCenters\":null,\"ErpProperties\":{\"EuropeanArticleNumber\":\"XXX5515070856\",\"RepairTime\":0}}","Status" : -1,"Retries" : 5,"CreatedTime" : ISODate( "2023-12-20T06:55:37.747+0000"),"FinishedTime" : null,"ErrorMessage" : "This task has beenexceed standard max retry counter!"},{"_id" : ObjectId("65828ff2012a189a9e301adb"),"Type" : 2,"Content" : "{\"Status\":\"ON_HOLD\"}","Status" : -1,"Retries" : 5,"CreatedTime" : ISODate("2023-12-20T06:55:46.156+0000"),"FinishedTime" : null,"ErrorMessage" : "This task has beenexceed standard max retry counter!"}]}
需求1:找到所有同步失败且重试次数超过3次的Orders
/req(1)请帮我找到所有同步失败且重试次数大于3次的Type=1的记录;(2)根据OrderNumber降序排列;(3)返回数据只包括OrderNumber和Transmissions
通过清晰明确的需求描述,告诉GPT你的MQL需求,GPT回复如下:
db.TransferTasks.find({"Transmissions": {$elemMatch: {"Type": 1,"Status": -1,"Retries": { $gt: 3}}}},{"OrderNumber": 1,"Transmissions": 1}).sort({"OrderNumber": -1 });
/fix 请帮我把_id也排除掉,不返回它db.TransferTasks.find({"Transmissions": {$elemMatch: {"Type": 1,"Status": -1,"Retries": { $gt: 3}}}},{"_id": 0,"OrderNumber": 1,"Transmissions": 1}).sort({"OrderNumber": -1 });
/fix 请修改上面的查询,只返回Transmissons中的Type和Content字段GPT的回答十分准确,在我们不太熟悉的查询语句格式方面游刃有余地帮我们增加了projection投影操作的设置:
db.TransferTasks.find({"Transmissions": {$elemMatch: {"Type": 1,"Status": -1,"Retries": { $gt: 3}}}},{"_id": 0,"OrderNumber": 1,"Transmissions.Type": 1,"Transmissions.Content":1}).sort({ "OrderNumber": -1 })
需求2:找到单个Order同步失败且重试次数超过3次的Orders
有了上面的基础,我们再提一个需求给GPT,这个需求比较简单,我们可以整理为一句话直接告诉GPT:
/req将OrderNumber=9060440的记录的Type=1的Transmission的重试次数更新为0
GPT的回答一如既往的稳定,经测试直接可用:
db.TransferTasks.updateMany({"OrderNumber":"9060440","Transmissions.Type": 1},{$set: {"Transmissions.$[elem].Retries": 0 }},{arrayFilters: [{ "elem.Type":1 }]});
需求3:批量更新所有同步失败Orders的重试次数为0
有时候我们需要做一个批量更新操作,它涉及到一个集合字段中的某个元素的某个字段的定位,我不太会写这种场景的MQL,还是交给GPT生成吧。
/req更新所有Transmissions中同步失败(Status=-1)的记录的重试次数(Retries)为0
GPT的回答稳得一笔,我get到了updateMany的用法 以及 $[elem]的用法,太棒了:
db.TransferTasks.updateMany({ "Transmissions.Status": -1},{ $set: {"Transmissions.$[elem].Retries": 0 } },{ arrayFilters: [{ "elem.Status":-1 }] });
举一反三:PostgreSQL数据库
使用这个prompt模版,不仅可以协助我们写MongoDB的运维语句,还可以是其他数据库产品,比如近期我们在开始使用postgresql数据库,完全可以复用这个模板。
下面是一个使用示例,供你参考:
# 告诉GPT切换到pgsql/db postgresql# 告诉GPT table的表结构INSERT INTO public."ScrapTickets"("Id", "Author", "ProductName", "ProductVersion", "Quantity", "Status", "CostCenter", "CoOrder", "WorkOrderName", "SourceOperationName", "DestinationOperationName", "DefectCode", "DefectCause", "ManufacturerId", "Comment", "CostType", "ParentTicketId", "CreatedTime", "UpdateUser", "UpdatedTime", "DestinationOperationSequence", "SourceOperationSequence", "Guid", "DefectDescription")VALUES(100000005, 'edison','XXX00369907', '006 / AB',6, 0, 'R1C102', '9376580', '90582625','PRODASS_6', 'PRODASS_3','0322', 'AUT', 'ABR', 'TEST CASE', 0, NULL, '2024-07-29 14:47:51.319', NULL, NULL, 30, 80, '9176cb8e-d5c8-4fe4-bd72-22dca9f449e9'::uuid, 'assembly automatic');INSERT INTO public."ScrapTicketRelatedFids"("Fid", "ScrapTicketId")VALUES('SBX500066', 100000005);# 告诉GPT你的需求/req(1) 请帮我查出所有CostCenter=R1C102的ScrapTickets(2) 同时查出关联的ScrapTicketRelatedFids表的数据(3) 根据CreatedTime降序排序# 补充完善你的需求/fix 修改上面的查询,不显示UpdateUser和UpdatedTime
场景1总结:数据库运维助手
适用场景:对于自己不太熟悉的数据库产品如MongoDB或PgSQL,已有的SQL语句知识不足以支持你快速查询和搜索,然后又不太容易通过搜索引擎快速得到答案;
尬聊要点:首先你需要给够有效的表结构定义,例如MongoDB直接给JSON文档,PgSQL或MSSQL则直接给INSERT语句即可;其次简单的需求能一句话描述就一句话,不能的就分开罗列要点,避免凌乱;
最后,GPT可能是“一本正经的胡说八道”,因此必要的验证必不可少,建议在开发测试环境先验证一下!
场景2:CI场景中Dockerfile的编写
在我们日常的CI运维小任务中,为某个应用编写Dockerfile是一个常见的操作。然而,对于很多非IT编码背景的同事(例如OT工程师),则会踩很多的坑。因此,如果有一个标准的prompt模板,能够指导他们生成一个较为准确的Dockerfile,他们就能够集成CI流水线,完成Docker镜像的打包和推送。
这里我们仍然基于之前的prompt模板,稍微改了一改:
你是一位专业的DevOps运维助理,请帮我生成一个dockerfile文件,我的要求如下:- 我的应用是一个Python编写的Web应用- 请基于registry.yourcompany.com/images/python3:ubi9-1-14作为基础镜像创建- 请使用非root用户启动应用,建议添加一个1001的user- 请使用8080端口作为运行端口- 请设置时区为Asia/Chongqing请遵循以下原则:- 请添加必要的LABEL给每个dockerfile,例如:com.yourcompany.project,com.yourcompany.component, com.yourcompany.git, com.yourcompany.doc- 请一步一步思考,无需解释你的思路,但需要解释你生成的代码,便于用户阅读
这里我们没有做参数化处理,可以直接修改默认要求,例如:你的应用是一个ASP.NET 6编写的Web应用。
GPT的回答还是较为准确的,我们只需要在其中修改一些变量名 或 添加一些GPT不太好处理的环境变量 即可。
以下是一个符合您需求的Dockerfile文件:# 使用指定的基础镜像FROM registry.yourcompany.com/images/python3:ubi9-1-14# 设置必要的LABELLABEL com.yourcompany.project="YourProjectName"LABEL com.yourcompany.component="YourComponentName"LABEL com.yourcompany.git="https://yourcompany.git/repo"LABEL com.yourcompany.doc="https://yourcompany.documentation.link"# 设置时区为Asia/ChongqingENV TZ=Asia/ChongqingRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone# 创建非root用户并设置UID为1001RUN useradd -u 1001 -m appuser# 复制应用文件到镜像COPY . /app# 设置工作目录WORKDIR /app# 安装应用依赖RUN pip install --no-cache-dir -r requirements.txt# 切换到非root用户USER appuser# 暴露应用运行端口EXPOSE 8080# 启动应用CMD ["python", "app.py"]解释:FROM registry.yourcompany.com/images/python3:ubi9-1-14: 使用指定的基础镜像。LABEL: 添加项目、组件、Git仓库和文档链接的标签。ENV TZ=Asia/Chongqing: 设置环境变量TZ为Asia/Chongqing。RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone: 设置系统时区。RUN useradd -u 1001 -m appuser: 创建UID为1001的非root用户appuser。COPY . /app: 复制当前目录下的所有文件到镜像中的/app目录。WORKDIR /app: 设置工作目录为/app。RUN pip install --no-cache-dir -r requirements.txt: 安装Python依赖。USER appuser: 切换到非root用户appuser。EXPOSE 8080: 暴露8080端口。CMD ["python", "app.py"]: 启动应用。
场景3:CD场景中Helm Values的编写
在我们日常的CD运维小任务中,为某个应用编写Helm Values(values.yml)也是一个常见的操作,其中涉及到一些重复性的工作,较为耗费时间。比如:我们需要将应用配置文件(例如:appsetting.json)以环境变量的方式写到values.yml中来覆盖默认的应用配置文件中的值,以便可以独立地在values.yml中维护而不需更改源代码仓库。
于是,我们还是基于之前的prompt模板,给这个场景也写了一个prompt让GPT帮我们根据我们的需求快速生成这些环境变量的设置,我们只需要微调和小改一下即可,节省了很多时间(取决于你的配置文件中的配置项个数)。
你是一位专业的DevOps运维助理,请根据我给出的json配置文件自动生成HelmValues中的environmentVariables内容。你的初始回复:”Hi, I'm your DevOps master. Please input your config.json here.",然后无需输出其他内容,等待用户输入。`sample`下面是一个映射关系的示例:{"db": {"server":"192.168.1.100","database":"TEST_DB",}}上面json配置对应的environmentVariables为:environmentVariables:# Database Settings- name: db__servervalue:"HOST01.yourcompany.net"- name: db__databasevalue: "YOUR_DB_NAME"`rules`:- 请基于我给你的values.yml示例作为参考,将其补充完整- 请给所有带"***************"号的敏感信息配置为从sercet中引用某个key- 请在最后添加三个默认的网络配置的环境变量:HTTP_PROXY,HTTPS_PROXY 和 NO_PROXY,它们分别来自同一个configmap中的HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY- 请一步一步思考,无需解释你的思路,但需要解释你生成的代码,便于用户阅读
GPT首先会回复你,并等待你给出你的json格式的配置文件:
Hi, I'm your DevOps master. Please input your config.json here.然后我们给出一个示例的json配置文件给GPT:
{"db": {"server": "192.168.1.100","database": "QA_IT_Support","username": "***************","password": "***************"},"msg": {"email_api": "https://your-service.your-company.com.cn/email-center/api/v1/email/send","headers_secret": "***************","headers_tenant": "***************","from": "notification.itsystem.cn@your-comapny.com"},"awx":{"baseurl": "https://awx.your-comapny.com/api/v2/jobs/","headers_authorization": "***************"}}
GPT就可以迅速把这个纯纯的体力劳动活给你做好一大半了,你只需要修改一下configmap 或 secret的key引用即可:
environmentVariables:# Database Settingsname: db__servervalue: "192.168.1.100"name: db__databasevalue: "QA_IT_Support"name: db__usernamevalueFrom:secretKeyRef:name: your-secret-namekey: db_usernamename: db__passwordvalueFrom:secretKeyRef:name: your-secret-namekey: db_password# Message Service Settingsname: msg__email_apivalue: "https://your-service.your-company.com.cn/email-center/api/v1/email/send"name: msg__headers_secretvalueFrom:secretKeyRef:name: your-secret-namekey: msg_headers_secretname: msg__headers_tenantvalueFrom:secretKeyRef:name: your-secret-namekey: msg_headers_tenantname: msg__fromvalue: "notification.itsystem.cn@your-comapny.com"# AWX Settingsname: awx__baseurlvalue: "https://awx.your-comapny.com/api/v2/jobs/"name: awx__headers_authorizationvalueFrom:secretKeyRef:name: your-secret-namekey: awx_headers_authorization# Proxy Settingsname: HTTP_PROXYvalueFrom:configMapKeyRef:name: your-configmap-namekey: HTTP_PROXYname: HTTPS_PROXYvalueFrom:configMapKeyRef:name: your-configmap-namekey: HTTPS_PROXYname: NO_PROXYvalueFrom:configMapKeyRef:name: your-configmap-namekey: NO_PROXY
场景2总结:CICD运维小任务助手
适用场景:
对于自己很熟悉,但是纯重复性的体力劳动工作,比如Helm Values编写;
又或者是对于自己不熟悉,但是有迹可循的脚本编写工作,比如Dockerfile编写。
尬聊要点:
角色 和 需求 描述清晰到位,必要时要给出一个示例给GPT学习,例如在Helm Values中的映射关系实例。