docs: update the framework of doc site (#207)
Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>
This commit is contained in:
8
docSite/content/docs/workflow/_index.md
Normal file
8
docSite/content/docs/workflow/_index.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
weight: 400
|
||||
title: "高级编排"
|
||||
description: "FastGPT 高级编排文档"
|
||||
icon: "family_history"
|
||||
draft: false
|
||||
images: []
|
||||
---
|
||||
8
docSite/content/docs/workflow/examples/_index.md
Normal file
8
docSite/content/docs/workflow/examples/_index.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
weight: 440
|
||||
title: "编排示例"
|
||||
description: "介绍 FastGPT 的高级编排实践案例"
|
||||
icon: "list"
|
||||
draft: false
|
||||
images: []
|
||||
---
|
||||
456
docSite/content/docs/workflow/examples/google_search.md
Normal file
456
docSite/content/docs/workflow/examples/google_search.md
Normal file
@@ -0,0 +1,456 @@
|
||||
---
|
||||
title: "联网 GPT"
|
||||
description: "将 FastGPT 外接搜索引擎"
|
||||
icon: "search"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 441
|
||||
---
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
如上图,利用 HTTP 模块,你可以轻松的外接一个搜索引擎。这里以调用 Google Search API 为例。
|
||||
|
||||
## 注册 Google Search API
|
||||
|
||||
[参考这篇文章](https://zhuanlan.zhihu.com/p/174666017)
|
||||
|
||||
## 写一个 Google Search 接口
|
||||
|
||||
这里用 [Laf](https://laf.dev/) 快速实现一个接口,即写即发布,无需部署。务必打开 POST 请求方式。
|
||||
|
||||
```ts
|
||||
import cloud from '@lafjs/cloud';
|
||||
|
||||
const googleSearchKey = '';
|
||||
const googleCxId = '';
|
||||
const baseurl = 'https://www.googleapis.com/customsearch/v1';
|
||||
|
||||
export default async function (ctx: FunctionContext) {
|
||||
const { searchKey } = ctx.body;
|
||||
|
||||
if (!searchKey) {
|
||||
return {
|
||||
prompt: ''
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const { data } = await cloud.fetch.get(baseurl, {
|
||||
params: {
|
||||
q: searchKey,
|
||||
cx: googleCxId,
|
||||
key: googleSearchKey,
|
||||
c2coff: 1,
|
||||
start: 1,
|
||||
end: 5,
|
||||
dateRestrict: 'm[1]'
|
||||
}
|
||||
});
|
||||
const result = data.items.map((item) => item.snippet).join('\n');
|
||||
return { prompt: `搜索词: ${searchKey};google 搜索结果: ${result}` };
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return {
|
||||
prompt: ''
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 模块编排
|
||||
|
||||
复制下面配置,点击「高级编排」右上角的导入按键,导入该配置,导入后将接口地址复制到「HTTP 模块」。
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"moduleId": "userChatInput",
|
||||
"name": "用户问题(对话入口)",
|
||||
"flowType": "questionInput",
|
||||
"position": {
|
||||
"x": 464.32198615344566,
|
||||
"y": 1602.2698463081606
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"type": "systemInput",
|
||||
"label": "用户问题",
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"label": "用户问题",
|
||||
"type": "source",
|
||||
"valueType": "string",
|
||||
"targets": [
|
||||
{
|
||||
"moduleId": "6g2075",
|
||||
"key": "content"
|
||||
},
|
||||
{
|
||||
"moduleId": "aijmbb",
|
||||
"key": "userChatInput"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "history",
|
||||
"name": "聊天记录",
|
||||
"flowType": "historyNode",
|
||||
"position": {
|
||||
"x": 452.5466249541586,
|
||||
"y": 1276.3930310334215
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "maxContext",
|
||||
"type": "numberInput",
|
||||
"label": "最长记录数",
|
||||
"value": 6,
|
||||
"min": 0,
|
||||
"max": 50,
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"type": "hidden",
|
||||
"label": "聊天记录",
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "history",
|
||||
"label": "聊天记录",
|
||||
"valueType": "chat_history",
|
||||
"type": "source",
|
||||
"targets": [
|
||||
{
|
||||
"moduleId": "6g2075",
|
||||
"key": "history"
|
||||
},
|
||||
{
|
||||
"moduleId": "aijmbb",
|
||||
"key": "history"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "6g2075",
|
||||
"name": "文本内容提取",
|
||||
"flowType": "contentExtract",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 971.5119545668634,
|
||||
"y": 1118.186021718385
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "switch",
|
||||
"type": "target",
|
||||
"label": "触发器",
|
||||
"valueType": "any",
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "description",
|
||||
"type": "textarea",
|
||||
"valueType": "string",
|
||||
"label": "提取要求描述",
|
||||
"description": "写一段提取要求,告诉 AI 需要提取哪些内容",
|
||||
"required": true,
|
||||
"placeholder": "例如: \n1. 你是一个实验室预约助手。根据用户问题,提取出姓名、实验室号和预约时间",
|
||||
"value": "你是谷歌搜索机器人,可以生成搜索词。你需要自行判断是否需要生成搜索词,如果不需要则返回空字符串。",
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"type": "target",
|
||||
"label": "聊天记录",
|
||||
"valueType": "chat_history",
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "content",
|
||||
"type": "target",
|
||||
"label": "需要提取的文本",
|
||||
"required": true,
|
||||
"valueType": "string",
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "extractKeys",
|
||||
"type": "custom",
|
||||
"label": "目标字段",
|
||||
"description": "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段",
|
||||
"value": [
|
||||
{
|
||||
"desc": "搜索词",
|
||||
"key": "searchKey",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "success",
|
||||
"label": "字段完全提取",
|
||||
"valueType": "boolean",
|
||||
"type": "source",
|
||||
"targets": []
|
||||
},
|
||||
{
|
||||
"key": "failed",
|
||||
"label": "提取字段缺失",
|
||||
"valueType": "boolean",
|
||||
"type": "source",
|
||||
"targets": [
|
||||
{
|
||||
"moduleId": "aijmbb",
|
||||
"key": "switch"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "fields",
|
||||
"label": "完整提取结果",
|
||||
"description": "一个 JSON 字符串,例如:{\"name:\":\"YY\",\"Time\":\"2023/7/2 18:00\"}",
|
||||
"valueType": "string",
|
||||
"type": "source",
|
||||
"targets": []
|
||||
},
|
||||
{
|
||||
"key": "searchKey",
|
||||
"label": "提取结果-搜索词",
|
||||
"description": "无法提取时不会返回",
|
||||
"valueType": "string",
|
||||
"type": "source",
|
||||
"targets": [
|
||||
{
|
||||
"moduleId": "5fk9ru",
|
||||
"key": "searchKey"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "5fk9ru",
|
||||
"name": "HTTP模块",
|
||||
"flowType": "httpRequest",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1481.5339897373183,
|
||||
"y": 1290.2958964143072
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "url",
|
||||
"value": "https://d8dns0.laf.dev/google_web_search",
|
||||
"type": "input",
|
||||
"label": "请求地址",
|
||||
"description": "请求目标地址",
|
||||
"placeholder": "https://api.fastgpt.run/getInventory",
|
||||
"required": true,
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "switch",
|
||||
"type": "target",
|
||||
"label": "触发器",
|
||||
"valueType": "any",
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"type": "target",
|
||||
"label": "搜索词",
|
||||
"edit": true,
|
||||
"key": "searchKey",
|
||||
"required": true,
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"label": "搜索词",
|
||||
"valueType": "string",
|
||||
"type": "source",
|
||||
"edit": true,
|
||||
"targets": [],
|
||||
"key": "searchKey"
|
||||
},
|
||||
{
|
||||
"label": "搜索结果",
|
||||
"valueType": "string",
|
||||
"type": "source",
|
||||
"edit": true,
|
||||
"targets": [
|
||||
{
|
||||
"moduleId": "aijmbb",
|
||||
"key": "systemPrompt"
|
||||
}
|
||||
],
|
||||
"key": "prompt"
|
||||
},
|
||||
{
|
||||
"key": "finish",
|
||||
"label": "请求结束",
|
||||
"valueType": "boolean",
|
||||
"type": "source",
|
||||
"targets": [
|
||||
{
|
||||
"moduleId": "aijmbb",
|
||||
"key": "switch"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"moduleId": "aijmbb",
|
||||
"name": "AI 对话",
|
||||
"flowType": "chatNode",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 2086.6387991825745,
|
||||
"y": 1090.812798225035
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "model",
|
||||
"type": "custom",
|
||||
"label": "对话模型",
|
||||
"value": "gpt-3.5-turbo-16k",
|
||||
"list": [],
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "temperature",
|
||||
"type": "slider",
|
||||
"label": "温度",
|
||||
"value": 0,
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"step": 1,
|
||||
"markList": [
|
||||
{
|
||||
"label": "严谨",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"label": "发散",
|
||||
"value": 10
|
||||
}
|
||||
],
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "maxToken",
|
||||
"type": "custom",
|
||||
"label": "回复上限",
|
||||
"value": 8000,
|
||||
"min": 100,
|
||||
"max": 4000,
|
||||
"step": 50,
|
||||
"markList": [
|
||||
{
|
||||
"label": "100",
|
||||
"value": 100
|
||||
},
|
||||
{
|
||||
"label": "4000",
|
||||
"value": 4000
|
||||
}
|
||||
],
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "systemPrompt",
|
||||
"type": "textarea",
|
||||
"label": "系统提示词",
|
||||
"valueType": "string",
|
||||
"description": "模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}",
|
||||
"placeholder": "模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。可使用变量,例如 {{language}}",
|
||||
"value": "",
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "limitPrompt",
|
||||
"type": "textarea",
|
||||
"valueType": "string",
|
||||
"label": "限定词",
|
||||
"description": "限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 \"Laf\" 无关内容,直接回复: \"我不知道\"。\n2. 你仅回答关于 \"xxx\" 的问题,其他问题回复: \"xxxx\"",
|
||||
"placeholder": "限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。可使用变量,例如 {{language}}。引导例子:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 \"Laf\" 无关内容,直接回复: \"我不知道\"。\n2. 你仅回答关于 \"xxx\" 的问题,其他问题回复: \"xxxx\"",
|
||||
"value": "上文是谷歌搜索的结果,你可以提供实时信息,根据搜索结果回答问题。当前时间是{{cTime}}。",
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "switch",
|
||||
"type": "target",
|
||||
"label": "触发器",
|
||||
"valueType": "any",
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "quoteQA",
|
||||
"type": "target",
|
||||
"label": "引用内容",
|
||||
"valueType": "kb_quote",
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"type": "target",
|
||||
"label": "聊天记录",
|
||||
"valueType": "chat_history",
|
||||
"connected": true
|
||||
},
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"type": "target",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"valueType": "string",
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "answerText",
|
||||
"label": "模型回复",
|
||||
"description": "直接响应,无需配置",
|
||||
"type": "hidden",
|
||||
"targets": []
|
||||
},
|
||||
{
|
||||
"key": "finish",
|
||||
"label": "回复结束",
|
||||
"description": "AI 回复完成后触发",
|
||||
"valueType": "boolean",
|
||||
"type": "source",
|
||||
"targets": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 流程说明
|
||||
|
||||
1. 提取模块将用户的问题提取成搜索关键词。
|
||||
2. 将搜索关键词传入 HTTP 模块。
|
||||
3. HTTP 模块调用谷歌搜索接口,返回搜索内容。
|
||||
4. 将搜索内容传入【AI 对话】的提示词,引导模型进行回答。
|
||||
87
docSite/content/docs/workflow/intro.md
Normal file
87
docSite/content/docs/workflow/intro.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: "高级编排介绍"
|
||||
description: "快速了解 FastGPT 高级编排"
|
||||
icon: "circle"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 410
|
||||
---
|
||||
|
||||
FastGPT 从 V4 版本开始采用新的交互方式来构建 AI 应用。使用了 Flow 节点编排的方式来实现复杂工作流,提高可玩性和扩展性。但同时也提高了上手的门槛,有一定开发背景的用户使用起来会比较容易。
|
||||
|
||||

|
||||
|
||||
## 什么是模块?
|
||||
|
||||
在程序中,模块可以理解为一个个 Function 或者接口。可以理解为它就是一个**步骤**。将多个模块一个个拼接起来,即可一步步的去实现最终的 AI 输出。
|
||||
|
||||
如下图,这是一个最简单的 AI 对话。它由用户输入的问题、聊天记录以及 AI 对话模块组成。
|
||||
|
||||

|
||||
|
||||
执行流程如下:
|
||||
|
||||
1. 用户输入问题后,会向服务器发送一个请求,并携带问题。从而得到【用户问题】模块的输出。
|
||||
2. 根据设置的【最长记录数】来获取数据库中的记录数,从而得到【聊天记录】模块的输出。
|
||||
经过上面两个流程,就得到了左侧两个蓝色点的结果。结果会被注入到右侧的【AI】对话模块。
|
||||
3. 【AI 对话】模块根据传入的聊天记录和用户问题,调用对话接口,从而实现回答。(这里的对话结果输出隐藏了起来,默认只要触发了对话模块,就会往客户端输出内容)
|
||||
|
||||
### 模块分类
|
||||
|
||||
从功能上,模块可以分为 3 类:
|
||||
|
||||
1. **只读模块**:全局变量、用户引导。
|
||||
2. **系统模块**:聊天记录(无输入,直接从数据库取)、用户问题(流程入口)。
|
||||
3. **功能模块**:知识库搜索、AI 对话等剩余模块。(这些模块都有输入和输出,可以自由组合)。
|
||||
|
||||
### 模块的组成
|
||||
|
||||
每个模块会包含 3 个核心部分:固定参数、外部输入(左边有个圆圈)和输出(右边有个圆圈)。
|
||||
|
||||
+ 对于只读模块,只需要根据提示填写即可,不参与流程运行。
|
||||
+ 对于系统模块,通常只有固定参数和输出,主要需要关注输出到哪个位置。
|
||||
+ 对于功能模块,通常这 3 部分都是重要的,以下图的 AI 对话为例:
|
||||
|
||||

|
||||
|
||||
- 对话模型、温度、回复上限、系统提示词和限定词为固定参数,同时系统提示词和限定词也可以作为外部输入,意味着如果你有输入流向了系统提示词,那么原本填写的内容就会被**覆盖**。
|
||||
- 触发器、引用内容、聊天记录和用户问题则为外部输入,需要从其他模块的输出流入。
|
||||
- 回复结束则为该模块的输出。
|
||||
|
||||
### 模块什么时候被执行?
|
||||
|
||||
模块执行的原则:
|
||||
|
||||
1. 仅关心**已连接的**外部输入,即左边的圆圈被连接了。
|
||||
2. 当连接内容都有值时触发。
|
||||
|
||||
#### 示例 1:
|
||||
|
||||
聊天记录模块会自动执行,因此聊天记录输入会自动赋值。当用户发送问题时,【用户问题】模块会输出值,此时【AI 对话】模块的用户问题输入也会被赋值。两个连接的输入都被赋值后,会执行 【AI 对话】模块。
|
||||
|
||||

|
||||
|
||||
#### 例子 2:
|
||||
|
||||
下图是一个知识库搜索例子。
|
||||
|
||||
1. 历史记录会流入【AI 对话】模块。
|
||||
2. 用户的问题会流入【知识库搜索】和【AI 对话】模块,由于【AI 对话】模块的触发器和引用内容还是空,此时不会执行。
|
||||
3. 【知识库搜索】模块仅一个外部输入,并且被赋值,开始执行。
|
||||
4. 【知识库搜索】结果为空时,“搜索结果不为空”的值为空,不会输出,因此【AI 对话】模块会因为触发器没有赋值而无法执行。而“搜索结果为空”会有输出,流向指定回复的触发器,因此【指定回复】模块进行输出。
|
||||
5. 【知识库搜索】结果不为空时,“搜索结果不为空”和“引用内容”都有输出,会流向【AI 对话】,此时【AI 对话】的 4 个外部输入都被赋值,开始执行。
|
||||
|
||||

|
||||
|
||||
## 如何连接模块
|
||||
|
||||
1. 为了方便识别不同输入输出的类型,FastGPT 给每个模块的输入输出连接点赋予不同的颜色,你可以把相同颜色的连接点连接起来。其中,灰色代表任意类型,可以随意连接。
|
||||
2. 位于左侧的连接点为输入,右侧的为输出,连接只能将一个输入和输出连接起来,不能连接“输入和输入”或者“输出和输出”。
|
||||
3. 可以点击连接线中间的 x 来删除连接线。
|
||||
4. 可以左键点击选中连接线
|
||||
|
||||
## 如何阅读?
|
||||
|
||||
1. 建议从左往右阅读。
|
||||
2. 从 **用户问题** 模块开始。用户问题模块,代表的是用户发送了一段文本,触发任务开始。
|
||||
3. 关注【AI 对话】和【指定回复】模块,这两个模块是输出答案的地方。
|
||||
8
docSite/content/docs/workflow/modules/_index.md
Normal file
8
docSite/content/docs/workflow/modules/_index.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
weight: 420
|
||||
title: "模块介绍"
|
||||
description: "介绍 FastGPT 的常用模块"
|
||||
icon: "apps"
|
||||
draft: false
|
||||
images: []
|
||||
---
|
||||
71
docSite/content/docs/workflow/modules/ai_chat.md
Normal file
71
docSite/content/docs/workflow/modules/ai_chat.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: "AI 对话"
|
||||
description: "FastGPT AI 对话模块介绍"
|
||||
icon: "chat"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 423
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 可重复添加(复杂编排时防止线太乱,可以更美观)
|
||||
- 有外部输入
|
||||
- 有静态配置
|
||||
- 触发执行
|
||||
- 核心模块
|
||||
|
||||

|
||||
|
||||
## 参数说明
|
||||
|
||||
### 对话模型
|
||||
|
||||
可以通过 [config.json](/docs/installation/reference/models/) 配置可选的对话模型,通过 [one-api](/docs/installation/one-api/) 来实现多模型接入。
|
||||
|
||||
### 温度 & 回复上限
|
||||
|
||||
+ **温度**:越低回答越严谨,少废话(实测下来,感觉差别不大)
|
||||
+ **回复上限**:最大回复 token 数量(只有 OpenAI 模型有效)。注意,是回复!不是总 tokens。
|
||||
|
||||
### 系统提示词(可被外部输入覆盖)
|
||||
|
||||
被放置在上下文数组的最前面,role 为 system,用于引导模型。具体用法参考各搜索引擎的教程~
|
||||
|
||||
### 限定词(可被外部输入覆盖)
|
||||
|
||||
与系统提示词类似,role 也是 system 类型,只不过位置会被放置在问题前,拥有更强的引导作用。
|
||||
|
||||
### 引用内容
|
||||
|
||||
接收一个外部输入的数组,主要是由【知识库搜索】模块生成,也可以由 HTTP 模块从外部引入。数据结构示例如下:
|
||||
|
||||
```ts
|
||||
type DataType = {
|
||||
kb_id?: string;
|
||||
id?: string;
|
||||
q: string;
|
||||
a: string;
|
||||
source?: string;
|
||||
};
|
||||
// 如果是外部引入的内容,尽量不要携带 kb_id 和 id
|
||||
const quoteList: DataType[] = [
|
||||
{ kb_id: '11', id: '222', q: '你还', a: '哈哈', source: '' },
|
||||
{ kb_id: '11', id: '333', q: '你还', a: '哈哈', source: '' },
|
||||
{ kb_id: '11', id: '444', q: '你还', a: '哈哈', source: '' }
|
||||
];
|
||||
```
|
||||
|
||||
## 完整上下文组成
|
||||
|
||||
最终发送给 LLM 大模型的数据是一个数组,内容和顺序如下:
|
||||
|
||||
```bash
|
||||
[
|
||||
系统提示词
|
||||
引用内容
|
||||
聊天记录
|
||||
限定词
|
||||
问题
|
||||
]
|
||||
```
|
||||
60
docSite/content/docs/workflow/modules/content_extract.md
Normal file
60
docSite/content/docs/workflow/modules/content_extract.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: "内容提取"
|
||||
description: "FastGPT 内容提取模块介绍"
|
||||
icon: "content_paste_go"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 424
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 可重复添加
|
||||
- 有外部输入
|
||||
- 需要手动配置
|
||||
- 触发执行
|
||||
- function_call 模块
|
||||
- 核心模块
|
||||
|
||||

|
||||
|
||||
## 功能
|
||||
|
||||
从文本中提取结构化数据,通常是配合 HTTP 模块实现扩展。也可以做一些直接提取操作,例如:翻译。
|
||||
|
||||
## 参数说明
|
||||
|
||||
### 提取要求描述
|
||||
|
||||
顾名思义,给模型设置一个目标,需要提取哪些内容。
|
||||
|
||||
**示例 1**
|
||||
|
||||
> 你是实验室预约助手,从对话中提取出姓名,预约时间,实验室号。当前时间 {{cTime}}
|
||||
|
||||
**示例 2**
|
||||
|
||||
> 你是谷歌搜索助手,从对话中提取出搜索关键词
|
||||
|
||||
**示例 3**
|
||||
|
||||
> 将我的问题直接翻译成英文,不要回答问题
|
||||
|
||||
### 历史记录
|
||||
|
||||
通常需要一些历史记录,才能更完整的提取用户问题。例如上图中需要提供姓名、时间和实验室名,用户可能一开始只给了时间和实验室名,没有提供自己的姓名。再经过一轮缺失提示后,用户输入了姓名,此时需要结合上一次的记录才能完整的提取出 3 个内容。
|
||||
|
||||
### 目标字段
|
||||
|
||||
目标字段与提取的结果相对应,从上图可以看到,每增加一个字段,输出会增加一个对应的出口。
|
||||
|
||||
+ **key**: 字段的唯一标识,不可重复!
|
||||
+ **字段描述**:描述该字段是关于什么的,例如:姓名、时间、搜索词等等。
|
||||
+ **必须**:是否强制模型提取该字段,可能提取出来是空字符串。
|
||||
|
||||
## 输出介绍
|
||||
|
||||
- **字段完全提取**:说明用户的问题中包含需要提取的所有内容。
|
||||
- **提取字段缺失**:与 “字段完全提取” 对立,有缺失提取的字段时触发。
|
||||
- **完整提取结果**: 一个 JSON 字符串,包含所有字段的提取结果。
|
||||
- **目标字段提取结果**:类型均为字符串。
|
||||
18
docSite/content/docs/workflow/modules/guide.md
Normal file
18
docSite/content/docs/workflow/modules/guide.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: "用户引导"
|
||||
description: "FastGPT 用户引导模块介绍"
|
||||
icon: "psychology"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 426
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 仅可添加 1 个
|
||||
- 无外部输入
|
||||
- 不参与实际调度
|
||||
|
||||
如图,可以在用户提问前给予一定引导。并可以设置引导问题。
|
||||
|
||||

|
||||
19
docSite/content/docs/workflow/modules/history.md
Normal file
19
docSite/content/docs/workflow/modules/history.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: "历史记录"
|
||||
description: "FastGPT 历史记录模块介绍"
|
||||
icon: "history"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 427
|
||||
---
|
||||
|
||||
# 特点
|
||||
|
||||
- 可重复添加(防止复杂编排时线太乱,重复添加可以更美观)
|
||||
- 无外部输入
|
||||
- 流程入口
|
||||
- 自动执行
|
||||
|
||||
每次对话时,会从数据库取最多 n 条聊天记录作为上下文。注意,不是指本轮对话最多 n 条上下文,本轮对话还包括:提示词、限定词、引用内容和问题。
|
||||
|
||||

|
||||
104
docSite/content/docs/workflow/modules/http.md
Normal file
104
docSite/content/docs/workflow/modules/http.md
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
title: "HTTP 模块"
|
||||
description: "FastGPT HTTP 模块介绍"
|
||||
icon: "http"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 428
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 可重复添加
|
||||
- 有外部输入
|
||||
- 手动配置
|
||||
- 触发执行
|
||||
- 核中核模块
|
||||
|
||||

|
||||
|
||||
## 介绍
|
||||
|
||||
HTTP 模块会向对应的地址发送一个 POST 请求(Body 中携带 JSON 类型的参数,具体的参数可自定义),并接收一个 JSON 响应值,字段也是自定义。如上图中,我们定义了一个入参:「提取的字段」(定义的 key 为 appointment,类型为 string)和一个出参:「提取结果」(定义的 key 为 response,类型为 string)。
|
||||
|
||||
那么,这个请求的命令为:
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://xxxx.laf.dev/appointment-lab' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"appointment":"{\"name\":\"小明\",\"time\":\"2023/08/16 15:00\",\"labname\":\"子良A323\"}"
|
||||
}'
|
||||
```
|
||||
|
||||
响应为:
|
||||
|
||||
```json
|
||||
{
|
||||
"response": "您已经有一个预约记录了,每人仅能同时预约一个实验室:\n 姓名:小明\n 时间: 2023/08/15 15:00\n 实验室: 子良A323\n "
|
||||
}
|
||||
```
|
||||
|
||||
{{% alert context="warning" %}}
|
||||
如果你不想额外部署服务,可以使用 [Laf](https://laf.dev/) 来快速开发上线接口,即写即发,无需部署。
|
||||
|
||||
下面是在 Laf 上编写的一个请求示例:
|
||||
{{% /alert %}}
|
||||
|
||||
```ts
|
||||
import cloud from '@lafjs/cloud';
|
||||
const db = cloud.database();
|
||||
|
||||
export default async function (ctx: FunctionContext) {
|
||||
const { appointment } = ctx.body;
|
||||
const { name, time, labname } = JSON.parse(appointment);
|
||||
|
||||
const missData = [];
|
||||
if (!name) missData.push('你的姓名');
|
||||
if (!time) missData.push('需要预约的时间');
|
||||
if (!labname) missData.push('实验室名称');
|
||||
|
||||
if (missData.length > 0) {
|
||||
return {
|
||||
response: `请提供: ${missData.join('、')}`
|
||||
};
|
||||
}
|
||||
|
||||
const { data: record } = await db
|
||||
.collection('LabAppointment')
|
||||
.where({
|
||||
name,
|
||||
status: 'unStart'
|
||||
})
|
||||
.getOne();
|
||||
|
||||
if (record) {
|
||||
return {
|
||||
response: `您已经有一个预约记录了,每人仅能同时预约一个实验室:
|
||||
姓名:${record.name}
|
||||
时间: ${record.time}
|
||||
实验室: ${record.labname}
|
||||
`
|
||||
};
|
||||
}
|
||||
|
||||
await db.collection('LabAppointment').add({
|
||||
name,
|
||||
time,
|
||||
labname,
|
||||
status: 'unStart'
|
||||
});
|
||||
|
||||
return {
|
||||
response: `预约成功。
|
||||
姓名:${name}
|
||||
时间: ${time}
|
||||
实验室: ${labname}
|
||||
`
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
基于 HTTP 模块可以无限扩展,比如操作数据库、执行联网搜索、发送邮箱等等。如果你有有趣的案例,欢迎提交 PR 到 [编排案例](/docs/category/examples)
|
||||
17
docSite/content/docs/workflow/modules/input.md
Normal file
17
docSite/content/docs/workflow/modules/input.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "用户问题"
|
||||
description: "FastGPT 用户问题模块介绍"
|
||||
icon: "input"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 430
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 可重复添加(防止复杂编排时线太乱,重复添加可以更美观)
|
||||
- 无外部输入
|
||||
- 流程入口
|
||||
- 自动执行
|
||||
|
||||

|
||||
78
docSite/content/docs/workflow/modules/question.md
Normal file
78
docSite/content/docs/workflow/modules/question.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: "问题分类"
|
||||
description: "FastGPT 问题分类模块介绍"
|
||||
icon: "quiz"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 425
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 可重复添加
|
||||
- 有外部输入
|
||||
- 需要手动配置
|
||||
- 触发执行
|
||||
- function_call 模块
|
||||
|
||||

|
||||
|
||||
## 功能
|
||||
|
||||
可以将用户的问题进行分类,分类后执行不同操作。在一些较模糊的场景中,分类效果不是很明显。
|
||||
|
||||
## 参数说明
|
||||
|
||||
### 系统提示词
|
||||
|
||||
被放置在对话最前面,可用于补充说明分类内容的定义。例如问题会被分为:
|
||||
|
||||
1. 打招呼
|
||||
2. Laf 常见问题
|
||||
3. 其他问题
|
||||
|
||||
由于 Laf 不是一个明确的东西,需要给它一个定义,此时提示词里可以填入 Laf 的定义:
|
||||
|
||||
```
|
||||
Laf 是云开发平台,可以快速的开发应用
|
||||
Laf 是一个开源的 BaaS 开发平台(Backend as a Service)
|
||||
Laf 是一个开箱即用的 serverless 开发平台
|
||||
Laf 是一个集「函数计算」、「数据库」、「对象存储」等于一身的一站式开发平台
|
||||
Laf 可以是开源版的腾讯云开发、开源版的 Google Firebase、开源版的 UniCloud
|
||||
```
|
||||
|
||||
### 聊天记录
|
||||
|
||||
适当增加一些聊天记录,可以联系上下文进行分类。
|
||||
|
||||
### 用户问题
|
||||
|
||||
用户输入的内容。
|
||||
|
||||
### 分类内容
|
||||
|
||||
依然以这 3 个分类为例,可以看到最终组成的 Function。其中返回值由系统随机生成,不需要关心。
|
||||
|
||||
1. 打招呼
|
||||
2. Laf 常见问题
|
||||
3. 其他问题
|
||||
|
||||
```js
|
||||
const agentFunction = {
|
||||
name: agentFunName,
|
||||
description: '判断用户问题的类型属于哪方面,返回对应的枚举字段',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
description: `打招呼,返回: abc;Laf 常见问题,返回:vvv;其他问题,返回:aaa`
|
||||
enum: ["abc","vvv","aaa"]
|
||||
}
|
||||
},
|
||||
required: ['type']
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
上面的 Function 必然会返回 `type = abc,vvv,aaa` 其中一个值,从而实现分类判断。
|
||||
32
docSite/content/docs/workflow/modules/reply.md
Normal file
32
docSite/content/docs/workflow/modules/reply.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: "指定回复"
|
||||
description: "FastGPT 指定回复模块介绍"
|
||||
icon: "reply"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 429
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 可重复添加(防止复杂编排时线太乱,重复添加可以更美观)
|
||||
- 可手动输入
|
||||
- 可外部输入
|
||||
- 会输出结果给客户端
|
||||
|
||||
制定回复模块通常用户特殊状态回复,当然你也可以像图 2 一样,实现一些比较骚的操作~ 触发逻辑非常简单:
|
||||
|
||||
1. 一种是写好回复内容,通过触发器触发。
|
||||
2. 一种是不写回复内容,直接由外部输入触发,并回复输入的内容。
|
||||
|
||||
{{< figure
|
||||
src="/imgs/specialreply.png"
|
||||
alt=""
|
||||
caption="图 1"
|
||||
>}}
|
||||
|
||||
{{< figure
|
||||
src="/imgs/specialreply2.png"
|
||||
alt=""
|
||||
caption="图 2"
|
||||
>}}
|
||||
24
docSite/content/docs/workflow/modules/trigger.md
Normal file
24
docSite/content/docs/workflow/modules/trigger.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: "触发器"
|
||||
description: "FastGPT 触发器模块介绍"
|
||||
icon: "work_history"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 421
|
||||
---
|
||||
|
||||
细心的同学可以发现,在每个功能模块里都会有一个叫【触发器】的外部输入,并且是 any 类型。
|
||||
|
||||
它的**核心作用**就是控制模块的执行时机,以下图两个知识库搜索中的【AI 对话】模块为例子:
|
||||
|
||||
| 图 1 | 图 2 |
|
||||
| ---------------------------- | ---------------------------- |
|
||||
|  |  |
|
||||
|
||||
【知识库搜索】模块中,由于**引用内容**始终会有输出,会导致【AI 对话】模块的**引用内容**输入无论有没有搜到内容都会被赋值。如果此时不连接触发器(图 2),在搜索结束后必定会执行【AI 对话】模块。
|
||||
|
||||
有时候,你可能希望空搜索时候进行额外处理,例如:回复固定内容、调用其他提示词的 GPT、发送一个 HTTP 请求…… 此时就需要用到触发器,需要将 **搜索结果不为空** 和 **触发器** 连接起来。
|
||||
|
||||
当搜索结果为空时,【知识库搜索】模块不会输出 **搜索结果不为空** 的结果,因此 【AI 对话】 模块的触发器始终为空,便不会执行。
|
||||
|
||||
总之,记住模块执行的逻辑就可以灵活的使用触发器:**外部输入字段(有连接的才有效)全部被赋值时才会被执行**。
|
||||
35
docSite/content/docs/workflow/modules/variable.md
Normal file
35
docSite/content/docs/workflow/modules/variable.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "全局变量"
|
||||
description: "FastGPT 全局变量模块介绍"
|
||||
icon: "variables"
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 422
|
||||
---
|
||||
|
||||
## 特点
|
||||
|
||||
- 仅可添加 1 个
|
||||
- 需要手动配置
|
||||
- 对其他模块有影响
|
||||
- 可作为用户引导
|
||||
|
||||
## 说明
|
||||
|
||||
可以在对话前设置一些问题,让用户输入或选择,并将用户输入/选择的结果注入到其他模块中。目前仅会注入到 string 类型的数据里(对应蓝色圆圈的输入)。
|
||||
|
||||
如下图,定义了两个变量:目标语言和下拉框测试(忽略)
|
||||
|
||||
用户在对话前会被要求先填写目标语言,配合用户引导,我们就构建了一个简单的翻译机器人。**目标语言**的 `key:language` 被写入到【AI 对话】模块的限定词里。
|
||||
|
||||

|
||||
|
||||
通过完整对话记录我们可以看到,实际的限定词从:“将我的问题直接翻译成{{language}}” 变成了 “将我的问题直接翻译成英语”,因为 {{language}} 被变量替换了。
|
||||
|
||||

|
||||
|
||||
## 系统级变量
|
||||
|
||||
除了用户自定义设置的变量外,还会有一些系统变量:
|
||||
|
||||
+ **cTime**: 当前时间。例如:2023/3/3 20:22
|
||||
Reference in New Issue
Block a user