FastGPT-05-最佳实践与实战案例
本文档提供 FastGPT 的框架使用示例、实战经验和最佳实践,帮助开发者快速上手并掌握高级技巧。
1. 快速开始:从零到第一个应用
1.1 最小可运行示例
目标:创建一个最简单的 AI 对话应用。
步骤:
// 1. 初始化项目(假设已有 FastGPT 环境)
import { MongoApp } from '@fastgpt/service/core/app/schema';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
// 2. 创建应用
const app = await MongoApp.create({
teamId: 'your-team-id',
tmbId: 'your-member-id',
name: '我的第一个AI助手',
type: 'simple',
nodes: [
{
nodeId: 'start',
flowNodeType: FlowNodeTypeEnum.workflowStart,
name: '开始',
position: { x: 300, y: 300 },
inputs: [
{
key: 'userChatInput',
renderTypeList: ['reference'],
valueType: 'string',
label: '用户问题'
}
],
outputs: [
{
id: 'userChatInput',
key: 'userChatInput',
label: '用户问题',
valueType: 'string'
}
]
},
{
nodeId: 'ai',
flowNodeType: FlowNodeTypeEnum.chatNode,
name: 'AI对话',
position: { x: 800, y: 300 },
inputs: [
{
key: 'model',
value: 'gpt-3.5-turbo',
valueType: 'string'
},
{
key: 'systemPrompt',
value: '你是一个友好的AI助手,善于回答各种问题。',
valueType: 'string'
},
{
key: 'userChatInput',
value: ['start', 'userChatInput'], // 引用上游节点
valueType: 'string'
}
]
}
],
edges: [
{
source: 'start',
target: 'ai',
sourceHandle: 'start-source-right',
targetHandle: 'ai-target-left'
}
]
});
console.log('应用创建成功,ID:', app._id);
// 3. 测试对话
import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch';
const result = await dispatchWorkFlow({
runningUserInfo: { teamId: 'your-team-id', tmbId: 'your-member-id' },
runningAppInfo: { id: app._id, name: app.name },
runtimeNodes: app.nodes,
runtimeEdges: app.edges,
variables: {
cTime: new Date().toISOString()
},
histories: [],
chatConfig: {},
mode: 'test',
usageSource: 'test'
});
console.log('AI回复:', result.assistantResponses);
关键点:
- 工作流至少包含
workflowStart和一个业务节点 - 节点通过
edges连接 - 节点输入可以引用上游节点输出(使用数组格式
[nodeId, outputKey])
2. 知识库 RAG 实战
2.1 创建知识库并上传文档
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
import { uploadFile } from '@fastgpt/service/common/file/gridfs/controller';
import { fileParseQueue } from '@fastgpt/service/worker/controller';
// 1. 创建知识库
const dataset = await MongoDataset.create({
teamId: 'team-id',
tmbId: 'member-id',
name: '产品文档知识库',
vectorModel: 'text-embedding-ada-002',
chunkSettings: {
chunkSize: 512,
chunkOverlap: 50,
chunkSplitMode: 'paragraph'
}
});
// 2. 上传文件
const file = {
originalname: 'product-manual.pdf',
buffer: fs.readFileSync('/path/to/product-manual.pdf')
};
const { fileId } = await uploadFile({
teamId: dataset.teamId,
file
});
// 3. 创建Collection
const collection = await MongoDatasetCollection.create({
teamId: dataset.teamId,
datasetId: dataset._id,
name: file.originalname,
type: 'file',
fileId,
trainingType: 'auto'
});
// 4. 发送解析任务
await fileParseQueue.add('parse', {
collectionId: String(collection._id),
datasetId: String(dataset._id),
teamId: dataset.teamId,
fileId,
filePath: file.originalname
});
console.log('文件解析任务已提交,Collection ID:', collection._id);
2.2 配置知识库检索应用
// 创建带知识库的应用
const app = await MongoApp.create({
teamId: 'team-id',
tmbId: 'member-id',
name: '产品客服助手',
type: 'simple',
nodes: [
{
nodeId: 'start',
flowNodeType: FlowNodeTypeEnum.workflowStart,
// ... 省略inputs/outputs
},
{
nodeId: 'dataset',
flowNodeType: FlowNodeTypeEnum.datasetSearchNode,
name: '知识库检索',
position: { x: 500, y: 300 },
inputs: [
{
key: 'datasetIds',
value: [dataset._id], // 知识库ID
valueType: 'selectDataset'
},
{
key: 'query',
value: ['start', 'userChatInput'], // 引用用户输入
valueType: 'string'
},
{
key: 'similarity',
value: 0.5, // 相似度阈值
valueType: 'number'
},
{
key: 'limit',
value: 5000, // 最大Token
valueType: 'number'
},
{
key: 'searchMode',
value: 'mixedRecall', // 混合检索
valueType: 'string'
},
{
key: 'usingReRank',
value: true, // 启用重排
valueType: 'boolean'
}
],
outputs: [
{
id: 'quoteQA',
key: 'quoteQA',
label: '引用内容',
valueType: 'datasetQuote'
}
]
},
{
nodeId: 'ai',
flowNodeType: FlowNodeTypeEnum.chatNode,
name: 'AI回答',
position: { x: 1000, y: 300 },
inputs: [
{
key: 'model',
value: 'gpt-4',
valueType: 'string'
},
{
key: 'systemPrompt',
value: `你是产品客服助手。请根据知识库内容回答用户问题。
规则:
1. 优先使用知识库内容回答
2. 如果知识库没有相关信息,告知用户
3. 保持专业、友好的语气`,
valueType: 'string'
},
{
key: 'userChatInput',
value: ['start', 'userChatInput'],
valueType: 'string'
},
{
key: 'quoteQA',
value: ['dataset', 'quoteQA'], // 引用知识库结果
valueType: 'datasetQuote'
}
]
}
],
edges: [
{ source: 'start', target: 'dataset' },
{ source: 'dataset', target: 'ai' }
]
});
2.3 检索效果优化技巧
问题:检索结果不准确
解决方案:
- 调整分块策略:
// 针对不同类型的文档使用不同的分块模式
const chunkSettings = {
// 长文档(技术文档、手册)
longDoc: {
chunkSize: 800,
chunkOverlap: 100,
chunkSplitMode: 'paragraph'
},
// 短文档(FAQ)
shortDoc: {
chunkSize: 300,
chunkOverlap: 30,
chunkSplitMode: 'qa'
},
// 表格数据
table: {
chunkSize: 1000,
chunkOverlap: 0,
chunkSplitMode: 'chunk'
}
};
- 启用查询扩展:
// 在知识库检索前添加查询扩展节点
{
nodeId: 'queryExtension',
flowNodeType: FlowNodeTypeEnum.queryExtension,
name: '查询扩展',
inputs: [
{
key: 'query',
value: ['start', 'userChatInput'],
valueType: 'string'
},
{
key: 'model',
value: 'gpt-3.5-turbo',
valueType: 'string'
}
],
outputs: [
{
key: 'queries',
label: '扩展查询',
valueType: 'arrayString'
}
]
}
// 将扩展后的查询传递给知识库节点
{
key: 'query',
value: ['queryExtension', 'queries'],
valueType: 'arrayString'
}
- 使用混合检索 + 重排:
// 配置最佳检索参数
{
searchMode: 'mixedRecall', // 混合检索
embeddingWeight: 0.7, // 向量检索权重70%
usingReRank: true, // 启用重排
rerankWeight: 0.8, // 重排权重80%
similarity: 0.3 // 相似度阈值(放宽)
}
3. Agent 工具调用实战
3.1 创建 HTTP 工具
场景:调用天气 API 查询天气。
import { MongoHttpTool } from '@fastgpt/service/core/app/httpTools/schema';
// 1. 创建HTTP工具
const weatherTool = await MongoHttpTool.create({
teamId: 'team-id',
appId: app._id,
name: '天气查询',
description: '查询指定城市的实时天气信息',
url: 'https://api.weatherapi.com/v1/current.json',
method: 'GET',
headers: [],
params: [
{
key: 'key',
type: 'string',
value: 'your-weather-api-key',
required: true
},
{
key: 'q',
type: 'string',
description: '城市名称(中文或英文)',
required: true
}
],
responseMapping: {
temperature: '$.current.temp_c',
condition: '$.current.condition.text',
humidity: '$.current.humidity'
}
});
// 2. 配置Agent工作流
const agentApp = await MongoApp.create({
teamId: 'team-id',
tmbId: 'member-id',
name: '天气助手Agent',
type: 'simple',
nodes: [
{
nodeId: 'start',
flowNodeType: FlowNodeTypeEnum.workflowStart,
// ... 省略
},
{
nodeId: 'agent',
flowNodeType: FlowNodeTypeEnum.agent,
name: 'Agent',
position: { x: 500, y: 300 },
inputs: [
{
key: 'model',
value: 'gpt-4', // Agent需要支持function calling的模型
valueType: 'string'
},
{
key: 'systemPrompt',
value: '你是一个智能助手,可以查询天气信息。当用户询问天气时,使用天气查询工具获取实时数据。',
valueType: 'string'
},
{
key: 'userChatInput',
value: ['start', 'userChatInput'],
valueType: 'string'
},
{
key: 'maxRunTimes',
value: 5, // 最多5轮工具调用
valueType: 'number'
}
]
},
{
nodeId: 'weatherTool',
flowNodeType: FlowNodeTypeEnum.tool,
name: '天气工具',
position: { x: 800, y: 500 },
toolConfig: {
httpTool: {
toolId: weatherTool._id
}
}
}
],
edges: [
{ source: 'start', target: 'agent' },
{
source: 'agent',
target: 'weatherTool',
sourceHandle: 'agent-source-tool'
},
{
source: 'weatherTool',
target: 'agent',
targetHandle: 'agent-target-tool'
}
]
});
测试:
curl -X POST http://localhost:3000/api/v2/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"appId": "agent-app-id",
"chatId": "test-chat",
"stream": false,
"messages": [
{
"role": "user",
"content": "北京今天天气怎么样?"
}
]
}'
预期响应:
{
"choices": [
{
"message": {
"role": "assistant",
"content": "北京今天的天气是晴,温度15°C,湿度60%。"
}
}
]
}
3.2 多工具协作
场景:查询天气 + 推荐穿衣。
// 添加第二个工具:穿衣建议
const clothingTool = await MongoHttpTool.create({
teamId: 'team-id',
appId: app._id,
name: '穿衣建议',
description: '根据温度推荐合适的穿衣建议',
url: 'https://api.example.com/clothing-advice',
method: 'POST',
params: [
{
key: 'temperature',
type: 'number',
description: '温度(摄氏度)',
required: true
},
{
key: 'weather',
type: 'string',
description: '天气状况(晴、雨、雪等)',
required: true
}
]
});
// 在Agent节点中添加第二个工具
{
nodeId: 'clothingTool',
flowNodeType: FlowNodeTypeEnum.tool,
name: '穿衣工具',
toolConfig: {
httpTool: {
toolId: clothingTool._id
}
}
}
// Agent会自动协调两个工具的调用顺序
// 1. 先调用天气查询工具获取温度和天气
// 2. 再调用穿衣建议工具
// 3. 综合两个结果生成最终回答
4. 高级工作流模式
4.1 条件分支(if-else)
场景:根据用户输入类型分发到不同处理流程。
// 配置工作流
const app = await MongoApp.create({
nodes: [
{
nodeId: 'start',
flowNodeType: FlowNodeTypeEnum.workflowStart,
// ...
},
{
nodeId: 'classify',
flowNodeType: FlowNodeTypeEnum.classifyQuestion,
name: '问题分类',
inputs: [
{
key: 'model',
value: 'gpt-3.5-turbo',
valueType: 'string'
},
{
key: 'systemPrompt',
value: '将用户问题分类为:技术问题、售前咨询、售后服务、其他',
valueType: 'string'
},
{
key: 'userChatInput',
value: ['start', 'userChatInput'],
valueType: 'string'
},
{
key: 'agents',
value: [
{ key: 'tech', value: '技术问题' },
{ key: 'sales', value: '售前咨询' },
{ key: 'support', value: '售后服务' },
{ key: 'other', value: '其他' }
],
valueType: 'array'
}
],
outputs: [
{
key: 'cqResult',
label: '分类结果',
valueType: 'string'
}
]
},
{
nodeId: 'techHandler',
flowNodeType: FlowNodeTypeEnum.chatNode,
name: '技术支持AI',
inputs: [
{
key: 'systemPrompt',
value: '你是技术支持专家,擅长解决技术问题...',
valueType: 'string'
}
// ...
]
},
{
nodeId: 'salesHandler',
flowNodeType: FlowNodeTypeEnum.chatNode,
name: '售前咨询AI',
inputs: [
{
key: 'systemPrompt',
value: '你是销售顾问,擅长产品介绍和报价...',
valueType: 'string'
}
// ...
]
}
// ... 其他处理节点
],
edges: [
{ source: 'start', target: 'classify' },
// 条件边
{
source: 'classify',
target: 'techHandler',
sourceHandle: 'classify-source-tech' // 分类结果为'tech'时触发
},
{
source: 'classify',
target: 'salesHandler',
sourceHandle: 'classify-source-sales'
}
// ...
]
});
4.2 循环处理
场景:批量处理列表数据。
// 批量翻译文本列表
const app = await MongoApp.create({
nodes: [
{
nodeId: 'start',
flowNodeType: FlowNodeTypeEnum.workflowStart,
inputs: [
{
key: 'textList',
valueType: 'arrayString',
label: '文本列表'
}
]
},
{
nodeId: 'loop',
flowNodeType: FlowNodeTypeEnum.loop,
name: '循环',
inputs: [
{
key: 'loopInputArray',
value: ['start', 'textList'],
valueType: 'arrayString'
}
]
},
{
nodeId: 'loopStart',
flowNodeType: FlowNodeTypeEnum.loopStart,
name: '循环开始',
outputs: [
{
key: 'loopStartInput',
label: '当前文本',
valueType: 'string'
},
{
key: 'index',
label: '索引',
valueType: 'number'
}
]
},
{
nodeId: 'translate',
flowNodeType: FlowNodeTypeEnum.chatNode,
name: '翻译',
inputs: [
{
key: 'model',
value: 'gpt-3.5-turbo',
valueType: 'string'
},
{
key: 'systemPrompt',
value: '将以下文本翻译成英文',
valueType: 'string'
},
{
key: 'userChatInput',
value: ['loopStart', 'loopStartInput'],
valueType: 'string'
}
],
outputs: [
{
key: 'answerText',
label: '翻译结果',
valueType: 'string'
}
]
},
{
nodeId: 'loopEnd',
flowNodeType: FlowNodeTypeEnum.loopEnd,
name: '循环结束',
inputs: [
{
key: 'loopOutputValue',
value: ['translate', 'answerText'],
valueType: 'string'
}
]
}
],
edges: [
{ source: 'start', target: 'loop' },
{ source: 'loop', target: 'loopStart' },
{ source: 'loopStart', target: 'translate' },
{ source: 'translate', target: 'loopEnd' },
{ source: 'loopEnd', target: 'loop' } // 循环边
]
});
5. 性能优化实战
5.1 知识库检索优化
问题:知识库检索慢(>3s)
优化方案:
- 向量数据库索引优化:
-- PostgreSQL PG Vector
CREATE INDEX ON dataset_data_vector USING ivfflat (vector vector_cosine_ops)
WITH (lists = 100);
-- 定期 VACUUM ANALYZE
VACUUM ANALYZE dataset_data_vector;
- 分批检索:
// 对于多个知识库,分批并行检索
const datasetIds = ['id1', 'id2', 'id3', 'id4'];
const batchSize = 2;
const allResults = [];
for (let i = 0; i < datasetIds.length; i += batchSize) {
const batch = datasetIds.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(id => searchDatasetData({ datasetIds: [id], ...params }))
);
allResults.push(...batchResults);
}
- 缓存热点查询:
import { getRedisCache, setRedisCache } from '@fastgpt/service/common/redis/cache';
const cacheKey = `dataset:search:${hashQuery(query)}`;
let results = await getRedisCache(cacheKey);
if (!results) {
results = await searchDatasetData(params);
await setRedisCache(cacheKey, results, 300); // 缓存5分钟
}
5.2 LLM 调用优化
问题:LLM 响应慢,成本高
优化方案:
- 使用更快的模型:
// 非关键场景使用 gpt-3.5-turbo
// 关键场景使用 gpt-4
const model = isComplexTask ? 'gpt-4' : 'gpt-3.5-turbo';
- 缩短 Prompt:
// 优化前:
const systemPrompt = `
你是一个专业的客服助手...(1000字)
规则:
1. xxx
2. xxx
...(20条规则)
`;
// 优化后:
const systemPrompt = `
专业客服。规则:礼貌、准确、简洁。
知识库优先,不懂就说不懂。
`;
- 流式响应:
// 总是启用 stream,提升用户体验
const result = await createLLMResponse({
body: {
model: 'gpt-4',
stream: true, // 启用流式
messages
},
onStreaming({ text }) {
// 实时推送到前端
res.write(`data: ${JSON.stringify({ content: text })}\n\n`);
}
});
5.3 数据库查询优化
问题:对话历史加载慢
优化方案:
- 创建索引:
// MongoDB 索引
db.chatitems.createIndex({ chatId: 1, _id: -1 });
db.chatitems.createIndex({ appId: 1, teamId: 1, time: -1 });
- 分页加载:
// 只加载最近N条消息
const histories = await MongoChatItem.find({ chatId })
.sort({ _id: -1 })
.limit(30) // 最多30条
.lean();
- 使用投影减少数据传输:
// 只查询必要字段
const histories = await MongoChatItem.find(
{ chatId },
'obj value time' // 只查询这三个字段
).lean();
6. 错误处理与调试
6.1 常见错误及解决方案
错误 1:Token 超限
// 错误信息
"This model's maximum context length is 4096 tokens"
// 解决方案:限制历史消息长度
const limitedHistories = histories.slice(-10); // 最多保留10轮
// 或者:使用更大上下文的模型
const model = 'gpt-4-32k'; // 32k上下文
错误 2:知识库检索无结果
// 调试:检查向量是否正确生成
const { vectors } = await getVectorsByText({
model: embeddingModel,
input: ['测试文本'],
type: 'query'
});
console.log('向量维度:', vectors[0].length); // 应该是1536
console.log('向量前5个值:', vectors[0].slice(0, 5));
// 调试:检查相似度阈值
// 降低相似度阈值
similarity: 0.3 // 从0.5降到0.3
错误 3:工作流节点执行失败
// 开启调试模式
const result = await dispatchWorkFlow({
...params,
mode: 'debug', // 开启调试
responseDetail: true // 返回详细信息
});
// 查看每个节点的执行结果
result.flowResponses.forEach(res => {
console.log('节点:', res.moduleName);
console.log('状态:', res.status);
console.log('错误:', res.error);
console.log('耗时:', res.runningTime, 'ms');
});
6.2 日志与监控
结构化日志:
import { addLog } from '@fastgpt/service/common/system/log';
// 记录关键操作
addLog.info('Chat completed', {
appId,
chatId,
teamId,
duration: Date.now() - startTime,
tokenUsed: result.usage.totalTokens,
nodeCount: result.flowResponses.length
});
// 记录错误
try {
await someOperation();
} catch (error) {
addLog.error('Operation failed', error, {
appId,
chatId,
context: 'additional info'
});
throw error;
}
性能监控:
// 使用OpenTelemetry
import { withSpan } from '@fastgpt/service/common/otel/trace';
const result = await withSpan('dataset-search', async () => {
return searchDatasetData(params);
});
7. 生产部署检查清单
7.1 环境配置
- MongoDB 连接池配置(maxPoolSize ≥ 50)
- Redis 连接配置(集群模式)
- 向量数据库索引已创建
- S3 对象存储配置正确
- OneAPI/模型服务配置正确
7.2 安全配置
- 修改默认 ROOT_KEY
- 配置 CORS 白名单
- 启用 API 限流
- 配置 Sandbox 资源限制
- 敏感信息使用环境变量
7.3 性能配置
- 数据库索引已创建
- Redis 缓存已启用
- 文件上传大小限制已配置
- Worker 并发数已调整
- LLM 超时时间已配置
7.4 监控告警
- 日志收集(ELK/Loki)
- 性能监控(Prometheus + Grafana)
- 错误告警(钉钉/企微/邮件)
- 资源监控(CPU/内存/磁盘)
8. 实战案例:智能客服系统
8.1 系统架构
需求:
- 支持多轮对话
- 知识库检索
- 无法回答时转人工
- 记录对话评分
工作流设计:
[工作流开始] → [知识库检索] → [置信度判断]
↓
信心不足 → [转人工]
↓
信心充足 → [AI回答] → [自定义反馈]
完整配置:
const app = await MongoApp.create({
name: '智能客服',
nodes: [
{
nodeId: 'start',
flowNodeType: FlowNodeTypeEnum.workflowStart,
// ...
},
{
nodeId: 'dataset',
flowNodeType: FlowNodeTypeEnum.datasetSearchNode,
inputs: [
{ key: 'datasetIds', value: [datasetId] },
{ key: 'query', value: ['start', 'userChatInput'] },
{ key: 'similarity', value: 0.6 },
{ key: 'limit', value: 3000 }
],
outputs: [
{ key: 'quoteQA', label: '引用内容' },
{ key: 'similarity', label: '相似度' }
]
},
{
nodeId: 'ifElse',
flowNodeType: FlowNodeTypeEnum.ifElseNode,
inputs: [
{
key: 'condition',
value: ['dataset', 'similarity'],
valueType: 'number'
},
{
key: 'ifCondition',
value: '> 0.7', // 相似度 > 0.7
valueType: 'string'
}
]
},
{
nodeId: 'ai',
flowNodeType: FlowNodeTypeEnum.chatNode,
inputs: [
{ key: 'model', value: 'gpt-4' },
{
key: 'systemPrompt',
value: '你是客服助手,根据知识库回答问题...'
},
{ key: 'userChatInput', value: ['start', 'userChatInput'] },
{ key: 'quoteQA', value: ['dataset', 'quoteQA'] }
]
},
{
nodeId: 'transfer',
flowNodeType: FlowNodeTypeEnum.assignedAnswer,
inputs: [
{
key: 'text',
value: '抱歉,我无法准确回答您的问题。正在为您转接人工客服...',
valueType: 'string'
}
]
},
{
nodeId: 'feedback',
flowNodeType: FlowNodeTypeEnum.customFeedback,
inputs: [
{
key: 'feedbacks',
value: [
{ key: 'good', label: '👍 有帮助' },
{ key: 'bad', label: '👎 无帮助' }
]
}
]
}
],
edges: [
{ source: 'start', target: 'dataset' },
{ source: 'dataset', target: 'ifElse' },
{
source: 'ifElse',
target: 'ai',
sourceHandle: 'ifElse-source-true' // 条件为真
},
{
source: 'ifElse',
target: 'transfer',
sourceHandle: 'ifElse-source-false' // 条件为假
},
{ source: 'ai', target: 'feedback' }
]
});
8.2 数据分析
收集对话评分:
// 查询对话反馈
const feedbacks = await MongoChatItem.aggregate([
{ $match: { appId: app._id, customFeedbacks: { $exists: true } } },
{ $unwind: '$customFeedbacks' },
{
$group: {
_id: '$customFeedbacks.key',
count: { $sum: 1 }
}
}
]);
console.log('评分统计:', feedbacks);
// [{ _id: 'good', count: 85 }, { _id: 'bad', count: 15 }]
// 计算满意度
const totalFeedbacks = feedbacks.reduce((sum, f) => sum + f.count, 0);
const goodCount = feedbacks.find(f => f._id === 'good')?.count || 0;
const satisfaction = (goodCount / totalFeedbacks * 100).toFixed(2);
console.log('满意度:', satisfaction, '%');
总结
本文档涵盖了 FastGPT 的主要使用场景和最佳实践:
- 快速入门:最小可运行示例
- 知识库 RAG:创建、检索、优化
- Agent 工具:HTTP工具、多工具协作
- 高级工作流:条件分支、循环处理
- 性能优化:数据库、LLM、缓存
- 错误处理:常见问题、调试技巧
- 生产部署:配置检查清单
- 实战案例:智能客服系统
通过这些实践,开发者可以快速掌握 FastGPT 并构建生产级 AI 应用。