diff --git a/ExcelHelper.py b/ExcelHelper.py new file mode 100644 index 0000000..1f0d882 --- /dev/null +++ b/ExcelHelper.py @@ -0,0 +1,48 @@ +import openpyxl +from openpyxl.styles import Font + +class ExcelHelper: + def __init__(self, data): + """ + 初始化 ExcelHelper 实例 + :param data: 包含多个数组的列表,每个数组包含字典,每个字典有 'title' 和 'content' 键 + """ + self.data = data + self.workbook = openpyxl.Workbook() + self.sheet = self.workbook.active + + def create_excel(self, filename): + """ + 创建 Excel 文件并保存 + :param filename: 保存的文件名 + """ + start_row = 1 + for array in self.data: + col = 1 + for item in array: + self.sheet.cell(row=start_row, column=col, value=item['title']).font = Font(bold=True) + self.sheet.cell(row=start_row + 1, column=col, value=item['content']) + col += 1 + # 在每个数组之间添加两行空行 + start_row += 3 + + self.workbook.save(filename) + print(f"Excel 文件已保存为 {filename}") + +# # 示例数据 +# data = [ +# [ +# {'title': 'Title 1', 'content': 'Content 1'}, +# {'title': 'Title 2', 'content': 'Content 2'}, +# {'title': 'Title 3', 'content': 'Content 3'} +# ], +# [ +# {'title': 'Title 4', 'content': 'Content 4'}, +# {'title': 'Title 5', 'content': 'Content 5'}, +# {'title': 'Title 6', 'content': 'Content 6'} +# ] +# ] + +# # 创建 ExcelHelper 实例并生成 Excel 文件 +# excel_helper = ExcelHelper(data) +# excel_helper.create_excel('output.xlsx') diff --git a/README.md b/README.md index e8fd9e6..2a6e9b8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # market_assistant +pip install -r requirements.txt + +可参考customer_aqusition.json定义prompt提问链 +结果输出到output.txt \ No newline at end of file diff --git a/customer_aqusition_0.json b/customer_aqusition_0.json new file mode 100644 index 0000000..cb6ed0b --- /dev/null +++ b/customer_aqusition_0.json @@ -0,0 +1,19 @@ +[ + { + "id": 200, + "topic": "客户选择的标准化", + "title": "客户性质类别", + "prompt": "在客户选择的标准化上,请列出该公司的客户性质、类别,并判断是否一致? 如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 210, + "negative_next": -1 + + }, + { + "id": 210, + "topic": "客户选择的标准化", + "title": "统一部门", + "prompt": "在客户选择的标准化上,该公司是否由同一部门接触客户?如果有,请列出该部门?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": -1, + "negative_next": -1 + } +] \ No newline at end of file diff --git a/customer_aqusition_1.json b/customer_aqusition_1.json new file mode 100644 index 0000000..3405f16 --- /dev/null +++ b/customer_aqusition_1.json @@ -0,0 +1,43 @@ +[ + { + "id": 100, + "topic": "获客流程标准化", + "title": "销售阶段定义", + "prompt": "在获客流程的标准化上面,该公司是否有销售阶段定义?如果有,都有哪些阶段? 如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 110, + "negative_next": 130 + + }, + { + "id": 110, + "topic": "获客流程标准化", + "title": "阶段转化标准", + "prompt": "在获客流程的标准化上面,该公司是否有销售阶段的转化标准?如果有,请详细列出每个阶段的转化标准?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 120, + "negative_next": 130 + }, + { + "id": 120, + "topic": "获客流程标准化", + "title": "CRM每个阶段关键留存信息抽取", + "prompt": "在获客流程的标准化上面,该公司在每个销售阶段是否由CRM做关键留存信息抽取?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 130, + "negative_next": 130 + }, + { + "id": 130, + "topic": "获客流程标准化", + "title": "阶段目标", + "prompt": "在获客流程的标准化上面,该公司在每个销售阶段是否有阶段目标?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 140, + "negative_next": 140 + }, + { + "id": 140, + "topic": "获客流程标准化", + "title": "阶段活动", + "prompt": "在获客流程的标准化上面,该公司在每个销售阶段是否定义了阶段活动?如果有,请列出。如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": -1, + "negative_next": -1 + } +] \ No newline at end of file diff --git a/customer_aqusition_2.json b/customer_aqusition_2.json new file mode 100644 index 0000000..5cc37bb --- /dev/null +++ b/customer_aqusition_2.json @@ -0,0 +1,75 @@ +[ + { + "id": 300, + "topic": "工具模版标准化", + "title": "案例与样板客户", + "prompt": "该公司是否有成功案例和样板客户,以及相关的标准化案例文档?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 310, + "negative_next": 310 + + }, + { + "id": 310, + "topic": "工具模版标准化", + "title": "产品介绍与竞品分析", + "prompt": "在工具流程的标准化上面,该公司是否有自己的产品介绍以及竞品分析,包括但不限于分析竞品的优缺点,制定针对竞品的策略?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 320, + "negative_next": 320 + }, + { + "id": 320, + "topic": "工具模版标准化", + "title": "产品DEMO与优势证明", + "prompt": "在工具流程的标准化上面,该公司是否有产品的相关demo,并在demo中描述产品的优势?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 330, + "negative_next": 330 + }, + { + "id": 330, + "topic": "工具模版标准化", + "title": "各类标准模版材料", + "prompt": "在工具流程的标准化上面,该公司是否有至少一类模版文件,包括但不限于:POC环境要求清单、测试报告模版、招标参数模版、可研报告模板、立项报告模版?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 340, + "negative_next": 340 + }, + { + "id": 340, + "topic": "工具模版标准化", + "title": "模版更新机制", + "prompt": "在工具流程的标准化上面,该公司是否有定期更新模版以适应市场变化的机制?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 400, + "negative_next": 400 + }, + { + "id": 400, + "topic": "培训与指导", + "title": "产品知识与销售技巧", + "prompt": "在培训与指导上面,该公司是否有一些培训材料?这些培训内容里,是否明确讲述了产品优势?是否采用有效的培训方法,比如在销售价值传递方法或者技巧方面,做出应有的指导?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 410, + "negative_next": 410 + }, + { + "id": 500, + "topic": "市场活动与宣传资料", + "title": "标准化的宣传", + "prompt": "在市场活动与宣传资料上面,该公司是否有标准化的宣传材料,以及明确的宣传重点?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 510, + "negative_next": 510 + }, + { + "id": 510, + "topic": "市场活动与宣传资料", + "title": "客户群影响和反馈", + "prompt": "在市场活动与宣传资料上面,该公司是否有收集相关的市场反馈,比如这些活动是否对客户群起到了一定范围的影响,影响的重点是怎样的?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 600, + "negative_next": 600 + }, + { + "id": 600, + "topic": "产品优势总结", + "title": "产品优势传递方法", + "prompt": "在产品优势总结上面,该公司是否有系统化的方法来总结和传递产品优势,比如是否有效利用CRM系统来管理客户信息和销售流程,或者是否有记录和展现销售行动的机制,以确保销售策略的一致性和可追踪性?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": -1, + "negative_next": -1 + } +] \ No newline at end of file diff --git a/customer_aqusition_3.json b/customer_aqusition_3.json new file mode 100644 index 0000000..70876da --- /dev/null +++ b/customer_aqusition_3.json @@ -0,0 +1,59 @@ +[ + { + "id": 800, + "topic": "指标", + "title": "销售周期长度", + "prompt": "该公司销售指标是否定义了销售周期长度?如果有,是多少?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 810, + "negative_next": 810 + + }, + { + "id": 810, + "topic": "指标", + "title": "阶段转换率", + "prompt": "该公司销售指标是否定义了销售阶段转换率?如果有,请列出?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 820, + "negative_next": 820 + }, + { + "id": 820, + "topic": "指标", + "title": "客户触点数量", + "prompt": "该公司销售指标是否定义了客户触点数量?如果有,请列出。如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 830, + "negative_next": 830 + }, + { + "id": 830, + "topic": "指标", + "title": "赢单率", + "prompt": "该公司销售指标是否定义了赢单率?如果有,请列出。如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 840, + "negative_next": 840 + }, + { + "id": 840, + "topic": "指标", + "title": "客户信息管理一致性", + "prompt": "该公司销售指标是否确保客户信息管理一致性?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 850, + "negative_next": 850 + }, + { + "id": 850, + "topic": "指标", + "title": "销售活动一致性", + "prompt": "该公司销售指标是否确保销售活动一致性?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": 860, + "negative_next": 860 + }, + { + "id": 860, + "topic": "指标", + "title": "CRM填写频度和完整性", + "prompt": "该公司销售指标是否确保CRM填写频度和完整性?如果答案是肯定的,请在最后附加一句“正向处理”,如果是否定的或无法确定附加一句“负向处理”", + "affirm_next": -1, + "negative_next": -1 + } +] \ No newline at end of file diff --git a/output.xlsx b/output.xlsx new file mode 100644 index 0000000..87f2432 Binary files /dev/null and b/output.xlsx differ diff --git a/output_副本.xlsx b/output_副本.xlsx new file mode 100644 index 0000000..87f2432 Binary files /dev/null and b/output_副本.xlsx differ diff --git a/promptAgent.py b/promptAgent.py new file mode 100644 index 0000000..dcde4ef --- /dev/null +++ b/promptAgent.py @@ -0,0 +1,124 @@ +import json +import requests +from ExcelHelper import ExcelHelper + +def handle_response(data_dict): + message = data_dict.get("message") + if len(message) > 0: + content = message.get("content") + if len(content) > 0: + response_type = content.get("type") + if response_type == "text": + text = content.get("text", "No text provided") + return f"{text}" + + elif response_type == "image": + images = content.get("image", []) + image_urls = ", ".join(image.get("image_url") for image in images) + return f"{image_urls}" + + elif response_type == "code": + return f"{content.get('code')}" + + elif response_type == "execution_output": + return f"{content.get('content')}" + + elif response_type == "system_error": + return f"{content.get('content')}" + + elif response_type == "tool_calls": + return f"{data_dict['tool_calls']}" + + elif response_type == "browser_result": + content = json.loads(content.get("content", "{}")) + return f"Browser Result - Title: {content.get('title')} URL: {content.get('url')}" + +def send_message(assistant_id, access_token, prompt, conversation_id=None, file_list=None, meta_data=None): + url = "https://chatglm.cn/chatglm/assistant-api/v1/stream" + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" + } + data = { + "assistant_id": assistant_id, + "prompt": prompt, + } + + + if conversation_id: + data["conversation_id"] = conversation_id + if file_list: + data["file_list"] = file_list + if meta_data: + data["meta_data"] = meta_data + + with requests.post(url, json=data, headers=headers) as response: + if response.status_code == 200: + for line in response.iter_lines(): + if line: + decoded_line = line.decode('utf-8') + if decoded_line.startswith('data:'): + data_dict = json.loads(decoded_line[5:]) + output = handle_response(data_dict) + + + else: + return "Request failed", response.status_code + print(output) + return output + +def get_access_token(api_key, api_secret): + url = "https://chatglm.cn/chatglm/assistant-api/v1/get_token" + data = { + "api_key": api_key, + "api_secret": api_secret + } + + response = requests.post(url, json=data) + token_info = response.json() + return token_info['result']['access_token'] + +def process_nodes(process): + if (process == None): + return + item = process[0] + + while (item != None): + prompt = item['prompt'] + print(f'process node {item}') + result = send_message(assistant_id, access_token, prompt) + item['content'] = result + # if String result contains "继续处理" + if "正向处理" in result: + item = next((element for element in process if element['id'] == item["affirm_next"]), None) + else: + item = next((element for element in process if element['id'] == item["negative_next"]), None) + + for item in process: + if item.get('content') is None: + item['content'] = "" + + return process + + +# 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' +token = get_access_token(api_key, api_secret) + +assistant_id = "669e203f9752cb52401d2871" +access_token = token + +excelData = [] + +# load customer aqusition process +for index in range(0, 4): + file_path = f'customer_aqusition_{index}.json' + customer_aqusition_process = json.loads(open(file_path, 'r').read()) + customer_aqusition_process = process_nodes(customer_aqusition_process) + excelData.append(customer_aqusition_process) + + +# 创建 ExcelHelper 实例并生成 Excel 文件 +excel_helper = ExcelHelper(excelData) +excel_helper.create_excel('output.xlsx') \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a717bf1 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +openpyxl \ No newline at end of file