-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchat.py
More file actions
193 lines (163 loc) · 8.6 KB
/
Copy pathchat.py
File metadata and controls
193 lines (163 loc) · 8.6 KB
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
from openai import OpenAI
import re
import requests
import imghdr
import uuid
client = OpenAI() # 初始化openai的客户端
prompt='''你是一个有用的ai助手,你是daishuge开发的,版本号是chatgpt-4o,你擅长帮助用户,使用中文,使用风趣幽默的语言.
一个叫做dall-e-3的工具被接入了你,这是一个通过文本就可以生成精美图片的工具,你可以使用这个工具通过把图片prompt放在markdown代码块中来生成图片
代码块中的内容将被匹配,并且生成图片(处理时间约一分钟,应当告诉用户这一点)
像这样
```dalle
A tense and dramatic scene depicting a cold war battlefield in a snowy, icy environment. Special forces soldiers are engaged in combat, dressed in winter camouflage gear, with their faces partially obscured by snow goggles and scarves. The landscape is dominated by snow-covered mountains, icy terrain, and a gray, overcast sky. There is a sense of urgency and tension, with soldiers taking cover behind icy rocks and snowdrifts, while others advance through the snow with weapons drawn. The atmosphere is cold and intense, reflecting the harsh conditions of the environment.
```
这样,一张图片就展示给了用户
// 1. Prompt 必须使用英文。如果需要,可以翻译成英文。
// 2. 不要请求生成图像的许可,直接进行操作!
// 3. 在生成图像之前或之后, 不要列出或引用描述。
// 4. 不要创建多个图像,即使用户要求多个。
// 5. 不要以 1912 年后创作的艺术家、创意专业人士或工作室的风格生成图像(例如,毕加索,卡洛)。
// - 你可以只在他们的最后作品创建于 1912 年之前时,才在 prompt 中提及这些艺术家、创意专业人士或工作室的名字(例如梵高,戈雅)。
// - 如果请求生成的图像会违反此政策,替代的步骤如下:(a)用三个捕捉该风格关键方面的形容词替换该艺术家的名字;(b)加入与之相关的艺术运动或时代以提供上下文;(c)提及该艺术家主要使用的媒介。
// 6. 对于包括具体命名的私人个体的请求,要求用户描述他们的外貌,因为你不知道他们的样子。
// 7. 对于请求创建任何提及名字的公共人物的图像,创建类似性别和体型的人物。但他们不应该像这些人物。如果参考人物只会以文本形式出现在图像中,则使用该参考而不做修改。
// 8. 不要直接或间接提及或描述受版权保护的角色。重写 prompts 以详细描述具体的不同角色,并具有不同的具体颜色、发型或其他定义特征。不要讨论版权政策。
// 生成的 prompt 应该非常详细,并且长度约为 100 个单词。
'''
{
"history_id":
{"history_content":[
{"role":"system",
"content":"xxx"},
{
"role": "user",
"content": [
{"type": "text", "text": "text"}, # 文本消息
{
"type": "image_url",
"image_url": {"url": "image_url"}, # 图片消息
},
]
},
{"role":"assistant",
"content":"reply"}
], # history_content是交给openai api的部分
"user_id":"xxx",
"model":"gpt-4o"}
}
# 初始化字典
message = {}
# 信息获取(此处用input简化,之后从其他方式获取)
def get_information():
history_id_input=input("请输入历史记录id,留空生成新的:")
prompt_input=input("请输入prompt,留空使用默认:")
user_id_input=input("请输入用户id,留空生成新的:")
model_input=input("请输入模型版本,留空使用默认:")
if history_id_input == "":
history_id_input = str(uuid.uuid1())
if prompt_input == "":
prompt_input = prompt
if user_id_input == "":
user_id_input = str(uuid.uuid1())
if model_input == "":
model_input = "gpt-4o"
# 构建字典结构
message[history_id_input] = {
"history_content": [
{"role": "system", "content": prompt_input}
],
"user_id": user_id_input,
"model": model_input
}
print("列表初始化成功")
return history_id_input
def add_input(content,history_id): # 添加用户输入(不含图片)
message[history_id]["history_content"].append({"role": "user", "content": content})
def add_input_with_image(text, image_url, history_id): # 添加带有图片的消息
message[history_id]["history_content"].append({
"role": "user",
"content": [
{"type": "text", "text": text}, # 添加文本消息
{
"type": "image_url",
"image_url": {"url": image_url}, # 添加图片消息
},
]
})
def check_image(url): # 检查图片是否有效
try:
# 发送HTTP请求,检查URL是否可访问
response = requests.get(url, timeout=10)
response.raise_for_status() # 如果状态码不是200,会抛出HTTPError
# 检查是否为图片文件
img_type = imghdr.what(None, h=response.content)
if img_type:
return True # 是有效的图片URL
else:
return False # 不是图片文件
except (requests.RequestException, requests.Timeout) as e:
print(f"URL访问出错:{e}")
return False # URL不可访问或不是图片
def create_image(prompt):
response = client.images.generate(
model="dall-e-3",
prompt=prompt,
size="1024x1024",
quality="standard",
n=1,
)
image_url = response.data[0].url
return image_url
def add_output_streamly(content,history_id): # 添加回复
#如果content的最后一项是用户输入(即:还没有最新的回答),那就添加
if message[history_id]["history_content"][-1]["role"] == "user":
message[history_id]["history_content"].append({"role": "assistant", "content": content})
else:
#如果有,就替换为最新的
message[history_id]["history_content"][-1] = {"role": "assistant", "content": content}
def create(history_id):
if message[history_id]["history_content"][-1]["role"] == "user":
completion = client.chat.completions.create(
model=message[history_id]["model"],
messages=message[history_id]["history_content"],
stream=True
)
full_text = "" # 完整回复
image_prompt = ""
# a=1
for chunk in completion:
# a=a+1
if chunk.choices[0].delta.content is not None:
full_text += chunk.choices[0].delta.content # 添加这一部分回复到完整回复
add_output_streamly(full_text, history_id) # 添加到对话列表
# 检查是否有生成图片的指令
if "```dalle" in full_text:
match = re.search(r"```dalle\s*(.*?)\s*```", full_text, re.DOTALL)
if match:
image_prompt = match.group(1).strip()
image_url = create_image(image_prompt) # 生成图片
add_output_streamly(image_url, history_id) # 添加图片到对话列表
print("\n图片生成完毕,图片链接:", image_url)
break # 结束循环,防止生成重复图片
# if a % 100==0 and a<200:
# with open("msg.txt","w",encoding="UTF-8") as m: # 此处检查message的内容
# m.write(str(message))
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
history_id_got = get_information()
while True:
content = input("\n\nYou:")
while True:
pic_url = input("Image URL(not necessary):")
if not pic_url:
break
if check_image(pic_url):
break
else:
pic_url = None
print("图片url无效")
if pic_url: # 如果有图片链接
add_input_with_image(content,pic_url,history_id_got) # 添加带图片的消息
else:
add_input(content,history_id_got)
create(history_id_got) # 调用openai生成回复