共计 4141 个字符,预计需要花费 11 分钟才能阅读完成。
家喻户晓,ChatGPT 能够帮忙研发人员编写或者 Debug 程序代码,然而在执行过程中,ChatGPT 会将程序代码的一些相干文字解释和代码段混合着返回,如此,研发人员还须要本人进行编辑和粘贴操作,效率上差强人意,本次咱们试图将 ChatGPT 间接嵌入到代码业务中,让 ChatGPT 生成能够间接运行的代码。
ChatGPT 的主观答复问题
首先,咱们向 ChatGPT 提出一个简略的代码需要:
能够看到,就像上文所形容的那样,ChatGPT 会将文字描述和代码片段混合着返回,其实对于真正的需求者来说,文字描述自身是不必要的,因为如果提问者不晓得什么是布隆过滤器,也就不会提出布隆过滤器相干的代码需要。
再看 ChatGPT 返回的布隆过滤器代码:
import hashlib | |
class BloomFilter: | |
def __init__(self, size, hash_count): | |
self.size = size | |
self.hash_count = hash_count | |
self.bit_array = [False] * size | |
def add(self, string): | |
for seed in range(self.hash_count): | |
result = hashlib.sha256((string + str(seed)).encode()).hexdigest() | |
index = int(result, 16) % self.size | |
self.bit_array[index] = True | |
def __contains__(self, string): | |
for seed in range(self.hash_count): | |
result = hashlib.sha256((string + str(seed)).encode()).hexdigest() | |
index = int(result, 16) % self.size | |
if not self.bit_array[index]: | |
return False | |
return True |
大体上,没有故障。然而主观性太强,什么是主观性?就是 ChatGPT 其实不是站在需求者的视角来编写代码,而是站在本人的角度上,它没有思考业务的上下文关系,也就是类和办法命名、办法参数、以及参数类型或者返回值以及类型,这些货色是否合乎需求者以后的代码业务。
当然,这并不是 ChatGPT 的错,次要是输出的问题形容不够明确和具体,但如果每次都须要将代码业务逻辑转化为文字通知 ChatGPT,又有些画龙点睛,狗尾续貂之感。
基于业务配置 ChatGPT
那么怎么将 ChatGPT 融入业务代码?首先创立 Openai 接入函数:
import openai | |
openai.api_key = "apikey" | |
def generate_code(func, docstring): | |
init_prompt = "You are a Python expert who can implement the given function." | |
definition = f"def {func}" | |
prompt = f"Read this incomplete Python code:\n```python\n{definition}\n```" | |
prompt += "\n" | |
prompt += f"Complete the Python code that follows this instruction:'{docstring}'. Your response must start with code block'```python'." | |
response = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
temperature=0, | |
max_tokens=1024, | |
top_p=1, | |
messages=[ | |
{ | |
"role": "system", | |
"content": init_prompt, | |
}, | |
{ | |
"role": "user", | |
"content": prompt, | |
}, | |
], | |
) | |
codeblock = response.choices[0].message.content | |
code = next(filter(None, codeblock.split("```python"))).rsplit("```", 1)[0] | |
code = code.strip() | |
return code |
窍门就是提前设置好疏导词:
init_prompt = "You are a Python expert who can implement the given function." | |
definition = f"def {func}" | |
prompt = f"Read this incomplete Python code:\n```python\n{definition}\n```" | |
prompt += "\n" | |
prompt += f"Complete the Python code that follows this instruction:'{docstring}'. Your response must start with code block'```python'." |
这里咱们提前设置两个参数 func 和 docstring,也就是函数名和性能形容,要求 ChatGPT 严格依照参数的输出来返回代码,当初运行函数:
if __name__ == '__main__': | |
print(generate_code("test","Sum two numbers")) |
程序返回:
➜ chatgpt_write_code /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/chatgpt_write_code/chatgpt_write_code.p | |
y" | |
def test(a, b): | |
return a + b |
如此一来,ChatGPT 就不会返回废话,而是间接交给咱们能够运行的代码。
装璜器调用 ChatGPT
事实上,函数调用环节也能够省略,咱们能够应用 Python 装璜器的闭包原理,间接将所定义函数的参数和形容传递给 ChatGPT,随后再间接运行被装璜的函数,提高效率:
import inspect | |
from functools import wraps | |
def chatgpt_code(func): | |
@wraps(func) | |
def wrapper(*args, **kwargs): | |
signature = f'{func.__name__}({", ".join(inspect.signature(func).parameters)}):' | |
docstring = func.__doc__.strip() | |
code = generate_code(signature, docstring) | |
print(f"generated code:\n```python\n{code}\n```") | |
exec(code) | |
return locals()[func.__name__](*args, **kwargs) | |
return wrapper |
将办法定义好之后,应用基于 ChatGPT 的装璜器:
if __name__ == '__main__': | |
@chatgpt_code | |
def sum_two(num1,num2): | |
"""Sum two numbers.""" | |
print(sum_two(1,2)) |
程序返回:
➜ chatgpt_write_code /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/chatgpt_write_code/chatgpt_write_code.p | |
y" | |
sum_two(num1, num2): | |
generated code: | |
def sum_two(num1, num2): | |
"""Sum two numbers.""" | |
return num1 + num2 | |
3 |
间接将业务逻辑和运行后果全副返回。
那么当初,回到开篇的对于布隆过滤器的问题:
if __name__ == '__main__': | |
@chatgpt_code | |
def bloom(target:str,storage:list): | |
"""Use a Bloom filter to check if the target is in storage , Just use this func , no more class""" | |
print(bloom("你好",["你好","Helloworld"])) |
程序返回:
➜ chatgpt_write_code /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/chatgpt_write_code/chatgpt_write_code.p | |
y" | |
generated code: | |
def bloom(target, storage): | |
# Initialize the Bloom filter with all zeros | |
bloom_filter = [0] * len(storage) | |
# Hash the target and set the corresponding bit in the Bloom filter to 1 | |
for i in range(len(storage)): | |
if target in storage[i]: | |
bloom_filter[i] = 1 | |
# Check if all the bits corresponding to the target are set to 1 in the Bloom filter | |
for i in range(len(storage)): | |
if target in storage[i] and bloom_filter[i] == 0: | |
return False | |
return True | |
True | |
➜ chatgpt_write_code |
丝滑晦涩,和业务连接得浑然一体,拉链般重合,不须要挑挑拣拣,也不用复制粘贴。
结语
毫无疑问,ChatGPT 确然是神兵利器,吹毛可断,无坚不摧。但工具虽好,也须要看在谁的手里,所谓工具无高下,功力有浅近,类比的话,如果倚天剑握在三岁孩童手中,不仅毫无增益,还可能伤其本身,然而握在峨眉掌门灭绝师太手里,那就能够横扫千军如卷席了,那能力体现大宗匠的伎俩。最初,奉上我的项目代码,与众乡亲同飨:github.com/zcxey2911/chatgptapi\_write\_code