mirror of
https://github.com/guohuadeng/app-odoo.git
synced 2025-02-23 04:11:36 +02:00
prepare #I6SC9C 处理azure私聊群聊,app_chatgpt优化,指定用户时增加使用情况
This commit is contained in:
@@ -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',
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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 |
Reference in New Issue
Block a user