mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-22 12:20:34 +00:00
4.8.13 feature (#3118)
* chore(ui): login page & workflow page (#3046) * login page & number input & multirow select & llm select * workflow * adjust nodes * New file upload (#3058) * feat: toolNode aiNode readFileNode adapt new version * update docker-compose * update tip * feat: adapt new file version * perf: file input * fix: ts * feat: add chat history time label (#3024) * feat:add chat and logs time * feat: add chat history time label * code perf * code perf --------- Co-authored-by: 勤劳上班的卑微小张 <jiazhan.zhang@ggimage.com> * add chatType (#3060) * pref: slow query of full text search (#3044) * Adapt findLast api;perf: markdown zh format. (#3066) * perf: context code * fix: adapt findLast api * perf: commercial plugin run error * perf: markdown zh format * perf: dockerfile proxy (#3067) * fix ui (#3065) * fix ui * fix * feat: support array reference multi-select (#3041) * feat: support array reference multi-select * fix build * fix * fix loop multi-select * adjust condition * fix get value * array and non-array conversion * fix plugin input * merge func * feat: iframe code block;perf: workflow selector type (#3076) * feat: iframe code block * perf: workflow selector type * node pluginoutput check (#3074) * feat: View will move when workflow check error;fix: ui refresh error when continuous file upload (#3077) * fix: plugin output check * fix: ui refresh error when continuous file upload * feat: View will move when workflow check error * add dispatch try catch (#3075) * perf: workflow context split (#3083) * perf: workflow context split * perf: context * 4.8.13 test (#3085) * perf: workflow node ui * chat iframe url * feat: support sub route config (#3071) * feat: support sub route config * dockerfile * fix upload * delete unused code * 4.8.13 test (#3087) * fix: image expired * fix: datacard navbar ui * perf: build action * fix: workflow file upload refresh (#3088) * fix: http tool response (#3097) * loop node dynamic height (#3092) * loop node dynamic height * fix * fix * feat: support push chat log (#3093) * feat: custom uid/metadata * to: custom info * fix: chat push latest * feat: add chat log envs * refactor: move timer to pushChatLog * fix: using precise log --------- Co-authored-by: Finley Ge <m13203533462@163.com> * 4.8.13 test (#3098) * perf: loop node refresh * rename context * comment * fix: ts * perf: push chat log * array reference check & node ui (#3100) * feat: loop start add index (#3101) * feat: loop start add index * update doc * 4.8.13 test (#3102) * fix: loop index;edge parent check * perf: reference invalid check * fix: ts * fix: plugin select files and ai response check (#3104) * fix: plugin select files and ai response check * perf: text editor selector;tool call tip;remove invalid image url; * perf: select file * perf: drop files * feat: source id prefix env (#3103) * 4.8.13 test (#3106) * perf: select file * perf: drop files * perf: env template * 4.8.13 test (#3107) * perf: select file * perf: drop files * fix: imple mode adapt files * perf: push chat log (#3109) * fix: share page load title error (#3111) * 4.8.13 perf (#3112) * fix: share page load title error * update file input doc * perf: auto add file urls * perf: auto ser loop node offset height * 4.8.13 test (#3117) * perf: plugin * updat eaction * feat: add more share config (#3120) * feat: add more share config * add i18n en * fix: missing subroute (#3121) * perf: outlink config (#3128) * update action * perf: outlink config * fix: ts (#3129) * 更新 docSite 文档内容 (#3131) * fix: null pointer (#3130) * fix: null pointer * perf: not input text * update doc url * perf: outlink default value (#3134) * update doc (#3136) * 4.8.13 test (#3137) * update doc * perf: completions chat api * Restore docSite content based on upstream/4.8.13-dev (#3138) * Restore docSite content based on upstream/4.8.13-dev * 4813.md缺少更正 * update doc (#3141) --------- Co-authored-by: heheer <heheer@sealos.io> Co-authored-by: papapatrick <109422393+Patrickill@users.noreply.github.com> Co-authored-by: 勤劳上班的卑微小张 <jiazhan.zhang@ggimage.com> Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com> Co-authored-by: a.e. <49438478+I-Info@users.noreply.github.com> Co-authored-by: Finley Ge <m13203533462@163.com> Co-authored-by: Jiangween <145003935+Jiangween@users.noreply.github.com>
This commit is contained in:
8
docSite/content/zh-cn/docs/use-cases/app-cases/_index.md
Normal file
8
docSite/content/zh-cn/docs/use-cases/app-cases/_index.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: "应用搭建案例"
|
||||
description: "FastGPT 应用场景及功能实现的搭建案例"
|
||||
icon: "construction"
|
||||
draft: false
|
||||
weight: 600
|
||||
---
|
||||
<!-- 600 ~ 700 -->
|
471
docSite/content/zh-cn/docs/use-cases/app-cases/dalle3.md
Normal file
471
docSite/content/zh-cn/docs/use-cases/app-cases/dalle3.md
Normal file
@@ -0,0 +1,471 @@
|
||||
---
|
||||
title: 'Dalle3 绘图'
|
||||
description: '使用 HTTP 模块绘制图片'
|
||||
icon: 'image'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 614
|
||||
---
|
||||
|
||||
| | |
|
||||
| --------------------- | --------------------- |
|
||||
|  |  |
|
||||
|
||||
## OpenAI Dalle3 接口
|
||||
|
||||
先来看下官方接口的参数和响应值:
|
||||
|
||||
Body
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "dall-e-3",
|
||||
"prompt": "A cute baby sea otter",
|
||||
"n": 1,
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
|
||||
Response
|
||||
|
||||
```json
|
||||
{
|
||||
"created": 1589478378,
|
||||
"data": [
|
||||
{
|
||||
"url": "https://..."
|
||||
},
|
||||
{
|
||||
"url": "https://..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 编排思路
|
||||
|
||||
1. 通过 AI 来优化图片绘制的提示词(这步省略了,自己找提示词即可)
|
||||
2. 通过 `【HTTP 请求】模块` 调用 Dalle3 接口,获取图片的 URL。
|
||||
3. 通过 `【文本加工】模块` 来构建 `Markdown` 的图片格式。
|
||||
4. 通过 `【指定回复】模块` 来直接输出图片链接。
|
||||
|
||||
### 1. 构建 HTTP 模块
|
||||
|
||||
请求参数直接复制 Dalle3 接口的即可,并求改 prompt 为变量。需要增加一个 `Headers.Authorization` 。
|
||||
|
||||
Body:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "dall-e-3",
|
||||
"prompt": "{{prompt}}",
|
||||
"n": 1,
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
|
||||
Headers:
|
||||
|
||||
`Authorization: Bearer sk-xxx`
|
||||
|
||||
Response:
|
||||
|
||||
响应值需要根据 Dalle3 接口的返回值进行获取,我们只绘制了1张图片,所以只需要取第一张图片的 URL 即可。给 HTTP 模块增加一个自定义输出 `data[0].url` 。
|
||||
|
||||
### 2. 文本加工 - 构建图片链接
|
||||
|
||||
在 `Markdown` 语法中 `` 表示插入图片,图片链接由【HTTP 请求】模块输出。
|
||||
|
||||
因此可以增加一个输入来接收 `【HTTP 请求】模块` 的图片链接输出,并在 `【文本加工】模块 - 文本` 中通过变量来引用图片链接,从而得到一个完整的 `Markdown` 图片格式。
|
||||
|
||||
### 3. 指定回复
|
||||
|
||||
指定回复可以直接输出传入的内容到客户端,因此可以直接输出加工好的 `Markdown` 图片格式即可。
|
||||
|
||||
## 编排代码
|
||||
|
||||
{{% details title="编排配置" closed="true" %}}
|
||||
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"nodeId": "userGuide",
|
||||
"name": "系统配置",
|
||||
"intro": "可以配置应用的系统参数",
|
||||
"avatar": "/imgs/workflow/userGuide.png",
|
||||
"flowNodeType": "userGuide",
|
||||
"position": {
|
||||
"x": 531.2422736065552,
|
||||
"y": -486.7611729549753
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "welcomeText",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "core.app.Welcome Text",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"key": "variables",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "core.app.Chat Variable",
|
||||
"value": []
|
||||
},
|
||||
{
|
||||
"key": "questionGuide",
|
||||
"valueType": "boolean",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "core.app.Question Guide",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "tts",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"value": {
|
||||
"type": "web"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "whisper",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"value": {
|
||||
"open": false,
|
||||
"autoSend": false,
|
||||
"autoTTSResponse": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "scheduleTrigger",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"value": null
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "448745",
|
||||
"name": "流程开始",
|
||||
"intro": "",
|
||||
"avatar": "/imgs/workflow/userChatInput.svg",
|
||||
"flowNodeType": "workflowStart",
|
||||
"position": {
|
||||
"x": 532.1275542407774,
|
||||
"y": 46.03775600322817
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"toolDescription": "用户问题"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "userChatInput",
|
||||
"key": "userChatInput",
|
||||
"label": "core.module.input.label.user question",
|
||||
"valueType": "string",
|
||||
"type": "static"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "tMyUnRL5jIrC",
|
||||
"name": "HTTP 请求",
|
||||
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
|
||||
"avatar": "/imgs/workflow/http.png",
|
||||
"flowNodeType": "httpRequest468",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 921.2377506442713,
|
||||
"y": -483.94114977914256
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "system_addInputParam",
|
||||
"renderTypeList": [
|
||||
"addInputParam"
|
||||
],
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"description": "core.module.input.description.HTTP Dynamic Input",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "prompt",
|
||||
"valueType": "string",
|
||||
"label": "prompt",
|
||||
"renderTypeList": [
|
||||
"reference"
|
||||
],
|
||||
"description": "",
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
},
|
||||
"value": [
|
||||
"448745",
|
||||
"userChatInput"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "system_httpMethod",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"value": "POST",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "system_httpReqUrl",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Url",
|
||||
"placeholder": "https://api.ai.com/getInventory",
|
||||
"required": false,
|
||||
"value": "https://api.openai.com/v1/images/generations"
|
||||
},
|
||||
{
|
||||
"key": "system_httpHeader",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [
|
||||
{
|
||||
"key": "Authorization",
|
||||
"type": "string",
|
||||
"value": "Bearer "
|
||||
}
|
||||
],
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Header",
|
||||
"placeholder": "core.module.input.description.Http Request Header",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpParams",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpJsonBody",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": "{\n \"model\": \"dall-e-3\",\n \"prompt\": \"{{prompt}}\",\n \"n\": 1,\n \"size\": \"1024x1024\"\n}",
|
||||
"label": "",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "system_addOutputParam",
|
||||
"key": "system_addOutputParam",
|
||||
"type": "dynamic",
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "httpRawResponse",
|
||||
"key": "httpRawResponse",
|
||||
"label": "原始响应",
|
||||
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
|
||||
"valueType": "any",
|
||||
"type": "static"
|
||||
},
|
||||
{
|
||||
"id": "DeKGGioBwaMf",
|
||||
"type": "dynamic",
|
||||
"key": "data[0].url",
|
||||
"valueType": "string",
|
||||
"label": "data[0].url"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "CO3POL8svbbi",
|
||||
"name": "文本加工",
|
||||
"intro": "可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。",
|
||||
"avatar": "/imgs/workflow/textEditor.svg",
|
||||
"flowNodeType": "pluginModule",
|
||||
"showStatus": false,
|
||||
"position": {
|
||||
"x": 1417.5940290051137,
|
||||
"y": -478.81889618104356
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "system_addInputParam",
|
||||
"valueType": "dynamic",
|
||||
"label": "动态外部数据",
|
||||
"renderTypeList": [
|
||||
"addInputParam"
|
||||
],
|
||||
"required": false,
|
||||
"description": "",
|
||||
"canEdit": false,
|
||||
"value": "",
|
||||
"editField": {
|
||||
"key": true
|
||||
},
|
||||
"dynamicParamDefaultValue": {
|
||||
"inputType": "reference",
|
||||
"valueType": "string",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "url",
|
||||
"valueType": "string",
|
||||
"label": "url",
|
||||
"renderTypeList": [
|
||||
"reference"
|
||||
],
|
||||
"required": true,
|
||||
"description": "",
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true
|
||||
},
|
||||
"value": [
|
||||
"tMyUnRL5jIrC",
|
||||
"DeKGGioBwaMf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "文本",
|
||||
"valueType": "string",
|
||||
"label": "文本",
|
||||
"renderTypeList": [
|
||||
"textarea"
|
||||
],
|
||||
"required": true,
|
||||
"description": "",
|
||||
"canEdit": false,
|
||||
"value": "",
|
||||
"editField": {
|
||||
"key": true
|
||||
},
|
||||
"maxLength": "",
|
||||
"dynamicParamDefaultValue": {
|
||||
"inputType": "reference",
|
||||
"valueType": "string",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "text",
|
||||
"type": "static",
|
||||
"key": "text",
|
||||
"valueType": "string",
|
||||
"label": "text",
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"pluginId": "community-textEditor"
|
||||
},
|
||||
{
|
||||
"nodeId": "7mapnCgHfKW6",
|
||||
"name": "指定回复",
|
||||
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
|
||||
"avatar": "/imgs/workflow/reply.png",
|
||||
"flowNodeType": "answerNode",
|
||||
"position": {
|
||||
"x": 1922.5628399315042,
|
||||
"y": -471.67391598231796
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "text",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.Response content",
|
||||
"description": "core.module.input.description.Response content",
|
||||
"placeholder": "core.module.input.description.Response content",
|
||||
"selectedTypeIndex": 1,
|
||||
"value": [
|
||||
"CO3POL8svbbi",
|
||||
"text"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "448745",
|
||||
"target": "tMyUnRL5jIrC",
|
||||
"sourceHandle": "448745-source-right",
|
||||
"targetHandle": "tMyUnRL5jIrC-target-left"
|
||||
},
|
||||
{
|
||||
"source": "tMyUnRL5jIrC",
|
||||
"target": "CO3POL8svbbi",
|
||||
"sourceHandle": "tMyUnRL5jIrC-source-right",
|
||||
"targetHandle": "CO3POL8svbbi-target-left"
|
||||
},
|
||||
{
|
||||
"source": "CO3POL8svbbi",
|
||||
"target": "7mapnCgHfKW6",
|
||||
"sourceHandle": "CO3POL8svbbi-source-right",
|
||||
"targetHandle": "7mapnCgHfKW6-target-left"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{{% /details %}}
|
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: "英语作文纠错机器人"
|
||||
description: "使用 FastGPT 创建一个用于英语作文纠错的机器人,帮助用户检测并纠正语言错误"
|
||||
icon: "spellcheck"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 608
|
||||
---
|
||||
|
||||
FastGPT 提供了一种基于 LLM Model 搭建应用的简便方式。
|
||||
|
||||
本文通过搭建一个英语作文纠错机器人,介绍一下如何使用 **工作流**
|
||||
|
||||
## 搭建过程
|
||||
|
||||
### 1. 创建工作流
|
||||
|
||||

|
||||
|
||||
可以从 *多轮翻译机器人* 开始创建。
|
||||
|
||||
> 多轮翻译机器人是 @米开朗基杨 同学创建的,同样也是一个值得学习的工作流。
|
||||
|
||||
### 2. 获取输入,使用大模型进行分析
|
||||
|
||||
我们期望让大模型处理文字,返回一个结构化的数据,由我们自己处理。
|
||||
|
||||

|
||||
|
||||
**提示词** 是最重要的一个参数,这里提供的提示词仅供参考:
|
||||
|
||||
~~~Markdown
|
||||
## 角色
|
||||
资深英语写作专家
|
||||
|
||||
## 任务
|
||||
对输入的原文进行分析。 找出其中的各种错误, 包括但不限于单词拼写错误、 语法错误等。
|
||||
注意: 忽略标点符号前后空格的问题。
|
||||
注意: 对于存在错误的句子, 提出修改建议是指指出这个句子中的具体部分, 然后提出将这一个部分修改替换为什么。
|
||||
|
||||
## 输出格式
|
||||
不要使用 Markdown 语法, 输入 JSON 格式的内容。
|
||||
输出的"reason"的内容使用中文。
|
||||
直接输出一个列表, 其成员为一个相同类型的对象, 定义如下
|
||||
您正在找回 FastGPT 账号
|
||||
```
|
||||
{
|
||||
“raw”: string; // 表示原文
|
||||
“reason”: string; // 表示原因
|
||||
“suggestion”: string; // 修改建议
|
||||
}
|
||||
```
|
||||
~~~
|
||||
|
||||
可以在模型选择的窗口中设置禁用 AI 回复。
|
||||
|
||||
这样就看不到输出的 json 格式的内容了。
|
||||
|
||||

|
||||
|
||||
### 3. 数据处理
|
||||
|
||||
上面的大模型输出了一个 json,这里要进行数据处理。数据处理可以使用代码执行组件。
|
||||
|
||||

|
||||
|
||||
```JavaScript
|
||||
function main({data}){
|
||||
const array = JSON.parse(data)
|
||||
return {
|
||||
content: array.map(
|
||||
(item, index) => {
|
||||
return `
|
||||
## 分析${index+1}
|
||||
- **错误**: ${item.raw}
|
||||
- **分析**: ${item.reason}
|
||||
- **修改建议**: ${item.suggestion}
|
||||
`
|
||||
}
|
||||
).join('')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
上面的代码将 JSON 解析为 Object, 然后拼接成一串 Markdown 语法的字符串。
|
||||
|
||||
FastGPT 的指定回复组件可以将 Markdown 解析为 Html 返回。
|
||||
|
||||
## 发布
|
||||
|
||||
可以使用发布渠道进行发布。
|
||||
|
||||

|
||||
|
||||
可以选择通过 URL 访问,或者是直接嵌入你的网页中。
|
||||
|
||||
> [点我使用](https://share.fastgpt.in/chat/share?shareId=b4r173wkcjae7wpnexcvmyc3)
|
411
docSite/content/zh-cn/docs/use-cases/app-cases/feishu_webhook.md
Normal file
411
docSite/content/zh-cn/docs/use-cases/app-cases/feishu_webhook.md
Normal file
@@ -0,0 +1,411 @@
|
||||
---
|
||||
title: '发送飞书webhook通知'
|
||||
description: '利用工具调用模块,发送一个飞书webhook通知'
|
||||
icon: 'image'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 618
|
||||
---
|
||||
|
||||
该文章展示如何发送一个简单的飞书webhook通知,以此类推,发送其他类型的通知也可以这么操作。
|
||||
|
||||
| | |
|
||||
| --------------------- | --------------------- |
|
||||
|  |  |
|
||||
|
||||
## 1. 准备飞书机器人
|
||||
|
||||
| | | |
|
||||
| --------------------- | --------------------- |--------------------- |
|
||||
|  |  | |
|
||||
|
||||
## 2. 导入编排代码
|
||||
|
||||
复制下面配置,点击「高级编排」右上角的导入按键,导入该配置,导入后将飞书提供的接口地址复制到「HTTP 模块」。
|
||||
|
||||
{{% details title="编排配置" closed="true" %}}
|
||||
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"nodeId": "userGuide",
|
||||
"name": "系统配置",
|
||||
"intro": "可以配置应用的系统参数",
|
||||
"avatar": "/imgs/workflow/userGuide.png",
|
||||
"flowNodeType": "userGuide",
|
||||
"position": {
|
||||
"x": 303.41163758039283,
|
||||
"y": -552.297639861266
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "workflowStartNodeId",
|
||||
"name": "流程开始",
|
||||
"intro": "",
|
||||
"avatar": "/imgs/workflow/userChatInput.svg",
|
||||
"flowNodeType": "workflowStart",
|
||||
"position": {
|
||||
"x": 529.3935295017156,
|
||||
"y": 197.114018410347
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"toolDescription": "用户问题"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "userChatInput",
|
||||
"key": "userChatInput",
|
||||
"label": "core.module.input.label.user question",
|
||||
"valueType": "string",
|
||||
"type": "static"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "u6IAOEssxoZT",
|
||||
"name": "工具调用",
|
||||
"intro": "通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。",
|
||||
"avatar": "/imgs/workflow/tool.svg",
|
||||
"flowNodeType": "tools",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1003.146243538873,
|
||||
"y": 48.52327869406625
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "model",
|
||||
"renderTypeList": [
|
||||
"settingLLMModel",
|
||||
"reference"
|
||||
],
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"valueType": "string",
|
||||
"llmModelType": "all",
|
||||
"value": "gpt-3.5-turbo"
|
||||
},
|
||||
{
|
||||
"key": "temperature",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 0,
|
||||
"valueType": "number",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"step": 1
|
||||
},
|
||||
{
|
||||
"key": "maxToken",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 2000,
|
||||
"valueType": "number",
|
||||
"min": 100,
|
||||
"max": 4000,
|
||||
"step": 50
|
||||
},
|
||||
{
|
||||
"key": "systemPrompt",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"max": 3000,
|
||||
"valueType": "string",
|
||||
"label": "core.ai.Prompt",
|
||||
"description": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"placeholder": "core.app.tip.chatNodeSystemPromptTip"
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"renderTypeList": [
|
||||
"numberInput",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "chatHistory",
|
||||
"label": "core.module.input.label.chat history",
|
||||
"description": "最多携带多少轮对话记录",
|
||||
"required": true,
|
||||
"min": 0,
|
||||
"max": 50,
|
||||
"value": 6
|
||||
},
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"value": [
|
||||
"workflowStartNodeId",
|
||||
"userChatInput"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "answerText",
|
||||
"key": "answerText",
|
||||
"label": "core.module.output.label.Ai response content",
|
||||
"description": "core.module.output.description.Ai response content",
|
||||
"valueType": "string",
|
||||
"type": "static"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "fvY5hb0K646V",
|
||||
"name": "工具调用终止",
|
||||
"intro": "该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。",
|
||||
"avatar": "/imgs/workflow/toolStop.svg",
|
||||
"flowNodeType": "stopTool",
|
||||
"position": {
|
||||
"x": 2367.838362362707,
|
||||
"y": 732.355988936165
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "x9rN2a4WnZmt",
|
||||
"name": "HTTP 请求",
|
||||
"intro": "向飞书发送一个webhooks通知信息。",
|
||||
"avatar": "/imgs/workflow/http.png",
|
||||
"flowNodeType": "httpRequest468",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1623.9214305901633,
|
||||
"y": 22.777089001645862
|
||||
},
|
||||
"version": "486",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "system_addInputParam",
|
||||
"renderTypeList": [
|
||||
"addInputParam"
|
||||
],
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"description": "core.module.input.description.HTTP Dynamic Input",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": [
|
||||
"reference"
|
||||
],
|
||||
"key": "text",
|
||||
"label": "text",
|
||||
"toolDescription": "发送的消息",
|
||||
"required": true,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "system_httpMethod",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"value": "POST",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "system_httpReqUrl",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Url",
|
||||
"placeholder": "https://api.ai.com/getInventory",
|
||||
"required": false,
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpHeader",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Header",
|
||||
"placeholder": "core.module.input.description.Http Request Header",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpParams",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpJsonBody",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": "{\r\n \"msg_type\": \"text\",\r\n \"content\": {\r\n \"text\": \"{{text}}\"\r\n }\r\n}",
|
||||
"label": "",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "system_addOutputParam",
|
||||
"key": "system_addOutputParam",
|
||||
"type": "dynamic",
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "error",
|
||||
"key": "error",
|
||||
"label": "请求错误",
|
||||
"description": "HTTP请求错误信息,成功时返回空",
|
||||
"valueType": "object",
|
||||
"type": "static"
|
||||
},
|
||||
{
|
||||
"id": "httpRawResponse",
|
||||
"key": "httpRawResponse",
|
||||
"label": "原始响应",
|
||||
"required": true,
|
||||
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
|
||||
"valueType": "any",
|
||||
"type": "static"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "aGHGqH2oUupj",
|
||||
"name": "指定回复",
|
||||
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
|
||||
"avatar": "/imgs/workflow/reply.png",
|
||||
"flowNodeType": "answerNode",
|
||||
"position": {
|
||||
"x": 2350.7077940158674,
|
||||
"y": 107.32448732713493
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "text",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "any",
|
||||
"required": true,
|
||||
"label": "core.module.input.label.Response content",
|
||||
"description": "core.module.input.description.Response content",
|
||||
"placeholder": "core.module.input.description.Response content",
|
||||
"value": "嘻嘻,发送成功"
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "workflowStartNodeId",
|
||||
"target": "u6IAOEssxoZT",
|
||||
"sourceHandle": "workflowStartNodeId-source-right",
|
||||
"targetHandle": "u6IAOEssxoZT-target-left"
|
||||
},
|
||||
{
|
||||
"source": "u6IAOEssxoZT",
|
||||
"target": "x9rN2a4WnZmt",
|
||||
"sourceHandle": "selectedTools",
|
||||
"targetHandle": "selectedTools"
|
||||
},
|
||||
{
|
||||
"source": "x9rN2a4WnZmt",
|
||||
"target": "fvY5hb0K646V",
|
||||
"sourceHandle": "x9rN2a4WnZmt-source-right",
|
||||
"targetHandle": "fvY5hb0K646V-target-left"
|
||||
},
|
||||
{
|
||||
"source": "x9rN2a4WnZmt",
|
||||
"target": "aGHGqH2oUupj",
|
||||
"sourceHandle": "x9rN2a4WnZmt-source-right",
|
||||
"targetHandle": "aGHGqH2oUupj-target-left"
|
||||
}
|
||||
],
|
||||
"chatConfig": {
|
||||
"variables": [
|
||||
{
|
||||
"id": "txq1ca",
|
||||
"key": "test",
|
||||
"label": "测试",
|
||||
"type": "custom",
|
||||
"required": true,
|
||||
"maxLen": 50,
|
||||
"enums": [
|
||||
{
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"questionGuide": false,
|
||||
"scheduledTriggerConfig": {
|
||||
"cronString": "",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"defaultPrompt": ""
|
||||
},
|
||||
"_id": "66715d4bf577287d39e35ecf"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{% /details %}}
|
||||
|
||||
|
||||
## 3. 流程说明
|
||||
|
||||
1. 为工具调用挂载一个HTTP模块,功能描述写上:调用飞书webhook,发送一个通知。
|
||||
2. HTTP模块的输入参数中,填写飞书机器人的地址,填写发送的通知内容。
|
||||
3. HTTP模块输出连接上一个工具终止模块,用于强制结束工具调用。不终止的话,会把调用结果返回给模型,模型会继续回答一次问题,浪费 Tokens
|
||||
4. HTTP模块输出再连上一个指定回复,直接回复一个发送成功,用于替代AI的回答。
|
432
docSite/content/zh-cn/docs/use-cases/app-cases/fixingEvidence.md
Normal file
432
docSite/content/zh-cn/docs/use-cases/app-cases/fixingEvidence.md
Normal file
@@ -0,0 +1,432 @@
|
||||
---
|
||||
title: '固定开头和结尾内容'
|
||||
description: '利用指定回复,创建固定的开头和结尾'
|
||||
icon: 'healing'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 610
|
||||
---
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
如上图,可以通过指定回复编排一个固定的开头和结尾内容。
|
||||
|
||||
## 模块编排
|
||||
|
||||
复制下面配置,点击「高级编排」右上角的导入按键,导入该配置。
|
||||
|
||||
{{% details title="编排配置" closed="true" %}}
|
||||
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"nodeId": "7z5g5h",
|
||||
"name": "流程开始",
|
||||
"intro": "",
|
||||
"avatar": "/imgs/workflow/userChatInput.svg",
|
||||
"flowNodeType": "workflowStart",
|
||||
"position": {
|
||||
"x": -269.50851681351924,
|
||||
"y": 1657.6123698022448
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "问题输入",
|
||||
"required": true,
|
||||
"toolDescription": "用户问题",
|
||||
"type": "systemInput",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0,
|
||||
"value": [
|
||||
"7z5g5h",
|
||||
"userChatInput"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "userChatInput",
|
||||
"type": "static",
|
||||
"key": "userChatInput",
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.user question"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "nlfwkc",
|
||||
"name": "AI 对话",
|
||||
"intro": "AI 大模型对话",
|
||||
"avatar": "/imgs/workflow/AI.png",
|
||||
"flowNodeType": "chatNode",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 907.2058332478431,
|
||||
"y": 1348.9992737142143
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "model",
|
||||
"renderTypeList": [
|
||||
"settingLLMModel",
|
||||
"reference"
|
||||
],
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"valueType": "string",
|
||||
"type": "selectLLMModel",
|
||||
"required": true,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": "gpt-3.5-turbo",
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "temperature",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 0,
|
||||
"valueType": "number",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"step": 1,
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "maxToken",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 2000,
|
||||
"valueType": "number",
|
||||
"min": 100,
|
||||
"max": 4000,
|
||||
"step": 50,
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "isResponseAnswerText",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": true,
|
||||
"valueType": "boolean",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "quoteTemplate",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"valueType": "string",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "quotePrompt",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"valueType": "string",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "systemPrompt",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"max": 300,
|
||||
"valueType": "string",
|
||||
"label": "core.ai.Prompt",
|
||||
"description": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"placeholder": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"type": "textarea",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"value": "",
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"renderTypeList": [
|
||||
"numberInput",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "chatHistory",
|
||||
"label": "core.module.input.label.chat history",
|
||||
"required": true,
|
||||
"min": 0,
|
||||
"max": 30,
|
||||
"value": 6,
|
||||
"type": "numberInput",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "问题输入",
|
||||
"required": true,
|
||||
"toolDescription": "用户问题",
|
||||
"type": "custom",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": true,
|
||||
"selectedTypeIndex": 0,
|
||||
"value": [
|
||||
"7z5g5h",
|
||||
"userChatInput"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "quoteQA",
|
||||
"renderTypeList": [
|
||||
"settingDatasetQuotePrompt"
|
||||
],
|
||||
"label": "",
|
||||
"debugLabel": "知识库引用",
|
||||
"description": "core.module.Dataset quote.Input description",
|
||||
"valueType": "datasetQuote",
|
||||
"type": "target",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": true,
|
||||
"selectedTypeIndex": 0,
|
||||
"value": [
|
||||
"fljhzy",
|
||||
"quoteQA"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "answerText",
|
||||
"type": "static",
|
||||
"key": "answerText",
|
||||
"valueType": "string",
|
||||
"label": "core.module.output.label.Ai response content",
|
||||
"description": "core.module.output.description.Ai response content"
|
||||
},
|
||||
{
|
||||
"id": "history",
|
||||
"type": "static",
|
||||
"key": "history",
|
||||
"valueType": "chatHistory",
|
||||
"label": "core.module.output.label.New context",
|
||||
"description": "core.module.output.description.New context"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "q9equb",
|
||||
"name": "core.module.template.App system setting",
|
||||
"intro": "可以配置应用的系统参数。",
|
||||
"avatar": "/imgs/workflow/userGuide.png",
|
||||
"flowNodeType": "userGuide",
|
||||
"position": {
|
||||
"x": -275.92529567956024,
|
||||
"y": 1094.1001488133452
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "welcomeText",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "core.app.Welcome Text",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": "你好,我是电影《星际穿越》 AI 助手,有什么可以帮助你的?\n[导演是谁]\n[剧情介绍]\n[票房分析]",
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "variables",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "core.module.Variable",
|
||||
"value": [],
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "questionGuide",
|
||||
"valueType": "boolean",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"type": "switch",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "tts",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "whisper",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"key": "scheduleTrigger",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"value": null
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "tc90wz",
|
||||
"name": "指定回复",
|
||||
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
|
||||
"avatar": "/imgs/workflow/reply.png",
|
||||
"flowNodeType": "answerNode",
|
||||
"position": {
|
||||
"x": 159.49274056478237,
|
||||
"y": 1621.4635230667668
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "text",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "core.module.input.label.Response content",
|
||||
"description": "core.module.input.description.Response content",
|
||||
"placeholder": "core.module.input.description.Response content",
|
||||
"type": "textarea",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"value": "这是开头\\n",
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "U5T3dMVY4wj7",
|
||||
"name": "指定回复",
|
||||
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
|
||||
"avatar": "/imgs/workflow/reply.png",
|
||||
"flowNodeType": "answerNode",
|
||||
"position": {
|
||||
"x": 1467.0625486167608,
|
||||
"y": 1597.346243737531
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "text",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.Response content",
|
||||
"description": "core.module.input.description.Response content",
|
||||
"placeholder": "core.module.input.description.Response content",
|
||||
"value": "这是结尾"
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "7z5g5h",
|
||||
"target": "tc90wz",
|
||||
"sourceHandle": "7z5g5h-source-right",
|
||||
"targetHandle": "tc90wz-target-left"
|
||||
},
|
||||
{
|
||||
"source": "tc90wz",
|
||||
"target": "nlfwkc",
|
||||
"sourceHandle": "tc90wz-source-right",
|
||||
"targetHandle": "nlfwkc-target-left"
|
||||
},
|
||||
{
|
||||
"source": "nlfwkc",
|
||||
"target": "U5T3dMVY4wj7",
|
||||
"sourceHandle": "nlfwkc-source-right",
|
||||
"targetHandle": "U5T3dMVY4wj7-target-left"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{{% /details %}}
|
||||
|
1285
docSite/content/zh-cn/docs/use-cases/app-cases/google_search.md
Normal file
1285
docSite/content/zh-cn/docs/use-cases/app-cases/google_search.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,853 @@
|
||||
---
|
||||
title: '实验室预约'
|
||||
description: '展示高级编排操作数据库的能力'
|
||||
icon: 'database'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 612
|
||||
---
|
||||
|
||||
| | |
|
||||
| --------------------- | --------------------- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
|
||||
|
||||
本示例演示了利用工具调用,自动选择调用知识库搜索实验室相关内容,或调用 HTTP 模块实现数据库的 CRUD 操作。
|
||||
|
||||
以一个实验室预约为例,用户可以通过对话系统预约、取消、修改预约和查询预约记录。
|
||||
|
||||
## 1. 全局变量使用
|
||||
|
||||
通过设计一个全局变量,让用户输入姓名,模拟用户身份信息。实际使用过程中,通常是直接通过嵌入 Token 来标记用户身份。
|
||||
|
||||
## 2. 工具调用
|
||||
|
||||

|
||||
|
||||
背景知识中,引导模型调用工具去执行不通的操作。
|
||||
|
||||
{{% alert icon="🤗" context="warning" %}}
|
||||
**Tips:** 这里需要增加适当的上下文,方便模型结合历史纪录进行判断和决策~
|
||||
{{% /alert %}}
|
||||
|
||||
## 3. HTTP 模块
|
||||
|
||||

|
||||
|
||||
HTTP模块中,需要设置 3 个工具参数:
|
||||
|
||||
- 预约行为:可取 get, put, post, delete 四个值,分别对应查询、修改、新增、删除操作。当然,你也可以写4个HTTP模块,来分别处理。
|
||||
- labname: 实验室名。非必填,因为查询和删除时候,不需要。
|
||||
- time: 预约时间。
|
||||
|
||||
|
||||
# 总结
|
||||
|
||||
1. 工具调用模块是非常强大的功能,可以在一定程度上替代问题分类和内容提取。
|
||||
2. 通过工具模块,动态的调用不同的工具,可以将复杂业务解耦。
|
||||
|
||||
|
||||
# 附件
|
||||
|
||||
## 编排配置
|
||||
|
||||
可直接复制,导入到 FastGPT 中。
|
||||
|
||||
{{% details title="编排配置" closed="true" %}}
|
||||
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"nodeId": "userChatInput",
|
||||
"name": "流程开始",
|
||||
"intro": "当用户发送一个内容后,流程将会从这个模块开始执行。",
|
||||
"avatar": "/imgs/workflow/userChatInput.svg",
|
||||
"flowNodeType": "workflowStart",
|
||||
"position": {
|
||||
"x": 309.7143912167367,
|
||||
"y": 1501.2761754220846
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "问题输入",
|
||||
"required": true,
|
||||
"toolDescription": "用户问题",
|
||||
"type": "systemInput",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0,
|
||||
"value": [
|
||||
"userChatInput",
|
||||
"userChatInput"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "userChatInput",
|
||||
"type": "static",
|
||||
"key": "userChatInput",
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.user question"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "eg5upi",
|
||||
"name": "指定回复",
|
||||
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
|
||||
"avatar": "/imgs/workflow/reply.png",
|
||||
"flowNodeType": "answerNode",
|
||||
"position": {
|
||||
"x": 1962.729630445213,
|
||||
"y": 2295.9791334948304
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "text",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "core.module.input.label.Response content",
|
||||
"description": "core.module.input.description.Response content",
|
||||
"placeholder": "core.module.input.description.Response content",
|
||||
"type": "textarea",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": true,
|
||||
"selectedTypeIndex": 1,
|
||||
"value": [
|
||||
"40clf3",
|
||||
"result"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "kge59i",
|
||||
"name": "用户引导",
|
||||
"intro": "可以配置应用的系统参数。",
|
||||
"avatar": "/imgs/workflow/userGuide.png",
|
||||
"flowNodeType": "userGuide",
|
||||
"position": {
|
||||
"x": -327.218389965887,
|
||||
"y": 1504.8056414948464
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "welcomeText",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "core.app.Welcome Text",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": "你好,我是实验室助手,请问有什么可以帮助你的么?如需预约或修改预约实验室,请提供姓名、时间和实验室名称。\n[实验室介绍]\n[开放时间]\n[预约]",
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "variables",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "core.module.Variable",
|
||||
"value": [
|
||||
{
|
||||
"id": "gt9b23",
|
||||
"key": "name",
|
||||
"label": "name",
|
||||
"type": "input",
|
||||
"required": true,
|
||||
"maxLen": 50,
|
||||
"enums": [
|
||||
{
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "questionGuide",
|
||||
"valueType": "boolean",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"type": "switch",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "tts",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": {
|
||||
"type": "model",
|
||||
"model": "tts-1",
|
||||
"voice": "alloy"
|
||||
},
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "whisper",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "scheduleTrigger",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"value": null
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "40clf3",
|
||||
"name": "HTTP请求",
|
||||
"intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
|
||||
"avatar": "/imgs/workflow/http.png",
|
||||
"flowNodeType": "httpRequest468",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1118.6532653446993,
|
||||
"y": 1955.886106913907
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "system_httpMethod",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"value": "POST",
|
||||
"required": true,
|
||||
"type": "custom",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": [
|
||||
"reference"
|
||||
],
|
||||
"key": "action",
|
||||
"label": "action",
|
||||
"toolDescription": "预约行为,一共四种:\nget - 查询预约情况\nput - 更新预约\npost - 新增预约\ndelete - 删除预约",
|
||||
"required": true,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": [
|
||||
"reference"
|
||||
],
|
||||
"key": "labname",
|
||||
"label": "labname",
|
||||
"toolDescription": "实验室名称",
|
||||
"required": false,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": [
|
||||
"reference"
|
||||
],
|
||||
"key": "time",
|
||||
"label": "time",
|
||||
"toolDescription": "预约时间,按 YYYY/MM/DD HH:mm 格式返回",
|
||||
"required": false,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "system_httpReqUrl",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Url",
|
||||
"placeholder": "https://api.ai.com/getInventory",
|
||||
"required": false,
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": "https://d8dns0.laf.dev/appointment-lab",
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "system_httpHeader",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Header",
|
||||
"placeholder": "core.module.input.description.Http Request Header",
|
||||
"required": false,
|
||||
"type": "custom",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "system_httpParams",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"required": false,
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "system_httpJsonBody",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": "{\r\n \"name\": \"{{name}}\",\r\n \"time\": \"{{time}}\",\r\n \"labname\": \"{{labname}}\",\r\n \"action\": \"{{action}}\"\r\n}",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"type": "hidden",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false,
|
||||
"selectedTypeIndex": 0
|
||||
},
|
||||
{
|
||||
"key": "system_addInputParam",
|
||||
"renderTypeList": [
|
||||
"addInputParam"
|
||||
],
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"description": "core.module.input.description.HTTP Dynamic Input",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "system_addOutputParam",
|
||||
"type": "dynamic",
|
||||
"key": "system_addOutputParam",
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "result",
|
||||
"type": "static",
|
||||
"key": "result",
|
||||
"valueType": "string",
|
||||
"label": "result",
|
||||
"description": "result",
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"name": true,
|
||||
"description": true,
|
||||
"dataType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "httpRawResponse",
|
||||
"type": "static",
|
||||
"key": "httpRawResponse",
|
||||
"valueType": "any",
|
||||
"label": "原始响应",
|
||||
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "fYxwWym8flYL",
|
||||
"name": "工具调用",
|
||||
"intro": "通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。",
|
||||
"avatar": "/imgs/workflow/tool.svg",
|
||||
"flowNodeType": "tools",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 933.9342354248961,
|
||||
"y": 1229.3563445150553
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "model",
|
||||
"renderTypeList": [
|
||||
"settingLLMModel",
|
||||
"reference"
|
||||
],
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"valueType": "string",
|
||||
"llmModelType": "all",
|
||||
"value": "gpt-3.5-turbo"
|
||||
},
|
||||
{
|
||||
"key": "temperature",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 0,
|
||||
"valueType": "number",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"step": 1
|
||||
},
|
||||
{
|
||||
"key": "maxToken",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 2000,
|
||||
"valueType": "number",
|
||||
"min": 100,
|
||||
"max": 4000,
|
||||
"step": 50
|
||||
},
|
||||
{
|
||||
"key": "systemPrompt",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"max": 3000,
|
||||
"valueType": "string",
|
||||
"label": "core.ai.Prompt",
|
||||
"description": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"placeholder": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"value": "当前时间为: {{cTime}}\n你是实验室助手,用户可能会询问实验室相关介绍或预约实验室。\n请选择合适的工具去帮助他们。"
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"renderTypeList": [
|
||||
"numberInput",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "chatHistory",
|
||||
"label": "core.module.input.label.chat history",
|
||||
"required": true,
|
||||
"min": 0,
|
||||
"max": 30,
|
||||
"value": 6
|
||||
},
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"value": [
|
||||
"userChatInput",
|
||||
"userChatInput"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "JSSQtDgwmmbE",
|
||||
"name": "知识库搜索",
|
||||
"intro": "调用“语义检索”和“全文检索”能力,从“知识库”中查找实验室介绍和使用规则等信息。",
|
||||
"avatar": "/imgs/workflow/db.png",
|
||||
"flowNodeType": "datasetSearchNode",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 447.0795498711184,
|
||||
"y": 1971.5311041711186
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "datasets",
|
||||
"renderTypeList": [
|
||||
"selectDataset",
|
||||
"reference"
|
||||
],
|
||||
"label": "core.module.input.label.Select dataset",
|
||||
"value": [],
|
||||
"valueType": "selectDataset",
|
||||
"list": [],
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "similarity",
|
||||
"renderTypeList": [
|
||||
"selectDatasetParamsModal"
|
||||
],
|
||||
"label": "",
|
||||
"value": 0.4,
|
||||
"valueType": "number"
|
||||
},
|
||||
{
|
||||
"key": "limit",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 1500,
|
||||
"valueType": "number"
|
||||
},
|
||||
{
|
||||
"key": "searchMode",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"valueType": "string",
|
||||
"value": "embedding"
|
||||
},
|
||||
{
|
||||
"key": "usingReRank",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"valueType": "boolean",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "datasetSearchUsingExtensionQuery",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"valueType": "boolean",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"key": "datasetSearchExtensionModel",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"valueType": "string",
|
||||
"value": "gpt-3.5-turbo"
|
||||
},
|
||||
{
|
||||
"key": "datasetSearchExtensionBg",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"valueType": "string",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"toolDescription": "需要检索的内容"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "quoteQA",
|
||||
"key": "quoteQA",
|
||||
"label": "core.module.Dataset quote.label",
|
||||
"description": "特殊数组格式,搜索结果为空时,返回空数组。",
|
||||
"type": "static",
|
||||
"valueType": "datasetQuote"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "IdntVQiTopHT",
|
||||
"name": "工具调用终止",
|
||||
"intro": "该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。",
|
||||
"avatar": "/imgs/workflow/toolStop.svg",
|
||||
"flowNodeType": "stopTool",
|
||||
"position": {
|
||||
"x": 1969.73331750207,
|
||||
"y": 2650.0258908119413
|
||||
},
|
||||
"inputs": [],
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "40clf3",
|
||||
"target": "eg5upi",
|
||||
"sourceHandle": "40clf3-source-right",
|
||||
"targetHandle": "eg5upi-target-left"
|
||||
},
|
||||
{
|
||||
"source": "userChatInput",
|
||||
"target": "fYxwWym8flYL",
|
||||
"sourceHandle": "userChatInput-source-right",
|
||||
"targetHandle": "fYxwWym8flYL-target-left"
|
||||
},
|
||||
{
|
||||
"source": "fYxwWym8flYL",
|
||||
"target": "40clf3",
|
||||
"sourceHandle": "selectedTools",
|
||||
"targetHandle": "selectedTools"
|
||||
},
|
||||
{
|
||||
"source": "fYxwWym8flYL",
|
||||
"target": "JSSQtDgwmmbE",
|
||||
"sourceHandle": "selectedTools",
|
||||
"targetHandle": "selectedTools"
|
||||
},
|
||||
{
|
||||
"source": "40clf3",
|
||||
"target": "IdntVQiTopHT",
|
||||
"sourceHandle": "40clf3-source-right",
|
||||
"targetHandle": "IdntVQiTopHT-target-left"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{{% /details %}}
|
||||
|
||||
## Laf 云函数代码
|
||||
|
||||
可以在 [Laf](https://laf.dev/) 中快速构建 HTTP 接口。
|
||||
|
||||
{{% details title="函数代码" closed="true" %}}
|
||||
|
||||
```ts
|
||||
import cloud from '@lafjs/cloud'
|
||||
const db = cloud.database()
|
||||
|
||||
type RequestType = {
|
||||
name: string;
|
||||
time?: string;
|
||||
labname?: string;
|
||||
action: 'post' | 'delete' | 'put' | 'get'
|
||||
}
|
||||
|
||||
export default async function (ctx: FunctionContext) {
|
||||
try {
|
||||
const { action,...body } = ctx.body as RequestType
|
||||
|
||||
if (action === 'get') {
|
||||
return await getRecord(ctx.body)
|
||||
}
|
||||
if (action === 'post') {
|
||||
return await createRecord(ctx.body)
|
||||
}
|
||||
if (action === 'put') {
|
||||
return await putRecord(ctx.body)
|
||||
}
|
||||
if (action === 'delete') {
|
||||
return await removeRecord(ctx.body)
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
result: "异常"
|
||||
}
|
||||
} catch (err) {
|
||||
return {
|
||||
result: "异常"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function putRecord({ name, time, labname }: RequestType) {
|
||||
const missData = []
|
||||
if (!name) missData.push("你的姓名")
|
||||
|
||||
if (missData.length > 0) {
|
||||
return {
|
||||
result: `请提供: ${missData.join("、")}`
|
||||
}
|
||||
}
|
||||
|
||||
const { data: record } = await db.collection("LabAppointment").where({
|
||||
name, status: "unStart"
|
||||
}).getOne()
|
||||
|
||||
if (!record) {
|
||||
return {
|
||||
result: `${name} 还没有预约记录`
|
||||
}
|
||||
}
|
||||
|
||||
const updateWhere = {
|
||||
name,
|
||||
time: time || record.time,
|
||||
labname: labname || record.labname
|
||||
}
|
||||
|
||||
await db.collection("LabAppointment").where({
|
||||
name, status: "unStart"
|
||||
}).update(updateWhere)
|
||||
|
||||
return {
|
||||
result: `修改预约成功。
|
||||
姓名:${name}·
|
||||
时间: ${updateWhere.time}
|
||||
实验室名: ${updateWhere.labname}
|
||||
` }
|
||||
}
|
||||
|
||||
|
||||
async function getRecord({ name }: RequestType) {
|
||||
if (!name) {
|
||||
return {
|
||||
result: "请提供你的姓名"
|
||||
}
|
||||
}
|
||||
const { data } = await db.collection('LabAppointment').where({ name, status: "unStart" }).getOne()
|
||||
|
||||
if (!data) {
|
||||
return {
|
||||
result: `${name} 没有预约中的记录`
|
||||
}
|
||||
}
|
||||
return {
|
||||
result: `${name} 有一条预约记录:
|
||||
姓名:${data.name}
|
||||
时间: ${data.time}
|
||||
实验室名: ${data.labname}
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
async function removeRecord({ name }: RequestType) {
|
||||
if (!name) {
|
||||
return {
|
||||
result: "请提供你的姓名"
|
||||
}
|
||||
}
|
||||
const { deleted } = await db.collection('LabAppointment').where({ name, status: "unStart" }).remove()
|
||||
|
||||
if (deleted > 0) {
|
||||
return {
|
||||
result: `取消预约记录成功: ${name}`
|
||||
}
|
||||
}
|
||||
return {
|
||||
result: ` ${name} 没有预约中的记录`
|
||||
}
|
||||
}
|
||||
|
||||
async function createRecord({ name, time, labname }: RequestType) {
|
||||
const missData = []
|
||||
if (!name) missData.push("你的姓名")
|
||||
if (!time) missData.push("需要预约的时间")
|
||||
if (!labname) missData.push("实验室名名称")
|
||||
|
||||
if (missData.length > 0) {
|
||||
return {
|
||||
result: `请提供: ${missData.join("、")}`
|
||||
}
|
||||
}
|
||||
|
||||
const { data: record } = await db.collection("LabAppointment").where({
|
||||
name, status: "unStart"
|
||||
}).getOne()
|
||||
|
||||
if (record) {
|
||||
return {
|
||||
result: `您已经有一个预约记录了:
|
||||
姓名:${record.name}
|
||||
时间: ${record.time}
|
||||
实验室名: ${record.labname}
|
||||
|
||||
每人仅能同时预约一个实验室名。
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
await db.collection("LabAppointment").add({
|
||||
name, time, labname, status: "unStart"
|
||||
})
|
||||
|
||||
return {
|
||||
result: `预约成功。
|
||||
姓名:${name}
|
||||
时间: ${time}
|
||||
实验室名: ${labname}
|
||||
` }
|
||||
}
|
||||
```
|
||||
|
||||
{{% /details %}}
|
@@ -0,0 +1,315 @@
|
||||
---
|
||||
title: "多轮翻译机器人"
|
||||
description: "如何使用 FastGPT 构建一个多轮翻译机器人,实现连续的对话翻译功能"
|
||||
icon: "translate"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 606
|
||||
---
|
||||
|
||||
吴恩达老师提出了一种反思翻译的大语言模型(LLM)翻译工作流程——[GitHub - andrewyng/translation-agent](https://github.com/andrewyng/translation-agent),具体工作流程如下:
|
||||
|
||||
1. 提示一个 LLM 将文本从 `source_language` 翻译到 `target_language`;
|
||||
2. 让 LLM 反思翻译结果并提出建设性的改进建议;
|
||||
3. 使用这些建议来改进翻译。
|
||||
|
||||
这个翻译流程应该是目前比较新的一种翻译方式,利用 LLM 对自己的翻译结果进行改进来获得较好的翻译效果
|
||||
|
||||
项目中展示了可以利用对长文本进行分片,然后分别进行反思翻译处理,以突破 LLM 对 tokens 数量的限制,真正实现长文本一键高效率高质量翻译。
|
||||
|
||||
项目还通过给大模型限定国家地区,已实现更精确的翻译,如美式英语、英式英语之分;同时提出一些可能能带来更好效果的优化,如对于一些 LLM 未曾训练到的术语(或有多种翻译方式的术语)建立术语表,进一步提升翻译的精确度等等
|
||||
|
||||
而这一切都能通过 Fastgpt 工作流轻松实现,本文将手把手教你如何复刻吴恩达老师的 translation-agent
|
||||
|
||||
# 单文本块反思翻译
|
||||
|
||||
先从简单的开始,即不超出 LLM tokens 数量限制的单文本块翻译
|
||||
|
||||
## 初始翻译
|
||||
|
||||
第一步先让 LLM 对源文本块进行初始翻译(翻译的提示词在源项目中都有)
|
||||
|
||||

|
||||
|
||||
通过`文本拼接`模块引用 源语言、目标语言、源文本这三个参数,生成提示词,传给 LLM,让它给出第一版的翻译
|
||||
|
||||
## 反思
|
||||
|
||||
然后让 LLM 对第一步生成的初始翻译给出修改建议,称之为 反思
|
||||
|
||||

|
||||
|
||||
这时的提示词接收 5 个参数,源文本、初始翻译、源语言、目标语言 以及限定词地区国家,这样 LLM 会对前面生成的翻译提出相当多的修改建议,为后续的提升翻译作准备
|
||||
|
||||
## 提升翻译
|
||||
|
||||

|
||||
|
||||
在前文生成了初始翻译以及相应的反思后,将这二者输入给第三次 LLM 翻译,这样我们就能获得一个比较高质量的翻译结果
|
||||
|
||||
完整的工作流如下
|
||||
|
||||

|
||||
|
||||
## 运行效果
|
||||
|
||||
由于考虑之后对这个反思翻译的复用,所以创建了一个插件,那么在下面我直接调用这个插件就能使用反思翻译,效果如下
|
||||
|
||||
随机挑选了一段哈利波特的文段
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
可以看到反思翻译后的效果还是好上不少的,其中反思的输出如下
|
||||
|
||||

|
||||
|
||||
# 长文反思翻译
|
||||
|
||||
在掌握了对短文本块的反思翻译后,我们能轻松的通过分片和循环,实现对长文本也即多文本块的反思翻译
|
||||
|
||||
整体的逻辑是,首先对传入文本的 tokens数量做判断,如果不超过设置的 tokens 限制,那么直接调用单文本块反思翻译,如果超过设置的 tokens限制,那么切割为合理的大小,再分别进行对应的反思翻译处理
|
||||
|
||||
## 计算 tokens
|
||||
|
||||

|
||||
|
||||
首先,我使用了 Laf函数 模块来实现对输入文本的 tokens 的计算
|
||||
|
||||
laf函数的使用相当简单,即开即用,只需要在 laf 创建个应用,然后安装 tiktoken 依赖,导入如下代码即可
|
||||
|
||||
```TypeScript
|
||||
const { Tiktoken } = require("tiktoken/lite");
|
||||
const cl100k_base = require("tiktoken/encoders/cl100k_base.json");
|
||||
|
||||
interface IRequestBody {
|
||||
str: string
|
||||
}
|
||||
|
||||
interface RequestProps extends IRequestBody {
|
||||
systemParams: {
|
||||
appId: string,
|
||||
variables: string,
|
||||
histories: string,
|
||||
cTime: string,
|
||||
chatId: string,
|
||||
responseChatItemId: string
|
||||
}
|
||||
}
|
||||
|
||||
interface IResponse {
|
||||
message: string;
|
||||
tokens: number;
|
||||
}
|
||||
|
||||
export default async function (ctx: FunctionContext): Promise<IResponse> {
|
||||
const { str = "" }: RequestProps = ctx.body
|
||||
|
||||
const encoding = new Tiktoken(
|
||||
cl100k_base.bpe_ranks,
|
||||
cl100k_base.special_tokens,
|
||||
cl100k_base.pat_str
|
||||
);
|
||||
const tokens = encoding.encode(str);
|
||||
encoding.free();
|
||||
|
||||
return {
|
||||
message: 'ok',
|
||||
tokens: tokens.length
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
再回到 Fastgpt,点击“同步参数”,再连线将源文本传入,即可计算 tokens 数量
|
||||
|
||||
## 计算单文本块大小
|
||||
|
||||

|
||||
|
||||
由于不涉及第三方包,只是一些数据处理,所以直接使用 代码运行 模块处理即可
|
||||
|
||||
```TypeScript
|
||||
function main({tokenCount, tokenLimit}){
|
||||
const numChunks = Math.ceil(tokenCount / tokenLimit);
|
||||
let chunkSize = Math.floor(tokenCount / numChunks);
|
||||
|
||||
const remainingTokens = tokenCount % tokenLimit;
|
||||
if (remainingTokens > 0) {
|
||||
chunkSize += Math.floor(remainingTokens / numChunks);
|
||||
}
|
||||
|
||||
return {chunkSize};
|
||||
}
|
||||
```
|
||||
|
||||
通过上面的代码,我们就能算出不超过 token限制的合理单文本块大小是多少了
|
||||
|
||||
## 获得切分后源文本块
|
||||
|
||||

|
||||
|
||||
通过单文本块大小和源文本,我们再编写一个函数调用 langchain 的 textsplitters 包来实现文本分片,具体代码如下
|
||||
|
||||
```TypeScript
|
||||
import cloud from '@lafjs/cloud'
|
||||
import { TokenTextSplitter } from "@langchain/textsplitters";
|
||||
|
||||
interface IRequestBody {
|
||||
text: string
|
||||
chunkSize: number
|
||||
}
|
||||
|
||||
interface RequestProps extends IRequestBody {
|
||||
systemParams: {
|
||||
appId: string,
|
||||
variables: string,
|
||||
histories: string,
|
||||
cTime: string,
|
||||
chatId: string,
|
||||
responseChatItemId: string
|
||||
}
|
||||
}
|
||||
|
||||
interface IResponse {
|
||||
output: string[];
|
||||
}
|
||||
|
||||
export default async function (ctx: FunctionContext): Promise<IResponse>{
|
||||
const { text = '', chunkSize=1000 }: RequestProps = ctx.body;
|
||||
|
||||
const splitter = new TokenTextSplitter({
|
||||
encodingName:"gpt2",
|
||||
chunkSize: Number(chunkSize),
|
||||
chunkOverlap: 0,
|
||||
});
|
||||
|
||||
const output = await splitter.splitText(text);
|
||||
|
||||
return {
|
||||
output
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这样我们就获得了切分好的文本,接下去的操作就类似单文本块反思翻译
|
||||
|
||||
## 多文本块翻译
|
||||
|
||||
这里应该还是不能直接调用前面的单文本块反思翻译,因为提示词中会涉及一些上下文的处理(或者可以修改下前面写好的插件,多传点参数进去)
|
||||
|
||||
详细的和前面类似,就是提示词进行一些替换,以及需要做一些很简单的数据处理,整体效果如下
|
||||
|
||||
### 多文本块初始翻译
|
||||
|
||||

|
||||
|
||||
### 多文本块反思
|
||||
|
||||

|
||||
|
||||
### 多文本块提升翻译
|
||||
|
||||

|
||||
|
||||
## 循环执行
|
||||
|
||||
长文反思翻译比较关键的一个部分,就是对多个文本块进行循环反思翻译
|
||||
|
||||
Fastgpt 提供了工作流线路可以返回去执行的功能,所以我们可以写一个很简单的判断函数,来判断结束或是接着执行
|
||||
|
||||

|
||||
|
||||
也就是通过判断当前处理的这个文本块,是否是最后一个文本块,从而判断是否需要继续执行,就这样,我们实现了长文反思翻译的效果
|
||||
|
||||
完整工作流如下
|
||||
|
||||

|
||||
|
||||
## 运行效果
|
||||
|
||||
首先输入全局设置
|
||||
|
||||

|
||||
|
||||
然后输入需要翻译的文本,这里我选择了一章哈利波特的英文原文来做翻译,其文本长度通过 openai 对 tokens 数量的判断如下
|
||||
|
||||

|
||||
|
||||
实际运行效果如下
|
||||
|
||||

|
||||
|
||||
可以看到还是能满足阅读需求的
|
||||
|
||||
# 进一步调优
|
||||
|
||||
## 提示词调优
|
||||
|
||||
在源项目中,给 AI 的系统提示词还是比较的简略的,我们可以通过比较完善的提示词,来督促 LLM 返回更合适的翻译,进一步提升翻译的质量
|
||||
|
||||
比如初始翻译中,
|
||||
|
||||
```TypeScript
|
||||
# Role: 资深翻译专家
|
||||
|
||||
## Background:
|
||||
你是一位经验丰富的翻译专家,精通{{source_lang}}和{{target_lang}}互译,尤其擅长将{{source_lang}}文章译成流畅易懂的{{target_lang}}。你曾多次带领团队完成大型翻译项目,译文广受好评。
|
||||
|
||||
## Attention:
|
||||
- 翻译过程中要始终坚持"信、达、雅"的原则,但"达"尤为重要
|
||||
- 译文要符合{{target_lang}}的表达习惯,通俗易懂,连贯流畅
|
||||
- 避免使用过于文绉绉的表达和晦涩难懂的典故引用
|
||||
|
||||
## Constraints:
|
||||
- 必须严格遵循四轮翻译流程:直译、意译、校审、定稿
|
||||
- 译文要忠实原文,准确无误,不能遗漏或曲解原意
|
||||
|
||||
## Goals:
|
||||
- 通过四轮翻译流程,将{{source_lang}}原文译成高质量的{{target_lang}}译文
|
||||
- 译文要准确传达原文意思,语言表达力求浅显易懂,朗朗上口
|
||||
- 适度使用一些熟语俗语、流行网络用语等,增强译文的亲和力
|
||||
- 在直译的基础上,提供至少2个不同风格的意译版本供选择
|
||||
|
||||
## Skills:
|
||||
- 精通{{source_lang}} {{target_lang}}两种语言,具有扎实的语言功底和丰富的翻译经验
|
||||
- 擅长将{{source_lang}}表达习惯转换为地道自然的{{target_lang}}
|
||||
- 对当代{{target_lang}}语言的发展变化有敏锐洞察,善于把握语言流行趋势
|
||||
|
||||
## Workflow:
|
||||
1. 第一轮直译:逐字逐句忠实原文,不遗漏任何信息
|
||||
2. 第二轮意译:在直译的基础上用通俗流畅的{{target_lang}}意译原文,至少提供2个不同风格的版本
|
||||
3. 第三轮校审:仔细审视译文,消除偏差和欠缺,使译文更加地道易懂
|
||||
4. 第四轮定稿:择优选取,反复修改润色,最终定稿出一个简洁畅达、符合大众阅读习惯的译文
|
||||
|
||||
## OutputFormat:
|
||||
- 只需要输出第四轮定稿的回答
|
||||
|
||||
## Suggestions:
|
||||
- 直译时力求忠实原文,但不要过于拘泥逐字逐句
|
||||
- 意译时在准确表达原意的基础上,用最朴实无华的{{target_lang}}来表达
|
||||
- 校审环节重点关注译文是否符合{{target_lang}}表达习惯,是否通俗易懂
|
||||
- 定稿时适度采用一些熟语谚语、网络流行语等,使译文更接地气- 善于利用{{target_lang}}的灵活性,用不同的表述方式展现同一内容,提高译文的可读性
|
||||
```
|
||||
|
||||
从而返回更准确更高质量的初始翻译,后续的反思和提升翻译也可以修改更准确的提示词,如下
|
||||
|
||||

|
||||
|
||||
然后再让我们来看看运行效果
|
||||
|
||||

|
||||
|
||||
给了和之前相同的一段文本进行测试,测试效果还是比较显著的,就比如红框部分,之前的翻译如下
|
||||
|
||||

|
||||
|
||||
从“让你的猫头鹰给我写信”这样有失偏颇的翻译,变成“给我写信,你的猫头鹰会知道怎么找到我”这样较为准确的翻译
|
||||
|
||||
## 其他调优
|
||||
|
||||
比如限定词调优,源项目中已经做了示范,就是加上国家地区这个限定词,实测确实会有不少提升
|
||||
|
||||
出于 LLM 的卓越能力,我们能够通过设置不同的prompt来获取不同的翻译结果,也就是可以很轻松地通过设置特殊的限定词,来实现特定的,更精确的翻译
|
||||
|
||||
而对于一些超出 LLM 理解的术语等,也可以利用 Fastgpt 的知识库功能进行相应扩展,进一步完善翻译机器人的功能
|
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: "如何提交应用模板"
|
||||
description: "指南:如何向 FastGPT 提交应用模板"
|
||||
icon: "template_submission"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 602
|
||||
---
|
||||
|
||||
|
||||
## 什么模板可以合并
|
||||
|
||||
目前合并进仓库的应用模板,会在「模板市场」中全部展示给用户。
|
||||
|
||||
为了控制模板的质量以及避免数量过多带来的繁琐,并不是所有的模板都会被合并到开源仓库中,你可以提前 PR 与我们沟通模板的内容。
|
||||
|
||||
预估最后总体的数量不会很多,控制在 50 个左右,一半来自 FastGPT Team,一半来自社区用户。
|
||||
|
||||
## 如何写一个应用模板
|
||||
|
||||
1. ### 跑通 FastGPT dev 环境
|
||||
|
||||
需要在 dev 环境下执行下面的操作。
|
||||
|
||||
> 可参照 [FastGPT|快速开始本地开发](https://doc.fastgpt.in/docs/development/intro/)
|
||||
|
||||
1. ### 在 FastGPT 工作台中,创建一个应用
|
||||
|
||||
创建空白工作流即可。
|
||||
|
||||

|
||||
|
||||
1. ### 创建应用模板
|
||||
|
||||
应用模板配置以及相关资源,都会在 **projects/app/public/appMarketTemplates** 目录下。
|
||||
|
||||

|
||||
|
||||
1. 在 **projects/app/public/appMarketTemplates** 目录下,创建一个文件夹,名称为模板对应的 id。
|
||||
2. 在刚刚创建的文件夹中,再创建一个 **template.json** 文件,复制粘贴并填写如下配置:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "模板名",
|
||||
"intro": "模板描述,会展示在模板市场的展示页",
|
||||
"author": "填写你的名字",
|
||||
"avatar": "模板头像,可以将图片文件放在同一个文件夹中,然后填写相应路径",
|
||||
|
||||
"tags": ["模板标签"], // writing(文本创作),image-generation(图片生成),web-search(联网搜索),
|
||||
// roleplay(角色扮演), office-services(办公服务) 暂时分为 5 类,从中选择相应的标签
|
||||
|
||||
"type": "模板类别", // simple(简易应用), advanced(工作流), plugin(插件)
|
||||
|
||||
"workflow": { // 这个对象先不管,待会直接粘贴导出的工作流即可
|
||||
"nodes": [],
|
||||
"edges": [],
|
||||
"chatConfig": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. ### 完成应用编排并测试
|
||||
|
||||
完成应用编排后,可以点击右上角的发布。
|
||||
|
||||
1. ### 复制配置到 template.json
|
||||
|
||||
鼠标放置在左上角应用的头像和名称上,会出现对于下拉框操作,可以导出工作流配置。
|
||||
|
||||
导出的配置,会自动复制到剪切板,可以直接到 template.json 文件中粘贴使用,替换步骤 2 中,**workflow** 的值。
|
||||
|
||||

|
||||
|
||||
1. ### 验证模板是否加载成功
|
||||
|
||||
刷新页面,打开模板市场,看其是否成功加载,并点击「使用」测试其功能。
|
||||
|
||||

|
||||
|
||||
1. ### 提交 PR
|
||||
|
||||
如果你觉得你的模板需要提交到开源仓库,可以通过 PR 形式向我们提交。
|
||||
|
||||
- 写清楚模板的介绍和功能
|
||||
- 配上模板运行的效果图
|
||||
- 模板参数填写说明,需要在 PR 中写清楚。例如,有些模板需要去某个提供商申请 key,需要附上对应的地址和教程,后续我们会加入到文档中。
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
---
|
||||
weight: 500
|
||||
title: "外部调用 FastGPT"
|
||||
description: "外部应用通过多种方式调用 FastGPT 功能的教程"
|
||||
icon: "cloud"
|
||||
draft: false
|
||||
images: []
|
||||
---
|
||||
<!-- 500 ~ 600 -->
|
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: "接入飞书机器人教程"
|
||||
description: "FastGPT 接入飞书机器人教程"
|
||||
icon: "chat"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 504
|
||||
---
|
||||
|
||||
从 4.8.10 版本起,FastGPT 商业版支持直接接入飞书机器人,无需额外的 API。
|
||||
|
||||
## 1. 申请飞书应用
|
||||
|
||||
开一个免费的测试企业更方便进行调试。
|
||||
|
||||
1. 在[飞书开放平台](https://open.feishu.cn/app)的开发者后台申请企业自建应用。
|
||||
|
||||

|
||||
|
||||
添加一个**机器人**应用。
|
||||
|
||||
## 2. 在 FastGPT 新建发布渠道
|
||||
|
||||
在fastgpt中选择想要接入的应用,在 发布渠道 页面,新建一个接入飞书机器人的发布渠道,填写好基础信息。
|
||||
|
||||

|
||||
|
||||
## 3. 获取应用的 App ID, App Secret 两个凭证
|
||||
|
||||
在飞书开放平台开发者后台,刚刚创建的企业自建应用中,找到 App ID 和 App Secret,填入 FastGPT 新建发布渠道的对话框里面。
|
||||
|
||||

|
||||
|
||||
填入两个参数到 FastGPT 配置弹窗中。
|
||||
|
||||

|
||||
|
||||
(可选)在飞书开放平台开发者后台,点击事件与回调 -> 加密策略 获取 Encrypt Key,并填入飞书机器人接入的对话框里面
|
||||
|
||||

|
||||
|
||||
Encrypt Key 用于加密飞书服务器与 FastGPT 之间通信。
|
||||
建议如果使用 Https 协议,则不需要 Encrypt Key。如果使用 Http 协议通信,则建议使用 Encrypt Key
|
||||
Verification Token 默认生成的这个 Token 用于校验来源。但我们使用飞书官方推荐的另一种更为安全的校验方式,因此可以忽略这个配置项。
|
||||
## 4. 配置回调地址
|
||||
|
||||
新建好发布渠道后,点击**请求地址**,复制对应的请求地址。
|
||||
|
||||
在飞书控制台,点击左侧的 `事件与回调` ,点击`配置订阅方式`旁边的编辑 icon,粘贴刚刚复制的请求地址到输入框中。
|
||||
|
||||
| | | |
|
||||
| --- | --- | --- |
|
||||
|  |  |  |
|
||||
|
||||
## 5. 配置机器人回调事件和权限
|
||||
|
||||
* 添加 `接收消息` 事件
|
||||
|
||||
在`事件与回调`页面,点击`添加事件`。
|
||||
|
||||
搜索`接收消息`,或者直接搜索 `im.message.receive_v1` ,找到`接收消息 v2.0`的时间,勾选上并点击`确认添加`。
|
||||
|
||||
添加事件后,增加两个权限:点击对应权限,会有弹窗提示添加权限,添加上图两个权限。
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|
||||
不推荐启用上图中的两个“历史版本”,而是使用新版本的权限。
|
||||
- 若开启 “读取用户发给机器人的单聊消息”, 则单聊发送给机器人的消息将被送到 FastGPT
|
||||
- 若开启 “接收群聊中@机器人消息事件”, 则群聊中@机器人的消息将被送到 FastGPT
|
||||
- 若开启(不推荐开启)“获取群组中所有消息”,则群聊中所有消息都将被送到 FastGPT
|
||||
|
||||
## 6. 配置回复消息权限
|
||||
|
||||
在飞书控制台,点击左侧的 `权限管理` ,搜索框中输入`发消息`,找到`以应用的身份发消息`的权限,点击开通权限。
|
||||
|
||||

|
||||
|
||||
## 7. 发布机器人
|
||||
|
||||
点击飞书控制台左侧的`版本管理与发布`,即可发布机器人。
|
||||
|
||||

|
||||
|
||||
然后就可以在工作台里找到你的机器人啦。接下来就是把机器人拉进群组,或者单独与它对话。
|
||||
|
||||

|
||||
|
||||
## FAQ
|
||||
|
||||
### 发送了消息,没响应
|
||||
|
||||
1. 检查飞书机器人回调地址、权限等是否正确。
|
||||
2. 查看 FastGPT 对话日志,是否有对应的提问记录
|
||||
3. 如果有记录,飞书没回应,则是没给机器人开权限。
|
||||
4. 如果没记录,则可能是应用运行报错了,可以先试试最简单的机器人。(飞书机器人无法输入全局变量、文件、图片内容)
|
@@ -0,0 +1,8 @@
|
||||
---
|
||||
title: "iframe 接入"
|
||||
description: "通过 iframe 嵌入 FastGPT 内容到其他网页或应用"
|
||||
icon: "iframe"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 512
|
||||
---
|
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: '接入微信公众号教程'
|
||||
description: 'FastGPT 接入微信公众号教程'
|
||||
icon: 'description'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 506
|
||||
---
|
||||
|
||||
从 4.8.10 版本起,FastGPT 商业版支持直接接入微信公众号,无需额外的 API。
|
||||
|
||||
**注意⚠️: 目前只支持通过验证的公众号(服务号和订阅号都可以)**
|
||||
|
||||
## 1. 在 FastGPT 新建发布渠道
|
||||
|
||||
在 FastGPT 中选择想要接入的应用,在 *发布渠道* 页面,新建一个接入微信公众号的发布渠道,填写好基础信息。
|
||||
|
||||

|
||||
|
||||
## 2. 登录微信公众平台,获取 AppID 、 Secret和Token
|
||||
|
||||
### 1. https://mp.weixin.qq.com 登录微信公众平台,选择您的公众号。
|
||||
|
||||
**只支持通过验证的公众号,未通过验证的公众号暂不支持。**
|
||||
|
||||
开发者可以从这个链接申请微信公众号的测试号进行测试,测试号可以正常使用,但不能配置 AES Key
|
||||
|
||||

|
||||
|
||||
### 2. 把3个参数填入 FastGPT 配置弹窗中。
|
||||

|
||||
|
||||
## 3. 在 IP 白名单中加入 FastGPT 的 IP
|
||||
|
||||

|
||||
|
||||
私有部署的用户可自行查阅自己的 IP 地址。
|
||||
|
||||
海外版用户(cloud.tryfastgpt.ai)可以填写下面的 IP 白名单:
|
||||
|
||||
```
|
||||
34.87.20.17
|
||||
35.247.161.35
|
||||
34.87.51.146
|
||||
34.87.110.152
|
||||
35.247.163.68
|
||||
34.126.163.205
|
||||
34.87.20.189
|
||||
34.87.102.86
|
||||
35.240.227.100
|
||||
35.198.192.104
|
||||
34.143.149.171
|
||||
34.87.152.33
|
||||
34.124.237.188
|
||||
35.197.149.75
|
||||
34.87.44.74
|
||||
34.124.189.116
|
||||
34.87.79.202
|
||||
34.87.173.252
|
||||
34.143.240.160
|
||||
34.87.180.104
|
||||
34.142.157.52
|
||||
```
|
||||
|
||||
国内版用户(fastgpt.cn)可以填写下面的 IP 白名单:
|
||||
|
||||
```
|
||||
47.97.59.172
|
||||
121.43.108.48
|
||||
121.41.75.88
|
||||
121.41.178.7
|
||||
121.40.65.187
|
||||
121.196.235.183
|
||||
120.55.195.90
|
||||
120.55.193.112
|
||||
120.26.229.115
|
||||
112.124.41.79
|
||||
101.37.205.32
|
||||
47.98.190.173
|
||||
```
|
||||
|
||||
## 4. 获取AES Key,选择加密方式
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
1. 随机生成AESKey,填入 FastGPT 配置弹窗中。
|
||||
|
||||
2. 选择加密方式为安全模式。
|
||||
|
||||
## 5. 获取 URL
|
||||
|
||||
1. 在FastGPT确认创建,获取URL。
|
||||
|
||||

|
||||
|
||||
2. 填入微信公众平台的 URL 处,然后提交保存
|
||||

|
||||
|
||||
## 6. 启用服务器配置(如已自动启用,请忽略)
|
||||

|
||||
|
||||
## 7. 开始使用
|
||||
|
||||
现在用户向公众号发消息,消息则会被转发到 FastGPT,通过公众号返回对话结果。
|
@@ -4,14 +4,14 @@ description: "FastGPT 对接 chatgpt-on-wechat"
|
||||
icon: "chat"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 504
|
||||
weight: 509
|
||||
---
|
||||
|
||||
# 1 分钟对接 chatgpt-on-wechat
|
||||
|
||||
[chatgpt-on-wechat GitHub 地址](https://github.com/zhayujie/chatgpt-on-wechat)
|
||||
|
||||
由于 FastGPT 的 API 接口和 OpenAI 的规范一致,可以无需变更原来的应用即可使用 FastGPT 上编排好的应用。API 使用可参考 [这篇文章](/docs/course/openapi/)。编排示例,可参考 [高级编排介绍](/docs/workflow/intro)
|
||||
由于 FastGPT 的 API 接口和 OpenAI 的规范一致,可以无需变更原来的应用即可使用 FastGPT 上编排好的应用。API 使用可参考 [这篇文章](/docs/use-cases/external-integration/openapi/)。编排示例,可参考 [高级编排介绍](/docs/workflow/intro)
|
||||
|
||||
## 1. 获取 OpenAPI 密钥
|
||||
|
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "通过 API 访问应用"
|
||||
description: "通过 API 访问 FastGPT 应用"
|
||||
icon: "model_training"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 502
|
||||
---
|
||||
|
||||
在 FastGPT 中,你可以为每一个应用创建多个 API 密钥,用于访问应用的 API 接口。每个密钥仅能访问一个应用。完整的接口可以[查看应用对话接口](/docs/development/openapi/chat)。
|
||||
|
||||
## 获取 API 密钥
|
||||
|
||||
依次选择应用 -> 「API访问」,然后点击「API 密钥」来创建密钥。
|
||||
|
||||
{{% alert context="warning" %}}
|
||||
密钥需要自己保管好,一旦关闭就无法再复制密钥,只能创建新密钥再复制。
|
||||
{{% /alert %}}
|
||||
|
||||

|
||||
|
||||
{{% alert icon="🍅" context="success" %}}
|
||||
Tips: 安全起见,你可以设置一个额度或者过期时间,放置 key 被滥用。
|
||||
{{% /alert %}}
|
||||
|
||||
|
||||
## 替换三方应用的变量
|
||||
|
||||
```bash
|
||||
OPENAI_API_BASE_URL: https://api.fastgpt.in/api (改成自己部署的域名)
|
||||
OPENAI_API_KEY = 上一步获取到的密钥
|
||||
```
|
||||
|
||||
**[ChatGPT Next Web](https://github.com/Yidadaa/ChatGPT-Next-Web) 示例:**
|
||||
|
||||

|
||||
|
||||
**[ChatGPT Web](https://github.com/Chanzhaoyu/chatgpt-web) 示例:**
|
||||
|
||||

|
@@ -4,7 +4,7 @@ description: "FastGPT 接入微信和企业微信 "
|
||||
icon: "chat"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 506
|
||||
weight: 510
|
||||
---
|
||||
|
||||
# FastGPT 三分钟接入微信/企业微信
|
@@ -1,60 +0,0 @@
|
||||
---
|
||||
title: "使用 Gapier 快速导入Agent工具"
|
||||
description: "FastGPT 使用 Gapier 快速导入Agent工具"
|
||||
icon: "build"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 501
|
||||
---
|
||||
|
||||
FastGPT V4.7版本加入了工具调用,可以兼容 GPTs 的 Actions。这意味着,你可以直接导入兼容 GPTs 的 Agent 工具。
|
||||
|
||||
Gapier 是一个在线 GPTs Actions工具,提供了50多种现成工具,并且每天有免费额度进行测试,方便用户试用,官方地址为:[https://gapier.com/](https://gapier.com/)。
|
||||
|
||||

|
||||
|
||||
现在,我们开始把 Gapier 的工具导入到 FastGPT 中。
|
||||
|
||||
## 1. 创建插件
|
||||
|
||||
| Step1 | Step2 | Step3 |
|
||||
| --- | --- | --- |
|
||||
|  |  | 登录[Gapier](https://gapier.com/) 复制相关参数 <br>  |
|
||||
| Step4 | Step5 | Step6 |
|
||||
| 自定义请求头: Authorization<br>请求值: Bearer 复制的key <br>  |  |  |
|
||||
|
||||
创建完后,如果需要变更,无需重新创建,只需要修改对应参数即可,会自动做差值比较更新。
|
||||
|
||||

|
||||
|
||||
## 2. 应用绑定工具
|
||||
|
||||
### 简易模式
|
||||
|
||||
| Step1 | Step2 |
|
||||
| --- | --- | --- |
|
||||
|  |  |
|
||||
| Step3 | Step4 |
|
||||
|  |  |
|
||||
|
||||
### 高级编排
|
||||
|
||||
| Step1 | Step2 |
|
||||
| --- | --- | --- |
|
||||
|  |  |
|
||||
| Step3 | Step4 |
|
||||
|  |  |
|
||||
|
||||

|
||||
|
||||
## 3. 工具调用说明
|
||||
|
||||
### 不同模型的区别
|
||||
|
||||
不同模型调用工具采用不同的方法,有些模型支持 toolChoice 和 functionCall 效果会更好。不支持这两种方式的模型通过提示词调用,但是效果不是很好,并且为了保证顺利调用,FastGPT内置的提示词,仅支持每次调用一个工具。
|
||||
|
||||
具体哪些模型支持 functionCall 可以官网查看(当然,也需要OneAPI支持),同时需要调整模型配置文件中的对应字段(详细看配置字段说明)。
|
||||
|
||||
线上版用户,可以在模型选择时,看到是否支持函数调用的标识。
|
||||
|
||||

|
Reference in New Issue
Block a user