本文正在参加金石计划附加挑战赛——第一期命题
写在开始
大家都知道,在处理国际业务时,面对多语种用户群体,有时需要借助翻译工具来进行代码开发。那么,如何利用现有的资源高效地处理多语言业务呢?答案是:构建一个基于AI的语言处理器,并通过调用OpenAI接口来迅速应对代码中的多语言需求。接下来,我们将通过一个简单的例子来说明这一过程。
"La performance du systeme est plus lente que d'habitude.", /// 系统的性能比平时慢
"Mi monitor tiene pixeles que no se iluminan.", // 我的显示器有些像素不亮
"Il mio mouse non funziona", // 我的鼠标不工作了
"M6j klawisz Ctrl jest zepsuty", // 我的Ctrl键坏了
朋友们,上面的句子是英文吗?
实际上并不是。这些句子分别来自意大利语、法语和西班牙语。当遇到这样的情况时,如果不知道原文是什么语言,直接使用翻译工具可能会面临挑战,因为需要先确定源语言才能准确翻译。但是,现在有了AI的帮助,我们可以轻松解决这个问题。 下面,就让我们来看看如何将AI翻译功能集成到我们的代码中,实现无缝多语言支持。
出海“AI翻译”
1.环境搭建
1.Node.js环境下创建LLM项目的代码工程:
- 打开之前安装过 OpenAI 的项目的
package.json,将其中的dependencies: {}部分(即项目运行时所依赖的npm包)拷贝到我们新项目的package.json中。代码:
"dependencies": {
"dotenv": "^16.4.5",
"openai": "^4.73.0"
},
- 再输入
npm i这样就可以搭建好了。
2.使用dotenv管理环境变量
使用dotenv是程序员安全意识的一个重要体现,因为我们的 key 等重要信息不能以明文出现,所以我们通过使用dotenv 在项目的根目录下创建一个名为.env的文件来存储配置信息(如API密钥等敏感数据),这些信息不会被提交到git等之中,这样就可以保证我们敏感信息的安全性。
接下来我们就来演示如何正确地使用dotenv:
import dotenv from "dotenv";:导入dotenv模板。- 创建
.env文件,并且将我们的 key 放入其中。 dotenv.config();:将.env读入process.env对象中。
这样我们就可以安全的调用key ,通过process.env来获取key。
实战步骤:
- 1.创建函数,并且用户提供prompt 生成响应
// es6 默认参数值
// 通用的LLM 聊天完成接口函数, 复用
// 封装 通用大模型聊天接口函数,初始化聊天接口,
const getCompletion = async (prompt, model="gpt-3.5-turbo") => {
// 用户提的问题
const messages = [{
role: 'user',
content: prompt
}];
// AIGC chat 接口
//
const response = await client.chat.completions.create({
model: model,
messages: messages,
// LLM 生成内容的随机性
temperature: 0.9
})
// 解析返回结果 js对象里面的结果
return response.choices[0].message.content
}
- 2.重点部分,处理用户信息,使用异步进行处理“翻译这个过程”。这段代码套用其他业务也是可以的
const main = async () => {
const user_messages = [
"La performance du système est plus lente que d'habitude.", //系统的性能比平时慢
"Mi monitor tiene píxeles que no se iluminan.", //我的显示器有些像素点不亮。
"Il mio mouse non funziona", // 我的鼠标坏了
"Mój klawisz Ctrl jest zepsuty", // 我的Ctrl键坏了
"我的屏幕在闪烁"
]
// for of es6遍历:
for(let issue of user_messages) {
const resultPrompt = `请翻译为中文语: ${issue}`;
const result = await getCompletion(resultPrompt)
console.log(`意思是:${result}`);
}
}
结果:
- 同样可以增加语言判断,使用async 和await异步调用getCompletion函数
const main = async () => {
const user_messages = [
"La performance du système est plus lente que d'habitude.", //系统的性能比平时慢
"Mi monitor tiene píxeles que no se iluminan.", //我的显示器有些像素点不亮。
"Il mio mouse non funziona", // 我的鼠标坏了
"Mój klawisz Ctrl jest zepsuty", // 我的Ctrl键坏了
"我的屏幕在闪烁"
]
// for of es6遍历:
for(let issue of user_messages) {
const resultPrompt = `请翻译为中文语: ${issue}`;
const result = await getCompletion(resultPrompt)
console.log(`语句意思是:${result}`);
}
const prompt = `
Tell me what language this is "${user_messages}"
`
const countryLanguage = await getCompletion(prompt);
const resultPrompt = `
帮我翻译以下文字到中文,"${countryLanguage}"
`
const result = await getCompletion(resultPrompt)
console.log(`是${countryLanguage},翻译结果是:${result}`);
}
使用下面完整代码试一下吧
import OpenAI from "openai";
import dotenv from "dotenv";
dotenv.config() // 读取.env 配置内容到possess.env文件中
// promise 进程对象,
const client = new OpenAI({
// node 里的进程对象
apiKey: process.env.OPENAI_API_KEY,
baseURL:process.env.OPENAI_BASE_URL
})
// es6 默认参数值
// 通用的LLM 聊天完成接口函数, 复用
// 封装 通用大模型聊天接口函数,初始化聊天接口,
const getCompletion = async (prompt, model="gpt-3.5-turbo") => {
// 用户提的问题
const messages = [{
role: 'user',
content: prompt
}];
// AIGC chat 接口
//
const response = await client.chat.completions.create({
model: model,
messages: messages,
// LLM 生成内容的随机性
temperature: 0.9
})
// 解析返回结果 js对象里面的结果
return response.choices[0].message.content
}
const main = async () => {
const user_messages = [
"La performance du système est plus lente que d'habitude.", //系统的性能比平时慢
"Mi monitor tiene píxeles que no se iluminan.", //我的显示器有些像素点不亮。
"Il mio mouse non funziona", // 我的鼠标坏了
"Mój klawisz Ctrl jest zepsuty", // 我的Ctrl键坏了
"我的屏幕在闪烁"
]
// for of es6遍历:
for(let issue of user_messages) {
const resultPrompt = `请翻译为中文语: ${issue}`;
const result = await getCompletion(resultPrompt)
console.log(`语句意思是:${result}`);
}
const prompt = `
Tell me what language this is "${user_messages}"
`
const countryLanguage = await getCompletion(prompt);
const resultPrompt = `
帮我翻译以下文字到中文,"${countryLanguage}"
`
const result = await getCompletion(resultPrompt)
console.log(`是${countryLanguage},翻译结果是:${result}`);
}
main();
- 思考: 为什么for变量设定的变量,外部result不能访问?
- 词法作用域与块级作用域就很好理解,下面用代码实例进行解释
啥咋解释!?
词法作用域是在编译时决定的,而不是在运行时。这意味着变量的作用范围是在编写代码时就已经确定好了。
不清楚执行上下文和执行栈的伙伴可以看下链接转换台
示例分析
考虑以下代码段:
function foo() {
var a = 1;
let b = 2;
// 块级作用域
{
let b = 3;
var c = 4;
let d = 5;
console.log(a); // 输出: 1
console.log(b); // 输出: 3
}
console.log(b); // 输出: 2
console.log(c); // 输出: 4
// console.log(d); // 抛出错误: ReferenceError: d is not defined
}
foo();
在这个例子中,我们观察到了几个关键点:
- 变量提升:
var声明的变量会被提升至函数作用域的顶部,这意味着a和c实际上在整个foo函数体内都是可访问的。 - 块级作用域:
let和const引入了块级作用域的概念,即它们只在声明它们的{}块内有效。因此,虽然b被重新声明为3并且只在块内可见,但在块外部调用b时,输出的是最外层声明的2。 - 暂时性死区 (Temporal Dead Zone, TDZ) :尝试在
let或const变量声明前访问它们会导致错误。这是因为这些变量在初始化之前处于一个“暂时性死区”。例如,如果我们在{}块外尝试访问d,将会抛出ReferenceError。
暂时性死区 (TDZ)
另一个示例更好地展示了暂时性死区的概念:
console.log(a, func); // undefined, [Function: func]
// console.log(b); // 抛出错误: ReferenceError: Cannot access 'b' before initialization
var a = 1;
function func() {}
let b = 2;
b++; // 正常操作
console.log(b); // 输出: 3
在这个例子中:
var a声明的变量a被提升到了全局作用域的顶部,所以在首次console.log(a)时,输出undefined,因为此时a已经存在但还未被赋值。let b声明的变量b由于 TDZ 的存在,在其声明之前尝试访问会引发错误。func函数声明也会被提升,所以即使在实际声明之前调用func,也不会有问题。
执行上下文还可以看下面图文和代码进行理解:
var myname = 'lisi';
function bar() {
console.log(myname);
}
function foo() {
var myname = 'zhangsan';
console.log(myname);
}
bar();
foo();
(小声bb)这样看来接管海外外包,指日可待,AI出海趁了一波人工智能红利~~