mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
perf: flow value type
This commit is contained in:
@@ -4,7 +4,8 @@ import {
|
||||
FlowModuleTypeEnum,
|
||||
FlowInputItemTypeEnum,
|
||||
FlowOutputItemTypeEnum,
|
||||
SpecialInputKeyEnum
|
||||
SpecialInputKeyEnum,
|
||||
FlowValueTypeEnum
|
||||
} from './index';
|
||||
import type { AppItemType } from '@/types/app';
|
||||
import type { FlowModuleTemplateType } from '@/types/flow';
|
||||
@@ -56,7 +57,7 @@ export const UserGuideModule: FlowModuleTemplateType = {
|
||||
};
|
||||
export const UserInputModule: FlowModuleTemplateType = {
|
||||
logo: '/imgs/module/userChatInput.png',
|
||||
name: '用户问题',
|
||||
name: '用户问题(对话入口)',
|
||||
intro: '用户输入的内容。该模块通常作为应用的入口,用户在发送消息后会首先执行该模块。',
|
||||
flowType: FlowModuleTypeEnum.questionInput,
|
||||
url: '/app/modules/init/userChatInput',
|
||||
@@ -72,6 +73,7 @@ export const UserInputModule: FlowModuleTemplateType = {
|
||||
key: SystemInputEnum.userChatInput,
|
||||
label: '用户问题',
|
||||
type: FlowOutputItemTypeEnum.source,
|
||||
valueType: FlowValueTypeEnum.string,
|
||||
targets: []
|
||||
}
|
||||
]
|
||||
@@ -101,6 +103,7 @@ export const HistoryModule: FlowModuleTemplateType = {
|
||||
{
|
||||
key: SystemInputEnum.history,
|
||||
label: '聊天记录',
|
||||
valueType: FlowValueTypeEnum.chatHistory,
|
||||
type: FlowOutputItemTypeEnum.source,
|
||||
targets: []
|
||||
}
|
||||
@@ -155,6 +158,7 @@ export const ChatModule: FlowModuleTemplateType = {
|
||||
key: 'systemPrompt',
|
||||
type: FlowInputItemTypeEnum.textarea,
|
||||
label: '系统提示词',
|
||||
valueType: FlowValueTypeEnum.string,
|
||||
description: ChatModelSystemTip,
|
||||
placeholder: ChatModelSystemTip,
|
||||
value: ''
|
||||
@@ -162,6 +166,7 @@ export const ChatModule: FlowModuleTemplateType = {
|
||||
{
|
||||
key: 'limitPrompt',
|
||||
type: FlowInputItemTypeEnum.textarea,
|
||||
valueType: FlowValueTypeEnum.string,
|
||||
label: '限定词',
|
||||
description: ChatModelLimitTip,
|
||||
placeholder: ChatModelLimitTip,
|
||||
@@ -171,7 +176,8 @@ export const ChatModule: FlowModuleTemplateType = {
|
||||
{
|
||||
key: 'quoteQA',
|
||||
type: FlowInputItemTypeEnum.target,
|
||||
label: '引用内容'
|
||||
label: '引用内容',
|
||||
valueType: FlowValueTypeEnum.kbQuote
|
||||
},
|
||||
Input_Template_History,
|
||||
Input_Template_UserChatInput
|
||||
@@ -183,6 +189,14 @@ export const ChatModule: FlowModuleTemplateType = {
|
||||
description: '直接响应,无需配置',
|
||||
type: FlowOutputItemTypeEnum.hidden,
|
||||
targets: []
|
||||
},
|
||||
{
|
||||
key: 'finish',
|
||||
label: '回复结束',
|
||||
description: 'AI 回复完成后触发',
|
||||
valueType: FlowValueTypeEnum.boolean,
|
||||
type: FlowOutputItemTypeEnum.source,
|
||||
targets: []
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -236,12 +250,14 @@ export const KBSearchModule: FlowModuleTemplateType = {
|
||||
key: 'isEmpty',
|
||||
label: '搜索结果为空',
|
||||
type: FlowOutputItemTypeEnum.source,
|
||||
valueType: FlowValueTypeEnum.boolean,
|
||||
targets: []
|
||||
},
|
||||
{
|
||||
key: 'unEmpty',
|
||||
label: '搜索结果不为空',
|
||||
type: FlowOutputItemTypeEnum.source,
|
||||
valueType: FlowValueTypeEnum.boolean,
|
||||
targets: []
|
||||
},
|
||||
{
|
||||
@@ -249,6 +265,7 @@ export const KBSearchModule: FlowModuleTemplateType = {
|
||||
label: '引用内容',
|
||||
description: '搜索结果为空时不返回',
|
||||
type: FlowOutputItemTypeEnum.source,
|
||||
valueType: FlowValueTypeEnum.kbQuote,
|
||||
targets: []
|
||||
}
|
||||
]
|
||||
@@ -257,7 +274,8 @@ export const KBSearchModule: FlowModuleTemplateType = {
|
||||
export const AnswerModule: FlowModuleTemplateType = {
|
||||
logo: '/imgs/module/reply.png',
|
||||
name: '指定回复',
|
||||
intro: '该模块可以直接回复一段指定的内容。常用于引导、提示。',
|
||||
intro: '该模块可以直接回复一段指定的内容。常用于引导、提示',
|
||||
description: '该模块可以直接回复一段指定的内容。常用于引导、提示',
|
||||
flowType: FlowModuleTypeEnum.answerNode,
|
||||
inputs: [
|
||||
Input_Template_TFSwitch,
|
||||
@@ -265,7 +283,8 @@ export const AnswerModule: FlowModuleTemplateType = {
|
||||
key: SpecialInputKeyEnum.answerText,
|
||||
value: '',
|
||||
type: FlowInputItemTypeEnum.textarea,
|
||||
label: '回复的内容'
|
||||
label: '回复的内容',
|
||||
description: '可以使用 \\n 来实现换行'
|
||||
}
|
||||
],
|
||||
outputs: []
|
||||
@@ -309,6 +328,7 @@ export const ClassifyQuestionModule: FlowModuleTemplateType = {
|
||||
{
|
||||
key: 'systemPrompt',
|
||||
type: FlowInputItemTypeEnum.textarea,
|
||||
valueType: FlowValueTypeEnum.string,
|
||||
label: '系统提示词',
|
||||
description:
|
||||
'你可以添加一些特定内容的介绍,从而更好的识别用户的问题类型。这个内容通常是给模型介绍一个它不知道的内容。',
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import type { BoxProps } from '@chakra-ui/react';
|
||||
|
||||
export enum FlowInputItemTypeEnum {
|
||||
systemInput = 'systemInput', // history, userChatInput, variableInput
|
||||
input = 'input',
|
||||
@@ -35,6 +37,36 @@ export enum SpecialInputKeyEnum {
|
||||
'answerText' = 'text'
|
||||
}
|
||||
|
||||
export enum FlowValueTypeEnum {
|
||||
'string' = 'string',
|
||||
'number' = 'number',
|
||||
'boolean' = 'boolean',
|
||||
'chatHistory' = 'chatHistory',
|
||||
'kbQuote' = 'kbQuote',
|
||||
'other' = 'other'
|
||||
}
|
||||
|
||||
export const FlowValueTypeStyle: Record<`${FlowValueTypeEnum}`, BoxProps> = {
|
||||
[FlowValueTypeEnum.string]: {
|
||||
background: '#36ADEF'
|
||||
},
|
||||
[FlowValueTypeEnum.number]: {
|
||||
background: '#FB7C3C'
|
||||
},
|
||||
[FlowValueTypeEnum.boolean]: {
|
||||
background: '#E7D118'
|
||||
},
|
||||
[FlowValueTypeEnum.chatHistory]: {
|
||||
background: '#00A9A6'
|
||||
},
|
||||
[FlowValueTypeEnum.kbQuote]: {
|
||||
background: '#A558C9'
|
||||
},
|
||||
[FlowValueTypeEnum.other]: {
|
||||
background: '#9CA2A8'
|
||||
}
|
||||
};
|
||||
|
||||
export const initModuleType: Record<string, boolean> = {
|
||||
[FlowModuleTypeEnum.historyNode]: true,
|
||||
[FlowModuleTypeEnum.questionInput]: true
|
||||
|
@@ -1,22 +1,25 @@
|
||||
import { FlowInputItemType } from '@/types/flow';
|
||||
import { SystemInputEnum } from '../app';
|
||||
import { FlowInputItemTypeEnum } from './index';
|
||||
import { FlowInputItemTypeEnum, FlowValueTypeEnum } from './index';
|
||||
|
||||
export const Input_Template_TFSwitch: FlowInputItemType = {
|
||||
key: SystemInputEnum.switch,
|
||||
type: FlowInputItemTypeEnum.target,
|
||||
label: '触发器'
|
||||
label: '触发器',
|
||||
valueType: FlowValueTypeEnum.boolean
|
||||
};
|
||||
|
||||
export const Input_Template_History: FlowInputItemType = {
|
||||
key: SystemInputEnum.history,
|
||||
type: FlowInputItemTypeEnum.target,
|
||||
label: '聊天记录'
|
||||
label: '聊天记录',
|
||||
valueType: FlowValueTypeEnum.chatHistory
|
||||
};
|
||||
|
||||
export const Input_Template_UserChatInput: FlowInputItemType = {
|
||||
key: SystemInputEnum.userChatInput,
|
||||
type: FlowInputItemTypeEnum.target,
|
||||
label: '用户问题',
|
||||
required: true
|
||||
required: true,
|
||||
valueType: FlowValueTypeEnum.string
|
||||
};
|
||||
|
@@ -3,7 +3,6 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@/service/response';
|
||||
import { authUser } from '@/service/utils/auth';
|
||||
import { connectToDatabase, App } from '@/service/mongo';
|
||||
import { EditFormType } from '@/utils/app';
|
||||
import { AppModuleInputItemType } from '@/types/app';
|
||||
import { FlowModuleTypeEnum, SpecialInputKeyEnum } from '@/constants/flow';
|
||||
import { TaskResponseKeyEnum } from '@/constants/chat';
|
||||
|
@@ -11,7 +11,8 @@ import { Handle, Position } from 'reactflow';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 4);
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { FlowOutputItemTypeEnum } from '@/constants/flow';
|
||||
import { FlowOutputItemTypeEnum, FlowValueTypeEnum } from '@/constants/flow';
|
||||
import SourceHandle from '../render/SourceHandle';
|
||||
|
||||
const NodeCQNode = ({
|
||||
data: { moduleId, inputs, outputs, onChangeNode, ...props }
|
||||
@@ -82,19 +83,7 @@ const NodeCQNode = ({
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Handle
|
||||
style={{
|
||||
top: '50%',
|
||||
right: '-14px',
|
||||
transform: 'translate(50%,-50%)',
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
background: '#9CA2A8'
|
||||
}}
|
||||
type="source"
|
||||
id={item.key}
|
||||
position={Position.Right}
|
||||
/>
|
||||
<SourceHandle handleKey={item.key} valueType={FlowValueTypeEnum.boolean} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
@@ -1,31 +1,26 @@
|
||||
import React from 'react';
|
||||
import { Handle, Position, NodeProps } from 'reactflow';
|
||||
import { NodeProps } from 'reactflow';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import NodeCard from '../modules/NodeCard';
|
||||
import { FlowModuleItemType } from '@/types/flow';
|
||||
import Container from '../modules/Container';
|
||||
import { SystemInputEnum } from '@/constants/app';
|
||||
import { FlowValueTypeEnum } from '@/constants/flow';
|
||||
import SourceHandle from '../render/SourceHandle';
|
||||
|
||||
const QuestionInputNode = ({
|
||||
data: { inputs, outputs, onChangeNode, ...props }
|
||||
}: NodeProps<FlowModuleItemType>) => {
|
||||
return (
|
||||
<NodeCard minW={'220px'} {...props}>
|
||||
<NodeCard minW={'240px'} {...props}>
|
||||
<Container borderTop={'2px solid'} borderTopColor={'myGray.200'} textAlign={'end'}>
|
||||
<Box>用户问题</Box>
|
||||
<Handle
|
||||
style={{
|
||||
bottom: '0',
|
||||
right: '0',
|
||||
transform: 'translate(50%,-5px)',
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
background: '#9CA2A8'
|
||||
}}
|
||||
id={SystemInputEnum.userChatInput}
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
/>
|
||||
<Box position={'relative'}>
|
||||
用户问题
|
||||
<SourceHandle
|
||||
handleKey={SystemInputEnum.userChatInput}
|
||||
valueType={FlowValueTypeEnum.string}
|
||||
/>
|
||||
</Box>
|
||||
</Container>
|
||||
</NodeCard>
|
||||
);
|
||||
|
@@ -37,7 +37,11 @@ const NodeCard = ({
|
||||
</Box>
|
||||
{description && (
|
||||
<MyTooltip label={description} forceShow>
|
||||
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
||||
<QuestionOutlineIcon
|
||||
display={['none', 'inline']}
|
||||
transform={'translateY(-1px)'}
|
||||
ml={1}
|
||||
/>
|
||||
</MyTooltip>
|
||||
)}
|
||||
<Box flex={1} />
|
||||
|
@@ -12,10 +12,10 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import { FlowInputItemTypeEnum } from '@/constants/flow';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { Handle, Position } from 'reactflow';
|
||||
import MySelect from '@/components/Select';
|
||||
import MySlider from '@/components/Slider';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import TargetHandle from './TargetHandle';
|
||||
|
||||
export const Label = ({
|
||||
required = false,
|
||||
@@ -35,7 +35,7 @@ export const Label = ({
|
||||
)}
|
||||
{description && (
|
||||
<MyTooltip label={description} forceShow>
|
||||
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
||||
<QuestionOutlineIcon display={['none', 'inline']} transform={'translateY(-1px)'} ml={1} />
|
||||
</MyTooltip>
|
||||
)}
|
||||
</Box>
|
||||
@@ -61,6 +61,10 @@ const RenderBody = ({
|
||||
{!!item.label && (
|
||||
<Label required={item.required} description={item.description}>
|
||||
{item.label}
|
||||
|
||||
{(item.type === FlowInputItemTypeEnum.target || item.valueType) && (
|
||||
<TargetHandle handleKey={item.key} valueType={item.valueType} />
|
||||
)}
|
||||
</Label>
|
||||
)}
|
||||
<Box mt={2} className={'nodrag'}>
|
||||
@@ -148,22 +152,6 @@ const RenderBody = ({
|
||||
{item.type === FlowInputItemTypeEnum.custom && CustomComponent[item.key] && (
|
||||
<>{CustomComponent[item.key]({ ...item })}</>
|
||||
)}
|
||||
{item.type === FlowInputItemTypeEnum.target && (
|
||||
<Handle
|
||||
style={{
|
||||
top: '50%',
|
||||
left: '-14px',
|
||||
transform: 'translate(-50%,-50%)',
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
background: '#9CA2A8'
|
||||
}}
|
||||
id={item.key}
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
onConnect={(params) => console.log('handle onConnect', params)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
|
@@ -5,6 +5,7 @@ import { FlowOutputItemTypeEnum } from '@/constants/flow';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { Handle, Position } from 'reactflow';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import SourceHandle from './SourceHandle';
|
||||
|
||||
const Label = ({
|
||||
children,
|
||||
@@ -16,7 +17,7 @@ const Label = ({
|
||||
<Flex as={'label'} justifyContent={'right'} alignItems={'center'} position={'relative'}>
|
||||
{description && (
|
||||
<MyTooltip label={description} forceShow>
|
||||
<QuestionOutlineIcon display={['none', 'inline']} mr={1} />
|
||||
<QuestionOutlineIcon display={['none', 'inline']} transform={'translateY(-1px)'} mr={1} />
|
||||
</MyTooltip>
|
||||
)}
|
||||
{children}
|
||||
@@ -33,19 +34,7 @@ const RenderBody = ({ flowOutputList }: { flowOutputList: FlowOutputItemType[] }
|
||||
<Label description={item.description}>{item.label}</Label>
|
||||
<Box mt={FlowOutputItemTypeEnum.answer ? 0 : 2} className={'nodrag'}>
|
||||
{item.type === FlowOutputItemTypeEnum.source && (
|
||||
<Handle
|
||||
style={{
|
||||
top: '50%',
|
||||
right: '-14px',
|
||||
transform: 'translate(50%,-50%)',
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
background: '#9CA2A8'
|
||||
}}
|
||||
type="source"
|
||||
id={item.key}
|
||||
position={Position.Right}
|
||||
/>
|
||||
<SourceHandle handleKey={item.key} valueType={item.valueType} />
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
|
@@ -0,0 +1,42 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import { Handle, Position } from 'reactflow';
|
||||
import { FlowValueTypeEnum, FlowValueTypeStyle } from '@/constants/flow';
|
||||
|
||||
interface Props extends BoxProps {
|
||||
handleKey: string;
|
||||
valueType?: `${FlowValueTypeEnum}`;
|
||||
}
|
||||
|
||||
const SourceHandle = ({ handleKey, valueType, ...props }: Props) => {
|
||||
const valueStyle = useMemo(
|
||||
() =>
|
||||
valueType
|
||||
? FlowValueTypeStyle[valueType]
|
||||
: (FlowValueTypeStyle[FlowValueTypeEnum.other] as any),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
position={'absolute'}
|
||||
top={'50%'}
|
||||
right={'-16px'}
|
||||
transform={'translate(50%,-50%)'}
|
||||
{...props}
|
||||
>
|
||||
<Handle
|
||||
style={{
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
...valueStyle
|
||||
}}
|
||||
type="source"
|
||||
id={handleKey}
|
||||
position={Position.Right}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default SourceHandle;
|
@@ -0,0 +1,44 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import { Handle, OnConnect, Position } from 'reactflow';
|
||||
import { FlowValueTypeEnum, FlowValueTypeStyle } from '@/constants/flow';
|
||||
|
||||
interface Props extends BoxProps {
|
||||
handleKey: string;
|
||||
valueType?: `${FlowValueTypeEnum}`;
|
||||
onConnect?: OnConnect;
|
||||
}
|
||||
|
||||
const TargetHandle = ({ handleKey, valueType, onConnect, ...props }: Props) => {
|
||||
const valueStyle = useMemo(
|
||||
() =>
|
||||
valueType
|
||||
? FlowValueTypeStyle[valueType]
|
||||
: (FlowValueTypeStyle[FlowValueTypeEnum.other] as any),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
position={'absolute'}
|
||||
top={'50%'}
|
||||
left={'-16px'}
|
||||
transform={'translate(50%,-50%)'}
|
||||
{...props}
|
||||
>
|
||||
<Handle
|
||||
style={{
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
...valueStyle
|
||||
}}
|
||||
type="target"
|
||||
id={handleKey}
|
||||
datatype={valueStyle}
|
||||
position={Position.Left}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default TargetHandle;
|
@@ -30,6 +30,7 @@ export type ChatProps = {
|
||||
export type ChatResponse = {
|
||||
[TaskResponseKeyEnum.answerText]: string;
|
||||
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType;
|
||||
finish: boolean;
|
||||
};
|
||||
|
||||
/* request openai chat */
|
||||
@@ -143,7 +144,8 @@ export const dispatchChatCompletion = async (props: Record<string, any>): Promis
|
||||
maxToken,
|
||||
quoteList: filterQuoteQA,
|
||||
completeMessages
|
||||
}
|
||||
},
|
||||
finish: true
|
||||
};
|
||||
};
|
||||
|
||||
|
5
client/src/types/flow.d.ts
vendored
5
client/src/types/flow.d.ts
vendored
@@ -1,7 +1,8 @@
|
||||
import {
|
||||
FlowBodyItemTypeEnum,
|
||||
FlowInputItemTypeEnum,
|
||||
FlowOutputItemTypeEnum
|
||||
FlowOutputItemTypeEnum,
|
||||
FlowValueTypeEnum
|
||||
} from '@/constants/flow';
|
||||
import { Connection } from 'reactflow';
|
||||
import type { AppModuleItemType } from './app';
|
||||
@@ -18,6 +19,7 @@ export type FlowModuleItemChangeProps = {
|
||||
export type FlowInputItemType = {
|
||||
key: string; // 字段名
|
||||
value?: any;
|
||||
valueType?: `${FlowValueTypeEnum}`;
|
||||
type: `${FlowInputItemTypeEnum}`;
|
||||
label: string;
|
||||
connected?: boolean;
|
||||
@@ -39,6 +41,7 @@ export type FlowOutputItemType = {
|
||||
key: string; // 字段名
|
||||
label: string;
|
||||
description?: string;
|
||||
valueType?: `${FlowValueTypeEnum}`;
|
||||
type: `${FlowOutputItemTypeEnum}`;
|
||||
targets: FlowOutputTargetItemType[];
|
||||
};
|
||||
|
@@ -76,10 +76,7 @@ export const appModule2FlowNode = ({
|
||||
// replace item data
|
||||
const moduleItem: FlowModuleItemType = {
|
||||
...item,
|
||||
logo: template.logo,
|
||||
name: template.name,
|
||||
intro: template.intro,
|
||||
url: template.url,
|
||||
...template,
|
||||
inputs: template.inputs.map((templateInput) => {
|
||||
// use latest inputs
|
||||
const itemInput = item.inputs.find((item) => item.key === templateInput.key) || templateInput;
|
||||
|
106
docSite/docs/datasets/prompt.md
Normal file
106
docSite/docs/datasets/prompt.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# 提示词示例
|
||||
|
||||
## 客服
|
||||
|
||||
```
|
||||
您好您将扮演万千紧固件公司的售前客服。在第一次咨询中,您需要获取客户的联系人姓名和手机号码,并了解客户是终端生产企业还是工贸经销商。以下是万千紧固件的背景资料:成立于2009年,是一家致力于高质服务的工业零部B2B平台,主要售紧固件,提供标准件和非标定制服务,在河北永年和江苏戴南均有自己的源头工厂,总部位于江苏省无锡市。
|
||||
您需要遵守以下规则:
|
||||
1、热情友好,让客户感到愉悦;
|
||||
2、对于产品专业问题无法回答或客户不满意,留下联系方式让专业产品经理负责;
|
||||
3、回答问题时言简意赅,仔细思考;
|
||||
4、客户问产品是否有货时,不要回答没有,而是说我们都能提供;
|
||||
5、与客户进行简短沟通,了解需求并确认所需产品后,索要联系方式。
|
||||
|
||||
|
||||
样本示例1:
|
||||
客户:在吗?
|
||||
客服:在的,请问您需要咨询什么产品?
|
||||
客户:防盗螺栓有吗?
|
||||
客服:有的,我们提供全品类的紧固件产品,请告诉我具体的型号和用途。
|
||||
客户:用在铁塔机器上的,2040304不锈钢
|
||||
客服:请问需要多少件?
|
||||
客户:大概10万颗左右吧
|
||||
客户:给我个报价,优惠些,长期合作
|
||||
客服:非常抱歉,报价需要我们专业的产品同事,您能留下联系方式吗?我会安排他们立即与您联系。
|
||||
客户:王先,13928916752今天能联系么
|
||||
客服:可以的,我们的同事会在1个小时内与您联系,请注意接听来自无锡的电话。谢谢您的咨询。
|
||||
|
||||
样本示例2:
|
||||
客户:请问一下这个螺栓有没有33长度的?
|
||||
客服:您好,我是客服小万,请问您需要的是哪种螺栓?能说得更具体一些吗?
|
||||
客户:圆头方颈。
|
||||
客服:头部多大?
|
||||
客户:13。
|
||||
客户:M6的。
|
||||
客服:您要的是哪个材质的呢?
|
||||
客户:碳钢的,强度高一点。
|
||||
客服:您需要多少个呢?
|
||||
客户:大约2000个左右。
|
||||
客服:方便留下您的联系方式吗?
|
||||
客服:我会让同事在上午与您确认并回复。
|
||||
客户:18217699040。
|
||||
客服:请问您的姓氏是?
|
||||
客户:王。
|
||||
客服:好的。
|
||||
客户:谢谢。
|
||||
|
||||
样本示例3:
|
||||
客户:你们是生产还是贸易?
|
||||
客服:亲,感谢您的咨询。我们既生产也贸易,同时接受标准件和非标定制的订单。请问您需要采购什么产品?
|
||||
客户:SPR25x100L铜套的304材质螺母M64。
|
||||
客户:我想找源头工厂。
|
||||
客服:亲,我们就是源头工厂哦!请问您是关心价格还是质量呢?我们万千是国内大品牌,价格实惠,质量和交期都有保障。
|
||||
客户:工厂放心点,经销商门道太多。
|
||||
客服:亲,您可以放心,我们的产品质量有保障,如有不满意可退换;有问题我们也有专属客服经理24小时处理。
|
||||
客服:请问您具体需要多少数量呢?
|
||||
客户:2456个。
|
||||
客户:什么时候能给出报价?我这边比较着急使用。
|
||||
客服:亲,请留下您的联系方式,我会让我们专业的产品同事与您联系。
|
||||
客户:13928956789,李。
|
||||
|
||||
样本示例4:
|
||||
客户:你好,在吗?
|
||||
客服:在的。
|
||||
客服:请问您需要什么产品?
|
||||
客户:卡箍有吗?
|
||||
客服:有的,您需要哪一种?
|
||||
客户:我是用在电线杆上的。
|
||||
客户:我需要200个。
|
||||
客服:好的,您需要什么材质的?
|
||||
客户:有图片吗?我想看看是不是我需要的那种,材质无所谓。
|
||||
客服:好的,方便加您微信吗?在线上不方便发图片,加微信后我会给您发送图片以进行确认。
|
||||
客户:您的微信是多少?我加您。
|
||||
客服:好的,我的微信是18626076792,您可以添加一下。您也可以直接拨打电话与我们联系。
|
||||
客户:已添加,请通过微信沟通。
|
||||
客服:好的,已通过,我需要记录一下,请问您的电话方便吗?
|
||||
客户:187628100000。
|
||||
服:请问您的姓氏是?
|
||||
客户:陈。
|
||||
客服:好的。
|
||||
客户:谢谢。
|
||||
|
||||
样本示例5:
|
||||
户:87322.5。
|
||||
客服:好的,您是要扁圆头半空心铆钉吗?您需要具体什么材质的呢?
|
||||
客户:材质无所谓。您们的最低起订量是多少?
|
||||
客服:起订量这边需要帮您查询一下系统。您是只要规格,材质无所谓吗?
|
||||
客户:是的,因为不好买。
|
||||
客服:好的,这边稍后查一下系统,确认是否有现货。如果没有现货,是否可以接受定制?我们公司也支持定制服务。
|
||||
客户:定制需要多少起订量?您能帮我询问一下不同材质的要求吗?
|
||||
客服:好的,方便留下您的联系方式吗?稍后我们会安排专业的同事与您联系,直接对接沟通。
|
||||
客户:18190818931。
|
||||
客服:请问您的姓氏是?
|
||||
客户:杨。
|
||||
客服:好的,请稍等。
|
||||
|
||||
样品示例6
|
||||
客户:不锈钢201 M87,单价多少?
|
||||
客服说:你好,请问您需要的是哪一种螺丝?
|
||||
客户:外六角螺栓
|
||||
客服说:好的,你需要多少啊?我们量大优惠越大
|
||||
客户:10000左右
|
||||
客服说:好的,只有这一种产品需要帮你报价吗,还有其他的产品需要一并帮你确认价格吗?
|
||||
客户:全牙201不锈钢 M825
|
||||
客服说:好的,您总共有几种产品需要报价?
|
||||
客户:十几种
|
||||
```
|
Reference in New Issue
Block a user