prepare #I6SC9C 处理azure私聊群聊,app_chatgpt优化,指定用户时增加使用情况

This commit is contained in:
ivan deng
2023-04-13 08:39:24 +08:00
parent 753fea8ebb
commit 99d5005e4d
4 changed files with 57 additions and 52 deletions

View File

@@ -10,7 +10,7 @@
{ {
'name': 'Latest ChatGPT4 AI Center. GPT 4 for image, Dall-E Image.Multi Robot Support. Chat and Training', 'name': 'Latest ChatGPT4 AI Center. GPT 4 for image, Dall-E Image.Multi Robot Support. Chat and Training',
'version': '16.23.03.31', 'version': '16.23.04.13',
'author': 'Sunpop.cn', 'author': 'Sunpop.cn',
'company': 'Sunpop.cn', 'company': 'Sunpop.cn',
'maintainer': 'Sunpop.cn', 'maintainer': 'Sunpop.cn',

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import openai.openai_object
import requests, json import requests, json
import openai import openai
from odoo import api, fields, models, _ from odoo import api, fields, models, _
@@ -70,8 +70,8 @@ GPT-3 A set of models that can understand and generate natural language
Reduce the chance of repeating a token proportionally based on how often it has appeared in the text so far. Reduce the chance of repeating a token proportionally based on how often it has appeared in the text so far.
This decreases the likelihood of repeating the exact same text in a response. This decreases the likelihood of repeating the exact same text in a response.
""") """)
# 避免使用生僻词 # 越大模型就趋向于生成更新的话题,惩罚已经出现过的文本
presence_penalty = fields.Float('Presence penalty', default=0.2, presence_penalty = fields.Float('Presence penalty', default=0.5,
help=""" help="""
Reduce the chance of repeating any token that has appeared in the text at all so far. Reduce the chance of repeating any token that has appeared in the text at all so far.
This increases the likelihood of introducing new topics in a response. This increases the likelihood of introducing new topics in a response.
@@ -128,25 +128,28 @@ GPT-3 A set of models that can understand and generate natural language
return False return False
def get_ai_post(self, res, author_id=False, answer_id=False, **kwargs): def get_ai_post(self, res, author_id=False, answer_id=False, **kwargs):
if res and isinstance(res, dict): if res and author_id and isinstance(res, openai.openai_object.OpenAIObject) or isinstance(res, list):
data = res['content'].replace(' .', '.').strip() usage = json.loads(json.dumps(res['usage']))
if 'usage' in res: content = json.loads(json.dumps(res['choices'][0]['message']['content']))
usage = res['usage'] data = content.replace(' .', '.').strip()
if usage:
# todo: 不是写到 user ,是要写到指定 m2m 相关模型, 如: res.partner.ai.use
user_id = author_id.mapped('user_ids')[:1]
prompt_tokens = usage['prompt_tokens'] prompt_tokens = usage['prompt_tokens']
completion_tokens = usage['completion_tokens'] completion_tokens = usage['completion_tokens']
total_tokens = usage['total_tokens'] total_tokens = usage['total_tokens']
vals = { vals = {
'human_prompt_tokens': author_id.human_prompt_tokens + prompt_tokens, 'human_prompt_tokens': user_id.human_prompt_tokens + prompt_tokens,
'ai_completion_tokens': author_id.ai_completion_tokens + completion_tokens, 'ai_completion_tokens': user_id.ai_completion_tokens + completion_tokens,
'tokens_total': author_id.tokens_total + total_tokens, 'tokens_total': user_id.tokens_total + total_tokens,
'used_number': author_id.used_number + 1, 'used_number': user_id.used_number + 1,
} }
if not author_id.first_ask_time: if not user_id.first_ask_time:
ask_date = fields.Datetime.now() ask_date = fields.Datetime.now()
vals.update({ vals.update({
'first_ask_time': ask_date 'first_ask_time': ask_date
}) })
author_id.write(vals) user_id.write(vals)
# res = self.filter_sensitive_words(data) # res = self.filter_sensitive_words(data)
else: else:
data = res data = res
@@ -204,32 +207,33 @@ GPT-3 A set of models that can understand and generate natural language
stop = ["Human:", "AI:"] stop = ["Human:", "AI:"]
# 以下处理 open ai # 以下处理 open ai
if self.ai_model in ['gpt-3.5-turbo', 'gpt-3.5-turbo-0301']: if self.ai_model in ['gpt-3.5-turbo', 'gpt-3.5-turbo-0301']:
messages = [{"role": "user", "content": data}] # 基本与 azure 同,要处理 api_base
openai.api_key = self.openapi_api_key
openai.api_base = o_url.replace('/chat/completions', '')
if isinstance(data, list):
messages = data
else:
messages = [{"role": "user", "content": data}]
# Ai角色设定 # Ai角色设定
sys_content = self.get_ai_system(kwargs.get('sys_content')) sys_content = self.get_ai_system(kwargs.get('sys_content'))
if sys_content: if sys_content:
messages.insert(0, sys_content) messages.insert(0, sys_content)
pdata = { response = openai.ChatCompletion.create(
"model": self.ai_model, model=self.ai_model,
"messages": messages, messages=messages,
"temperature": self.temperature or 0.9, n=1,
"max_tokens": self.max_tokens or 1000, temperature=self.temperature or 0.9,
"top_p": self.top_p or 0.6, max_tokens=self.max_tokens or 600,
"frequency_penalty": self.frequency_penalty or 0.5, top_p=self.top_p or 0.6,
"presence_penalty": self.presence_penalty or 0.2, frequency_penalty=self.frequency_penalty or 0.5,
"stop": stop presence_penalty=self.presence_penalty or 0.5,
} stop=stop,
_logger.warning('=====================open input pdata: %s' % pdata) request_timeout=self.ai_timeout or 120,
response = requests.post(o_url, data=json.dumps(pdata), headers=headers, timeout=R_TIMEOUT) )
try: if 'choices' in response:
res = response.json() return response
if 'choices' in res: else:
# for rec in res: _logger.warning('=====================Openai output data: %s' % response)
# res = rec['message']['content']
res = '\n'.join([x['message']['content'] for x in res['choices']])
return res
except Exception as e:
_logger.warning("Get Response Json failed: %s", e)
elif self.ai_model == 'dall-e2': elif self.ai_model == 'dall-e2':
# todo: 处理 图像引擎,主要是返回参数到聊天中 # todo: 处理 图像引擎,主要是返回参数到聊天中
# image_url = response['data'][0]['url'] # image_url = response['data'][0]['url']
@@ -285,20 +289,21 @@ GPT-3 A set of models that can understand and generate natural language
response = openai.ChatCompletion.create( response = openai.ChatCompletion.create(
engine=self.engine, engine=self.engine,
messages=messages, messages=messages,
# 返回的回答数量
n=1,
temperature=self.temperature or 0.9, temperature=self.temperature or 0.9,
max_tokens=self.max_tokens or 600, max_tokens=self.max_tokens or 600,
top_p=self.top_p or 0.6, top_p=self.top_p or 0.6,
frequency_penalty=self.frequency_penalty or 0.5, frequency_penalty=self.frequency_penalty or 0.5,
presence_penalty=self.presence_penalty or 0.2, presence_penalty=self.presence_penalty or 0.5,
stop=stop, stop=stop,
request_timeout=self.ai_timeout or 120, request_timeout=self.ai_timeout or 120,
) )
if 'choices' in response: if 'choices' in response:
res = response['choices'][0]['message'] return response
return res
else: else:
_logger.warning('=====================azure output data: %s' % response) _logger.warning('=====================azure output data: %s' % response)
return _('Azure no response') return _("Response Timeout, please speak again.")
@api.onchange('provider') @api.onchange('provider')
def _onchange_provider(self): def _onchange_provider(self):

View File

@@ -32,18 +32,18 @@ class Channel(models.Model):
if self.channel_type in ['group', 'channel']: if self.channel_type in ['group', 'channel']:
# 群聊增加时间限制,当前找所有人,不限制 author_id # 群聊增加时间限制,当前找所有人,不限制 author_id
domain += [('date', '>=', afterTime)] domain += [('date', '>=', afterTime)]
ai_msg_list = message_model.with_context(tz='UTC').search(domain, order="id desc", limit=chat_count) ai_msg_list = message_model.with_context(tz='UTC').search(domain, order="id desc", limit=chat_count)
for ai_msg in ai_msg_list: for ai_msg in ai_msg_list:
user_content = ai_msg.parent_id.description.replace("<p>", "").replace("</p>", "").replace('@%s' % answer_id.name, '').lstrip() user_content = ai_msg.parent_id.description.replace("<p>", "").replace("</p>", "").replace('@%s' % answer_id.name, '').lstrip()
ai_content = str(ai_msg.body).replace("<p>", "").replace("</p>", "").replace("<p>", "") ai_content = str(ai_msg.body).replace("<p>", "").replace("</p>", "").replace("<p>", "")
context_history.insert(0, { context_history.insert(0, {
'role': 'assistant', 'role': 'assistant',
'content': ai_content, 'content': ai_content,
}) })
context_history.insert(0, { context_history.insert(0, {
'role': 'user', 'role': 'user',
'content': user_content, 'content': user_content,
}) })
return context_history return context_history
def get_ai_response(self, ai, messages, channel, user_id, message): def get_ai_response(self, ai, messages, channel, user_id, message):

Binary file not shown.

Before

Width:  |  Height:  |  Size: 964 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB