sales action/action result analysis
1. 销售动作映射;2. 销售动作到行动结果分析; 3. 销售动作到抽象销售动作
This commit is contained in:
parent
f42fc08d70
commit
d2ac3e0472
|
|
@ -79,7 +79,6 @@ class AgentProxy:
|
||||||
if decoded_line.startswith('data:'):
|
if decoded_line.startswith('data:'):
|
||||||
data_dict = json.loads(decoded_line[5:])
|
data_dict = json.loads(decoded_line[5:])
|
||||||
output = self.handle_response(data_dict)
|
output = self.handle_response(data_dict)
|
||||||
print(output)
|
|
||||||
else:
|
else:
|
||||||
return "Request failed", response.status_code
|
return "Request failed", response.status_code
|
||||||
return output
|
return output
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
import pandas as pd
|
||||||
|
from AgentProxy import AgentProxy
|
||||||
|
from datetime import datetime # Add this import
|
||||||
|
|
||||||
|
# Here you need to replace the API Key and API Secret with your,I provide a test key and secret here
|
||||||
|
api_key = '25bda2c39c0f8ca0'
|
||||||
|
api_secret = 'e0008b9b9727cb8ceea5a132dbe62495'
|
||||||
|
assistant_id = "66bb09a84673b57506fe7bbd"
|
||||||
|
agent = AgentProxy(assistant_id, api_key, api_secret)
|
||||||
|
|
||||||
|
|
||||||
|
sales_stages = ["Prospecting", "Evaluation", "Qualification", "Bidding / Negotiating", "Contract Review", "Closed Won", "Cancel", "Closed Lost"]
|
||||||
|
|
||||||
|
|
||||||
|
sales_stage_definition = '''
|
||||||
|
|
||||||
|
1. **Prospecting(潜在客户开发)**:这一阶段涉及识别和开发潜在客户。销售人员通过各种渠道(如电话、电子邮件、社交媒体等)寻找潜在买家。-阶段转化标准:①客户有需求 ②有明确的项目联系人;
|
||||||
|
|
||||||
|
2. **Evaluation(评估)**:在评估阶段,销售团队会评估潜在客户的需求,确定他们是否与公司的产品或服务相匹配。同时,潜在客户也在评估不同的供应商。-阶段转化标准:①客户有预算 ②有明确的项目时间 ③有预期的产品和数量
|
||||||
|
|
||||||
|
3. **Qualification(资格认定)**:这一阶段的目标是确定潜在客户是否具有成为合格销售机会的潜力。这通常涉及对客户的预算、需求、决策过程和时间线等进行评估。-阶段转化标准:①项目预算批准、项目已立项 ②有确定产品和数量;或③完成场景应用/技术适用性验证,客户确定平凯入围(完成poc)
|
||||||
|
|
||||||
|
4. **Bidding / Negotiating(投标/谈判)**:在这个阶段,销售人员会向客户提交正式的报价或提案,并进行必要的谈判,以达成最终的销售协议。-阶段转化标准:①完成可交付评审;②报价单通过审批;③投标结果确认赢标或完成商务谈判,确定价格和SOW,客户启动合同流程
|
||||||
|
|
||||||
|
5. **Contract Review(合同审查)**:一旦谈判完成,双方将审查合同条款,确保所有细节都得到妥善处理,并准备好签署。-阶段转化标准:完成飞书合同协商审批,确认合同条款(包括付款条件、服务开通时间等)
|
||||||
|
|
||||||
|
6. **Closed Won(成功关闭)**:这是销售流程的最终目标,表示交易已经成功完成,客户已经购买了产品或服务。-阶段转化标准:完成合同签署,合同归档
|
||||||
|
|
||||||
|
7. **Cancel(取消)**:在某些情况下,交易可能会在过程的任何阶段取消。这可能是因为客户改变了主意,或者发现产品或服务不再符合他们的需求。-阶段标准:①客户明确回复项目取消 ②客户明确表示没有预算 ③内部立项未通过
|
||||||
|
|
||||||
|
8. **Closed Lost(失败关闭)**:如果销售机会没有成功,它将被标记为“失败关闭”。这可能是因为竞争、价格问题或客户需求的改变等原因。-阶段转化标准:①投标确认结果未赢标 ②客户明确表示选择友商 ③poc结果客户确认平凯未入围/未通过 ④商务谈判失败 ⑤其他如商务关系没有竞争机会
|
||||||
|
上述每个阶段的阶段转化标准是准出标准,只有在满足该准出标准,才可以进入到下一个阶段
|
||||||
|
'''
|
||||||
|
|
||||||
|
abstract_actions = [
|
||||||
|
"客户接触与需求识别",
|
||||||
|
"产品演示与方案提供",
|
||||||
|
"商务谈判与合同准备",
|
||||||
|
"项目支持与优化",
|
||||||
|
"市场分析与策略调整",
|
||||||
|
"内部协调与支持",
|
||||||
|
"合同审查与订单处理",
|
||||||
|
"客户关系维护",
|
||||||
|
"后续跟进与机会挖掘"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Read the Excel file
|
||||||
|
df = pd.read_excel('output_top200.xlsx')
|
||||||
|
|
||||||
|
# Iterate over each row in the DataFrame
|
||||||
|
for index, row in df.iterrows():
|
||||||
|
# Extract the information from the column "当前详细状态及Close节奏"
|
||||||
|
|
||||||
|
try:
|
||||||
|
detailed_status = row['当前详细状态及Close节奏']
|
||||||
|
print(f"Processing row {index} at current time: {datetime.now()}")
|
||||||
|
detailed_current_stage = row['Sales stage']
|
||||||
|
prompt = (f"某公司销售人员填写的销售动作日志为: {detailed_status} , "
|
||||||
|
f"销售动作可归类到如下抽象销售动作列表:{','.join(abstract_actions)},"
|
||||||
|
f"请分析销售动作日志,提取出销售动作,将销售动作按照上述抽象销售动作列表进行归类,同时分析该销售动作是否产生了行动结果以及如果有其行动结果是什么,并尝试将行动结果进行抽象化、概括化"
|
||||||
|
f"请按照如下格式输出分析结果:"
|
||||||
|
f"销售动作-销售动作归类-销售动作行动结果-抽象销售动作行动结果")
|
||||||
|
|
||||||
|
analysis_result = agent.send_message(prompt)
|
||||||
|
print(analysis_result)
|
||||||
|
df.at[index, '行动结果'] = analysis_result # Directly update the DataFrame
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error processing row {index}: {e}")
|
||||||
|
df.at[index, '行动结果'] = f"Error: {e}" # Log the error in the DataFrame
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
df.to_excel('analysis_result_action_result_top200.xlsx', index=False)
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,57 @@
|
||||||
|
import json
|
||||||
|
import pandas as pd
|
||||||
|
import re
|
||||||
|
import json # Add this line at the top of your script
|
||||||
|
from AgentProxy import AgentProxy
|
||||||
|
|
||||||
|
with open('mapping.json', 'r') as file:
|
||||||
|
json_data = file.read()
|
||||||
|
|
||||||
|
mapping = json.loads(json_data)
|
||||||
|
|
||||||
|
print(len(mapping))
|
||||||
|
|
||||||
|
|
||||||
|
# Read the Excel file
|
||||||
|
df = pd.read_excel('analysis_result_top200.xlsx')
|
||||||
|
statistic = {}
|
||||||
|
|
||||||
|
# Iterate through the "example" column
|
||||||
|
for index, row in df.iterrows():
|
||||||
|
text = row['销售动作分析']
|
||||||
|
# Extract text enclosed by '**', by using regular expression
|
||||||
|
print(index)
|
||||||
|
stage = row['Sales stage']
|
||||||
|
if stage not in statistic:
|
||||||
|
statistic[stage] = {}
|
||||||
|
statistic[stage]['total'] = 0
|
||||||
|
statistic[stage]['total'] += 1
|
||||||
|
|
||||||
|
matches = re.findall(r'\*\*(.*?)\*\*', text)
|
||||||
|
for match in matches:
|
||||||
|
print(f"{match}") # Print as markdown title # iterate all the matches
|
||||||
|
abstract_action = next((item['abstract_action'] for item in mapping if item['action'] == match), None)
|
||||||
|
if abstract_action:
|
||||||
|
print(f"Matched Abstract Action: {abstract_action}")
|
||||||
|
|
||||||
|
if abstract_action not in statistic[stage]:
|
||||||
|
statistic[stage][abstract_action] = 0
|
||||||
|
statistic[stage][abstract_action] += 1
|
||||||
|
if len(matches) > 0:
|
||||||
|
df.at[index, '销售动作'] = ','.join(matches)
|
||||||
|
else:
|
||||||
|
df.at[index, '销售动作'] = ''
|
||||||
|
|
||||||
|
df.to_excel('analysis_result_top200.xlsx', index=False)
|
||||||
|
|
||||||
|
print(statistic)
|
||||||
|
|
||||||
|
action_dict = {}
|
||||||
|
# Calculate the percentage distribution of each action within each stage
|
||||||
|
for stage, actions in statistic.items():
|
||||||
|
total = actions.pop('total')
|
||||||
|
print(f"Stage: {stage}")
|
||||||
|
for action, count in actions.items():
|
||||||
|
percentage = (count / total) * 100
|
||||||
|
print(f" {action}: {percentage:.2f}%")
|
||||||
|
action_dict[action] = action
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
import pandas as pd
|
||||||
|
import re
|
||||||
|
import json # Add this line at the top of your script
|
||||||
|
from AgentProxy import AgentProxy
|
||||||
|
|
||||||
|
|
||||||
|
# Read the Excel file
|
||||||
|
df = pd.read_excel('analysis_result_top200.xlsx')
|
||||||
|
statistic = {}
|
||||||
|
|
||||||
|
# Iterate through the "example" column
|
||||||
|
for index, row in df.iterrows():
|
||||||
|
text = row['销售动作分析']
|
||||||
|
# Extract text enclosed by '**', by using regular expression
|
||||||
|
print(index)
|
||||||
|
stage = row['Sales stage']
|
||||||
|
if stage not in statistic:
|
||||||
|
statistic[stage] = {}
|
||||||
|
statistic[stage]['total'] = 0
|
||||||
|
statistic[stage]['total'] += 1
|
||||||
|
|
||||||
|
matches = re.findall(r'\*\*(.*?)\*\*', text)
|
||||||
|
for match in matches:
|
||||||
|
print(f"{match}") # Print as markdown title # iterate all the matches
|
||||||
|
if match not in statistic[stage]:
|
||||||
|
statistic[stage][match] = 0
|
||||||
|
statistic[stage][match] += 1
|
||||||
|
if len(matches) > 0:
|
||||||
|
df.at[index, '销售动作'] = ','.join(matches)
|
||||||
|
else:
|
||||||
|
df.at[index, '销售动作'] = ''
|
||||||
|
|
||||||
|
df.to_excel('analysis_result_top200.xlsx', index=False)
|
||||||
|
|
||||||
|
print(statistic)
|
||||||
|
|
||||||
|
action_dict = {}
|
||||||
|
# Calculate the percentage distribution of each action within each stage
|
||||||
|
for stage, actions in statistic.items():
|
||||||
|
total = actions.pop('total')
|
||||||
|
print(f"Stage: {stage}")
|
||||||
|
for action, count in actions.items():
|
||||||
|
percentage = (count / total) * 100
|
||||||
|
print(f" {action}: {percentage:.2f}%")
|
||||||
|
action_dict[action] = action
|
||||||
|
|
||||||
|
print(len(action_dict.keys()))
|
||||||
|
prompt_abstract_actions = f"以下是销售动作的文字描述,{','.join(action_dict.keys())} 请根据这些结果,总结出抽象的销售动作,以便于将上述销售动作归纳到抽象的销售动作中"
|
||||||
|
api_key = '25bda2c39c0f8ca0'
|
||||||
|
api_secret = 'e0008b9b9727cb8ceea5a132dbe62495'
|
||||||
|
assistant_id = "66bb09a84673b57506fe7bbd"
|
||||||
|
agent = AgentProxy(assistant_id, api_key, api_secret)
|
||||||
|
# res = agent.send_message(prompt_abstract_actions)
|
||||||
|
# print(res)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
abstract_actions = [
|
||||||
|
"客户接触与需求识别",
|
||||||
|
"产品演示与方案提供",
|
||||||
|
"商务谈判与合同准备",
|
||||||
|
"项目支持与优化",
|
||||||
|
"市场分析与策略调整",
|
||||||
|
"内部协调与支持",
|
||||||
|
"合同审查与订单处理",
|
||||||
|
"客户关系维护",
|
||||||
|
"后续跟进与机会挖掘"
|
||||||
|
]
|
||||||
|
|
||||||
|
full_mapping = []
|
||||||
|
for i in range(0, len(action_dict.keys()), 20):
|
||||||
|
group = list(action_dict.keys())[i:i+20]
|
||||||
|
prompt_abstract_actions = f"以下是销售动作的文字描述,{','.join(group)}; 以下是抽象销售动作, {','.join(abstract_actions)}; 请根据上述信息,将销售动作归纳到抽象的销售动作中并给出映射关系, 用json数组返回,销售动作字段为action, 抽象销售动作字段为abstract_action"
|
||||||
|
res = agent.send_message(prompt_abstract_actions)
|
||||||
|
|
||||||
|
try:
|
||||||
|
json_match = re.search(r'```json\s*(.*?)\s*```', res, re.DOTALL)
|
||||||
|
|
||||||
|
if json_match:
|
||||||
|
json_data = json_match.group(1)
|
||||||
|
mapping = json.loads(json_data)
|
||||||
|
else:
|
||||||
|
mapping = []
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error parsing response: {e}")
|
||||||
|
mapping = []
|
||||||
|
print(res)
|
||||||
|
print(mapping)
|
||||||
|
full_mapping.extend(mapping)
|
||||||
|
print(full_mapping)
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,100 @@
|
||||||
|
text = """
|
||||||
|
根据您提供的销售动作描述,我们可以将其归纳到更抽象的销售动作类别中。下面是每个具体销售动作与其对应的抽象销售动作的映射关系,以JSON数组的形式返回:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"action": "决策与结果评估",
|
||||||
|
"abstract_action": "项目支持与优化"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "合同审查与修改",
|
||||||
|
"abstract_action": "合同审查与订单处理"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "技术支持和协调",
|
||||||
|
"abstract_action": "技术支持与交流"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "项目推广",
|
||||||
|
"abstract_action": "市场分析与策略调整"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "培训",
|
||||||
|
"abstract_action": "内部协调与支持"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "需求确认",
|
||||||
|
"abstract_action": "客户接触与需求识别"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "项目审批",
|
||||||
|
"abstract_action": "内部协调与支持"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "需求调研",
|
||||||
|
"abstract_action": "客户接触与需求识别"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "产品测试与调优",
|
||||||
|
"abstract_action": "项目支持与优化"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "竞品分析",
|
||||||
|
"abstract_action": "市场分析与策略调整"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "适配工作",
|
||||||
|
"abstract_action": "项目支持与优化"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "项目立项跟进",
|
||||||
|
"abstract_action": "内部协调与支持"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "报价沟通",
|
||||||
|
"abstract_action": "商务谈判与合同准备"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "市场信息收集",
|
||||||
|
"abstract_action": "市场分析与策略调整"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "客户需求沟通",
|
||||||
|
"abstract_action": "客户接触与需求识别"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "技术支持与交流",
|
||||||
|
"abstract_action": "技术支持与交流"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "预算与采购流程跟进",
|
||||||
|
"abstract_action": "内部协调与支持"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "立项材料准备",
|
||||||
|
"abstract_action": "内部协调与支持"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "内部协调与汇报",
|
||||||
|
"abstract_action": "内部协调与支持"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "合同与商务谈判",
|
||||||
|
"abstract_action": "商务谈判与合同准备"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
这个映射关系可以帮助理解每个具体销售动作在更广泛销售过程中的作用和位置。"""
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
# Use a regular expression to find the JSON array within the text
|
||||||
|
json_match = re.search(r'```json\s*(.*?)\s*```', text, re.DOTALL)
|
||||||
|
|
||||||
|
if json_match:
|
||||||
|
json_data = json_match.group(1)
|
||||||
|
mapping = json.loads(json_data)
|
||||||
|
else:
|
||||||
|
mapping = []
|
||||||
|
print(mapping)
|
||||||
Binary file not shown.
Loading…
Reference in New Issue