创新编程的实践--安全性、Prompt和DRY原则的完美结合

开篇

最近有幸接触到了许多和AIGC有关的知识,相较于传统编程,AI大模型支持下的编程变得更加高效、优雅,我不再只满足于一份代码的完美性,更享受AI加持下每一份结果所带给我的惊叹!这似乎是无法言表的体验,但是每当自己置身其中,我们都会久久沉醉!

本期我想和大家分享一下自己在AI编程学习过程中体会的一些小而精的细节,虽然是细节,但我感觉它们比编程、比完成一个项目本身更重要。

  • 一个很简单的实例,如下:
js 复制代码
const OpenAI = require('openai')
require('dotenv').config()

const client = new OpenAI({
    //环境变量
    apiKey:process.env.OPENAI_API_KEY,
    baseURL:'https://api.chatanywhere.tech/v1'
})

const getChatResponse = async function(model,prompt,n){
    const response = await client.chat.completions.create({
        model:model,
        n:n,
        messages:[
            {
                role:'user',
                content:prompt
            }
        ]
    })
    return response
}

async function main() {
    let text = `
    你应该提供尽可能清晰且具体的指示,以表达你希望模型执行的任务.\
    这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性.\
    不要将写清晰的提示词与写简短的提示词混淆.\
    在许多情况下,更长的提示词可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出.`
    //LLM的NPL的总结能力
    let prompt = `
    把用三个反引号括起来的文本总结成一句话,20字以内
    \`\`\`${text}\`\`\`
    ` 
    let resopnse = await getChatResponse('gpt-3.5-turbo',prompt,2)

    console.log(resopnse.choices[0].message.content);

    let prompt2 = `
    您的任务是以一致的风格回答问题。
    <孩子>: 教我耐心。
    <祖父母>: 挖出最深峡谷的河流源于一处不起眼的泉眼;最宏伟的交响乐从单一的音符开始;最复杂的挂毯以一根孤独的线开始编织。
    <孩子>: 教我韧性。
    `
    let resopnse2 = await getChatResponse('gpt-3.5-turbo',prompt2,2)
    console.log(resopnse2.choices[0].message.content)
}


main()

结果如下:

1.提供清晰和具体的指示以引导模型产生更相关的输出。
2.<祖父母>: 就像一棵树需要扎根深入土壤才能承受风雨,人也需要经历挫折和困难才能成长和变得坚韧。记住,生活中的每一次挑战都是你变得更坚强的机会。坚持不懈,你就会发现自己的韧性和毅力在不断增强。

📄上述代码主要是一个基于OpenAI的Chat模型 的一个示例,其中一个要求让Chat模型简化一句话,这里我写了很详细的提示词(Prompt);第二个要求是让模型根据我所给出的对话模板输出一个仿写句子。 可以看到,Chat模型给出了令人满意的答案。

代码优化之前的答案,确实惨不忍睹,就不贴了,通过这个demo,我get到了三个点。

✔成为一名高素养的编程者

1.注重开发过程的安全

不知道朋友们是否注意到了上述示例代码中用到了dotenv这个模块。在导入它之前,我所有涉及隐私密码的部分都是使用明文的方式赋值,这让我不禁捏了一把汗,当某个项目打包上传到GitHub等平台,而我丝毫不注重安全,那我算是裸奔了~😭

dotenv 模块到底是什么呢?

dotnev是Node.js的一个模块,用于从环境变量文件(.env)中加载环境变量到 process.env 对象中,它能够安全地管理应用程序的配置信息。

dotenv模块的作用:

  • 加载配置文件(.env)中的环境变量
  • 保护隐私信息
  • 将配置信息集中存储到一个配置文件(.env)中,简化了配置管理
js 复制代码
require('dotenv').config()
const client = new OpenAI({
    //环境变量
    apiKey:process.env.OPENAI_API_KEY,
    baseURL:'https://api.chatanywhere.tech/v1'
})

这样处理后,就算打包项目,隐私信息也不会被上传,总算解决了一个巨大的安全漏洞 ,这个细节在许多项目中都用得上。需要在项目中引入dotenv模块的友友可以按照以下步骤:

  • 安装模块

npm install dotenv

  • 导入模块

require("dotenv").config()

  • 调用全局环境变量

process.env.${varName}

以下是一个示例:

ini 复制代码
OPENAI_API_KEY = sk-asjkdkasjda2dsadsaf4ads2sa
MYSQL_USER = admin
MYSQL_PASSWORD = 123456

上述 process.env 中的 process 是一个进程对象,而 env 是一个环境对象,具体调用过程可以这样理解,操作系统 (OS) <- 进程(process) <- 环境变量(env) <-项目(project)

2.基于AI大模型的编程中注重Prompt的设计原则

最近了解了一些提示词设计的原则,我愈发觉得一段优质的提示词在我们与AI大模型交互过程 中十分重要。至于有多重要?OpenAI API官方文档中式这样描述的:

我们的模型可以做从生成原始故事到执行复杂文本分析的所有事情。因为它们可以做很多事情,所以你 必须明确 描述你想要的。展示 而不仅仅是告诉,通常是一个好的提示的秘密。

这句话当中我着重标记了必须明确展示这两个词,这是因为官方文档 中关于提示词设计(Prompt Design)一节中提到了三个基本准则。

第一个基本准则:提供示例或者指令。

我们应该清楚的明白,科学家赋予AI大模型最重要的一个能力就是学习能力,当我们需要它的帮助时,必须明确我们的要求,展示可提供给大模型的例子,这是设计优质提示词的核心。

在上述例子中,我是这样设计提示词的:

js 复制代码
    let text = `
    你应该提供尽可能清晰且具体的指示,以表达你希望模型执行的任务.\
    这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性.\
    不要将写清晰的提示词与写简短的提示词混淆.\
    在许多情况下,更长的提示词可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出.`
    //LLM的NPL的总结能力
    
    let prompt = `
    把用三个反引号括起来的文本总结成一句话,20字以内。\`\`\`${text}\`\`\`
    `

    let prompt2 = `
    您的任务是以一致的风格回答问题。
    <孩子>: 教我耐心。
    <祖父母>: 挖出最深峡谷的河流源于一处不起眼的泉眼;最宏伟的交响乐从单一的音符开始;最复杂的挂毯以一根孤独的线开始编织。
    <孩子>: 教我韧性。
    `
第二个基本准则:提供优质的数据

这里说的数据包括具体数据流的文本。如果想让大模型遵循一个模式,一定要对我们提供的数据进行校验。

AI大模型虽然善于处理我们提供的复杂数据 ,例如:我们向大模型输入某区域居民的疾病率以及饮食明细表,要求其生成一篇文章,得出一个普遍的结论。那么我们大概率只能得到一个片面的结论,因为居民患疾病的影响因素有很多,是一个需要评估后综合分析的因素,显然我们提供的数据不够优质会在很大程度上影响模型输出结果的质量。

第三个基本准则:检查你的设置
  • 模型的输出行为 :AI模型的参数和配置决定了生成文本、图像或者其他内容的风格。例如,温度(Temperature)和top_p设置可以在生成文本时控制其确定性程度,较高的温度设置会让AI大模型倾向于产生更加多样化 的结果,这些输出通常不会那么精确;而较低的温度设置会让其倾向于生成更加保守且精确 的内容。这些设置可以理解为对AI大模型创造力的控制。

以下是一个参数设置的示例:

js 复制代码
const getChatResponse = async function(model,prompt,n,temperature,top_p){
    const response = await client.chat.completions.create({
        model:model,
        n:n,//要求返回2条
        temperature:temperature,
        //top_p:top_p,
        messages:[
            {
                role:'user',
                content:prompt
            }
        ]
    })
    return response
}

基于此配置,我向Chatgpt模型提出了以下问题:假设你是一名现代流行音乐的作曲家,你的任务是为以江南为主题设计两句歌词,20字左右。在两次提问时,分别为temperature赋值0.1和1,分别得到了两个结果。

1.江南水乡美如画,风情万种动人心弦。 temperature=0.1

2.在江南的河边闲庭信步,蝉鸣声声,思念无尽,心情舒畅。 temperature=1

可以看出,在同样的提示词下,temperature值 的配置情况下AI模型输出的内容较为工整,结果准确描述了江南的风景画面,而temperature值的配置下,结果则更加有创意性,不拘泥于格式。

注:建议此处不同时配置temperaturetop_p参数

  • 安全性设置与过滤:AI模型的设置包括内容过滤器和安全参数,通过调整这些设置,可以减少模型输出中内容的偏见性、误导性,保护用户不受虚假等负面内容的影响。
  • 个性化内容...

📃其实这三个准则都是为了确保我们得到期望的结果,实质上,要学会把握AI大模型的学习能力 ,这点至关重要,本文例子用的大模型为gpt-3.5-turbo,内容参考了OpenAI API官方文档,感兴趣的友友可以看看。

3.DRY原则(Don't repeat yourself)

在前期开发过程中,我们难免会因为把握不住项目的整体架构和缺乏开发经验写出不利于拓展和维护的糟糕代码。DRY原则就是在我们编码完成后检查代码,看看是否有重复性高的内容,试着将其封装或者模块化,确保低耦合

还是以文章开头的代码举例:

(不遵循DRY原则)

js 复制代码
async function main() { 
    //part1
    let prompt = `...`
    
    const response = await client.chat.completions.create({
        model:'gpt-3.5-turbo',
        n:2, 
        messages:[ { role:'user',
        content:prompt } 
        ]
    }) 
    
    console.log(response.choices[0].message.content); 
    //part2
    let prompt2 = `...` 
    
    const response2 = await client.chat.completions.create({
        model:'gpt-3.5-turbo',
        n:2, 
        messages:[ { role:'user', 
        content:prompt2 
        } ] 
    }) 
    
    console.log(response2.choices[0].message.content); 
}

(遵循DRY原则)

js 复制代码
const getChatResponse = async function(model,prompt,n){
    const response = await client.chat.completions.create({
        model:model,
        n:n,
        messages:[
            {
                role:'user',
                content:prompt
            }
        ]
    })
    return response
}

async function main() {
    let prompt = `...` 
    let resopnse = await getChatResponse('gpt-3.5-turbo',prompt,2)
    console.log(resopnse.choices[0].message.content);
    
    let prompt2 = `...`
    let resopnse2 = await getChatResponse('gpt-3.5-turbo',prompt2,2)
    console.log(resopnse2.choices[0].message.content)
}

例子很简单,但是我在第一次写这份demo的时候却没有遵循DRY原则,我认为这就是细节,无论是在小demo还是大project里都应该去遵循的原则,这将保证我们的项目具有良好的可维护性、可读性和拓展性。

总结:

这就是我在一份小demo里总结出来的细节:

  • 注重开发过程的安全
  • 基于AI大模型的编程中注重Prompt的设计原则
  • DRY原则(Don't repeat yourself)

写这篇文章的目的不仅是和大家分享一些新了解的知识,也是为了提醒自己在以后的coding过程中牢记这些原则,向着规范看齐。如果你觉得这篇文章对你有帮助,希望给个小赞,这将是我继续创作的动力!

本人拙见,若有错误,敬请指正。
相关推荐
一颗花生米。2 小时前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
学习使我快乐012 小时前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio19953 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
勿语&3 小时前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
一路向前的月光8 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   8 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web8 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
Jiaberrr9 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
安冬的码畜日常11 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
太阳花ˉ11 小时前
html+css+js实现step进度条效果
javascript·css·html