Compare commits

..

25 Commits

Author SHA1 Message Date
archer
8af3d85b8a add gemini model 2025-01-25 14:25:10 +08:00
archer
fcf14af64d comment 2025-01-25 14:21:21 +08:00
heheer
991fbe254c fix interactive edge (#3659)
* fix interactive edge

* fix
2025-01-25 14:12:12 +08:00
Archer
ab0fc517dc fix: err tip (#3666)
* fix: err tip

* perf: training queue

* doc
2025-01-25 14:10:56 +08:00
Archer
92105e9a0b reload buffer (#3665)
* reload buffer

* reload buffer

* tts selector
2025-01-25 13:12:21 +08:00
Archer
d2948d7e57 feat: markdown extension (#3663)
* feat: markdown extension

* media cros

* rerank test

* default price

* perf: default model

* fix: cannot custom provider

* fix: default model select

* update bg

* perf: default model selector

* fix: usage export

* i18n

* fix: rerank

* update init extension

* perf: ip limit check

* doubao model order

* web default modle

* perf: tts selector

* perf: tts error

* qrcode package
2025-01-24 23:42:04 +08:00
heheer
02fcb6a61e export usage csv i18n (#3660)
* export usage csv i18n

* fix build
2025-01-24 19:09:08 +08:00
a.e.
4f5a12f33b fix: false triggerd org selection (#3661) 2025-01-24 19:07:36 +08:00
Archer
38efa3e050 feat: default model (#3662)
* move model config

* feat: default model
2025-01-24 18:44:43 +08:00
a.e.
5ce889942a fix: POST 500 error on dingtalk bot (#3655) 2025-01-24 14:10:40 +08:00
Archer
60c72d05d1 model perf (#3657)
* fix: model

* dataset quote

* perf: model config

* model tag

* doubao model config

* perf: config model

* feat: model test
2025-01-24 14:10:14 +08:00
Archer
99ce976b06 4.8.20 test (#3656)
* provider

* perf: model config
2025-01-23 18:32:45 +08:00
heheer
2c03abc6e1 add default model config (#3653) 2025-01-23 18:19:57 +08:00
Archer
34b510cba1 perf: usages list;perf: move components (#3654)
* perf: usages list

* team sub plan load

* perf: usage dashboard code

* perf: dashboard ui

* perf: move components
2025-01-23 17:29:39 +08:00
heheer
0c05add8b2 feat: usage filter & export & dashbord (#3538)
* feat: usage filter & export & dashbord

* adjust ui

* fix tmb scroll

* fix code & selecte all

* merge
2025-01-23 10:54:30 +08:00
Archer
e009be51e7 Aiproxy (#3649)
* model config

* feat: model config ui

* perf: rename variable

* feat: custom request url

* perf: model buffer

* perf: init model

* feat: json model config

* auto login

* fix: ts

* update packages

* package

* fix: dockerfile
2025-01-22 22:59:28 +08:00
Archer
16629e32a7 4819 doc (#3646) 2025-01-22 10:01:09 +08:00
a.e.
d67474170a fix: permission conflict after moving (#3639) 2025-01-21 22:35:10 +08:00
Yee
e02a7ab350 chore: add intern and moka provider (#3640)
* chore: add intern and moka provider

* fix: svg show issue
2025-01-21 22:32:49 +08:00
heheer
d491105752 fix model provider icon (#3644) 2025-01-21 22:31:52 +08:00
shilin
fe59eadcee fix: 数字输入框无法输入0 (#3641) 2025-01-21 18:56:57 +08:00
Archer
946bd20dbf fix: loal file api error (#3637)
* update doc

* fix: loal file api error

* fix: number input import

* feat: icon load
2025-01-21 16:46:49 +08:00
Archer
3c97757e4d 4.8.19-feature (#3636)
* feat: sync org from wecom, pref: member list pagination (#3549)

* feat: sync org

* chore: fe

* chore: loading

* chore: type

* pref: team member list change to pagination. Edit a sort of list apis.

* feat: member update avatar

* chore: user avatar move to tmb

* chore: init scripts move user avatar

* chore: sourceMember

* fix: list api sourceMember

* fix: member sync

* fix: pagination

* chore: adjust code

* chore: move changeOwner to pro

* chore: init v4819 script

* chore: adjust code

* chore: UserBox

* perf: scroll page code

* perf: list data

* docs:更新用户答疑 (#3576)

* docs: add custom uid docs (#3572)

* fix: pagination bug (#3577)

* 4.8.19 test (#3584)

* faet: dataset search filter

* fix: scroll page

* fix: collection list api old version (#3591)

* fix: collection list api format

* fix: type error of addSourceMemeber

* fix: scroll fetch (#3592)

* fix: yuque dataset file folder can enter (#3593)

* perf: load members;perf: yuque load;fix: workflow llm params cannot close (#3594)

* chat openapi doc

* feat: dataset openapi doc

* perf: load members

* perf: member load code

* perf: yuque load

* fix: workflow llm params cannot close

* fix: api dataset reference tag preview (#3600)

* perf: doc

* feat: chat page config

* fix: http parse (#3634)

* update doc

* fix: http parse

* fix code run node reset template (#3633)

Co-authored-by: Archer <545436317@qq.com>

* docs:faq (#3627)

* docs:faq

* docsFix

* perf: sleep plugin

* fix: selector

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
Co-authored-by: Jiangween <145003935+Jiangween@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
2025-01-20 19:42:33 +08:00
shilin
9f33729ca9 feat(core): 添加 sleep 插件 (#3583)
(cherry picked from commit 09bdc63977)
2025-01-20 18:31:47 +08:00
Archer
a8d456f448 Update docker.md (#3599) 2025-01-15 13:16:57 +08:00
589 changed files with 10941 additions and 5839 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -25,249 +25,6 @@ weight: 707
"qaMaxProcess": 15, // 问答拆分线程数量
"tokenWorkers": 50, // Token 计算线程保持数,会持续占用内存,不能设置太大。
"pgHNSWEfSearch": 100 // 向量搜索参数。越大搜索越精确但是速度越慢。设置为100有99%+精度。
},
"llmModels": [
{
"provider": "OpenAI", // 模型提供商主要用于分类展示目前已经内置提供商包括https://github.com/labring/FastGPT/blob/main/packages/global/core/ai/provider.ts, 可 pr 提供新的提供商,或直接填写 Other
"model": "gpt-4o-mini", // 模型名(对应OneAPI中渠道的模型名)
"name": "gpt-4o-mini", // 模型别名
"maxContext": 125000, // 最大上下文
"maxResponse": 16000, // 最大回复
"quoteMaxToken": 120000, // 最大引用内容
"maxTemperature": 1.2, // 最大温度
"charsPointsPrice": 0, // n积分/1k token商业版
"censor": false, // 是否开启敏感校验(商业版)
"vision": true, // 是否支持图片输入
"datasetProcess": true, // 是否设置为文本理解模型QA务必保证至少有一个为true否则知识库会报错
"usedInClassify": true, // 是否用于问题分类务必保证至少有一个为true
"usedInExtractFields": true, // 是否用于内容提取务必保证至少有一个为true
"usedInToolCall": true, // 是否用于工具调用务必保证至少有一个为true
"usedInQueryExtension": true, // 是否用于问题优化务必保证至少有一个为true
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice如果为false则使用 functionCall如果仍为 false则使用提示词模式
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
"customExtractPrompt": "", // 自定义内容提取提示词
"defaultSystemChatPrompt": "", // 对话默认携带的系统提示词
"defaultConfig": {}, // 请求API时挟带一些默认配置比如 GLM4 的 top_p
"fieldMap": {} // 字段映射o1 模型需要把 max_tokens 映射为 max_completion_tokens
},
{
"provider": "OpenAI",
"model": "gpt-4o",
"name": "gpt-4o",
"maxContext": 125000,
"maxResponse": 4000,
"quoteMaxToken": 120000,
"maxTemperature": 1.2,
"charsPointsPrice": 0,
"censor": false,
"vision": true,
"datasetProcess": true,
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": true,
"functionCall": false,
"customCQPrompt": "",
"customExtractPrompt": "",
"defaultSystemChatPrompt": "",
"defaultConfig": {},
"fieldMap": {}
},
{
"provider": "OpenAI",
"model": "o1-mini",
"name": "o1-mini",
"maxContext": 125000,
"maxResponse": 65000,
"quoteMaxToken": 120000,
"maxTemperature": 1.2,
"charsPointsPrice": 0,
"censor": false,
"vision": false,
"datasetProcess": true,
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": false,
"functionCall": false,
"customCQPrompt": "",
"customExtractPrompt": "",
"defaultSystemChatPrompt": "",
"defaultConfig": {
"temperature": 1,
"max_tokens": null,
"stream": false
}
},
{
"provider": "OpenAI",
"model": "o1-preview",
"name": "o1-preview",
"maxContext": 125000,
"maxResponse": 32000,
"quoteMaxToken": 120000,
"maxTemperature": 1.2,
"charsPointsPrice": 0,
"censor": false,
"vision": false,
"datasetProcess": true,
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": false,
"functionCall": false,
"customCQPrompt": "",
"customExtractPrompt": "",
"defaultSystemChatPrompt": "",
"defaultConfig": {
"temperature": 1,
"max_tokens": null,
"stream": false
}
}
],
"vectorModels": [
{
"provider": "OpenAI",
"model": "text-embedding-3-small",
"name": "text-embedding-3-small",
"charsPointsPrice": 0,
"defaultToken": 512,
"maxToken": 3000,
"weight": 100
},
{
"provider": "OpenAI",
"model": "text-embedding-3-large",
"name": "text-embedding-3-large",
"charsPointsPrice": 0,
"defaultToken": 512,
"maxToken": 3000,
"weight": 100,
"defaultConfig": {
"dimensions": 1024
}
},
{
"provider": "OpenAI",
"model": "text-embedding-ada-002", // 模型名与OneAPI对应
"name": "Embedding-2", // 模型展示名
"charsPointsPrice": 0, // n积分/1k token
"defaultToken": 700, // 默认文本分割时候的 token
"maxToken": 3000, // 最大 token
"weight": 100, // 优先训练权重
"defaultConfig": {}, // 自定义额外参数。例如,如果希望使用 embedding3-large 的话,可以传入 dimensions:1024来返回1024维度的向量。目前必须小于1536维度
"dbConfig": {}, // 存储时的额外参数(非对称向量模型时候需要用到)
"queryConfig": {} // 参训时的额外参数
}
],
"reRankModels": [],
"audioSpeechModels": [
{
"provider": "OpenAI",
"model": "tts-1",
"name": "OpenAI TTS1",
"charsPointsPrice": 0,
"voices": [
{ "label": "Alloy", "value": "alloy", "bufferId": "openai-Alloy" },
{ "label": "Echo", "value": "echo", "bufferId": "openai-Echo" },
{ "label": "Fable", "value": "fable", "bufferId": "openai-Fable" },
{ "label": "Onyx", "value": "onyx", "bufferId": "openai-Onyx" },
{ "label": "Nova", "value": "nova", "bufferId": "openai-Nova" },
{ "label": "Shimmer", "value": "shimmer", "bufferId": "openai-Shimmer" }
]
}
],
"whisperModel": {
"provider": "OpenAI",
"model": "whisper-1",
"name": "Whisper1",
"charsPointsPrice": 0
}
}
```
## 内置的模型提供商ID
为了方便模型分类展示FastGPT 内置了部分模型提供商的名字和 Logo。如果你期望补充提供商可[提交 Issue](https://github.com/labring/FastGPT/issues),并提供几个信息:
1. 厂商官网地址
2. 厂商 SVG logo建议是正方形图片。
目前已支持的提供商, 复制 "-" 之前的字符串,作为 provider 的值。
- OpenAI
- Claude
- Gemini
- Meta
- MistralAI
- AliCloud - 阿里云
- Qwen - 通义千问
- Doubao - 豆包
- ChatGLM - 智谱
- DeepSeek - 深度求索
- Moonshot - 月之暗面
- MiniMax
- SparkDesk - 讯飞星火
- Hunyuan - 腾讯混元
- Baichuan - 百川
- Yi - 零一万物
- Ernie - 文心一言
- StepFun - 阶跃星辰
- Ollama
- BAAI - 智源研究院
- FishAudio
- Other - 其他
## ReRank 模型接入
由于 OneAPI 不支持 Rerank 模型,所以需要单独配置接入,这里
### 使用硅基流动的在线模型
有免费的 `bge-reranker-v2-m3` 模型可以使用。
1. [点击注册硅基流动账号](https://cloud.siliconflow.cn/i/TR9Ym0c4)
2. 进入控制台,获取 API key: https://cloud.siliconflow.cn/account/ak
3. 修改 FastGPT 配置文件
```json
{
"reRankModels": [
{
"model": "BAAI/bge-reranker-v2-m3", // 这里的model需要对应 siliconflow 的模型名
"name": "BAAI/bge-reranker-v2-m3",
"requestUrl": "https://api.siliconflow.cn/v1/rerank",
"requestAuth": "siliconflow 上申请的 key"
}
]
}
```
### 私有部署模型
请使用 4.6.6-alpha 以上版本,配置文件中的 `reRankModels` 为重排模型虽然是数组不过目前仅有第1个生效。
1. [部署 ReRank 模型](/docs/development/custom-models/bge-rerank/)
1. 找到 FastGPT 的配置文件中的 `reRankModels` 4.6.6 以前是 `ReRankModels`
2. 修改对应的值:
```json
{
"reRankModels": [
{
"model": "bge-reranker-base", // 随意
"name": "检索重排-base", // 随意
"charsPointsPrice": 0,
"requestUrl": "{{host}}/v1/rerank",
"requestAuth": "安全凭证,已自动补 Bearer"
}
]
}
```
```

View File

@@ -118,10 +118,17 @@ services:
```
## 接入 FastGPT
参考 [ReRank模型接入](/docs/development/configuration/#rerank-接入)host 变量为部署的域名
1. 打开 FastGPT 模型配置,新增一个重排模型
2. 填写模型配置表单:模型 ID 为`bge-reranker-base`,地址填写`{{host}}/v1/rerank`host 为你部署的域名/IP:Port。
![alt text](/imgs/image-102.png)
## QA
### 403报错
FastGPT中自定义请求 Token 和环境变量的 ACCESS_TOKEN 不一致。
### Docker 运行提示 `Bus error (core dumped)`
尝试增加 `docker-compose.yml` 配置项 `shm_size` ,以增加容器中的共享内存目录大小。

View File

@@ -144,7 +144,6 @@ curl --location --request POST 'https://<oneapi_url>/v1/chat/completions' \
"usedInClassify": true, // 是否用于问题分类务必保证至少有一个为true
"usedInExtractFields": true, // 是否用于内容提取务必保证至少有一个为true
"usedInToolCall": true, // 是否用于工具调用务必保证至少有一个为true
"usedInQueryExtension": true, // 是否用于问题优化务必保证至少有一个为true
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice如果为false则使用 functionCall如果仍为 false则使用提示词模式
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型

View File

@@ -23,19 +23,19 @@ weight: 707
### PgVector版本
体验测试首选
非常轻量,适合数据量在 5000 万以下。
{{< table "table-hover table-striped-columns" >}}
| 环境 | 最低配置(单节点) | 推荐配置 |
| ---- | ---- | ---- |
| 测试 | 2c2g | 2c4g |
| 测试(可以把计算进程设置少一些) | 2c4g | 2c8g |
| 100w 组向量 | 4c8g 50GB | 4c16g 50GB |
| 500w 组向量 | 8c32g 200GB | 16c64g 200GB |
{{< /table >}}
### Milvus版本
生产部署首选,对于千万级以上向量性能更优秀。
对于亿级以上向量性能更优秀。
[点击查看 Milvus 官方推荐配置](https://milvus.io/docs/prerequisite-docker.md)
@@ -202,6 +202,10 @@ docker restart oneapi
首次运行,会自动初始化 root 用户,密码为 `1234`(与环境变量中的`DEFAULT_ROOT_PSW`一致),日志里会提示一次`MongoServerError: Unable to read from a snapshot due to pending collection catalog changes;`可忽略。
### 6. 配置模型
[点击查看模型配置教程](/docs/development/modelConfig/intro/)
## FAQ
### Mongo 副本集自动初始化失败

View File

@@ -19,6 +19,24 @@ images: []
## 二、通用问题
### 通过sealos部署的话是否没有本地部署的一些限制
![](/imgs/faq1.png)
这是索引模型的长度限制,通过任何方式部署都一样的,但不同索引模型的配置不一样,可以在后台修改参数。
### 怎么挂载小程序配置文件
将验证文件,挂载到指定位置:/app/projects/app/public/xxxx.txt
然后重启。例如:
![](/imgs/faq2.png)
### 数据库3306端口被占用了启动服务失败
![](/imgs/faq3.png)
把端口映射改成 3307 之类的,例如 3307:3306。
### 本地部署的限制
具体内容参考https://fael3z0zfze.feishu.cn/wiki/OFpAw8XzAi36Guk8dfucrCKUnjg。

View File

@@ -0,0 +1,412 @@
---
title: 'FastGPT 模型配置说明'
description: 'FastGPT 模型配置说明'
icon: 'api'
draft: false
toc: true
weight: 744
---
在 4.8.20 版本以前FastGPT 模型配置在 `config.json` 文件中声明,你可以在 https://github.com/labring/FastGPT/blob/main/projects/app/data/model.json 中找到旧版的配置文件示例。
从 4.8.20 版本开始,你可以直接在 FastGPT 页面中进行模型配置,并且系统内置了大量模型,无需从 0 开始配置。下面介绍模型配置的基本流程:
## 1. 使用 OneAPI 对接模型提供商
可以使用 [OneAPI 接入教程](/docs/development/modelconfig/one-api) 来进行模型聚合,从而可以对接更多模型提供商。你需要先在各服务商申请好 API 接入 OneAPI 后,才能在 FastGPT 中使用这些模型。示例流程如下:
![alt text](/imgs/image-95.png)
除了各模型官方的服务外,还有一些第三方服务商提供模型接入服务,当然你也可以用 Ollama 等来部署本地模型,最终都需要接入 OneAPI下面是一些第三方服务商
{{% alert icon=" " context="info" %}}
- [SiliconCloud(硅基流动)](https://cloud.siliconflow.cn/i/TR9Ym0c4): 提供开源模型调用的平台。
- [Sealos AIProxy](https://hzh.sealos.run/?openapp=system-aiproxy): 提供国内各家模型代理,无需逐一申请 api。
{{% /alert %}}
在 OneAPI 配置好模型后,你就可以打开 FastGPT 页面,启用对应模型了。
## 2. 登录 root 用户
仅 root 用户可以进行模型配置。
## 3. 进入模型配置页面
登录 root 用户后,在`账号-模型提供商-模型配置`中,你可以看到所有内置的模型和自定义模型,以及哪些模型启用了。
![alt text](/image-90.png)
## 4. 配置介绍
{{% alert icon="🤖 " context="success" %}}
注意:目前语音识别模型和重排模型仅会生效一个,所以配置时候,只需要配置一个即可。
{{% /alert %}}
### 核心配置
- 模型 ID实际发出请求的`model`值,全局唯一。
- 自定义请求地址/Token如果需要绕过`OneAPI`,可以设置自定义请求地址和 Token。一般情况下不需要如果 OneAPI 不支持某些模型,可以使用该特性。
### 模型类型
1. 语言模型 - 进行文本对话,多模态模型支持图片识别。
2. 索引模型 - 对文本块进行索引,用于相关文本检索。
3. 语音合成 - 将文本转换为语音。
4. 语音识别 - 将语音转换为文本。
5. 重排模型 - 对文本进行重排,用于优化文本质量。
### 启用模型
系统内置了目前主流厂商的模型,如果你不熟悉配置,直接点击`启用`即可,需要注意到是,模型 ID 需要和 OneAPI 中渠道的`模型`一致。
| | |
| --- | --- |
| ![alt text](/imgs/image-91.png) | ![alt text](/imgs/image-92.png) |
### 修改模型配置
点击模型右侧的齿轮即可进行模型配置,不同类型模型的配置有区别。
| | |
| --- | --- |
| ![alt text](/imgs/image-93.png) | ![alt text](/imgs/image-94.png) |
### 新增自定义模型
如果系统内置的模型无法满足你的需求,你可以添加自定义模型。自定义模型中,如果`模型 ID`与系统内置的模型 ID 一致,则会被认为是修改系统模型。
| | |
| --- | --- |
| ![alt text](/imgs/image-96.png) | ![alt text](/imgs/image-97.png) |
### 通过配置文件配置
如果你觉得通过页面配置模型比较麻烦,你也可以通过配置文件来配置模型。或者希望快速将一个系统的配置,复制到另一个系统,也可以通过配置文件来实现。
| | |
| --- | --- |
| ![alt text](/imgs/image-98.png) | ![alt text](/imgs/image-99.png) |
**语言模型字段说明:**
```json
{
"model": "模型 ID",
"metadata": {
"isCustom": true, // 是否为自定义模型
"isActive": true, // 是否启用
"provider": "OpenAI", // 模型提供商主要用于分类展示目前已经内置提供商包括https://github.com/labring/FastGPT/blob/main/packages/global/core/ai/provider.ts, 可 pr 提供新的提供商,或直接填写 Other
"model": "gpt-4o-mini", // 模型ID(对应OneAPI中渠道的模型名)
"name": "gpt-4o-mini", // 模型别名
"maxContext": 125000, // 最大上下文
"maxResponse": 16000, // 最大回复
"quoteMaxToken": 120000, // 最大引用内容
"maxTemperature": 1.2, // 最大温度
"charsPointsPrice": 0, // n积分/1k token商业版
"censor": false, // 是否开启敏感校验(商业版)
"vision": true, // 是否支持图片输入
"datasetProcess": true, // 是否设置为文本理解模型QA务必保证至少有一个为true否则知识库会报错
"usedInClassify": true, // 是否用于问题分类务必保证至少有一个为true
"usedInExtractFields": true, // 是否用于内容提取务必保证至少有一个为true
"usedInToolCall": true, // 是否用于工具调用务必保证至少有一个为true
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice如果为false则使用 functionCall如果仍为 false则使用提示词模式
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
"customExtractPrompt": "", // 自定义内容提取提示词
"defaultSystemChatPrompt": "", // 对话默认携带的系统提示词
"defaultConfig": {}, // 请求API时挟带一些默认配置比如 GLM4 的 top_p
"fieldMap": {} // 字段映射o1 模型需要把 max_tokens 映射为 max_completion_tokens
}
}
```
**索引模型字段说明:**
```json
{
"model": "模型 ID",
"metadata": {
"isCustom": true, // 是否为自定义模型
"isActive": true, // 是否启用
"provider": "OpenAI", // 模型提供商
"model": "text-embedding-3-small", // 模型ID
"name": "text-embedding-3-small", // 模型别名
"charsPointsPrice": 0, // n积分/1k token
"defaultToken": 512, // 默认文本分割时候的 token
"maxToken": 3000 // 最大 token
}
}
```
**重排模型字段说明:**
```json
{
"model": "模型 ID",
"metadata": {
"isCustom": true, // 是否为自定义模型
"isActive": true, // 是否启用
"provider": "BAAI", // 模型提供商
"model": "bge-reranker-v2-m3", // 模型ID
"name": "ReRanker-Base", // 模型别名
"requestUrl": "", // 自定义请求地址
"requestAuth": "", // 自定义请求认证
"type": "rerank" // 模型类型
}
}
```
**语音合成模型字段说明:**
```json
{
"model": "模型 ID",
"metadata": {
"isActive": true, // 是否启用
"isCustom": true, // 是否为自定义模型
"type": "tts", // 模型类型
"provider": "FishAudio", // 模型提供商
"model": "fishaudio/fish-speech-1.5", // 模型ID
"name": "fish-speech-1.5", // 模型别名
"voices": [ // 音色
{
"label": "fish-alex", // 音色名称
"value": "fishaudio/fish-speech-1.5:alex", // 音色ID
},
{
"label": "fish-anna", // 音色名称
"value": "fishaudio/fish-speech-1.5:anna", // 音色ID
}
],
"charsPointsPrice": 0 // n积分/1k token
}
}
```
**语音识别模型字段说明:**
```json
{
"model": "whisper-1",
"metadata": {
"isActive": true, // 是否启用
"isCustom": true, // 是否为自定义模型
"provider": "OpenAI", // 模型提供商
"model": "whisper-1", // 模型ID
"name": "whisper-1", // 模型别名
"charsPointsPrice": 0, // n积分/1k token
"type": "stt" // 模型类型
}
}
```
## 模型测试
FastGPT 页面上提供了每类模型的简单测试,可以初步检查模型是否正常工作,会实际按模板发送一个请求。
![alt text](/imgs/image-105.png)
## 模型接入示例
### ReRank 模型接入
由于 OneAPI 不支持 Rerank 模型所以需要单独配置。FastGPT 中,模型配置支持自定义请求地址,可以绕过 OneAPI直接向提供商发起请求可以利用这个特性来接入 Rerank 模型。
#### 使用硅基流动的在线模型
有免费的 `bge-reranker-v2-m3` 模型可以使用。
1. [点击注册硅基流动账号](https://cloud.siliconflow.cn/i/TR9Ym0c4)
2. 进入控制台,获取 API key: https://cloud.siliconflow.cn/account/ak
3. 打开 FastGPT 模型配置,新增一个`BAAI/bge-reranker-v2-m3`的重排模型(如果系统内置了,也可以直接变更,无需新增)。
![alt text](/imgs/image-101.png)
#### 私有部署模型
[点击查看部署 ReRank 模型教程](/docs/development/custom-models/bge-rerank/)
## 旧版模型配置说明
配置好 OneAPI 后,需要在`config.json`文件中,手动的增加模型配置,并重启。
由于环境变量不利于配置复杂的内容FastGPT 采用了 ConfigMap 的形式挂载配置文件,你可以在 `projects/app/data/config.json` 看到默认的配置文件。可以参考 [docker-compose 快速部署](/docs/development/docker/) 来挂载配置文件。
**开发环境下**,你需要将示例配置文件 `config.json` 复制成 `config.local.json` 文件才会生效。
**Docker部署**,修改`config.json` 文件,需要重启容器。
下面配置文件示例中包含了系统参数和各个模型配置:
```json
{
"feConfigs": {
"lafEnv": "https://laf.dev" // laf环境。 https://laf.run (杭州阿里云) ,或者私有化的laf环境。如果使用 Laf openapi 功能,需要最新版的 laf 。
},
"systemEnv": {
"vectorMaxProcess": 15, // 向量处理线程数量
"qaMaxProcess": 15, // 问答拆分线程数量
"tokenWorkers": 50, // Token 计算线程保持数,会持续占用内存,不能设置太大。
"pgHNSWEfSearch": 100 // 向量搜索参数。越大搜索越精确但是速度越慢。设置为100有99%+精度。
},
"llmModels": [
{
"provider": "OpenAI", // 模型提供商主要用于分类展示目前已经内置提供商包括https://github.com/labring/FastGPT/blob/main/packages/global/core/ai/provider.ts, 可 pr 提供新的提供商,或直接填写 Other
"model": "gpt-4o-mini", // 模型名(对应OneAPI中渠道的模型名)
"name": "gpt-4o-mini", // 模型别名
"maxContext": 125000, // 最大上下文
"maxResponse": 16000, // 最大回复
"quoteMaxToken": 120000, // 最大引用内容
"maxTemperature": 1.2, // 最大温度
"charsPointsPrice": 0, // n积分/1k token商业版
"censor": false, // 是否开启敏感校验(商业版)
"vision": true, // 是否支持图片输入
"datasetProcess": true, // 是否设置为文本理解模型QA务必保证至少有一个为true否则知识库会报错
"usedInClassify": true, // 是否用于问题分类务必保证至少有一个为true
"usedInExtractFields": true, // 是否用于内容提取务必保证至少有一个为true
"usedInToolCall": true, // 是否用于工具调用务必保证至少有一个为true
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice如果为false则使用 functionCall如果仍为 false则使用提示词模式
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
"customExtractPrompt": "", // 自定义内容提取提示词
"defaultSystemChatPrompt": "", // 对话默认携带的系统提示词
"defaultConfig": {}, // 请求API时挟带一些默认配置比如 GLM4 的 top_p
"fieldMap": {} // 字段映射o1 模型需要把 max_tokens 映射为 max_completion_tokens
},
{
"provider": "OpenAI",
"model": "gpt-4o",
"name": "gpt-4o",
"maxContext": 125000,
"maxResponse": 4000,
"quoteMaxToken": 120000,
"maxTemperature": 1.2,
"charsPointsPrice": 0,
"censor": false,
"vision": true,
"datasetProcess": true,
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"toolChoice": true,
"functionCall": false,
"customCQPrompt": "",
"customExtractPrompt": "",
"defaultSystemChatPrompt": "",
"defaultConfig": {},
"fieldMap": {}
},
{
"provider": "OpenAI",
"model": "o1-mini",
"name": "o1-mini",
"maxContext": 125000,
"maxResponse": 65000,
"quoteMaxToken": 120000,
"maxTemperature": 1.2,
"charsPointsPrice": 0,
"censor": false,
"vision": false,
"datasetProcess": true,
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"toolChoice": false,
"functionCall": false,
"customCQPrompt": "",
"customExtractPrompt": "",
"defaultSystemChatPrompt": "",
"defaultConfig": {
"temperature": 1,
"max_tokens": null,
"stream": false
}
},
{
"provider": "OpenAI",
"model": "o1-preview",
"name": "o1-preview",
"maxContext": 125000,
"maxResponse": 32000,
"quoteMaxToken": 120000,
"maxTemperature": 1.2,
"charsPointsPrice": 0,
"censor": false,
"vision": false,
"datasetProcess": true,
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"toolChoice": false,
"functionCall": false,
"customCQPrompt": "",
"customExtractPrompt": "",
"defaultSystemChatPrompt": "",
"defaultConfig": {
"temperature": 1,
"max_tokens": null,
"stream": false
}
}
],
"vectorModels": [
{
"provider": "OpenAI",
"model": "text-embedding-3-small",
"name": "text-embedding-3-small",
"charsPointsPrice": 0,
"defaultToken": 512,
"maxToken": 3000,
"weight": 100
},
{
"provider": "OpenAI",
"model": "text-embedding-3-large",
"name": "text-embedding-3-large",
"charsPointsPrice": 0,
"defaultToken": 512,
"maxToken": 3000,
"weight": 100,
"defaultConfig": {
"dimensions": 1024
}
},
{
"provider": "OpenAI",
"model": "text-embedding-ada-002", // 模型名与OneAPI对应
"name": "Embedding-2", // 模型展示名
"charsPointsPrice": 0, // n积分/1k token
"defaultToken": 700, // 默认文本分割时候的 token
"maxToken": 3000, // 最大 token
"weight": 100, // 优先训练权重
"defaultConfig": {}, // 自定义额外参数。例如,如果希望使用 embedding3-large 的话,可以传入 dimensions:1024来返回1024维度的向量。目前必须小于1536维度
"dbConfig": {}, // 存储时的额外参数(非对称向量模型时候需要用到)
"queryConfig": {} // 参训时的额外参数
}
],
"reRankModels": [],
"audioSpeechModels": [
{
"provider": "OpenAI",
"model": "tts-1",
"name": "OpenAI TTS1",
"charsPointsPrice": 0,
"voices": [
{ "label": "Alloy", "value": "alloy", "bufferId": "openai-Alloy" },
{ "label": "Echo", "value": "echo", "bufferId": "openai-Echo" },
{ "label": "Fable", "value": "fable", "bufferId": "openai-Fable" },
{ "label": "Onyx", "value": "onyx", "bufferId": "openai-Onyx" },
{ "label": "Nova", "value": "nova", "bufferId": "openai-Nova" },
{ "label": "Shimmer", "value": "shimmer", "bufferId": "openai-Shimmer" }
]
}
],
"whisperModel": {
"provider": "OpenAI",
"model": "whisper-1",
"name": "Whisper1",
"charsPointsPrice": 0
}
}
```

View File

@@ -94,70 +94,16 @@ CHAT_API_KEY=sk-xxxxxx
![](/imgs/oneapi-demo1.png)
### 2. 修改 FastGPT 配置文件
### 2. 修改 FastGPT 模型配置
可以在 `/projects/app/src/data/config.json` 里找到配置文件(本地开发需要复制成 config.local.json,按下面内容修改配置文件,最新/更具体的配置说明,可查看[FastGPT 配置文件说明](/docs/development/configuration)
打开 FastGPT 模型配置,启动文心千帆模型,如果希望未内置,可以通过新增模型来配置
配置模型关键点在于`model` 需要与 OneAPI 渠道中的模型一致。
```json
{
"llmModels": [ // 语言模型配置
{
"model": "ERNIE-Bot", // 这里的模型需要对应 One API 的模型
"name": "文心一言", // 对外展示的名称
"avatar": "/imgs/model/openai.svg", // 模型的logo
"maxContext": 16000, // 最大上下文
"maxResponse": 4000, // 最大回复
"quoteMaxToken": 13000, // 最大引用内容
"maxTemperature": 1.2, // 最大温度
"charsPointsPrice": 0,
"censor": false,
"vision": false, // 是否支持图片输入
"datasetProcess": true, // 是否设置为知识库处理模型
"usedInClassify": true, // 是否用于问题分类
"usedInExtractFields": true, // 是否用于字段提取
"usedInToolCall": true, // 是否用于工具调用
"usedInQueryExtension": true, // 是否用于问题优化
"toolChoice": true, // 是否支持工具选择
"functionCall": false, // 是否支持函数调用
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
"customExtractPrompt": "", // 自定义内容提取提示词
"defaultSystemChatPrompt": "", // 对话默认携带的系统提示词
"defaultConfig":{} // 请求API时挟带一些默认配置比如 GLM4 的 top_p
}
],
"vectorModels": [ // 向量模型配置
{
"model": "text-embedding-ada-002",
"name": "Embedding-2",
"avatar": "/imgs/model/openai.svg",
"charsPointsPrice": 0,
"defaultToken": 700,
"maxToken": 3000,
"weight": 100
},
]
}
```
### 3. 重启 FastGPT
**Docker 版本**
```bash
docker-compose down
docker-compose up -d
```
**Sealos 版本**
直接找到 FastGPT 服务,点击重启即可。
![alt text](/imgs/image-103.png)
## 其他服务商接入参考
这章介绍一些提供商接入 OneAPI 的教程,配置后不要忘记修改 FastGPT 配置文件
这章介绍一些提供商接入 OneAPI 的教程,配置后不要忘记 FastGPT 模型配置中启用
### 阿里通义千问

View File

@@ -27,139 +27,13 @@ OPENAI_BASE_URL=https://api.siliconflow.cn/v1
CHAT_API_KEY=sk-xxxxxx
```
## 3. 修改 FastGPT 配置文件
## 3. 修改 FastGPT 模型配置
我们选取 SiliconCloud 中的模型作为 FastGPT 配置。这里配置了 `Qwen2.5 72b` 的纯语言和视觉模型;选择 `bge-m3` 作为向量模型;选择 `bge-reranker-v2-m3` 作为重排模型。选择 `fish-speech-1.5` 作为语音模型;选择 `SenseVoiceSmall` 作为语音输入模型
系统内置了几个硅基流动的模型进行体验,如果需要其他模型,可以手动添加
注意ReRank 模型仍需配置一次 Api Key
这里启动了 `Qwen2.5 72b` 的纯语言和视觉模型;选择 `bge-m3` 作为向量模型;选择 `bge-reranker-v2-m3` 作为重排模型。选择 `fish-speech-1.5` 作为语音模型;选择 `SenseVoiceSmall` 作为语音输入模型。
```json
{
"llmModels": [
{
"provider": "Other", // 模型提供商主要用于分类展示目前已经内置提供商包括https://github.com/labring/FastGPT/blob/main/packages/global/core/ai/provider.ts, 可 pr 提供新的提供商,或直接填写 Other
"model": "Qwen/Qwen2.5-72B-Instruct", // 模型名(对应OneAPI中渠道的模型名)
"name": "Qwen2.5-72B-Instruct", // 模型别名
"maxContext": 32000, // 最大上下文
"maxResponse": 4000, // 最大回复
"quoteMaxToken": 30000, // 最大引用内容
"maxTemperature": 1, // 最大温度
"charsPointsPrice": 0, // n积分/1k token商业版
"censor": false, // 是否开启敏感校验(商业版)
"vision": false, // 是否支持图片输入
"datasetProcess": true, // 是否设置为文本理解模型QA务必保证至少有一个为true否则知识库会报错
"usedInClassify": true, // 是否用于问题分类务必保证至少有一个为true
"usedInExtractFields": true, // 是否用于内容提取务必保证至少有一个为true
"usedInToolCall": true, // 是否用于工具调用务必保证至少有一个为true
"usedInQueryExtension": true, // 是否用于问题优化务必保证至少有一个为true
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice如果为false则使用 functionCall如果仍为 false则使用提示词模式
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
"customExtractPrompt": "", // 自定义内容提取提示词
"defaultSystemChatPrompt": "", // 对话默认携带的系统提示词
"defaultConfig": {}, // 请求API时挟带一些默认配置比如 GLM4 的 top_p
"fieldMap": {} // 字段映射o1 模型需要把 max_tokens 映射为 max_completion_tokens
},
{
"provider": "Other",
"model": "Qwen/Qwen2-VL-72B-Instruct",
"name": "Qwen2-VL-72B-Instruct",
"maxContext": 32000,
"maxResponse": 4000,
"quoteMaxToken": 30000,
"maxTemperature": 1,
"charsPointsPrice": 0,
"censor": false,
"vision": true,
"datasetProcess": false,
"usedInClassify": false,
"usedInExtractFields": false,
"usedInToolCall": false,
"usedInQueryExtension": false,
"toolChoice": false,
"functionCall": false,
"customCQPrompt": "",
"customExtractPrompt": "",
"defaultSystemChatPrompt": "",
"defaultConfig": {}
}
],
"vectorModels": [
{
"provider": "Other",
"model": "Pro/BAAI/bge-m3",
"name": "Pro/BAAI/bge-m3",
"charsPointsPrice": 0,
"defaultToken": 512,
"maxToken": 5000,
"weight": 100
}
],
"reRankModels": [
{
"model": "BAAI/bge-reranker-v2-m3", // 这里的model需要对应 siliconflow 的模型名
"name": "BAAI/bge-reranker-v2-m3",
"requestUrl": "https://api.siliconflow.cn/v1/rerank",
"requestAuth": "siliconflow 上申请的 key"
}
],
"audioSpeechModels": [
{
"model": "fishaudio/fish-speech-1.5",
"name": "fish-speech-1.5",
"voices": [
{
"label": "fish-alex",
"value": "fishaudio/fish-speech-1.5:alex",
"bufferId": "fish-alex"
},
{
"label": "fish-anna",
"value": "fishaudio/fish-speech-1.5:anna",
"bufferId": "fish-anna"
},
{
"label": "fish-bella",
"value": "fishaudio/fish-speech-1.5:bella",
"bufferId": "fish-bella"
},
{
"label": "fish-benjamin",
"value": "fishaudio/fish-speech-1.5:benjamin",
"bufferId": "fish-benjamin"
},
{
"label": "fish-charles",
"value": "fishaudio/fish-speech-1.5:charles",
"bufferId": "fish-charles"
},
{
"label": "fish-claire",
"value": "fishaudio/fish-speech-1.5:claire",
"bufferId": "fish-claire"
},
{
"label": "fish-david",
"value": "fishaudio/fish-speech-1.5:david",
"bufferId": "fish-david"
},
{
"label": "fish-diana",
"value": "fishaudio/fish-speech-1.5:diana",
"bufferId": "fish-diana"
}
]
}
],
"whisperModel": {
"model": "FunAudioLLM/SenseVoiceSmall",
"name": "SenseVoiceSmall",
"charsPointsPrice": 0
}
}
```
## 4. 重启 FastGPT
![alt text](/imgs/image-104.png)
## 5. 体验测试

View File

@@ -55,4 +55,28 @@ curl --location --request POST 'https://api.fastgpt.in/api/v1/chat/completions'
}
]
}'
```
```
## 自定义用户 ID
`v4.8.13`后支持传入自定义的用户 ID, 并且存入历史记录中。
```sh
curl --location --request POST 'https://api.fastgpt.in/api/v1/chat/completions' \
--header 'Authorization: Bearer fastgpt-xxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"chatId": "111",
"stream": false,
"detail": false,
"messages": [
{
"content": "导演是谁",
"role": "user"
}
],
"customUid": "xxxxxx"
}'
```
在历史记录中,该条记录的使用者会显示为 `xxxxxx`

View File

@@ -686,7 +686,7 @@ curl --location --request POST 'http://localhost:3000/api/core/chat/getHistories
- appId - 应用 Id
- offset - 偏移量,即从第几条数据开始取
- pageSize - 记录数量
- source - 对话源
- source - 对话源。source=api表示获取通过 API 创建的对话(不会获取到页面上的对话记录)
{{% /alert %}}
{{< /markdownify >}}

View File

@@ -733,6 +733,21 @@ data 为集合的 ID。
{{< tab tabName="请求示例" >}}
{{< markdownify >}}
**4.8.19+**
```bash
curl --location --request POST 'http://localhost:3000/api/core/dataset/collection/listv2' \
--header 'Authorization: Bearer {{authorization}}' \
--header 'Content-Type: application/json' \
--data-raw '{
"offset":0,
"pageSize": 10,
"datasetId":"6593e137231a2be9c5603ba7",
"parentId": null,
"searchText":""
}'
```
**4.8.19-(不再维护)**
```bash
curl --location --request POST 'http://localhost:3000/api/core/dataset/collection/list' \
--header 'Authorization: Bearer {{authorization}}' \
@@ -753,7 +768,7 @@ curl --location --request POST 'http://localhost:3000/api/core/dataset/collectio
{{< markdownify >}}
{{% alert icon=" " context="success" %}}
- pageNum: 页码(选填)
- offset: 偏移量
- pageSize: 每页数量最大30选填
- datasetId: 知识库的ID(必填)
- parentId: 父级Id选填
@@ -773,9 +788,7 @@ curl --location --request POST 'http://localhost:3000/api/core/dataset/collectio
"statusText": "",
"message": "",
"data": {
"pageNum": 1,
"pageSize": 10,
"data": [
"list": [
{
"_id": "6593e137231a2be9c5603ba9",
"parentId": null,

View File

@@ -34,7 +34,7 @@ FastGPT 使用了 one-api 项目来管理模型池,其可以兼容 OpenAI 、A
<a href="https://bja.sealos.run/?openapp=system-template%3FtemplateName%3Dfastgpt" rel="external" target="_blank"><img src="https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg" alt="Deploy on Sealos"/></a>
### 开始部署
### 1. 开始部署
由于需要部署数据库,部署完后需要等待 2~4 分钟才能正常访问。默认用了最低配置,首次访问时会有些慢。
@@ -52,27 +52,15 @@ FastGPT 使用了 one-api 项目来管理模型池,其可以兼容 OpenAI 、A
![](/imgs/sealos2.png)
### 登录
### 2. 登录
用户名:`root`
密码是刚刚一键部署时设置的`root_password`
### 修改配置文件和环境变量
### 3. 配置模型
在 Sealos 中,你可以打开`应用管理`App Launchpad看到部署的 FastGPT可以打开`数据库`Database看到对应的数据库。
`应用管理`中,选中 FastGPT点击变更可以看到对应的环境变量和配置文件。
![](/imgs/fastgptonsealos1.png)
{{% alert icon="🤖 " context="success" %}}
在 Sealos 上FastGPT 一共运行了 1 个服务和 2 个数据库,如暂停和删除请注意数据库一同操作。(你可以白天启动,晚上暂停它们,省钱大法)
{{% /alert %}}
### 更新
点击变更或重启会自动拉取镜像更新,请确保镜像`tag`正确。建议不要使用`latest`,改成固定版本号。
[点击查看模型配置教程](/docs/development/modelConfig/intro/)
## 收费
@@ -88,7 +76,20 @@ FastGPT 商业版共包含了2个应用fastgpt, fastgpt-plus和2个数据
点击右侧的详情,可以查看对应应用的详细信息。
### 修改配置文件和环境变量
在 Sealos 中,你可以打开`应用管理`App Launchpad看到部署的 FastGPT可以打开`数据库`Database看到对应的数据库。
`应用管理`中,选中 FastGPT点击变更可以看到对应的环境变量和配置文件。
![](/imgs/fastgptonsealos1.png)
{{% alert icon="🤖 " context="success" %}}
在 Sealos 上FastGPT 一共运行了 1 个服务和 2 个数据库,如暂停和删除请注意数据库一同操作。(你可以白天启动,晚上暂停它们,省钱大法)
{{% /alert %}}
### 如何更新/升级 FastGPT
[升级脚本文档](https://doc.tryfastgpt.ai/docs/development/upgrading/)先看下文档,看下需要升级哪个版本。注意,不要跨版本升级!!!!!
例如目前是4.5 版本要升级到4.5.1就先把镜像版本改成v4.5.1,执行一下升级脚本,等待完成后再继续升级。如果目标版本不需要执行初始化,则可以跳过。
@@ -148,8 +149,6 @@ SYSTEM_FAVICON 可以是一个网络地址
![](/imgs/onsealos8.png)
### 管理后台(已合并到plus)
### 商业版镜像配置文件
```

View File

@@ -31,7 +31,6 @@ weight: 813
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": false,
"functionCall": false,
"customCQPrompt": "",
@@ -56,7 +55,6 @@ weight: 813
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": false,
"functionCall": false,
"customCQPrompt": "",

View File

@@ -0,0 +1,46 @@
---
title: 'V4.8.19(进行中)'
description: 'FastGPT V4.8.19 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 805
---
## 更新指南
### 1. 更新镜像:
- 更新 fastgpt 镜像 tag: v4.8.19-beta
- 更新 fastgpt-pro 商业版镜像 tag: v4.8.19-beta
- Sandbox 镜像无需更新
### 2. 运行升级脚本
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成**FastGPT 域名**。
```bash
curl --location --request POST 'https://{{host}}/api/admin/initv4819' \
--header 'rootkey: {{rootkey}}' \
--header 'Content-Type: application/json'
```
迁移用户表的头像到成员表中。
## 完整更新内容
1. 新增 - 工作流知识库检索支持按知识库权限进行过滤。
2. 新增 - 飞书/语雀知识库查看原文。
3. 新增 - 流程等待插件,可以等待 n 毫秒后继续执行流程。
4. 新增 - 飞书机器人接入,支持配置私有化飞书地址。
5. 优化 - 成员列表分页加载。
6. 优化 - 统一分页加载代码。
7. 优化 - 对话页面加载时,可配置是否为独立页面。
8. 优化 - 成员头像迁移,移动到成员表。
9. 修复 - 语雀文件库导入时,嵌套文件内容无法展开的问题。
10. 修复 - 工作流编排中LLM 参数无法关闭问题。
11. 修复 - 工作流编排中,代码运行节点还原模板问题。
12. 修复 - HTTP 接口适配对象字符串解析。
13. 修复 - 通过 API 上传文件localFile接口图片过期标记未清除。
14. 修复 - 工作流导入编排时number input 类型无法覆盖。
15. 修复 - 部分模型提供商 logo 无法正常显示。

View File

@@ -0,0 +1,38 @@
---
title: 'V4.8.20(进行中)'
description: 'FastGPT V4.8.20 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 804
---
## 更新指南
### 1. 更新环境变量
如果有很早版本用户,配置了`ONEAPI_URL`的,需要统一改成`OPENAI_BASE_URL`
### 1. 更新镜像:
### 2. 运行升级脚本
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成**FastGPT 域名**。
```bash
curl --location --request POST 'https://{{host}}/api/admin/initv4820' \
--header 'rootkey: {{rootkey}}' \
--header 'Content-Type: application/json'
```
自动把原配置文件的模型加载到新版模型配置中
## 完整更新内容
1. 新增 - 可视化模型参数配置。预设超过 100 个模型配置。同时支持所有类型模型的一键测试。(预计下个版本会完全支持在页面上配置渠道)。
2. 新增 - 使用记录导出和仪表盘。
3. 新增 - markdown 语法扩展,支持音视频(代码块 audio 和 video
4. 优化 - 页面组件抽离,减少页面组件路由。
5. 优化 - 全文检索,忽略大小写。
6. 优化 - 问答生成和增强索引改成流输出,避免部分模型超时。

View File

@@ -21,6 +21,19 @@ weight: 908
定时执行会在应用发布后生效,会在后台生效。
## V4.8.18-FIX2中提到“ 1. 修复 HTTP 节点, {{}} 格式引用变量兼容问题。建议尽快替换 / 模式取变量, {{}} 语法已弃用。”替换{{}}引用格式是仅仅只有在http节点还是所有节点的都会有影响
只有 http 节点用到这个语法。
## 工作流类型的应用在运行预览可以正常提问返回,但是发布免登录窗口之后有问题。
一般是没正确发布,在工作流右上角点击【保存并发布】。
## 如何解决猜你想问使用中文回答显示
注意需要更新到V4.8.17及以上,把猜你想问的提示词改成中文。
![](/imgs/quizApp2.png)
## AI对话回答要求中的Markdown语法取消
修改知识库默认提示词, 默认用的是标准模板提示词,会要求按 Markdown 输出,可以去除该要求:
@@ -38,3 +51,32 @@ A: 通常是由于上下文不一致导致,可以在对话日志中,找到
| | | |
| --- | --- | --- |
| ![](/imgs/image-85.png) | ![](/imgs/image-86.png) | ![](/imgs/image-87.png) |
在针对知识库的回答要求里有, 要给它配置提示词,不然他就是默认的,默认的里面就有该语法。
## 工作流操作一个工作流以一个问题分类节点开始根据不同的分类导入到不同的分支访问相应的知识库和AI对话AI对话返回内容后怎么样不进入问题分类节点而是将问题到知识库搜索然后把历史记录一起作为背景再次AI查询。
做个判断器如果是初次开始对话也就是历史记录为0就走问题分类不为零直接走知识库和ai。
## 实时对话,设置 fastgpt 定时,比如每隔 3000MS 去拿一次 webhook发送过来的消息到AI页面
定时执行没有这么高频率的去拿信息的,想要实现在企微里面的实时对话的机器人,
目前通过低代码的工作流构建应该是不行的,只能自己写代码,然后去调用 FastGPT 的 APIKey 回复。企业微信似乎没有提供「自动监听」群聊消息的接口(或是通过 at 机器人这种触发消息推送)。应该只能发消息给应用,接收这个 https://developer.work.weixin.qq.com/document/path/90238 文档中的消息推送实现实时对话。或者是定时去拿群聊消息通过这个文档所示的接口https://developer.work.weixin.qq.com/document/path/98914然后用这个接口 https://developer.work.weixin.qq.com/document/path/90248 去推送消息。
## 工作流连接数据库
工作流提供该连接数据库功能,用这个数据库连接的 plugin 可以实现 text2SQL但是相对危险不建议做写入等操作。
![](/imgs/quizApp1.png)
## 关于循环体,协助理解循环体的循环条件和终止条件、循环的方式,循环体内参数调用后、在循环体内属于是局部作用域的参数还是全局作用域的参数
可理解为 for 函数,传一个数组,每个数据都执行一次。
## 公式无法正常显示
添加相关提示词,引导模型按 Markdown 输出公式
```bash
Latex inline: \(x^2\)
Latex block: $$e=mc^2$$
```

View File

@@ -16,6 +16,25 @@ weight: 910
* **文件处理模型**:用于数据处理的【增强处理】和【问答拆分】。在【增强处理】中,生成相关问题和摘要,在【问答拆分】中执行问答对生成。
* **索引模型**:用于向量化,即通过对文本数据进行处理和组织,构建出一个能够快速查询的数据结构。
## 知识库支持Excel类文件的导入
xlsx等都可以上传的不止支持CSV。
## 知识库tokens的计算方式
统一按gpt3.5标准。
## 误删除重排模型后重排模型怎么加入到fastgpt
![](/imgs/dataset3.png)
config.json文件里面配置后就可以勾选重排模型
## 线上平台上创建了应用和知识库,到期之后如果短期内不续费,数据是否会被清理。
免费版是三十天不登录后清空知识库,应用不会动。其他付费套餐到期后自动切免费版。
![](/imgs/dataset4.png)
## 基于知识库的查询但是问题相关的答案过多。ai回答到一半就不继续回答。
FastGPT回复长度计算公式:
@@ -37,7 +56,7 @@ FastGPT回复长度计算公式:
![](/imgs/dataset2.png)
1. 私有化部署的时候,后台配模型参数,可以在配置最大上文时,预留一些空间,比如 128000 的模型,可以只配置 120000, 剩余的空间后续会被安排给输出
另外私有化部署的时候,后台配模型参数,可以在配置最大上文时,预留一些空间,比如 128000 的模型,可以只配置 120000, 剩余的空间后续会被安排给输出
## 受到模型上下文的限制,有时候达不到聊天记录的轮次,连续对话字数过多就会报上下文不够的错误。
@@ -61,4 +80,4 @@ FastGPT回复长度计算公式:
![](/imgs/dataset2.png)
1. 私有化部署的时候,后台配模型参数,可以在配置最大上文时,预留一些空间,比如 128000 的模型,可以只配置 120000, 剩余的空间后续会被安排给输出
另外,私有化部署的时候,后台配模型参数,可以在配置最大上文时,预留一些空间,比如 128000 的模型,可以只配置 120000, 剩余的空间后续会被安排给输出

View File

@@ -8,4 +8,8 @@ weight: 918
## oneapi 官网是哪个
只有开源的 README没官网GitHub: https://github.com/songquanpeng/one-api
只有开源的 README没官网GitHub: https://github.com/songquanpeng/one-api
## 想做多用户
开源版未支持多用户,仅商业版支持。

View File

@@ -22,10 +22,11 @@ FastGPT v4.8.16 版本开始,商业版用户支持飞书知识库导入,用
## 2. 配置应用权限
创建应用后,进入应用可以配置相关权限,这里需要增加个权限:
创建应用后,进入应用可以配置相关权限,这里需要增加**3个权限**
1. 获取云空间文件夹下的云文档清单
2. 查看新版文档
3. 查看、评论、编辑和管理云空间中所有文件
![alt text](/imgs/image-41.png)

View File

@@ -1,6 +1,6 @@
---
title: "循环执行"
description: "FastGPT 循环运行节点介绍和使用"
title: "批量运行"
description: "FastGPT 批量运行节点介绍和使用"
icon: "input"
draft: false
toc: true
@@ -9,15 +9,15 @@ weight: 260
## 节点概述
【**循环运行**】节点是 FastGPT V4.8.11 版本新增的一个重要功能模块。它允许工作流对数组类型的输入数据进行迭代处理,每次处理数组中的一个元素,并自动执行后续节点,直到完成整个数组的处理。
【**批量运行**】节点是 FastGPT V4.8.11 版本新增的一个重要功能模块。它允许工作流对数组类型的输入数据进行迭代处理,每次处理数组中的一个元素,并自动执行后续节点,直到完成整个数组的处理。
这个节点的设计灵感来自编程语言中的循环结构,但以可视化的方式呈现。
![循环运行节点](/imgs/fastgpt-loop-node.png)
![批量运行节点](/imgs/fastgpt-loop-node.png)
> 在程序中,节点可以理解为一个个 Function 或者接口。可以理解为它就是一个**步骤**。将多个节点一个个拼接起来,即可一步步的去实现最终的 AI 输出。
【**循环运行**】节点本质上也是一个 Function它的主要职责是自动化地重复执行特定的工作流程。
【**批量运行**】节点本质上也是一个 Function它的主要职责是自动化地重复执行特定的工作流程。
## 核心特性
@@ -41,9 +41,9 @@ weight: 260
## 应用场景
【**循环运行**】节点的主要作用是通过自动化的方式扩展工作流的处理能力,使 FastGPT 能够更好地处理批量任务和复杂的数据处理流程。特别是在处理大规模数据或需要多轮迭代的场景下,循环运行节点能显著提升工作流的效率和自动化程度。
【**批量运行**】节点的主要作用是通过自动化的方式扩展工作流的处理能力,使 FastGPT 能够更好地处理批量任务和复杂的数据处理流程。特别是在处理大规模数据或需要多轮迭代的场景下,批量运行节点能显著提升工作流的效率和自动化程度。
【**循环运行**】节点特别适合以下场景:
【**批量运行**】节点特别适合以下场景:
1. **批量数据处理**
- 批量翻译文本
@@ -64,7 +64,7 @@ weight: 260
### 输入参数设置
【**循环运行**】节点需要配置两个核心输入参数:
【**批量运行**】节点需要配置两个核心输入参数:
1. **数组 (必填)**:接收一个数组类型的输入,可以是:
- 字符串数组 (`Array<string>`)
@@ -95,7 +95,7 @@ weight: 260
### 批量处理数组
假设我们有一个包含多个文本的数组,需要对每个文本进行 AI 处理。这是循环运行节点最基础也最常见的应用场景。
假设我们有一个包含多个文本的数组,需要对每个文本进行 AI 处理。这是批量运行节点最基础也最常见的应用场景。
#### 实现步骤
@@ -114,9 +114,9 @@ weight: 260
return { textArray: texts };
```
2. 配置循环运行节点
2. 配置批量运行节点
![配置循环运行节点](/imgs/fastgpt-loop-node-example-2.png)
![配置批量运行节点](/imgs/fastgpt-loop-node-example-2.png)
- 数组输入:选择上一步代码运行节点的输出变量 `textArray`。
- 循环体内添加一个【AI 对话】节点,用于处理每个文本。这里我们输入的 prompt 为:`请将这段文本翻译成英文`。
@@ -128,7 +128,7 @@ weight: 260
![运行流程](/imgs/fastgpt-loop-node-example-3.png)
1. 【代码运行】节点执行,生成测试数组
2. 【循环运行】节点接收数组,开始遍历
2. 【批量运行】节点接收数组,开始遍历
3. 对每个数组元素:
- 【AI 对话】节点处理当前元素
- 【指定回复】节点输出翻译后的文本
@@ -144,7 +144,7 @@ weight: 260
- 需要维护上下文的连贯性
- 翻译质量需要多轮优化
【**循环运行**】节点可以很好地解决这些问题。
【**批量运行**】节点可以很好地解决这些问题。
#### 实现步骤
@@ -281,9 +281,9 @@ weight: 260
这里我们用到了 [Jina AI 开源的一个强大的正则表达式](https://x.com/JinaAI_/status/1823756993108304135),它能利用所有可能的边界线索和启发式方法来精确切分文本。
2. 配置循环运行节点
2. 配置批量运行节点
![配置循环运行节点](/imgs/fastgpt-loop-node-example-5.png)
![配置批量运行节点](/imgs/fastgpt-loop-node-example-5.png)
- 数组输入:选择上一步代码运行节点的输出变量 `chunks`。
- 循环体内添加一个【代码运行】节点,对源文本进行格式化。

View File

@@ -212,7 +212,7 @@ export default async function (ctx: FunctionContext): Promise<IResponse>{
![](/imgs/translate13.png)
## 循环执
## 批量运
长文反思翻译比较关键的一个部分,就是对多个文本块进行循环反思翻译

View File

@@ -91,9 +91,9 @@ weight: 604
这个过程不仅提高了效率,还最大限度地减少了人为错误的可能性。
## 循环执
## 批量运
为了处理整个长字幕文件,我们需要一个循环执行机制。这是通过一个简单但有效的判断模块实现的:
为了处理整个长字幕文件,我们需要一个批量运行机制。这是通过一个简单但有效的判断模块实现的:
1. 检查当前翻译的文本块是否为最后一个。
2. 如果不是,则将工作流重定向到格式化原文本块节点。

View File

@@ -23,7 +23,6 @@ data:
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": true,
"functionCall": false,
"customCQPrompt": "",
@@ -45,7 +44,6 @@ data:
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": true,
"functionCall": false,
"customCQPrompt": "",
@@ -67,7 +65,6 @@ data:
"usedInClassify": true,
"usedInExtractFields": true,
"usedInToolCall": true,
"usedInQueryExtension": true,
"toolChoice": true,
"functionCall": false,
"customCQPrompt": "",
@@ -89,7 +86,6 @@ data:
"usedInClassify": false,
"usedInExtractFields": false,
"usedInToolCall": false,
"usedInQueryExtension": false,
"toolChoice": true,
"functionCall": false,
"customCQPrompt": "",

View File

@@ -2,12 +2,22 @@ import { ErrType } from '../errorCode';
import { i18nT } from '../../../../web/i18n/utils';
/* team: 503000 */
export enum UserErrEnum {
notUser = 'notUser',
userExist = 'userExist',
unAuthRole = 'unAuthRole',
account_psw_error = 'account_psw_error',
balanceNotEnough = 'balanceNotEnough',
unAuthSso = 'unAuthSso'
}
const errList = [
{
statusText: UserErrEnum.notUser,
message: i18nT('common:code_error.account_not_found')
},
{
statusText: UserErrEnum.userExist,
message: i18nT('common:code_error.account_exist')
},
{
statusText: UserErrEnum.account_psw_error,
message: i18nT('common:code_error.account_error')

View File

@@ -3,7 +3,7 @@ import type {
ChatModelItemType,
FunctionModelItemType,
LLMModelItemType,
VectorModelItemType,
EmbeddingModelItemType,
AudioSpeechModels,
STTModelType,
ReRankModelItemType
@@ -31,16 +31,18 @@ export type FastGPTConfigFileType = {
feConfigs: FastGPTFeConfigsType;
systemEnv: SystemEnvType;
subPlans?: SubPlanType;
llmModels: ChatModelItemType[];
vectorModels: VectorModelItemType[];
reRankModels: ReRankModelItemType[];
audioSpeechModels: AudioSpeechModelType[];
whisperModel: STTModelType;
// Abandon
llmModels?: ChatModelItemType[];
vectorModels?: EmbeddingModelItemType[];
reRankModels?: ReRankModelItemType[];
audioSpeechModels?: TTSModelType[];
whisperModel?: STTModelType;
};
export type FastGPTFeConfigsType = {
show_emptyChat?: boolean;
register_method?: ['email' | 'phone'];
register_method?: ['email' | 'phone' | 'sync'];
login_method?: ['email' | 'phone']; // Attention: login method is diffrent with oauth
find_password_method?: ['email' | 'phone'];
bind_notification_method?: ['email' | 'phone'];
@@ -76,7 +78,6 @@ export type FastGPTFeConfigsType = {
wecom?: {
corpid?: string;
agentid?: string;
secret?: string;
};
microsoft?: {
clientId?: string;

View File

@@ -15,15 +15,13 @@ export enum LLMModelTypeEnum {
all = 'all',
classify = 'classify',
extractFields = 'extractFields',
toolCall = 'toolCall',
queryExtension = 'queryExtension'
toolCall = 'toolCall'
}
export const llmModelTypeFilterMap = {
[LLMModelTypeEnum.all]: 'model',
[LLMModelTypeEnum.classify]: 'usedInClassify',
[LLMModelTypeEnum.extractFields]: 'usedInExtractFields',
[LLMModelTypeEnum.toolCall]: 'usedInToolCall',
[LLMModelTypeEnum.queryExtension]: 'usedInQueryExtension'
[LLMModelTypeEnum.toolCall]: 'usedInToolCall'
};
export enum EmbeddingTypeEnm {

View File

@@ -1,3 +1,4 @@
import { ModelTypeEnum } from './model';
import type { ModelProviderIdType } from './provider';
type PriceType = {
@@ -7,68 +8,73 @@ type PriceType = {
inputPrice?: number; // 1k tokens=n points
outputPrice?: number; // 1k tokens=n points
};
export type LLMModelItemType = PriceType & {
type BaseModelItemType = {
provider: ModelProviderIdType;
model: string;
name: string;
avatar?: string; // model icon, from provider
maxContext: number;
maxResponse: number;
quoteMaxToken: number;
maxTemperature: number;
censor?: boolean;
vision?: boolean;
isActive?: boolean;
isCustom?: boolean;
isDefault?: boolean;
// diff function model
datasetProcess?: boolean; // dataset
usedInClassify?: boolean; // classify
usedInExtractFields?: boolean; // extract fields
usedInToolCall?: boolean; // tool call
usedInQueryExtension?: boolean; // query extension
functionCall: boolean;
toolChoice: boolean;
customCQPrompt: string;
customExtractPrompt: string;
defaultSystemChatPrompt?: string;
defaultConfig?: Record<string, any>;
fieldMap?: Record<string, string>;
// If has requestUrl, it will request the model directly
requestUrl?: string;
requestAuth?: string;
};
export type VectorModelItemType = PriceType & {
provider: ModelProviderIdType;
model: string; // model name
name: string; // show name
avatar?: string;
defaultToken: number; // split text default token
maxToken: number; // model max token
weight: number; // training weight
hidden?: boolean; // Disallow creation
defaultConfig?: Record<string, any>; // post request config
dbConfig?: Record<string, any>; // Custom parameters for storage
queryConfig?: Record<string, any>; // Custom parameters for query
};
export type LLMModelItemType = PriceType &
BaseModelItemType & {
type: ModelTypeEnum.llm;
maxContext: number;
maxResponse: number;
quoteMaxToken: number;
maxTemperature: number;
export type ReRankModelItemType = PriceType & {
provider: ModelProviderIdType;
model: string;
name: string;
requestUrl: string;
requestAuth: string;
};
censor?: boolean;
vision?: boolean;
export type AudioSpeechModelType = PriceType & {
provider: ModelProviderIdType;
model: string;
name: string;
voices: { label: string; value: string; bufferId: string }[];
};
// diff function model
datasetProcess?: boolean; // dataset
usedInClassify?: boolean; // classify
usedInExtractFields?: boolean; // extract fields
usedInToolCall?: boolean; // tool call
export type STTModelType = PriceType & {
provider: ModelProviderIdType;
model: string;
name: string;
};
functionCall: boolean;
toolChoice: boolean;
customCQPrompt: string;
customExtractPrompt: string;
defaultSystemChatPrompt?: string;
defaultConfig?: Record<string, any>;
fieldMap?: Record<string, string>;
};
export type EmbeddingModelItemType = PriceType &
BaseModelItemType & {
type: ModelTypeEnum.embedding;
defaultToken: number; // split text default token
maxToken: number; // model max token
weight: number; // training weight
hidden?: boolean; // Disallow creation
defaultConfig?: Record<string, any>; // post request config
dbConfig?: Record<string, any>; // Custom parameters for storage
queryConfig?: Record<string, any>; // Custom parameters for query
};
export type ReRankModelItemType = PriceType &
BaseModelItemType & {
type: ModelTypeEnum.rerank;
};
export type TTSModelType = PriceType &
BaseModelItemType & {
type: ModelTypeEnum.tts;
voices: { label: string; value: string }[];
};
export type STTModelType = PriceType &
BaseModelItemType & {
type: ModelTypeEnum.stt;
};

View File

@@ -1,9 +1,18 @@
import { i18nT } from '../../../web/i18n/utils';
import type { LLMModelItemType, STTModelType, VectorModelItemType } from './model.d';
import type { LLMModelItemType, STTModelType, EmbeddingModelItemType } from './model.d';
import { getModelProvider, ModelProviderIdType } from './provider';
export enum ModelTypeEnum {
llm = 'llm',
embedding = 'embedding',
tts = 'tts',
stt = 'stt',
rerank = 'rerank'
}
export const defaultQAModels: LLMModelItemType[] = [
{
type: ModelTypeEnum.llm,
provider: 'OpenAI',
model: 'gpt-4o-mini',
name: 'gpt-4o-mini',
@@ -24,8 +33,9 @@ export const defaultQAModels: LLMModelItemType[] = [
}
];
export const defaultVectorModels: VectorModelItemType[] = [
export const defaultVectorModels: EmbeddingModelItemType[] = [
{
type: ModelTypeEnum.embedding,
provider: 'OpenAI',
model: 'text-embedding-3-small',
name: 'Embedding-2',
@@ -36,12 +46,15 @@ export const defaultVectorModels: VectorModelItemType[] = [
}
];
export const defaultWhisperModel: STTModelType = {
provider: 'OpenAI',
model: 'whisper-1',
name: 'whisper-1',
charsPointsPrice: 0
};
export const defaultSTTModels: STTModelType[] = [
{
type: ModelTypeEnum.stt,
provider: 'OpenAI',
model: 'whisper-1',
name: 'whisper-1',
charsPointsPrice: 0
}
];
export const getModelFromList = (
modelList: { provider: ModelProviderIdType; name: string; model: string }[],
@@ -55,15 +68,10 @@ export const getModelFromList = (
};
};
export enum ModelTypeEnum {
chat = 'chat',
embedding = 'embedding',
tts = 'tts',
stt = 'stt'
}
export const modelTypeList = [
{ label: i18nT('common:model.type.chat'), value: ModelTypeEnum.chat },
{ label: i18nT('common:model.type.chat'), value: ModelTypeEnum.llm },
{ label: i18nT('common:model.type.embedding'), value: ModelTypeEnum.embedding },
{ label: i18nT('common:model.type.tts'), value: ModelTypeEnum.tts },
{ label: i18nT('common:model.type.stt'), value: ModelTypeEnum.stt }
{ label: i18nT('common:model.type.stt'), value: ModelTypeEnum.stt },
{ label: i18nT('common:model.type.reRank'), value: ModelTypeEnum.rerank }
];

View File

@@ -7,6 +7,7 @@ export type ModelProviderIdType =
| 'Meta'
| 'MistralAI'
| 'Groq'
| 'Grok'
| 'AliCloud'
| 'Qwen'
| 'Doubao'
@@ -20,14 +21,17 @@ export type ModelProviderIdType =
| 'Baichuan'
| 'StepFun'
| 'Yi'
| 'Siliconflow'
| 'Ollama'
| 'BAAI'
| 'FishAudio'
| 'Intern'
| 'Moka'
| 'Other';
export type ModelProviderType = {
id: ModelProviderIdType;
name: string;
name: any;
avatar: string;
};
@@ -57,6 +61,11 @@ export const ModelProviderList: ModelProviderType[] = [
name: 'MistralAI',
avatar: 'model/mistral'
},
{
id: 'Grok',
name: 'Grok',
avatar: 'model/grok'
},
{
id: 'Groq',
name: 'Groq',
@@ -143,6 +152,21 @@ export const ModelProviderList: ModelProviderType[] = [
name: 'FishAudio',
avatar: 'model/fishaudio'
},
{
id: 'Intern',
name: i18nT('common:model_intern'),
avatar: 'model/intern'
},
{
id: 'Moka',
name: i18nT('common:model_moka'),
avatar: 'model/moka'
},
{
id: 'Siliconflow',
name: i18nT('common:model_siliconflow'),
avatar: 'model/siliconflow'
},
{
id: 'Other',
name: i18nT('common:model_other'),
@@ -153,6 +177,7 @@ export const ModelProviderMap = Object.fromEntries(
ModelProviderList.map((item, index) => [item.id, { ...item, order: index }])
);
export const getModelProvider = (provider: ModelProviderIdType) => {
export const getModelProvider = (provider?: ModelProviderIdType) => {
if (!provider) return ModelProviderMap.Other;
return ModelProviderMap[provider] ?? ModelProviderMap.Other;
};

View File

@@ -33,7 +33,7 @@ export const defaultWhisperConfig: AppWhisperConfigType = {
export const defaultQGConfig: AppQGConfigType = {
open: false,
model: 'gpt-4o-mini',
customPrompt: PROMPT_QUESTION_GUIDE
customPrompt: ''
};
export const defaultChatInputGuideConfig = {

View File

@@ -12,8 +12,9 @@ import { TeamTagSchema as TeamTagsSchemaType } from '@fastgpt/global/support/use
import { StoreEdgeItemType } from '../workflow/type/edge';
import { AppPermission } from '../../support/permission/app/controller';
import { ParentIdType } from '../../common/parentFolder/type';
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
import { FlowNodeInputTypeEnum } from '../../core/workflow/node/constant';
import { WorkflowTemplateBasicType } from '@fastgpt/global/core/workflow/type';
import { SourceMemberType } from '../../support/user/type';
export type AppSchema = {
_id: string;
@@ -63,6 +64,7 @@ export type AppListItemType = {
permission: AppPermission;
inheritPermission?: boolean;
private?: boolean;
sourceMember: SourceMemberType;
};
export type AppDetailType = AppSchema & {

View File

@@ -1,5 +1,7 @@
import { TeamMemberStatusEnum } from 'support/user/team/constant';
import { StoreEdgeItemType } from '../workflow/type/edge';
import { AppChatConfigType, AppSchema } from './type';
import { SourceMemberType } from 'support/user/type';
export type AppVersionSchemaType = {
_id: string;
@@ -20,4 +22,5 @@ export type VersionListItemType = {
time: Date;
isPublish: boolean | undefined;
tmbId: string;
sourceMember: SourceMemberType;
};

View File

@@ -75,5 +75,3 @@ export enum ChatStatusEnum {
running = 'running',
finish = 'finish'
}
export const MARKDOWN_QUOTE_SIGN = 'QUOTE SIGN';

View File

@@ -5,6 +5,7 @@ export type APIFileItem = {
type: 'file' | 'folder';
updateTime: Date;
createTime: Date;
hasChild?: boolean;
};
export type APIFileServer = {

View File

@@ -1,4 +1,4 @@
import type { LLMModelItemType, VectorModelItemType } from '../../core/ai/model.d';
import type { LLMModelItemType, EmbeddingModelItemType } from '../../core/ai/model.d';
import { PermissionTypeEnum } from '../../support/permission/constant';
import { PushDatasetDataChunkProps } from './api';
import {
@@ -11,6 +11,7 @@ import {
import { DatasetPermission } from '../../support/permission/dataset/controller';
import { Permission } from '../../support/permission/controller';
import { APIFileServer, FeishuServer, YuqueServer } from './apiDataset';
import { SourceMemberType } from 'support/user/type';
export type DatasetSchemaType = {
_id: string;
@@ -151,7 +152,7 @@ export type DatasetSimpleItemType = {
_id: string;
avatar: string;
name: string;
vectorModel: VectorModelItemType;
vectorModel: EmbeddingModelItemType;
};
export type DatasetListItemType = {
_id: string;
@@ -162,13 +163,14 @@ export type DatasetListItemType = {
intro: string;
type: `${DatasetTypeEnum}`;
permission: DatasetPermission;
vectorModel: VectorModelItemType;
vectorModel: EmbeddingModelItemType;
inheritPermission: boolean;
private?: boolean;
sourceMember?: SourceMemberType;
};
export type DatasetItemType = Omit<DatasetSchemaType, 'vectorModel' | 'agentModel'> & {
vectorModel: VectorModelItemType;
vectorModel: EmbeddingModelItemType;
agentModel: LLMModelItemType;
permission: DatasetPermission;
};

View File

@@ -34,7 +34,7 @@ export function getSourceNameIcon({
}
} catch (error) {}
return 'file/fill/manual';
return 'file/fill/file';
}
/* get dataset data default index */

View File

@@ -1,4 +1,4 @@
import { VectorModelItemType } from '../ai/model.d';
import { EmbeddingModelItemType } from '../ai/model.d';
import { NodeInputKeyEnum } from './constants';
export type SelectedDatasetType = { datasetId: string }[];

View File

@@ -152,6 +152,7 @@ export enum NodeInputKeyEnum {
datasetSearchExtensionModel = 'datasetSearchExtensionModel',
datasetSearchExtensionBg = 'datasetSearchExtensionBg',
collectionFilterMatch = 'collectionFilterMatch',
authTmbId = 'authTmbId',
// concat dataset
datasetQuoteList = 'system_datasetQuoteList',

View File

@@ -41,6 +41,10 @@ export type ChatDispatchProps = {
teamId: string;
tmbId: string; // App tmbId
};
runningUserInfo: {
teamId: string;
tmbId: string;
};
uid: string; // Who run this workflow
chatId?: string;

View File

@@ -176,6 +176,7 @@ export const checkNodeRunStatus = ({
}
visited.add(edge.source);
// 递归检测后面的 edge如果有其中一个成环则返回 true
const nextEdges = allEdges.filter((item) => item.target === edge.source);
return nextEdges.some((nextEdge) => checkIsCircular(nextEdge, new Set(visited)));
};
@@ -207,7 +208,23 @@ export const checkNodeRunStatus = ({
currentNode: node
});
// check skip(其中一组边,全 skip
// check active(其中一组边,至少有一个 active且没有 waiting 即可运行
if (
commonEdges.length > 0 &&
commonEdges.some((item) => item.status === 'active') &&
commonEdges.every((item) => item.status !== 'waiting')
) {
return 'run';
}
if (
recursiveEdges.length > 0 &&
recursiveEdges.some((item) => item.status === 'active') &&
recursiveEdges.every((item) => item.status !== 'waiting')
) {
return 'run';
}
// check skip其中一组边全是 skiped 则跳过运行)
if (commonEdges.length > 0 && commonEdges.every((item) => item.status === 'skipped')) {
return 'skip';
}
@@ -215,14 +232,6 @@ export const checkNodeRunStatus = ({
return 'skip';
}
// check active有一类边不全是 wait 即可运行)
if (commonEdges.length > 0 && commonEdges.every((item) => item.status !== 'waiting')) {
return 'run';
}
if (recursiveEdges.length > 0 && recursiveEdges.every((item) => item.status !== 'waiting')) {
return 'run';
}
return 'wait';
};

View File

@@ -89,6 +89,13 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
valueType: WorkflowIOValueTypeEnum.string,
value: ''
},
{
key: NodeInputKeyEnum.authTmbId,
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
valueType: WorkflowIOValueTypeEnum.boolean,
value: false
},
{
...Input_Template_UserChatInput,
toolDescription: i18nT('workflow:content_to_search')

View File

@@ -31,10 +31,7 @@ export const AiQueryExtension: FlowNodeTemplateType = {
showStatus: true,
version: '481',
inputs: [
{
...Input_Template_SelectAIModel,
llmModelType: LLMModelTypeEnum.queryExtension
},
Input_Template_SelectAIModel,
{
key: NodeInputKeyEnum.aiSystemPrompt,
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],

View File

@@ -89,6 +89,7 @@ export type NodeTemplateListItemType = {
hasTokenFee?: boolean; // 是否配置积分
instructions?: string; // 使用说明
courseUrl?: string; // 教程链接
sourceMember?: SourceMember;
};
export type NodeTemplateListType = {

View File

@@ -12,6 +12,7 @@ export type CreateTeamProps = {
avatar?: string;
defaultTeam?: boolean;
memberName?: string;
memberAvatar?: string;
};
export type UpdateTeamProps = Omit<ThirdPartyAccountType, 'externalWorkflowVariable'> & {
name?: string;

View File

@@ -5,8 +5,6 @@ export const OrgMemberCollectionName = 'team_org_members';
export const getOrgChildrenPath = (org: OrgSchemaType) => `${org.path}/${org.pathId}`;
// export enum OrgMemberRole {
// owner = 'owner',
// admin = 'admin',
// member = 'member'
// }
export enum SyncOrgSourceEnum {
wecom = 'wecom'
}

View File

@@ -13,6 +13,7 @@ type OrgSchemaType = {
};
type OrgMemberSchemaType = {
_id: string;
teamId: string;
orgId: string;
tmbId: string;
@@ -20,6 +21,6 @@ type OrgMemberSchemaType = {
type OrgType = Omit<OrgSchemaType, 'avatar'> & {
avatar: string;
members: OrgMemberSchemaType[];
permission: TeamPermission;
members: OrgMemberSchemaType[];
};

View File

@@ -44,6 +44,7 @@ export type TeamMemberSchema = {
name: string;
role: `${TeamMemberRoleEnum}`;
status: `${TeamMemberStatusEnum}`;
avatar: string;
defaultTeam: boolean;
};

View File

@@ -1,12 +1,12 @@
import { TeamPermission } from '../permission/user/controller';
import { UserStatusEnum } from './constant';
import { TeamMemberStatusEnum } from './team/constant';
import { TeamTmbItemType } from './team/type';
export type UserModelSchema = {
_id: string;
username: string;
password: string;
avatar: string;
promotionRate: number;
inviterId?: string;
openaiKey: string;
@@ -22,7 +22,7 @@ export type UserModelSchema = {
export type UserType = {
_id: string;
username: string;
avatar: string;
avatar: string; // it should be team member's avatar after 4.8.18
timezone: string;
promotionRate: UserModelSchema['promotionRate'];
team: TeamTmbItemType;
@@ -30,3 +30,9 @@ export type UserType = {
notificationAccount?: string;
permission: TeamPermission;
};
export type SourceMemberType = {
name: string;
avatar: string;
status: `${TeamMemberStatusEnum}`;
};

View File

@@ -6,6 +6,22 @@ export type CreateTrainingUsageProps = {
datasetId: string;
};
export type GetUsageProps = {
dateStart: Date;
dateEnd: Date;
sources?: UsageSourceEnum[];
teamMemberIds?: string[];
projectName?: string;
};
export type GetUsageDashboardProps = GetUsageProps & {
unit: 'day' | 'month';
};
export type GetUsageDashboardResponseItem = {
date: Date;
totalPoints: number;
};
export type ConcatUsageProps = UsageListItemCountType & {
teamId: string;
tmbId: string;

View File

@@ -18,30 +18,30 @@ export const UsageSourceMap = {
label: i18nT('common:core.chat.logs.online')
},
[UsageSourceEnum.api]: {
label: 'Api'
label: 'API'
},
[UsageSourceEnum.shareLink]: {
label: i18nT('common:core.chat.logs.free_login')
},
[UsageSourceEnum.training]: {
label: 'dataset.Training Name'
label: i18nT('common:dataset.Training Name')
},
[UsageSourceEnum.cronJob]: {
label: i18nT('common:cron_job_run_app')
},
[UsageSourceEnum.feishu]: {
label: i18nT('user:usage.feishu')
label: i18nT('account_usage:feishu')
},
[UsageSourceEnum.official_account]: {
label: i18nT('user:usage.official_account')
label: i18nT('account_usage:official_account')
},
[UsageSourceEnum.share]: {
label: i18nT('user:usage.share')
label: i18nT('account_usage:share')
},
[UsageSourceEnum.wecom]: {
label: i18nT('user:usage.wecom')
label: i18nT('account_usage:wecom')
},
[UsageSourceEnum.dingtalk]: {
label: i18nT('user:usage.dingtalk')
label: i18nT('account_usage:dingtalk')
}
};

View File

@@ -1,3 +1,4 @@
import { SourceMemberType } from '../../../support/user/type';
import { CreateUsageProps } from './api';
import { UsageSourceEnum } from './constants';
@@ -10,6 +11,7 @@ export type UsageListItemCountType = {
// deprecated
tokens?: number;
};
export type UsageListItemType = UsageListItemCountType & {
moduleName: string;
amount: number;
@@ -28,4 +30,5 @@ export type UsageItemType = {
source: UsageSchemaType['source'];
totalPoints: number;
list: UsageSchemaType['list'];
sourceMember: SourceMemberType;
};

View File

@@ -12,7 +12,8 @@ const staticPluginList = [
'DingTalkWebhook',
'WeWorkWebhook',
'google',
'bing'
'bing',
'delay'
];
// Run in worker thread (Have npm packages)
const packagePluginList = [

View File

@@ -0,0 +1,18 @@
import { delay } from '@fastgpt/global/common/system/utils';
type Props = {
ms: number;
};
type Response = Promise<Number>;
const main = async ({ ms }: Props): Response => {
if (typeof ms !== 'number' || ms <= 0 || ms > 300000) {
return ms;
}
await delay(ms);
return ms;
};
export default main;

View File

@@ -0,0 +1,318 @@
{
"author": "collin",
"version": "4817",
"name": "流程等待",
"avatar": "core/workflow/template/sleep",
"intro": "让工作流等待指定时间后运行",
"showStatus": true,
"weight": 1,
"isTool": true,
"templateType": "tools",
"workflow": {
"nodes": [
{
"nodeId": "pluginInput",
"name": "workflow:template.plugin_start",
"intro": "workflow:intro_plugin_input",
"avatar": "core/workflow/template/workflowStart",
"flowNodeType": "pluginInput",
"showStatus": false,
"position": {
"x": 627.6352390819724,
"y": -165.05298493910118
},
"version": "481",
"inputs": [
{
"renderTypeList": ["numberInput", "reference"],
"selectedTypeIndex": 0,
"valueType": "number",
"canEdit": true,
"key": "延迟时长",
"label": "延迟时长",
"description": "需要暂停的时间,单位毫秒",
"defaultValue": 1000,
"list": [
{
"label": "",
"value": ""
}
],
"maxFiles": 5,
"canSelectFile": true,
"canSelectImg": true,
"required": true,
"toolDescription": "需要暂停的时间,单位毫秒",
"max": 300000,
"min": 1
}
],
"outputs": [
{
"id": "ms",
"valueType": "number",
"key": "延迟时长",
"label": "延迟时长",
"type": "hidden"
}
]
},
{
"nodeId": "pluginOutput",
"name": "common:core.module.template.self_output",
"intro": "workflow:intro_custom_plugin_output",
"avatar": "core/workflow/template/pluginOutput",
"flowNodeType": "pluginOutput",
"showStatus": false,
"position": {
"x": 1921.839722563351,
"y": -160.05298493910115
},
"version": "481",
"inputs": [
{
"renderTypeList": ["reference"],
"valueType": "any",
"canEdit": true,
"key": "result",
"label": "result",
"isToolOutput": true,
"description": "",
"required": true,
"value": ["zCJC6zw7c14i", "httpRawResponse"]
}
],
"outputs": []
},
{
"nodeId": "pluginConfig",
"name": "common:core.module.template.system_config",
"intro": "",
"avatar": "core/workflow/template/systemConfig",
"flowNodeType": "pluginConfig",
"position": {
"x": 184.66337662472682,
"y": -216.05298493910115
},
"version": "4811",
"inputs": [],
"outputs": []
},
{
"nodeId": "zCJC6zw7c14i",
"name": "HTTP 请求",
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
"avatar": "core/workflow/template/httpRequest",
"flowNodeType": "httpRequest468",
"showStatus": true,
"position": {
"x": 1154.4041630064592,
"y": -455.0529849391012
},
"version": "481",
"inputs": [
{
"key": "system_addInputParam",
"renderTypeList": ["addInputParam"],
"valueType": "dynamic",
"label": "",
"required": false,
"description": "common:core.module.input.description.HTTP Dynamic Input",
"customInputConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"arrayAny",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": true
},
"valueDesc": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpMethod",
"renderTypeList": ["custom"],
"valueType": "string",
"label": "",
"value": "POST",
"required": true,
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpTimeout",
"renderTypeList": ["custom"],
"valueType": "number",
"label": "",
"value": 30,
"min": 5,
"max": 600,
"required": true,
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpReqUrl",
"renderTypeList": ["hidden"],
"valueType": "string",
"label": "",
"description": "common:core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"value": "delay",
"valueDesc": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpHeader",
"renderTypeList": ["custom"],
"valueType": "any",
"value": [],
"label": "",
"description": "common:core.module.input.description.Http Request Header",
"placeholder": "common:core.module.input.description.Http Request Header",
"required": false,
"valueDesc": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpParams",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpJsonBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": "{\n\"ms\": {{$pluginInput.ms$}}\n}",
"label": "",
"required": false,
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpFormBody",
"renderTypeList": ["hidden"],
"valueType": "any",
"value": [],
"label": "",
"required": false,
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
},
{
"key": "system_httpContentType",
"renderTypeList": ["hidden"],
"valueType": "string",
"value": "json",
"label": "",
"required": false,
"valueDesc": "",
"description": "",
"debugLabel": "",
"toolDescription": ""
}
],
"outputs": [
{
"id": "error",
"key": "error",
"label": "workflow:request_error",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"required": true,
"label": "workflow:raw_response",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
},
{
"id": "system_addOutputParam",
"key": "system_addOutputParam",
"type": "dynamic",
"valueType": "dynamic",
"label": "输出字段提取",
"customFieldConfig": {
"selectValueTypeList": [
"string",
"number",
"boolean",
"object",
"arrayString",
"arrayNumber",
"arrayBoolean",
"arrayObject",
"arrayAny",
"any",
"chatHistory",
"datasetQuote",
"dynamic",
"selectApp",
"selectDataset"
],
"showDescription": false,
"showDefaultValue": false
},
"description": "可以通过 JSONPath 语法来提取响应值中的指定字段",
"valueDesc": ""
}
]
}
],
"edges": [
{
"source": "pluginInput",
"target": "zCJC6zw7c14i",
"sourceHandle": "pluginInput-source-right",
"targetHandle": "zCJC6zw7c14i-target-left"
},
{
"source": "zCJC6zw7c14i",
"target": "pluginOutput",
"sourceHandle": "zCJC6zw7c14i-source-right",
"targetHandle": "pluginOutput-target-left"
}
],
"chatConfig": {
"welcomeText": ""
}
}
}

View File

@@ -0,0 +1,21 @@
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
import { ApiRequestProps } from '../../type/next';
export function parsePaginationRequest(req: ApiRequestProps) {
const {
pageSize = 10,
pageNum = 1,
offset = 0
} = Object.keys(req.body).includes('pageSize')
? req.body
: Object.keys(req.query).includes('pageSize')
? req.query
: {};
if (!pageSize || (pageNum === undefined && offset === undefined)) {
throw new Error(CommonErrEnum.missingParams);
}
return {
pageSize: Number(pageSize),
offset: offset ? Number(offset) : (Number(pageNum) - 1) * Number(pageSize)
};
}

View File

@@ -2,7 +2,7 @@ import type { NextApiResponse, NextApiRequest } from 'next';
import NextCors from 'nextjs-cors';
export async function withNextCors(req: NextApiRequest, res: NextApiResponse) {
const methods = ['GET', 'eHEAD', 'PUT', 'PATCH', 'POST', 'DELETE'];
const methods = ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'];
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',');
const origin = req.headers.origin;

View File

@@ -1,6 +1,5 @@
import { ApiRequestProps } from '../../type/next';
import requestIp from 'request-ip';
import { ERROR_ENUM } from '@fastgpt/global/common/error/errorCode';
import { authFrequencyLimit } from '../system/frequencyLimit/utils';
import { addSeconds } from 'date-fns';
import { NextApiResponse } from 'next';
@@ -9,7 +8,17 @@ import { jsonRes } from '../response';
// unit: times/s
// how to use?
// export default NextAPI(useQPSLimit(10), handler); // limit 10 times per second for a ip
export function useReqFrequencyLimit(seconds: number, limit: number, force = false) {
export function useIPFrequencyLimit({
id,
seconds,
limit,
force = false
}: {
id: string;
seconds: number;
limit: number;
force?: boolean;
}) {
return async (req: ApiRequestProps, res: NextApiResponse) => {
const ip = requestIp.getClientIp(req);
if (!ip || (process.env.USE_IP_LIMIT !== 'true' && !force)) {
@@ -17,14 +26,14 @@ export function useReqFrequencyLimit(seconds: number, limit: number, force = fal
}
try {
await authFrequencyLimit({
eventId: 'ip-qps-limit' + ip,
eventId: `ip-qps-limit-${id}-` + ip,
maxAmount: limit,
expiredTime: addSeconds(new Date(), seconds)
});
} catch (_) {
jsonRes(res, {
code: 429,
error: ERROR_ENUM.tooManyRequest
error: `Too many request, request ${limit} times every ${seconds} seconds`
});
}
};

View File

@@ -33,7 +33,15 @@ export const jsonRes = <T = any>(
addLog.error(`Api response error: ${url}`, ERROR_RESPONSE[errResponseKey]);
return res.status(code).json(ERROR_RESPONSE[errResponseKey]);
res.status(code);
if (message) {
res.send(message);
} else {
res.json(ERROR_RESPONSE[errResponseKey]);
}
return;
}
// another error

View File

@@ -6,8 +6,7 @@ import { FastGPTProUrl } from '../constants';
export const getFastGPTConfigFromDB = async () => {
if (!FastGPTProUrl) {
return {
config: {} as FastGPTConfigFileType,
configId: undefined
config: {} as FastGPTConfigFileType
};
}
@@ -18,9 +17,35 @@ export const getFastGPTConfigFromDB = async () => {
});
const config = res?.value || {};
// 利用配置文件的创建时间(更新时间)来做缓存,如果前端命中缓存,则不需要再返回配置文件
global.systemInitBufferId = res ? res.createTime.getTime().toString() : undefined;
return {
configId: res ? String(res._id) : undefined,
config: config as FastGPTConfigFileType
};
};
export const updateFastGPTConfigBuffer = async () => {
const res = await MongoSystemConfigs.findOne({
type: SystemConfigsTypeEnum.fastgpt
}).sort({
createTime: -1
});
if (!res) return;
res.createTime = new Date();
await res.save();
global.systemInitBufferId = res.createTime.getTime().toString();
};
export const reloadFastGPTConfigBuffer = async () => {
const res = await MongoSystemConfigs.findOne({
type: SystemConfigsTypeEnum.fastgpt
}).sort({
createTime: -1
});
if (!res) return;
global.systemInitBufferId = res.createTime.getTime().toString();
};

View File

@@ -13,15 +13,6 @@ export const initFastGPTConfig = (config?: FastGPTConfigFileType) => {
global.feConfigs = config.feConfigs;
global.systemEnv = config.systemEnv;
global.subPlans = config.subPlans;
global.llmModels = config.llmModels;
global.llmModelPriceType = global.llmModels.some((item) => typeof item.inputPrice === 'number')
? 'IO'
: 'Tokens';
global.vectorModels = config.vectorModels;
global.audioSpeechModels = config.audioSpeechModels;
global.whisperModel = config.whisperModel;
global.reRankModels = config.reRankModels;
};
export const systemStartCb = () => {

View File

@@ -2,7 +2,7 @@
import { PgVectorCtrl } from './pg/class';
import { getVectorsByText } from '../../core/ai/embedding';
import { InsertVectorProps } from './controller.d';
import { VectorModelItemType } from '@fastgpt/global/core/ai/model.d';
import { EmbeddingModelItemType } from '@fastgpt/global/core/ai/model.d';
import { MILVUS_ADDRESS, PG_ADDRESS } from './constants';
import { MilvusCtrl } from './milvus/class';
@@ -28,7 +28,7 @@ export const insertDatasetDataVector = async ({
...props
}: InsertVectorProps & {
query: string;
model: VectorModelItemType;
model: EmbeddingModelItemType;
}) => {
const { vectors, tokens } = await getVectorsByText({
model,

View File

@@ -1,5 +1,6 @@
import type { NextApiResponse } from 'next';
import { getAIApi } from '../config';
import { getTTSModel } from '../model';
export async function text2Speech({
res,
@@ -18,15 +19,26 @@ export async function text2Speech({
voice: string;
speed?: number;
}) {
const modelData = getTTSModel(model)!;
const ai = getAIApi();
const response = await ai.audio.speech.create({
model,
// @ts-ignore
voice,
input,
response_format: 'mp3',
speed
});
const response = await ai.audio.speech.create(
{
model,
// @ts-ignore
voice,
input,
response_format: 'mp3',
speed
},
modelData.requestUrl && modelData.requestAuth
? {
path: modelData.requestUrl,
headers: {
Authorization: `Bearer ${modelData.requestAuth}`
}
}
: {}
);
const readableStream = response.body as unknown as NodeJS.ReadableStream;
readableStream.pipe(res);

View File

@@ -2,6 +2,7 @@ import fs from 'fs';
import { getAxiosConfig } from '../config';
import axios from 'axios';
import FormData from 'form-data';
import { getSTTModel } from '../model';
export const aiTranscriptions = async ({
model,
@@ -14,13 +15,21 @@ export const aiTranscriptions = async ({
data.append('model', model);
data.append('file', fileStream);
const modelData = getSTTModel(model);
const aiAxiosConfig = getAxiosConfig();
const { data: result } = await axios<{ text: string }>({
method: 'post',
baseURL: aiAxiosConfig.baseUrl,
url: '/audio/transcriptions',
...(modelData.requestUrl
? { url: modelData.requestUrl }
: {
baseURL: aiAxiosConfig.baseUrl,
url: modelData.requestUrl || '/audio/transcriptions'
}),
headers: {
Authorization: aiAxiosConfig.authorization,
Authorization: modelData.requestAuth
? `Bearer ${modelData.requestAuth}`
: aiAxiosConfig.authorization,
...data.getHeaders()
},
data: data

View File

@@ -7,14 +7,14 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
import { addLog } from '../../common/system/log';
import { i18nT } from '../../../web/i18n/utils';
import { OpenaiAccountType } from '@fastgpt/global/support/user/team/type';
import { getLLMModel } from './model';
export const openaiBaseUrl = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
export const getAIApi = (props?: { userKey?: OpenaiAccountType; timeout?: number }) => {
const { userKey, timeout } = props || {};
const baseUrl =
userKey?.baseUrl || global?.systemEnv?.oneapiUrl || process.env.ONEAPI_URL || openaiBaseUrl;
const baseUrl = userKey?.baseUrl || global?.systemEnv?.oneapiUrl || openaiBaseUrl;
const apiKey = userKey?.key || global?.systemEnv?.chatApiKey || process.env.CHAT_API_KEY || '';
return new OpenAI({
@@ -29,8 +29,7 @@ export const getAIApi = (props?: { userKey?: OpenaiAccountType; timeout?: number
export const getAxiosConfig = (props?: { userKey?: OpenaiAccountType }) => {
const { userKey } = props || {};
const baseUrl =
userKey?.baseUrl || global?.systemEnv?.oneapiUrl || process.env.ONEAPI_URL || openaiBaseUrl;
const baseUrl = userKey?.baseUrl || global?.systemEnv?.oneapiUrl || openaiBaseUrl;
const apiKey = userKey?.key || global?.systemEnv?.chatApiKey || process.env.CHAT_API_KEY || '';
return {
@@ -63,12 +62,23 @@ export const createChatCompletion = async <T extends CompletionsBodyType>({
getEmptyResponseTip: () => string;
}> => {
try {
const modelConstantsData = getLLMModel(body.model);
const formatTimeout = timeout ? timeout : body.stream ? 60000 : 600000;
const ai = getAIApi({
userKey,
timeout: formatTimeout
});
const response = await ai.chat.completions.create(body, options);
const response = await ai.chat.completions.create(body, {
...options,
...(modelConstantsData.requestUrl ? { path: modelConstantsData.requestUrl } : {}),
headers: {
...options?.headers,
...(modelConstantsData.requestAuth
? { Authorization: `Bearer ${modelConstantsData.requestAuth}` }
: {})
}
});
const isStreamResponse =
typeof response === 'object' &&

View File

@@ -1,11 +0,0 @@
{
"provider": "OpenAI",
"model": "text-embedding-ada-002",
"name": "text-embedding-ada-002",
"defaultToken": 512, // 默认分块 token
"maxToken": 3000, // 最大分块 token
"weight": 0, // 权重
"charsPointsPrice": 0 // 积分/1k token
}

View File

@@ -1,33 +0,0 @@
{
"provider": "OpenAI",
"model": "gpt-4o-mini",
"name": "GPT-4o-mini", // alias
"maxContext": 125000, // 最大上下文
"maxResponse": 16000, // 最大回复
"quoteMaxToken": 60000, // 最大引用
"maxTemperature": 1.2, // 最大温度
"presencePenaltyRange": [-2, 2], // 惩罚系数范围
"frequencyPenaltyRange": [-2, 2], // 频率惩罚系数范围
"responseFormatList": ["text", "json_object", "json_schema"], // 响应格式
"showStopSign": true, // 是否显示停止符号
"vision": true, // 是否支持图片识别
"toolChoice": true, // 是否支持工具调用
"functionCall": false, // 是否支持函数调用(一般都可以 false 了,基本不用了)
"defaultSystemChatPrompt": "", // 默认系统提示
"datasetProcess": true, // 用于知识库文本处理
"usedInClassify": true, // 用于问题分类
"customCQPrompt": "", // 自定义问题分类提示
"usedInExtractFields": true, // 用于提取字段
"customExtractPrompt": "", // 自定义提取提示
"usedInToolCall": true, // 用于工具调用
"usedInQueryExtension": true, // 用于问题优化
"defaultConfig": {}, // 额外的自定义 body
"fieldMap": {}, // body 字段映射
"censor": false, // 是否开启敏感词过滤
"charsPointsPrice": 0 // n 积分/1k token
}

View File

@@ -0,0 +1,4 @@
{
"provider": "AliCloud",
"list": []
}

View File

@@ -0,0 +1,17 @@
{
"provider": "BAAI",
"list": [
{
"model": "bge-m3",
"name": "bge-m3",
"defaultToken": 512,
"maxToken": 8000,
"type": "embedding"
},
{
"model": "bge-reranker-v2-m3",
"name": "bge-reranker-v2-m3",
"type": "rerank"
}
]
}

View File

@@ -0,0 +1,4 @@
{
"provider": "Baichuan",
"list": []
}

View File

@@ -0,0 +1,147 @@
{
"provider": "ChatGLM",
"list": [
{
"model": "glm-4-air",
"name": "glm-4-air",
"maxContext": 128000,
"maxResponse": 4000,
"quoteMaxToken": 120000,
"maxTemperature": 0.99,
"vision": false,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "glm-4-flash",
"name": "glm-4-flash",
"maxContext": 128000,
"maxResponse": 4000,
"quoteMaxToken": 120000,
"maxTemperature": 0.99,
"vision": false,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "glm-4-long",
"name": "glm-4-long",
"maxContext": 1000000,
"maxResponse": 4000,
"quoteMaxToken": 900000,
"maxTemperature": 0.99,
"vision": false,
"toolChoice": false,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "glm-4-plus",
"name": "GLM-4-plus",
"maxContext": 128000,
"maxResponse": 4000,
"quoteMaxToken": 120000,
"maxTemperature": 0.99,
"vision": false,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "glm-4v-flash",
"name": "glm-4v-flash",
"maxContext": 8000,
"maxResponse": 1000,
"quoteMaxToken": 6000,
"maxTemperature": 0.99,
"vision": true,
"toolChoice": false,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "glm-4v-plus",
"name": "GLM-4v-plus",
"maxContext": 8000,
"maxResponse": 1000,
"quoteMaxToken": 6000,
"maxTemperature": 0.99,
"vision": true,
"toolChoice": false,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "embedding-3",
"name": "embedding-3",
"defaultToken": 512,
"maxToken": 8000,
"defaultConfig": {
"dimensions": 1024
},
"type": "embedding"
}
]
}

View File

@@ -0,0 +1,93 @@
{
"provider": "Claude",
"list": [
{
"model": "claude-3-5-haiku-20241022",
"name": "claude-3-5-haiku-20241022",
"maxContext": 200000,
"maxResponse": 8000,
"quoteMaxToken": 100000,
"maxTemperature": 1,
"vision": false,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "claude-3-5-sonnet-20240620",
"name": "Claude-3-5-sonnet-20240620",
"maxContext": 200000,
"maxResponse": 8000,
"quoteMaxToken": 100000,
"maxTemperature": 1,
"vision": true,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "claude-3-5-sonnet-20241022",
"name": "Claude-3-5-sonnet-20241022",
"maxContext": 200000,
"maxResponse": 8000,
"quoteMaxToken": 100000,
"maxTemperature": 1,
"vision": true,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
},
{
"model": "claude-3-opus-20240229",
"name": "claude-3-opus-20240229",
"maxContext": 200000,
"maxResponse": 4096,
"quoteMaxToken": 100000,
"maxTemperature": 1,
"vision": true,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {},
"fieldMap": {},
"type": "llm"
}
]
}

View File

@@ -0,0 +1,49 @@
{
"provider": "DeepSeek",
"list": [
{
"model": "deepseek-chat",
"name": "Deepseek-chat",
"maxContext": 64000,
"maxResponse": 4096,
"quoteMaxToken": 60000,
"maxTemperature": 1.5,
"vision": false,
"toolChoice": true,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"type": "llm"
},
{
"model": "deepseek-reasoner",
"name": "Deepseek-reasoner",
"maxContext": 64000,
"maxResponse": 4096,
"quoteMaxToken": 60000,
"maxTemperature": 1.5,
"vision": false,
"toolChoice": false,
"functionCall": false,
"defaultSystemChatPrompt": "",
"datasetProcess": true,
"usedInClassify": true,
"customCQPrompt": "",
"usedInExtractFields": true,
"usedInQueryExtension": true,
"customExtractPrompt": "",
"usedInToolCall": true,
"defaultConfig": {
"temperature": null
},
"fieldMap": {},
"type": "llm"
}
]
}

Some files were not shown because too many files have changed in this diff Show More