diff --git a/README.md b/README.md index f45e2fd51..a70295bfe 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b * [系统配置文件说明](https://doc.fastgpt.run/docs/development/configuration/) * [多模型配置](https://doc.fastgpt.run/docs/installation/one-api/) * [版本升级](https://doc.fastgpt.run/docs/installation/upgrading) -* [API 文档](https://kjqvjse66l.feishu.cn/docx/DmLedTWtUoNGX8xui9ocdUEjnNh?pre_pathname=%2Fdrive%2Fhome%2F) +* [API 文档](https://doc.fastgpt.run/docs/development/openapi?pre_pathname=%2Fdrive%2Fhome%2F) ## 🏘️ 社区交流群 @@ -118,4 +118,4 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b 1. 允许作为后台服务直接商用,但不允许直接使用 saas 服务商用。 2. 需保留相关版权信息。 3. 完整请查看 [FastGPT Open Source License](./LICENSE) -4. 联系方式:yujinlong@sealos.io, [点击查看定价策略](https://fael3z0zfze.feishu.cn/docx/F155dbirfo8vDDx2WgWc6extnwf) +4. 联系方式:yujinlong@sealos.io, [点击查看定价策略](https://doc.fastgpt.run/docs/commercial) diff --git a/docSite/assets/imgs/fastgpt-api2.png b/docSite/assets/imgs/fastgpt-api2.png new file mode 100644 index 000000000..4d9e8b2d5 Binary files /dev/null and b/docSite/assets/imgs/fastgpt-api2.png differ diff --git a/docSite/assets/imgs/getKbId.png b/docSite/assets/imgs/getKbId.png new file mode 100644 index 000000000..8b12c1165 Binary files /dev/null and b/docSite/assets/imgs/getKbId.png differ diff --git a/docSite/content/docs/commercial.md b/docSite/content/docs/commercial.md index 63fe82138..d849cd5a6 100644 --- a/docSite/content/docs/commercial.md +++ b/docSite/content/docs/commercial.md @@ -20,20 +20,24 @@ weight: 20 1. 自定义 title 和 logo 2. 用户注册,支付 (已有微信扫码支付,后续会补充支付方式) -3. 团队空间 (下期开发) -4. 完善的 OpenAPI -5. 高级编排额外插件 -6. 后台管理系统 (已有,持续更新) +3. API 访问限制,可配置:额度、过期时间 +4. 团队空间 (计划) +5. 完善的 OpenAPI(计划) +6. 高级编排额外插件(计划) +7. 后台管理系统 + a. 查询:用户、支付、应用、知识库 + b. 变更:用户 + c. 新增:用户 {{% /alert %}} ### 商业版定价 #### 交付费用 -+ 使用 [Sealos 公有云](https://sealos.io)交付:1w/年/套 (直接在 Sealos 公有云充值,便可**免费获取 FastGPT 商业版 License**,同时您充值的金额可用于部署其他云资源,相当于白嫖了一个 FastGPT 商业版)。 -+ 渠道商使用 Sealos 交付:返现 20% 成交额。 -+ 私有服务器交付:2w/年/套(如需部署支持,按技术服务费计算) -+ 渠道商私有服务器交付:1.3w/年/套(渠道商合同单独约谈,累计 5 套以上可签) ++ 使用 [Sealos 公有云](https://sealos.io)部署:1万元/年/套 (无部署费用。赠送 8000 sealos 公有云额度,可用于 FastGPT 或其他云资源)。 ++ 渠道商使用 Sealos 部署:返现 20% 成交额。 ++ 私有服务器部署:2万元/年/套(如需部署支持,按技术服务费计算) ++ 渠道商私有服务器部署:1.3万元/年/套(渠道商合同单独约谈,累计 5 套以上可签) #### 用户注册数量费用(按注册量算,不计量分享和 API) @@ -69,7 +73,8 @@ weight: 20 ## 联系方式 -通过邮箱联系 yujinlong@sealos.io +微信: allence1004 +邮箱: yujinlong@sealos.io ## QA @@ -77,7 +82,7 @@ weight: 20 完整版应用 = 开源版镜像 + 商业版镜像 - 我们会提供一个商业版镜像给你使用,还会提供一个简单的后台管理系统(目前只设置了简单的查询功能) + 我们会提供一个商业版镜像给你使用,该镜像需要一个 license 启动,license 有效期为 1 年。此外,还会提供一个简单的后台管理系统(目前只设置了简单的查询功能) 2. 二次开发如何操作? diff --git a/docSite/content/docs/custom-models/chatglm2-m3e.md b/docSite/content/docs/custom-models/chatglm2-m3e.md index 99753dbaa..a6c2f0533 100644 --- a/docSite/content/docs/custom-models/chatglm2-m3e.md +++ b/docSite/content/docs/custom-models/chatglm2-m3e.md @@ -62,19 +62,18 @@ Authorization 为 sk-aaabbbcccdddeeefffggghhhiiijjjkkk。model 为刚刚在 One 修改 config.json 配置文件,在 VectorModels 中加入 chatglm2 和 M3E 模型: ```json - "ChatModels": [ - //已有模型 - { - "model": "chatglm2", - "name": "chatglm2", - "contextMaxToken": 8000, - "quoteMaxToken": 4000, - "maxTemperature": 1.2, - "price": 0, - "defaultSystem": "" - } - ], - +"ChatModels": [ + //已有模型 + { + "model": "chatglm2", + "name": "chatglm2", + "contextMaxToken": 8000, + "quoteMaxToken": 4000, + "maxTemperature": 1.2, + "price": 0, + "defaultSystem": "" + } +], "VectorModels": [ { "model": "text-embedding-ada-002", diff --git a/docSite/content/docs/custom-models/chatglm2.md b/docSite/content/docs/custom-models/chatglm2.md index a2f1840d4..64bc009e5 100644 --- a/docSite/content/docs/custom-models/chatglm2.md +++ b/docSite/content/docs/custom-models/chatglm2.md @@ -99,21 +99,21 @@ Authorization 为 sk-aaabbbcccdddeeefffggghhhiiijjjkkk。model 为刚刚在 One ## 接入 FastGPT -修改 config.json 配置文件,在 VectorModels 中加入 chatglm2 和 M3E 模型: +修改 config.json 配置文件,在 VectorModels 中加入 chatglm2 模型: ```json - "ChatModels": [ - //已有模型 - { - "model": "chatglm2", - "name": "chatglm2", - "contextMaxToken": 8000, - "quoteMaxToken": 4000, - "maxTemperature": 1.2, - "price": 0, - "defaultSystem": "" - } - ], +"ChatModels": [ + //已有模型 + { + "model": "chatglm2", + "name": "chatglm2", + "contextMaxToken": 8000, + "quoteMaxToken": 4000, + "maxTemperature": 1.2, + "price": 0, + "defaultSystem": "" + } +] ``` ## 测试使用 diff --git a/docSite/content/docs/custom-models/m3e.md b/docSite/content/docs/custom-models/m3e.md index 0c232c6ec..31454e3fd 100644 --- a/docSite/content/docs/custom-models/m3e.md +++ b/docSite/content/docs/custom-models/m3e.md @@ -66,7 +66,7 @@ Authorization 为 sk-key。model 为刚刚在 One API 填写的自定义模型 "defaultToken": 500, "maxToken": 1800 } -], +] ``` ## 测试使用 diff --git a/docSite/content/docs/development/configuration.md b/docSite/content/docs/development/configuration.md index 8a47cfdac..7eda9ce26 100644 --- a/docSite/content/docs/development/configuration.md +++ b/docSite/content/docs/development/configuration.md @@ -22,17 +22,6 @@ weight: 520 这里介绍一些基础的配置字段: ```json -// 这个配置会控制前端的一些样式 -"FeConfig": { - "show_emptyChat": true, // 对话页面,空内容时,是否展示介绍页 - "show_register": false, // 是否展示注册按键(包括忘记密码,注册账号和三方登录) - "show_appStore": false, // 是否展示应用市场(不过目前权限还没做好,放开也没用) - "show_userDetail": false, // 是否展示用户详情(账号余额、OpenAI 绑定) - "show_git": true, // 是否展示 Git - "systemTitle": "FastGPT", // 系统的 title - "authorText": "Made by FastGPT Team.", // 签名 -}, -... ... // 这个配置文件是系统级参数 "SystemParams": { @@ -47,22 +36,11 @@ weight: 520 ```json { - "FeConfig": { - "show_emptyChat": true, - "show_register": false, - "show_appStore": false, - "show_userDetail": false, - "show_git": true, - "systemTitle": "FastGPT", - "authorText": "Made by FastGPT Team.", - "scripts": [] - }, "SystemParams": { "vectorMaxProcess": 15, "qaMaxProcess": 15, "pgIvfflatProbe": 20 }, - "plugins": {}, "ChatModels": [ { "model": "gpt-3.5-turbo", @@ -92,12 +70,6 @@ weight: 520 "defaultSystem": "" } ], - "QAModel": { - "model": "gpt-3.5-turbo-16k", - "name": "GPT35-16k", - "maxToken": 16000, - "price": 0 - }, "VectorModels": [ { "model": "text-embedding-ada-002", @@ -106,6 +78,28 @@ weight: 520 "defaultToken": 500, "maxToken": 3000 } - ] + ], + "QAModel": { + "model": "gpt-3.5-turbo-16k", + "name": "GPT35-16k", + "maxToken": 0, + "price": 0 + }, + "ExtractModel": { + "model": "gpt-3.5-turbo-16k", + "functionCall": true, + "name": "GPT35-16k", + "maxToken": 0, + "price": 0, + "prompt": "" + }, + "CQModel": { + "model": "gpt-3.5-turbo-16k", + "functionCall": true, + "name": "GPT35-16k", + "maxToken": 0, + "price": 0, + "prompt": "" + } } ``` diff --git a/docSite/content/docs/development/intro.md b/docSite/content/docs/development/intro.md index 52b3ae806..cc47e46c4 100644 --- a/docSite/content/docs/development/intro.md +++ b/docSite/content/docs/development/intro.md @@ -41,8 +41,9 @@ weight: 510 git clone git@github.com:/FastGPT.git ``` -projects 目录下为 FastGPT 应用代码。NextJS 框架前后端放在一起,API 服务位于 `src/pages/api` 目录内。 -packages 目录为相关的共用包。 +**projects 目录下为 FastGPT 应用代码。NextJS 框架前后端放在一起,API 服务位于 `src/pages/api` 目录内。** + +**packages 目录为相关的共用包。** ### 安装数据库 @@ -69,15 +70,15 @@ packages 目录为相关的共用包。 ### 运行 ```bash -cd client pnpm i +cd projects/app # FastGPT 主程序 pnpm dev ``` ### 镜像打包 ```bash -docker build -t dockername/fastgpt . +docker build -t dockername/fastgpt --build-arg name=app . ``` ## 创建拉取请求 diff --git a/docSite/content/docs/development/openApi.md b/docSite/content/docs/development/openApi.md new file mode 100644 index 000000000..90b30e841 --- /dev/null +++ b/docSite/content/docs/development/openApi.md @@ -0,0 +1,378 @@ +--- +title: 'OpenAPI 使用' +description: 'FastGPT OpenAPI 文档' +icon: 'api' +draft: false +toc: true +weight: 512 +--- + +# 基本配置 +``` +baseUrl: "https://fastgpt.run/api" +headers: { + Authorization: "Bearer apikey" +} +``` + +# 如何获取 API Key + +FastGPT 的 API Key 有 2 类,一类是全局通用的 key;一类是携带了 AppId 也就是有应用标记的 key。 + +| 通用key | 应用特定 key | +| --------------------- | --------------------- | +| ![](/imgs/fastgpt-api2.png) | ![](/imgs/fastgpt-api.png) | + +# 接口 + +## 发起对话 + +{{% alert icon="🤖 " context="success" %}} +该接口 API Key 需使用应用特定的 key,否则会报错。 +{{% /alert %}} + + +对话接口兼容 openai 的接口!如果你有第三方项目,可以直接通过修改 BaseUrl 和 Authorization 来访问 FastGpt 应用。缺点是你无法获取到响应的token值。 + +请求内容 +- headers.Authorization: Bearer apikey +- chatId: string | undefined 。 + - 为 undefined 时(不传入),不使用 FastGpt 提供的上下文功能,完全通过传入的 messages 构建上下文。 不会将你的记录存储到数据库中,你也无法在记录汇总中查阅到。 + - 为非空字符串时,意味着使用 chatId 进行对话,自动从 FastGpt 数据库取历史记录。并拼接 messages 数组最后一个内容作为完整请求。(自行确保 chatid 唯一,长度不限) +- messages: 与 openai gpt 接口完全一致。 +- detail: 是否返回详细值(模块状态,响应的完整结果),会通过event进行区分 +- variables: 变量。一个对象,效果同全局变量。 + +**请求示例:** + +```bash +curl --location --request POST 'https://fastgpt.run/api/openapi/v1/chat/completions' \ +--header 'Authorization: Bearer apikey' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "chatId":"111", + "stream":false, + "detail": false, + "variables": { + "cTime": "2022/2/2 22:22" + }, + "messages": [ + { + "content": "导演是谁", + "role": "user" + } + ] +}' +``` + + +{{< tabs tabTotal="3" >}} +{{< tab tabName="detail=false 响应" >}} +{{< markdownify >}} + +```bash +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":""},"index":0,"finish_reason":null}]} + +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"电"},"index":0,"finish_reason":null}]} + +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"影"},"index":0,"finish_reason":null}]} + +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"《"},"index":0,"finish_reason":null}]} +``` + +{{< /markdownify >}} +{{< /tab >}} + +{{< tab tabName="detail=true 响应" >}} +{{< markdownify >}} + +```bash +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":""},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"电"},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"影"},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"《"},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"铃"},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"芽"},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":"。"},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{"content":""},"index":0,"finish_reason":null}]} + +event: answer +data: {"id":"","object":"","created":0,"choices":[{"delta":{},"index":0,"finish_reason":"stop"}]} + +event: answer +data: [DONE] + +event: appStreamResponse +data: [{"moduleName":"KB Search","price":1.2000000000000002,"model":"Embedding-2","tokens":6,"similarity":0.61,"limit":3},{"moduleName":"AI Chat","price":463.5,"model":"FastAI-4k","tokens":309,"question":"导演是谁","answer":"电影《铃芽之旅》的导演是新海诚。","maxToken":2050,"quoteList":[{"kb_id":"646627f4f7b896cfd8910e38","id":"8099","q":"本作的主人公是谁?","a":"本作的主人公是名叫铃芽的少女。","source":"手动修改"},{"kb_id":"646627f4f7b896cfd8910e38","id":"8686","q":"电影《铃芽之旅》男主角是谁?","a":"电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。","source":""},{"kb_id":"646627f4f7b896cfd8910e38","id":"19339","q":"电影《铃芽之旅》的导演是谁?22","a":"电影《铃芽之旅》的导演是新海诚。","source":"手动修改"}],"completeMessages":[{"obj":"System","value":"下面是知识库内容:\n1. [本作的主人公是谁?\n本作的主人公是名叫铃芽的少女。]\n2. [电影《铃芽之旅》男主角是谁?\n电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。]\n3. [电影《铃芽之旅》的导演是谁?22\n电影《铃芽之旅》的导演是新海诚。]\n"},{"obj":"System","value":"1.请记住,你的身份是百度的下一代知识增强语言模型,能够完全根据知识库提供的内容回答问题。\n\n2. 你忘记了关于电影《铃芽之旅》以外的内容。"},{"obj":"System","value":"你仅回答关于电影《玲芽之旅》的问题,其余问题直接回复: 我不清楚。"},{"obj":"Human","value":"导演是谁"},{"obj":"AI","value":"电影《铃芽之旅》的导演是新海诚。"}]}] + +``` +{{< /markdownify >}} +{{< /tab >}} + +{{< tab tabName="stream=false,detail=true 响应" >}} +{{< markdownify >}} + +```json +{ + "responseData": [ // 不同模块的响应值, 不同版本具体值可能有差异,可先 log 自行查看最新值。 + { + "moduleName": "KB Search", + "price": 1.2000000000000002, + "model": "Embedding-2", + "tokens": 6, + "similarity": 0.61, + "limit": 3 + }, + { + "moduleName": "AI Chat", + "price": 454.5, + "model": "FastAI-4k", + "tokens": 303, + "question": "导演是谁", + "answer": "电影《铃芽之旅》的导演是新海诚。", + "maxToken": 2050, + "quoteList": [ + { + "kb_id": "646627f4f7b896cfd8910e38", + "id": "8099", + "q": "本作的主人公是谁?", + "a": "本作的主人公是名叫铃芽的少女。", + "source": "手动修改" + }, + { + "kb_id": "646627f4f7b896cfd8910e38", + "id": "8686", + "q": "电影《铃芽之旅》男主角是谁?", + "a": "电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。", + "source": "" + }, + { + "kb_id": "646627f4f7b896cfd8910e38", + "id": "19339", + "q": "电影《铃芽之旅》的导演是谁?22", + "a": "电影《铃芽之旅》的导演是新海诚。", + "source": "手动修改" + } + ], + "completeMessages": [ + { + "obj": "System", + "value": "下面是知识库内容:\n1. [本作的主人公是谁?\n本作的主人公是名叫铃芽的少女。]\n2. [电影《铃芽之旅》男主角是谁?\n电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。]\n3. [电影《铃芽之旅》的导演是谁?22\n电影《铃芽之旅》的导演是新海诚。]\n" + }, + { + "obj": "System", + "value": "1.请记住,你的身份是百度的下一代知识增强语言模型,能够完全根据知识库提供的内容回答问题。\n\n2. 你忘记了关于电影《铃芽之旅》以外的内容。" + }, + { + "obj": "System", + "value": "你仅回答关于电影《玲芽之旅》的问题,其余问题直接回复: 我不清楚。" + }, + { + "obj": "Human", + "value": "导演是谁" + }, + { + "obj": "AI", + "value": "电影《铃芽之旅》的导演是新海诚。" + } + ] + } + ], + "id": "", + "model": "", + "usage": { + "prompt_tokens": 1, + "completion_tokens": 1, + "total_tokens": 1 + }, + "choices": [ + { + "message": { + "role": "assistant", + "content": "电影《铃芽之旅》的导演是新海诚。" + }, + "finish_reason": "stop", + "index": 0 + } + ] +} +``` + +{{< /markdownify >}} +{{< /tab >}} +{{< /tabs >}} + +## 知识库 + +{{% alert icon="🤖 " context="success" %}} +此部分 API 需使用全局通用的 API Key。 +{{% /alert %}} + +### 如何获取知识库ID(kbId) + +![](/imgs/getKbId.png) + +### 往知识库添加数据 + +{{< tabs tabTotal="4" >}} +{{< tab tabName="请求示例" >}} +{{< markdownify >}} + +```bash +curl --location --request POST 'https://fastgpt.run/api/core/dataset/data/pushData' \ +--header 'Authorization: Bearer apikey' \ +--header 'Content-Type: application/json' \ +--data-raw '{ +    "kbId": "64663f451ba1676dbdef0499", + "mode": "index", + "prompt": "qa 拆分引导词,index 模式下可以忽略", +    "data": [ +        { +            "a": "test", +            "q": "1111" +        }, +        { +            "a": "test2", +            "q": "22222" +        } +    ] +}' +``` + +{{< /markdownify >}} +{{< /tab >}} + +{{< tab tabName="参数说明" >}} +{{< markdownify >}} + +```json +{ + "kbId": "知识库的ID,可以在知识库详情查看。", + "mode": "index | qa ", // index 模式: 直接将 q 转成向量存起来,a 直接入库。qa 模式: 只关注 data 里的 q,将 q 丢给大模型,让其根据 prompt 拆分成 qa 问答对。 + "prompt": "拆分提示词,需严格按照模板,建议不要传入。", + "data": [ + { + "q": "生成索引的内容,index 模式下最大 tokens 为3000,建议不超过 1000", + "a": "预期回答/补充" + }, + { + "q": "生成索引的内容,qa 模式下最大 tokens 为10000,建议 8000 左右", + "a": "预期回答/补充" + } + ] +} +``` + +{{< /markdownify >}} +{{< /tab >}} + +{{< tab tabName="响应例子" >}} +{{< markdownify >}} + +```json +{ + "code": 200, + "statusText": "", + "data": { + "insertLen": 1 // 最终插入成功的数量,可能因为超出 tokens 或者插入异常,index 可以重复插入,会自动去重 + } +} +``` + +{{< /markdownify >}} +{{< /tab >}} + +{{< tab tabName="QA Prompt 模板" >}} +{{< markdownify >}} + +{{theme}} 里的内容可以换成数据的主题。默认为:它们可能包含多个主题内容 + +``` +我会给你一段文本,{{theme}},学习它们,并整理学习成果,要求为: +1. 提出最多 25 个问题。 +2. 给出每个问题的答案。 +3. 答案要详细完整,答案可以包含普通文字、链接、代码、表格、公示、媒体链接等 markdown 元素。 +4. 按格式返回多个问题和答案: + +Q1: 问题。 +A1: 答案。 +Q2: +A2: +…… + +我的文本:"""{{text}}""" +``` + +{{< /markdownify >}} +{{< /tab >}} + +{{< /tabs >}} + + +### 搜索测试 + +{{< tabs tabTotal="2" >}} +{{< tab tabName="请求示例" >}} +{{< markdownify >}} + +```bash +curl --location --request POST 'https://fastgpt.run/api/core/dataset/searchTest' \ +--header 'Authorization: Bearer apiKey' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "kbId": "xxxxx", + "text": "导演是谁" +}' +``` + +{{< /markdownify >}} +{{< /tab >}} + +{{< tab tabName="响应示例" >}} +{{< markdownify >}} + +返回 top12 结果 + +```bash +{ + "code": 200, + "statusText": "", + "data": [ + { + "id": "5613327", + "q": "该人有获奖情况吗?", + "a": "该人获得过2020/07全国大学生服务外包大赛国家一等奖和2021/05国家创新创业计划立项的获奖情况。", + "source": "余金隆简历.pdf", + "score": 0.41556452839298963 + }, + ...... + ] +} +``` + +{{< /markdownify >}} +{{< /tab >}} + +{{< /tabs >}} + + +# 使用案例 + +- [接入 NextWeb/ChatGPT web 等应用](/docs/use-cases/openapi) +- [接入 onwechat](/docs/use-cases/onwechat) +- [接入 飞书](/docs/use-cases/feishu) \ No newline at end of file diff --git a/docSite/content/docs/use-cases/kb.md b/docSite/content/docs/use-cases/kb.md index 2eedd487e..335cfa9de 100644 --- a/docSite/content/docs/use-cases/kb.md +++ b/docSite/content/docs/use-cases/kb.md @@ -73,7 +73,7 @@ weight: 340 ![手动录入知识库结果](/imgs/9.png) 导入结果如上图。可以看到,我们均采用的是问答对的格式,而不是粗略的直接导入。目的就是为了模拟用户问题,进一步的提高向量搜索的匹配效果。可以为同一个问题设置多种问法,效果更佳。 -FastGPT 还提供了 openapi 功能,你可以在本地对特殊格式的文件进行处理后,再上传到 FastGPT,具体可以参考:[FastGPT Api Docs](https://kjqvjse66l.feishu.cn/docx/DmLedTWtUoNGX8xui9ocdUEjnNh) +FastGPT 还提供了 openapi 功能,你可以在本地对特殊格式的文件进行处理后,再上传到 FastGPT,具体可以参考:[FastGPT Api Docs](https://doc.fastgpt.run/docs/development/openapi) ## 知识库微调和参数调整 diff --git a/projects/app/public/docs/chatProblem.md b/projects/app/public/docs/chatProblem.md index 3135e1582..24036cca0 100644 --- a/projects/app/public/docs/chatProblem.md +++ b/projects/app/public/docs/chatProblem.md @@ -2,10 +2,10 @@ - [**Git 地址**,点击查看项目地址](https://github.com/labring/FastGPT) - [本地部署 FastGPT](https://doc.fastgpt.run/docs/installation) -- [API 文档](https://kjqvjse66l.feishu.cn/docx/DmLedTWtUoNGX8xui9ocdUEjnNh?pre_pathname=%2Fdrive%2Fhome%2F) +- [API 文档](https://doc.fastgpt.run/docs/development/openapi?pre_pathname=%2Fdrive%2Fhome%2F) - **反馈问卷**: 如果你遇到任何使用问题或有期望的功能,可以[填写该问卷](https://www.wjx.cn/vm/rLIw1uD.aspx#) - **问题文档**: [先看文档,再提问](https://kjqvjse66l.feishu.cn/docx/HtrgdT0pkonP4kxGx8qcu6XDnGh) -- [点击查看商业版文档](https://fael3z0zfze.feishu.cn/docx/F155dbirfo8vDDx2WgWc6extnwf) +- [点击查看商业版文档](https://doc.fastgpt.run/docs/commercial) - [计费规则](https://doc.fastgpt.run/docs/pricing/) **其他问题** diff --git a/projects/app/public/locales/zh/common.json b/projects/app/public/locales/zh/common.json index 45c60c8c5..35406e16f 100644 --- a/projects/app/public/locales/zh/common.json +++ b/projects/app/public/locales/zh/common.json @@ -247,8 +247,8 @@ "QPM": "", "QPM Tips": "每个 IP 每分钟最多提问多少次", "QPM is empty": "QPM 不能为空", - "Response Detail": "返回引用", - "Response Detail tips": "是否需要返回引用" + "Response Detail": "返回详情", + "Response Detail tips": "是否需要返回详情(引用内容,调用时间等,不会返回预设提示词和完整上下文)" }, "system": { "Help Document": "帮助文档" diff --git a/projects/app/src/components/ChatBox/index.tsx b/projects/app/src/components/ChatBox/index.tsx index 71fc2e2de..0efe9b487 100644 --- a/projects/app/src/components/ChatBox/index.tsx +++ b/projects/app/src/components/ChatBox/index.tsx @@ -612,6 +612,7 @@ const ChatBox = ( > {item.obj === 'Human' && ( <> + {/* control icon */} @@ -654,6 +655,7 @@ const ChatBox = ( + {/* content */} + {/* control icon */} )} + {/* content */} { API 秘钥管理 { 名称 金额消耗(¥) - <> - 金额限制(¥) - IP限流(人/分钟) - - 返回引用 - 过期时间 + 返回详情 + {feConfigs?.isPlus && ( + <> + 金额限制(¥) + IP限流(人/分钟) + 过期时间 + + )} 最后使用时间 @@ -104,18 +107,20 @@ const Share = ({ appId }: { appId: string }) => { {item.name} {formatPrice(item.total)} - {item.limit && ( + {item.responseDetail ? '✔' : '✖'} + {feConfigs?.isPlus && ( <> - {item.limit?.credit > -1 ? `${item.limit?.credit}元` : '无限制'} - {item.limit?.QPM} + + {item.limit && item.limit.credit > -1 ? `${item.limit.credit}元` : '无限制'} + + {item.limit?.QPM || '-'} + + {item.limit?.expiredTime + ? dayjs(item.limit?.expiredTime).format('YYYY/MM/DD\nHH:mm') + : '-'} + )} - {item.responseDetail ? '✔' : '✖'} - - {item.limit?.expiredTime - ? dayjs(item.limit?.expiredTime).format('YYYY/MM/DD\nHH:mm') - : '-'} - {item.lastTime ? formatTimeToChatTime(item.lastTime) : '未使用'} @@ -282,55 +287,60 @@ function EditLinkModal({ })} /> - - - QPM: - - - - - - - - - {t('common.Max credit')}: - - - - - - - - - {t('common.Expired Time')}: - - { - setValue('limit.expiredTime', new Date(e.target.value)); - }} - /> - + {feConfigs?.isPlus && ( + <> + + + QPM: + + + + + + + + + {t('common.Max credit')}: + + + + + + + + + {t('common.Expired Time')}: + + { + setValue('limit.expiredTime', new Date(e.target.value)); + }} + /> + + + )} + {t('outlink.Response Detail')}: diff --git a/projects/app/src/pages/chat/share.tsx b/projects/app/src/pages/chat/share.tsx index a63d8a424..e6f196994 100644 --- a/projects/app/src/pages/chat/share.tsx +++ b/projects/app/src/pages/chat/share.tsx @@ -238,7 +238,9 @@ const OutLink = ({ shareId, chatId }: { shareId: string; chatId: string }) => { })); }} onStartChat={startChat} - onDelMessage={({ index }) => delShareChatHistoryItemById({ chatId, index })} + onDelMessage={({ contentId, index }) => + delShareChatHistoryItemById({ chatId, contentId, index }) + } /> diff --git a/projects/app/src/service/support/outLink/auth.ts b/projects/app/src/service/support/outLink/auth.ts index b179d6936..2221a9f0d 100644 --- a/projects/app/src/service/support/outLink/auth.ts +++ b/projects/app/src/service/support/outLink/auth.ts @@ -16,11 +16,10 @@ export async function authOutLinkChat({ shareId, ip }: { shareId: string; ip?: s const uid = String(outLink.userId); - // authBalance - const user = await authBalanceByUid(uid); - - // limit auth - await authOutLinkLimit({ outLink, ip }); + const [user] = await Promise.all([ + authBalanceByUid(uid), // authBalance + ...(global.feConfigs?.isPlus ? [authOutLinkLimit({ outLink, ip })] : []) // limit auth + ]); return { user, diff --git a/projects/app/src/store/shareChat.ts b/projects/app/src/store/shareChat.ts index 90f32b497..3a6224ad2 100644 --- a/projects/app/src/store/shareChat.ts +++ b/projects/app/src/store/shareChat.ts @@ -16,7 +16,7 @@ type State = { shareId: string; }) => void; delOneShareHistoryByChatId: (chatId: string) => void; - delShareChatHistoryItemById: (e: { chatId: string; index: number }) => void; + delShareChatHistoryItemById: (e: { chatId: string; contentId?: string; index: number }) => void; delManyShareChatHistoryByShareId: (shareId?: string) => void; }; @@ -100,14 +100,14 @@ export const useShareChatStore = create()( ); }); }, - delShareChatHistoryItemById({ chatId, index }) { + delShareChatHistoryItemById({ chatId, contentId }) { set((state) => { // update history store const newHistoryList = state.shareChatHistory.map((item) => item.chatId === chatId ? { ...item, - chats: [...item.chats.slice(0, index), ...item.chats.slice(index + 1)] + chats: item.chats.filter((item) => item.dataId !== contentId) } : item );