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
f88c6031
authored
Apr 06, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: lafgpt。openapi schema
parent
8a02b3b0
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
84 additions
and
53 deletions
+84
-53
src/pages/api/chat/vectorGpt.ts
+2
-2
src/pages/api/openapi/lafGpt.ts
+53
-48
src/pages/chat/index.tsx
+0
-1
src/service/events/pushBill.ts
+1
-1
src/service/models/openapi.ts
+20
-0
src/types/mongoSchema.d.ts
+8
-1
No files found.
src/pages/api/chat/vectorGpt.ts
View file @
f88c6031
...
@@ -105,8 +105,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -105,8 +105,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
throw
new
Error
(
'对不起,我没有找到你的问题'
);
throw
new
Error
(
'对不起,我没有找到你的问题'
);
}
}
// textArr 筛选,最多 3
0
00 tokens
// textArr 筛选,最多 3
2
00 tokens
const
systemPrompt
=
systemPromptFilter
(
formatRedisPrompt
,
3
4
00
);
const
systemPrompt
=
systemPromptFilter
(
formatRedisPrompt
,
3
2
00
);
prompts
.
unshift
({
prompts
.
unshift
({
obj
:
'SYSTEM'
,
obj
:
'SYSTEM'
,
...
...
src/pages/api/openapi/lafGpt.ts
View file @
f88c6031
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
c
reateParser
,
ParsedEvent
,
ReconnectInterval
}
from
'eventsource-parser
'
;
import
{
c
onnectToDatabase
,
Model
}
from
'@/service/mongo
'
;
import
{
connectToDatabase
}
from
'@/service/mongo
'
;
import
{
getOpenAIApi
}
from
'@/service/utils/chat
'
;
import
{
getOpenAIApi
,
authChat
}
from
'@/service/utils/chat
'
;
import
{
authToken
}
from
'@/service/utils/tools
'
;
import
{
httpsAgent
,
openaiChatFilter
,
systemPromptFilter
}
from
'@/service/utils/tools'
;
import
{
httpsAgent
,
openaiChatFilter
,
systemPromptFilter
}
from
'@/service/utils/tools'
;
import
{
ChatCompletionRequestMessage
,
ChatCompletionRequestMessageRoleEnum
}
from
'openai'
;
import
{
ChatCompletionRequestMessage
,
ChatCompletionRequestMessageRoleEnum
}
from
'openai'
;
import
{
ChatItemType
}
from
'@/types/chat'
;
import
{
ChatItemType
}
from
'@/types/chat'
;
import
{
jsonRes
}
from
'@/service/response'
;
import
{
jsonRes
}
from
'@/service/response'
;
import
type
{
ModelSchema
}
from
'@/types/mongoSchema'
;
import
{
PassThrough
}
from
'stream'
;
import
{
PassThrough
}
from
'stream'
;
import
{
modelList
}
from
'@/constants/model'
;
import
{
ChatModelNameEnum
,
modelList
,
ChatModelNameMap
}
from
'@/constants/model'
;
import
{
pushChatBill
}
from
'@/service/events/pushBill'
;
import
{
pushChatBill
}
from
'@/service/events/pushBill'
;
import
{
connectRedis
}
from
'@/service/redis'
;
import
{
connectRedis
}
from
'@/service/redis'
;
import
{
VecModelDataPrefix
}
from
'@/constants/redis'
;
import
{
VecModelDataPrefix
}
from
'@/constants/redis'
;
import
{
vectorToBuffer
}
from
'@/utils/tools'
;
import
{
vectorToBuffer
}
from
'@/utils/tools'
;
import
{
openaiCreateEmbedding
}
from
'@/service/utils/openai'
;
import
{
openaiCreateEmbedding
,
getOpenApiKey
,
gpt35StreamResponse
}
from
'@/service/utils/openai'
;
import
{
gpt35StreamResponse
}
from
'@/service/utils/openai'
;
/* 发送提示词 */
/* 发送提示词 */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
...
@@ -33,13 +31,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -33,13 +31,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
});
try
{
try
{
const
{
chatId
,
prompt
}
=
req
.
body
as
{
const
{
prompt
,
modelId
}
=
req
.
body
as
{
prompt
:
ChatItemType
;
prompt
:
ChatItemType
;
chat
Id
:
string
;
model
Id
:
string
;
};
};
const
{
authorization
}
=
req
.
headers
;
const
{
authorization
}
=
req
.
headers
;
if
(
!
chatId
||
!
prompt
)
{
if
(
!
prompt
)
{
throw
new
Error
(
'缺少参数'
);
throw
new
Error
(
'缺少参数'
);
}
}
...
@@ -47,49 +45,57 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -47,49 +45,57 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const
redis
=
await
connectRedis
();
const
redis
=
await
connectRedis
();
let
startTime
=
Date
.
now
();
let
startTime
=
Date
.
now
();
const
{
chat
,
userApiKey
,
systemKey
,
userId
}
=
await
authChat
(
chatId
,
authorization
);
/* 凭证校验 */
const
userId
=
await
authToken
(
authorization
);
const
{
userApiKey
,
systemKey
}
=
await
getOpenApiKey
(
userId
);
const
model
:
ModelSchema
=
chat
.
modelId
;
/* 查找数据库里的模型信息 */
const
modelConstantsData
=
modelList
.
find
((
item
)
=>
item
.
model
===
model
.
service
.
modelName
);
const
model
=
await
Model
.
findById
(
modelId
);
if
(
!
model
)
{
throw
new
Error
(
'找不到模型'
);
}
const
modelConstantsData
=
modelList
.
find
(
(
item
)
=>
item
.
model
===
ChatModelNameEnum
.
VECTOR_GPT
);
if
(
!
modelConstantsData
)
{
if
(
!
modelConstantsData
)
{
throw
new
Error
(
'模型
加载异常
'
);
throw
new
Error
(
'模型
已下架
'
);
}
}
// 获取 chatAPI
// 获取 chatAPI
const
chatAPI
=
getOpenAIApi
(
userApiKey
||
systemKey
);
const
chatAPI
=
getOpenAIApi
(
userApiKey
||
systemKey
);
// 请求一次 chatgpt 拆解需求
// 请求一次 chatgpt 拆解需求
const
promptResponse
=
await
chatAPI
.
createChatCompletion
(
const
promptResponse
=
await
chatAPI
.
createChatCompletion
(
{
{
model
:
model
.
service
.
chatModel
,
model
:
ChatModelNameMap
[
ChatModelNameEnum
.
GPT35
]
,
temperature
:
0
,
temperature
:
0
,
// max_tokens: modelConstantsData.maxToken,
messages
:
[
messages
:
[
{
{
role
:
'system'
,
role
:
'system'
,
content
:
`服务端逻辑生成器。根据用户输入的需求,拆解成代码实现的步骤,并按格式返回: 1.\n2.\n3.\n ......
content
:
`服务端逻辑生成器.根据用户输入的需求,拆解成代码实现的步骤,并按格式返回: 1.\n2.\n3.\n ......
下面是一些例子:
下面是一些例子:
实现一个手机号发生注册验证码方法.
实现一个手机号注册账号的方法,包含两个函数
1. 从 query 中获取 phone.
* 发送手机验证码函数:
2. 校验手机号格式是否正确,不正确返回{error: "手机号格式错误"}.
1. 从 query 中获取 phone
3. 给 phone 发送一个短信验证码,验证码长度为6位字符串,内容为:你正在注册laf,验证码为:code.
2. 校验手机号格式是否正确,不正确返回{error: "手机号格式错误"}
4. 数据库添加数据,表为"codes",内容为 {phone, code}.
3. 给 phone 发送一个短信验证码,验证码长度为6位字符串,内容为:你正在注册laf, 验证码为:code
4. 数据库添加数据,表为"codes",内容为 {phone, code}
实现根据手机号注册账号,需要验证手机验证码.
* 注册函数
1. 从 body 中获取 phone 和 code.
1. 从 body 中获取 phone 和 code
2. 校验手机号格式是否正确,不正确返回{error: "手机号格式错误"}.
2. 校验手机号格式是否正确,不正确返回{error: "手机号格式错误"}
2. 获取数据库数据,表为"codes",查找是否有符合 phone, code 等于body参数的记录,没有的话返回 {error:"验证码不正确"}.
2. 获取数据库数据,表为"codes",查找是否有符合 phone, code 等于body参数的记录,没有的话返回 {error:"验证码不正确"}
4. 添加数据库数据,表为"users" ,内容为{phone, code, createTime}.
4. 添加数据库数据,表为"users" ,内容为{phone, code, createTime}
5. 删除数据库数据,删除 code 记录.
5. 删除数据库数据,删除 code 记录
---------------
更新博客记录。传入blogId,blogText,tags,还需要记录更新的时间.
更新博客记录。传入blogId,blogText,tags,还需要记录更新的时间
1. 从 body 中获取 blogId,blogText 和 tags.
1. 从 body 中获取 blogId,blogText 和 tags
2. 校验 blogId 是否为空,为空则返回 {error: "博客ID不能为空"}.
2. 校验 blogId 是否为空,为空则返回 {error: "博客ID不能为空"}
3. 校验 blogText 是否为空,为空则返回 {error: "博客内容不能为空"}.
3. 校验 blogText 是否为空,为空则返回 {error: "博客内容不能为空"}
4. 校验 tags 是否为数组,不是则返回 {error: "标签必须为数组"}.
4. 校验 tags 是否为数组,不是则返回 {error: "标签必须为数组"}
5. 获取当前时间,记录为 updateTime.
5. 获取当前时间,记录为 updateTime
6. 更新数据库数据,表为"blogs",更新符合 blogId 的记录的内容为{blogText, tags, updateTime}.
6. 更新数据库数据,表为"blogs",更新符合 blogId 的记录的内容为{blogText, tags, updateTime}
7. 返回结果 {message: "更新博客记录成功"}.`
7. 返回结果 {message: "更新博客记录成功"}`
},
},
{
{
role
:
'user'
,
role
:
'user'
,
...
@@ -120,16 +126,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -120,16 +126,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
});
// 读取对话内容
// 读取对话内容
const
prompts
=
[
...
chat
.
content
,
prompt
];
const
prompts
=
[
prompt
];
// 搜索系统提示词, 按相似度从 redis 中搜出相关的 q 和 text
// 搜索系统提示词, 按相似度从 redis 中搜出相关的 q 和 text
const
redisData
:
any
[]
=
await
redis
.
sendCommand
([
const
redisData
:
any
[]
=
await
redis
.
sendCommand
([
'FT.SEARCH'
,
'FT.SEARCH'
,
`idx:
${
VecModelDataPrefix
}
:hash`
,
`idx:
${
VecModelDataPrefix
}
:hash`
,
`@modelId:{
${
String
(
`@modelId:{
${
String
(
chat
.
modelId
.
_id
model
.
_id
)}
} @vector:[VECTOR_RANGE 0.25 $blob]=>{$YIELD_DISTANCE_AS: score}`
,
)}
} @vector:[VECTOR_RANGE 0.25 $blob]=>{$YIELD_DISTANCE_AS: score}`
,
// `@modelId:{${String(chat.modelId._id)}}=>[KNN 10 @vector $blob AS score]`,
'RETURN'
,
'RETURN'
,
'1'
,
'1'
,
'text'
,
'text'
,
...
@@ -162,8 +167,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -162,8 +167,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
throw
new
Error
(
'对不起,我没有找到你的问题'
);
throw
new
Error
(
'对不起,我没有找到你的问题'
);
}
}
// textArr 筛选,最多 3
0
00 tokens
// textArr 筛选,最多 3
2
00 tokens
const
systemPrompt
=
systemPromptFilter
(
formatRedisPrompt
,
3
4
00
);
const
systemPrompt
=
systemPromptFilter
(
formatRedisPrompt
,
3
2
00
);
prompts
.
unshift
({
prompts
.
unshift
({
obj
:
'SYSTEM'
,
obj
:
'SYSTEM'
,
...
@@ -185,7 +190,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -185,7 +190,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
content
:
item
.
value
content
:
item
.
value
})
})
);
);
console
.
log
(
formatPrompts
);
//
console.log(formatPrompts);
// 计算温度
// 计算温度
const
temperature
=
modelConstantsData
.
maxTemperature
*
(
model
.
temperature
/
10
);
const
temperature
=
modelConstantsData
.
maxTemperature
*
(
model
.
temperature
/
10
);
...
@@ -207,7 +212,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -207,7 +212,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
}
);
);
console
.
log
(
'api response time:'
,
`
${(
Date
.
now
()
-
startTime
)
/
1000
}
s`
);
console
.
log
(
'api response
.
time:'
,
`
${(
Date
.
now
()
-
startTime
)
/
1000
}
s`
);
step
=
1
;
step
=
1
;
const
{
responseContent
}
=
await
gpt35StreamResponse
({
const
{
responseContent
}
=
await
gpt35StreamResponse
({
...
@@ -215,6 +220,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -215,6 +220,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
stream
,
stream
,
chatResponse
chatResponse
});
});
console
.
log
(
'response done. time:'
,
`
${(
Date
.
now
()
-
startTime
)
/
1000
}
s`
);
const
promptsContent
=
formatPrompts
.
map
((
item
)
=>
item
.
content
).
join
(
''
);
const
promptsContent
=
formatPrompts
.
map
((
item
)
=>
item
.
content
).
join
(
''
);
// 只有使用平台的 key 才计费
// 只有使用平台的 key 才计费
...
@@ -222,7 +228,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -222,7 +228,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
isPay
:
!
userApiKey
,
isPay
:
!
userApiKey
,
modelName
:
model
.
service
.
modelName
,
modelName
:
model
.
service
.
modelName
,
userId
,
userId
,
chatId
,
text
:
promptsContent
+
responseContent
text
:
promptsContent
+
responseContent
});
});
}
catch
(
err
:
any
)
{
}
catch
(
err
:
any
)
{
...
...
src/pages/chat/index.tsx
View file @
f88c6031
...
@@ -120,7 +120,6 @@ const Chat = ({ chatId }: { chatId: string }) => {
...
@@ -120,7 +120,6 @@ const Chat = ({ chatId }: { chatId: string }) => {
const
urlMap
:
Record
<
string
,
string
>
=
{
const
urlMap
:
Record
<
string
,
string
>
=
{
[
ChatModelNameEnum
.
GPT35
]:
'/api/chat/chatGpt'
,
[
ChatModelNameEnum
.
GPT35
]:
'/api/chat/chatGpt'
,
[
ChatModelNameEnum
.
VECTOR_GPT
]:
'/api/chat/vectorGpt'
,
[
ChatModelNameEnum
.
VECTOR_GPT
]:
'/api/chat/vectorGpt'
,
// [ChatModelNameEnum.VECTOR_GPT]: '/api/chat/lafGpt',
[
ChatModelNameEnum
.
GPT3
]:
'/api/chat/gpt3'
[
ChatModelNameEnum
.
GPT3
]:
'/api/chat/gpt3'
};
};
...
...
src/service/events/pushBill.ts
View file @
f88c6031
...
@@ -15,7 +15,7 @@ export const pushChatBill = async ({
...
@@ -15,7 +15,7 @@ export const pushChatBill = async ({
isPay
:
boolean
;
isPay
:
boolean
;
modelName
:
string
;
modelName
:
string
;
userId
:
string
;
userId
:
string
;
chatId
:
string
;
chatId
?
:
string
;
text
:
string
;
text
:
string
;
})
=>
{
})
=>
{
let
billId
;
let
billId
;
...
...
src/service/models/openapi.ts
0 → 100644
View file @
f88c6031
import
{
Schema
,
model
,
models
,
Model
}
from
'mongoose'
;
import
{
OpenApiSchema
}
from
'@/types/mongoSchema'
;
const
OpenApiSchema
=
new
Schema
({
userId
:
{
type
:
Schema
.
Types
.
ObjectId
,
ref
:
'user'
,
required
:
true
},
createTime
:
{
type
:
Date
,
default
:
()
=>
new
Date
()
},
lastUsedTime
:
{
type
:
Date
,
default
:
()
=>
new
Date
()
}
});
export
const
OpenApi
:
Model
<
OpenApiSchema
>
=
models
[
'openapi'
]
||
model
(
'openapi'
,
OpenApiSchema
);
src/types/mongoSchema.d.ts
View file @
f88c6031
...
@@ -125,7 +125,7 @@ export interface DataSchema {
...
@@ -125,7 +125,7 @@ export interface DataSchema {
_id
:
string
;
_id
:
string
;
userId
:
string
;
userId
:
string
;
name
:
string
;
name
:
string
;
createTime
:
string
;
createTime
:
Date
;
type
:
DataType
;
type
:
DataType
;
}
}
...
@@ -148,3 +148,10 @@ export interface DataItemSchema {
...
@@ -148,3 +148,10 @@ export interface DataItemSchema {
export
interface
DataItemPopulate
extends
DataItemSchema
{
export
interface
DataItemPopulate
extends
DataItemSchema
{
userId
:
UserModelSchema
;
userId
:
UserModelSchema
;
}
}
export
interface
OpenApiSchema
{
_id
:
string
;
userId
:
string
;
createTime
:
Date
;
lastUsedTime
:
Date
;
}
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