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 检索效果优化技巧

问题:检索结果不准确

解决方案

  1. 调整分块策略
// 针对不同类型的文档使用不同的分块模式
const chunkSettings = {
  // 长文档(技术文档、手册)
  longDoc: {
    chunkSize: 800,
    chunkOverlap: 100,
    chunkSplitMode: 'paragraph'
  },
  
  // 短文档(FAQ)
  shortDoc: {
    chunkSize: 300,
    chunkOverlap: 30,
    chunkSplitMode: 'qa'
  },
  
  // 表格数据
  table: {
    chunkSize: 1000,
    chunkOverlap: 0,
    chunkSplitMode: 'chunk'
  }
};
  1. 启用查询扩展
// 在知识库检索前添加查询扩展节点
{
  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'
}
  1. 使用混合检索 + 重排
// 配置最佳检索参数
{
  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)

优化方案

  1. 向量数据库索引优化
-- 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;
  1. 分批检索
// 对于多个知识库,分批并行检索
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);
}
  1. 缓存热点查询
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 响应慢,成本高

优化方案

  1. 使用更快的模型
// 非关键场景使用 gpt-3.5-turbo
// 关键场景使用 gpt-4

const model = isComplexTask ? 'gpt-4' : 'gpt-3.5-turbo';
  1. 缩短 Prompt
// 优化前:
const systemPrompt = `
你是一个专业的客服助手...(1000字)
规则:
1. xxx
2. xxx
...(20条规则)
`;

// 优化后:
const systemPrompt = `
专业客服。规则:礼貌、准确、简洁。
知识库优先,不懂就说不懂。
`;
  1. 流式响应
// 总是启用 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 数据库查询优化

问题:对话历史加载慢

优化方案

  1. 创建索引
// MongoDB 索引
db.chatitems.createIndex({ chatId: 1, _id: -1 });
db.chatitems.createIndex({ appId: 1, teamId: 1, time: -1 });
  1. 分页加载
// 只加载最近N条消息
const histories = await MongoChatItem.find({ chatId })
  .sort({ _id: -1 })
  .limit(30) // 最多30条
  .lean();
  1. 使用投影减少数据传输
// 只查询必要字段
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 的主要使用场景和最佳实践:

  1. 快速入门:最小可运行示例
  2. 知识库 RAG:创建、检索、优化
  3. Agent 工具:HTTP工具、多工具协作
  4. 高级工作流:条件分支、循环处理
  5. 性能优化:数据库、LLM、缓存
  6. 错误处理:常见问题、调试技巧
  7. 生产部署:配置检查清单
  8. 实战案例:智能客服系统

通过这些实践,开发者可以快速掌握 FastGPT 并构建生产级 AI 应用。