Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
5249297c
authored
Mar 27, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: bill logs
parent
9280a21d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
160 additions
and
152 deletions
+160
-152
src/pages/api/chat/chatGpt.ts
+7
-7
src/pages/api/chat/gpt3.ts
+7
-7
src/service/events/generateAbstract.ts
+38
-44
src/service/events/generateQA.ts
+43
-36
src/service/events/pushBill.ts
+64
-57
src/service/response.ts
+1
-1
No files found.
src/pages/api/chat/chatGpt.ts
View file @
5249297c
...
@@ -148,13 +148,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -148,13 +148,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const
promptsContent
=
formatPrompts
.
map
((
item
)
=>
item
.
content
).
join
(
''
);
const
promptsContent
=
formatPrompts
.
map
((
item
)
=>
item
.
content
).
join
(
''
);
// 只有使用平台的 key 才计费
// 只有使用平台的 key 才计费
!
userApiKey
&&
pushChatBill
({
pushChatBill
({
isPay
:
!
userApiKey
,
modelName
:
model
.
service
.
modelName
,
modelName
:
model
.
service
.
modelName
,
userId
,
userId
,
chatId
,
chatId
,
text
:
promptsContent
+
responseContent
text
:
promptsContent
+
responseContent
});
});
}
catch
(
err
:
any
)
{
}
catch
(
err
:
any
)
{
if
(
step
===
1
)
{
if
(
step
===
1
)
{
// 直接结束流
// 直接结束流
...
...
src/pages/api/chat/gpt3.ts
View file @
5249297c
...
@@ -149,13 +149,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -149,13 +149,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
stream
.
destroy
();
stream
.
destroy
();
// 只有使用平台的 key 才计费
// 只有使用平台的 key 才计费
!
userApiKey
&&
pushChatBill
({
pushChatBill
({
isPay
:
!
userApiKey
,
modelName
:
model
.
service
.
modelName
,
modelName
:
model
.
service
.
modelName
,
userId
,
userId
,
chatId
,
chatId
,
text
:
promptText
+
responseContent
text
:
promptText
+
responseContent
});
});
}
catch
(
err
:
any
)
{
}
catch
(
err
:
any
)
{
// console.log(err?.response);
// console.log(err?.response);
if
(
step
===
1
)
{
if
(
step
===
1
)
{
...
...
src/service/events/generateAbstract.ts
View file @
5249297c
...
@@ -12,7 +12,7 @@ export async function generateAbstract(next = false): Promise<any> {
...
@@ -12,7 +12,7 @@ export async function generateAbstract(next = false): Promise<any> {
const
systemPrompt
:
ChatCompletionRequestMessage
=
{
const
systemPrompt
:
ChatCompletionRequestMessage
=
{
role
:
'system'
,
role
:
'system'
,
content
:
`总结助手,我会向你发送一段长文本,请从文本中归纳总结5至15条信息,
请直接输出总结内容,并按以下格式输出: 'A1:'\n'A2:'\n'A3:'
\n`
content
:
`总结助手,我会向你发送一段长文本,请从文本中归纳总结5至15条信息,
如果是英文,请增加一条中文的总结,并按以下格式输出: A1:\nA2:\nA3:
\n`
};
};
let
dataItem
:
DataItemSchema
|
null
=
null
;
let
dataItem
:
DataItemSchema
|
null
=
null
;
...
@@ -80,36 +80,36 @@ export async function generateAbstract(next = false): Promise<any> {
...
@@ -80,36 +80,36 @@ export async function generateAbstract(next = false): Promise<any> {
const
rawContent
:
string
=
abstractResponse
?.
data
.
choices
[
0
].
message
?.
content
||
''
;
const
rawContent
:
string
=
abstractResponse
?.
data
.
choices
[
0
].
message
?.
content
||
''
;
// 从 content 中提取摘要内容
// 从 content 中提取摘要内容
const
splitContents
=
splitText
(
rawContent
);
const
splitContents
=
splitText
(
rawContent
);
console
.
log
(
rawContent
);
//
console.log(rawContent);
// 生成词向量
// 生成词向量
const
vectorResponse
=
await
Promise
.
allSettled
(
//
const vectorResponse = await Promise.allSettled(
splitContents
.
map
((
item
)
=>
//
splitContents.map((item) =>
chatAPI
.
createEmbedding
(
//
chatAPI.createEmbedding(
{
//
{
model
:
'text-embedding-ada-002'
,
//
model: 'text-embedding-ada-002',
input
:
item
.
abstract
//
input: item.abstract
},
//
},
{
//
{
timeout
:
120000
,
//
timeout: 120000,
httpsAgent
//
httpsAgent
}
//
}
)
//
)
)
//
)
);
//
);
// 筛选成功的向量请求
// 筛选成功的向量请求
const
vectorSuccessResponse
=
vectorResponse
//
const vectorSuccessResponse = vectorResponse
.
map
((
item
:
any
,
i
)
=>
{
//
.map((item: any, i) => {
if
(
item
.
status
!==
'fulfilled'
)
{
//
if (item.status !== 'fulfilled') {
// 没有词向量的【摘要】不要
//
// 没有词向量的【摘要】不要
console
.
log
(
'获取词向量错误: '
,
item
);
//
console.log('获取词向量错误: ', item);
return
''
;
//
return '';
}
//
}
return
{
//
return {
abstract
:
splitContents
[
i
].
abstract
,
//
abstract: splitContents[i].abstract,
abstractVector
:
item
?.
value
?.
data
?.
data
?.[
0
]?.
embedding
//
abstractVector: item?.value?.data?.data?.[0]?.embedding
};
//
};
})
//
})
.
filter
((
item
)
=>
item
);
//
.filter((item) => item);
// 插入数据库,并修改状态
// 插入数据库,并修改状态
await
DataItem
.
findByIdAndUpdate
(
dataItem
.
_id
,
{
await
DataItem
.
findByIdAndUpdate
(
dataItem
.
_id
,
{
...
@@ -117,28 +117,22 @@ export async function generateAbstract(next = false): Promise<any> {
...
@@ -117,28 +117,22 @@ export async function generateAbstract(next = false): Promise<any> {
$push
:
{
$push
:
{
rawResponse
:
rawContent
,
rawResponse
:
rawContent
,
result
:
{
result
:
{
$each
:
vectorSuccessResponse
$each
:
splitContents
}
}
}
}
});
});
// 计费
!
userApiKey
&&
vectorSuccessResponse
.
length
>
0
&&
pushSplitDataBill
({
userId
:
dataItem
.
userId
,
type
:
'abstract'
,
text
:
systemPrompt
.
content
+
dataItem
.
text
+
rawContent
+
rawContent
.
substring
(
0
,
Math
.
floor
(
dataItem
.
text
.
length
/
10
))
// 向量价格是 gpt35 的1/10
});
console
.
log
(
console
.
log
(
`生成摘要成功,time:
${(
Date
.
now
()
-
startTime
)
/
1000
}
s`
,
`生成摘要成功,time:
${(
Date
.
now
()
-
startTime
)
/
1000
}
s`
,
`摘要匹配数量:
${
splitContents
.
length
}
`
,
`摘要匹配数量:
${
splitContents
.
length
}
`
`有向量摘要数量:
${
vectorSuccessResponse
.
length
}
`
);
);
// 计费
pushSplitDataBill
({
isPay
:
!
userApiKey
&&
splitContents
.
length
>
0
,
userId
:
dataItem
.
userId
,
type
:
'abstract'
,
text
:
systemPrompt
.
content
+
dataItem
.
text
+
rawContent
});
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
console
.
log
(
'error: 生成摘要错误'
,
dataItem
?.
_id
);
console
.
log
(
'error: 生成摘要错误'
,
dataItem
?.
_id
);
console
.
log
(
'response:'
,
error
);
console
.
log
(
'response:'
,
error
);
...
...
src/service/events/generateQA.ts
View file @
5249297c
...
@@ -12,7 +12,7 @@ export async function generateQA(next = false): Promise<any> {
...
@@ -12,7 +12,7 @@ export async function generateQA(next = false): Promise<any> {
const
systemPrompt
:
ChatCompletionRequestMessage
=
{
const
systemPrompt
:
ChatCompletionRequestMessage
=
{
role
:
'system'
,
role
:
'system'
,
content
:
`总结助手。我会向你发送一段长文本,请从中总结出5至15个问题和答案,答案请尽量详细,请按以下格式返回:
"Q1:"\n"A1:"\n"Q2:"\n"A2:"
\n`
content
:
`总结助手。我会向你发送一段长文本,请从中总结出5至15个问题和答案,答案请尽量详细,请按以下格式返回:
Q1:\nA1:\nQ2:\nA2:
\n`
};
};
let
dataItem
:
DataItemSchema
|
null
=
null
;
let
dataItem
:
DataItemSchema
|
null
=
null
;
...
@@ -58,61 +58,68 @@ export async function generateQA(next = false): Promise<any> {
...
@@ -58,61 +58,68 @@ export async function generateQA(next = false): Promise<any> {
const
chatAPI
=
getOpenAIApi
(
userApiKey
||
systemKey
);
const
chatAPI
=
getOpenAIApi
(
userApiKey
||
systemKey
);
// 请求 chatgpt 获取回答
// 请求 chatgpt 获取回答
const
response
=
await
Promise
.
allSettled
(
const
response
=
await
Promise
.
allSettled
(
[
0
,
0.5
,
0.8
].
map
((
temperature
)
=>
[
0.2
,
0.8
].
map
(
chatAPI
.
createChatCompletion
(
(
temperature
)
=>
{
chatAPI
model
:
ChatModelNameEnum
.
GPT35
,
.
createChatCompletion
(
temperature
:
temperature
,
n
:
1
,
messages
:
[
systemPrompt
,
{
{
role
:
'user'
,
model
:
ChatModelNameEnum
.
GPT35
,
content
:
dataItem
?.
text
||
''
temperature
:
temperature
,
n
:
1
,
messages
:
[
systemPrompt
,
{
role
:
'user'
,
content
:
dataItem
?.
text
||
''
}
]
},
{
timeout
:
120000
,
httpsAgent
}
}
]
)
},
.
then
((
res
)
=>
({
{
rawContent
:
res
?.
data
.
choices
[
0
].
message
?.
content
||
''
,
timeout
:
120000
,
result
:
splitText
(
res
?.
data
.
choices
[
0
].
message
?.
content
||
''
)
httpsAgent
}))
// 从 content 中提取 QA
}
)
)
)
);
);
// 过滤出成功的响应
// 过滤出成功的响应
const
successResponse
=
response
.
filter
((
item
)
=>
item
.
status
===
'fulfilled'
);
const
successResponse
:
{
// 提取响应内容
rawContent
:
string
;
const
rawContents
:
string
[]
=
successResponse
.
map
(
result
:
{
q
:
string
;
a
:
string
}[];
(
item
:
any
)
=>
item
?.
value
?.
data
.
choices
[
0
].
message
?.
content
||
''
}[]
=
response
.
filter
((
item
)
=>
item
.
status
===
'fulfilled'
).
map
((
item
:
any
)
=>
item
.
value
);
);
// 从 content 中提取 QA
const
rawContents
=
successResponse
.
map
((
item
)
=>
item
.
rawContent
);
const
splitResponses
=
rawContents
.
map
((
content
)
=>
splitText
(
content
)).
flat
();
const
results
=
successResponse
.
map
((
item
)
=>
item
.
result
).
flat
();
// 插入数据库,并修改状态
// 插入数据库,并修改状态
await
DataItem
.
findByIdAndUpdate
(
dataItem
.
_id
,
{
await
DataItem
.
findByIdAndUpdate
(
dataItem
.
_id
,
{
status
:
0
,
status
:
0
,
$push
:
{
$push
:
{
rawResponse
:
{
rawResponse
:
{
$each
:
rawContents
$each
:
successResponse
.
map
((
item
)
=>
item
.
rawContent
)
},
},
result
:
{
result
:
{
$each
:
splitResponse
s
$each
:
result
s
}
}
}
}
});
});
// 计费
!
userApiKey
&&
splitResponses
.
length
>
0
&&
pushSplitDataBill
({
userId
:
dataItem
.
userId
,
type
:
'QA'
,
text
:
systemPrompt
.
content
+
dataItem
.
text
+
rawContents
.
join
(
''
)
});
console
.
log
(
console
.
log
(
'生成QA成功,time:'
,
'生成QA成功,time:'
,
`
${(
Date
.
now
()
-
startTime
)
/
1000
}
s`
,
`
${(
Date
.
now
()
-
startTime
)
/
1000
}
s`
,
'QA数量:'
,
'QA数量:'
,
splitResponse
s
.
length
result
s
.
length
);
);
// 计费
pushSplitDataBill
({
isPay
:
!
userApiKey
&&
results
.
length
>
0
,
userId
:
dataItem
.
userId
,
type
:
'QA'
,
text
:
systemPrompt
.
content
+
dataItem
.
text
+
rawContents
.
join
(
''
)
});
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
console
.
log
(
'error: 生成QA错误'
,
dataItem
?.
_id
);
console
.
log
(
'error: 生成QA错误'
,
dataItem
?.
_id
);
console
.
log
(
'response:'
,
error
?.
response
);
console
.
log
(
'response:'
,
error
?.
response
);
...
...
src/service/events/pushBill.ts
View file @
5249297c
...
@@ -5,55 +5,58 @@ import { formatPrice } from '@/utils/user';
...
@@ -5,55 +5,58 @@ import { formatPrice } from '@/utils/user';
import
type
{
DataType
}
from
'@/types/data'
;
import
type
{
DataType
}
from
'@/types/data'
;
export
const
pushChatBill
=
async
({
export
const
pushChatBill
=
async
({
isPay
,
modelName
,
modelName
,
userId
,
userId
,
chatId
,
chatId
,
text
text
}:
{
}:
{
isPay
:
boolean
;
modelName
:
string
;
modelName
:
string
;
userId
:
string
;
userId
:
string
;
chatId
:
string
;
chatId
:
string
;
text
:
string
;
text
:
string
;
})
=>
{
})
=>
{
await
connectToDatabase
();
let
billId
;
let
billId
;
try
{
try
{
// 获取模型单价格
const
modelItem
=
modelList
.
find
((
item
)
=>
item
.
model
===
modelName
);
const
unitPrice
=
modelItem
?.
price
||
5
;
// 计算 token 数量
// 计算 token 数量
const
tokens
=
encode
(
text
);
const
tokens
=
encode
(
text
);
// 计算价格
const
price
=
unitPrice
*
tokens
.
length
;
console
.
log
(
'chat bill'
);
console
.
log
(
'token len:'
,
tokens
.
length
);
console
.
log
(
'text len: '
,
text
.
length
);
console
.
log
(
'text len: '
,
text
.
length
);
console
.
log
(
'price: '
,
`
${
formatPrice
(
price
)}
元`
);
console
.
log
(
'token len:'
,
tokens
.
length
);
if
(
isPay
)
{
await
connectToDatabase
();
try
{
// 获取模型单价格
// 插入 Bill 记录
const
modelItem
=
modelList
.
find
((
item
)
=>
item
.
model
===
modelName
);
const
res
=
await
Bill
.
create
({
// 计算价格
userId
,
const
unitPrice
=
modelItem
?.
price
||
5
;
type
:
'chat'
,
const
price
=
unitPrice
*
tokens
.
length
;
modelName
,
console
.
log
(
`chat bill, price:
${
formatPrice
(
price
)}
元`
);
chatId
,
textLen
:
text
.
length
,
tokenLen
:
tokens
.
length
,
price
});
billId
=
res
.
_id
;
// 账号扣费
try
{
await
User
.
findByIdAndUpdate
(
userId
,
{
// 插入 Bill 记录
$inc
:
{
balance
:
-
price
}
const
res
=
await
Bill
.
create
({
});
userId
,
}
catch
(
error
)
{
type
:
'chat'
,
console
.
log
(
'创建账单失败:'
,
error
);
modelName
,
billId
&&
Bill
.
findByIdAndDelete
(
billId
);
chatId
,
textLen
:
text
.
length
,
tokenLen
:
tokens
.
length
,
price
});
billId
=
res
.
_id
;
// 账号扣费
await
User
.
findByIdAndUpdate
(
userId
,
{
$inc
:
{
balance
:
-
price
}
});
}
catch
(
error
)
{
console
.
log
(
'创建账单失败:'
,
error
);
billId
&&
Bill
.
findByIdAndDelete
(
billId
);
}
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
error
);
console
.
log
(
error
);
...
@@ -61,10 +64,12 @@ export const pushChatBill = async ({
...
@@ -61,10 +64,12 @@ export const pushChatBill = async ({
};
};
export
const
pushSplitDataBill
=
async
({
export
const
pushSplitDataBill
=
async
({
isPay
,
userId
,
userId
,
text
,
text
,
type
type
}:
{
}:
{
isPay
:
boolean
;
userId
:
string
;
userId
:
string
;
text
:
string
;
text
:
string
;
type
:
DataType
;
type
:
DataType
;
...
@@ -74,39 +79,41 @@ export const pushSplitDataBill = async ({
...
@@ -74,39 +79,41 @@ export const pushSplitDataBill = async ({
let
billId
;
let
billId
;
try
{
try
{
// 获取模型单价格, 都是用 gpt35 拆分
const
modelItem
=
modelList
.
find
((
item
)
=>
item
.
model
===
ChatModelNameEnum
.
GPT35
);
const
unitPrice
=
modelItem
?.
price
||
5
;
// 计算 token 数量
// 计算 token 数量
const
tokens
=
encode
(
text
);
const
tokens
=
encode
(
text
);
// 计算价格
const
price
=
unitPrice
*
tokens
.
length
;
console
.
log
(
'splitData bill'
);
console
.
log
(
'token len:'
,
tokens
.
length
);
console
.
log
(
'text len: '
,
text
.
length
);
console
.
log
(
'text len: '
,
text
.
length
);
console
.
log
(
'price: '
,
`
${
formatPrice
(
price
)}
元`
);
console
.
log
(
'token len:'
,
tokens
.
length
);
if
(
isPay
)
{
try
{
// 获取模型单价格, 都是用 gpt35 拆分
const
modelItem
=
modelList
.
find
((
item
)
=>
item
.
model
===
ChatModelNameEnum
.
GPT35
);
const
unitPrice
=
modelItem
?.
price
||
5
;
// 计算价格
const
price
=
unitPrice
*
tokens
.
length
;
console
.
log
(
`splitData bill, price:
${
formatPrice
(
price
)}
元`
);
try
{
// 插入 Bill 记录
// 插入 Bill 记录
const
res
=
await
Bill
.
create
({
const
res
=
await
Bill
.
create
({
userId
,
userId
,
type
,
type
,
modelName
:
ChatModelNameEnum
.
GPT35
,
modelName
:
ChatModelNameEnum
.
GPT35
,
textLen
:
text
.
length
,
textLen
:
text
.
length
,
tokenLen
:
tokens
.
length
,
tokenLen
:
tokens
.
length
,
price
price
});
});
billId
=
res
.
_id
;
billId
=
res
.
_id
;
// 账号扣费
// 账号扣费
await
User
.
findByIdAndUpdate
(
userId
,
{
await
User
.
findByIdAndUpdate
(
userId
,
{
$inc
:
{
balance
:
-
price
}
$inc
:
{
balance
:
-
price
}
});
});
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
'创建账单失败:'
,
error
);
console
.
log
(
'创建账单失败:'
,
error
);
billId
&&
Bill
.
findByIdAndDelete
(
billId
);
billId
&&
Bill
.
findByIdAndDelete
(
billId
);
}
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
error
);
console
.
log
(
error
);
...
...
src/service/response.ts
View file @
5249297c
...
@@ -28,10 +28,10 @@ export const jsonRes = <T = any>(
...
@@ -28,10 +28,10 @@ export const jsonRes = <T = any>(
}
else
if
(
openaiError
[
error
?.
response
?.
statusText
])
{
}
else
if
(
openaiError
[
error
?.
response
?.
statusText
])
{
msg
=
openaiError
[
error
.
response
.
statusText
];
msg
=
openaiError
[
error
.
response
.
statusText
];
}
}
error
?.
response
&&
console
.
log
(
'chat err:'
,
error
?.
response
);
console
.
log
(
'error->'
);
console
.
log
(
'error->'
);
console
.
log
(
'code:'
,
error
.
code
);
console
.
log
(
'code:'
,
error
.
code
);
console
.
log
(
'statusText:'
,
error
?.
response
?.
statusText
);
console
.
log
(
'statusText:'
,
error
?.
response
?.
statusText
);
console
.
log
(
'data len:'
,
error
?.
response
?.
config
?.
data
.
length
);
console
.
log
(
'msg:'
,
msg
);
console
.
log
(
'msg:'
,
msg
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment