123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import json
- from typing import TypedDict, Optional
- from openai import OpenAI
- from pydantic import BaseModel
- from utils.file_util import ExcelFile
- class Keyword(BaseModel):
- user_intent: str
- similar_reply: list[str]
- keywords: list[str]
- regular: list[str]
- class CallKeyword:
- def __init__(self):
- api_key = "sk-TL1U0f39NF5xOFnm8bB39e9b73E2474b9753C6BfCe95B5Db" # 计价测试
- # api_key = "sk-uN8GZmYwwu8bKeZyF605D111AcCa48738cD777B1332348D1" # 调试
- base_url = "https://newapi.gkscrm.com/v1"
- self.model = "gpt-4o"
- # self.model = "qwen2.5:7b"
- # base_url = "http://localhost:11434/v1"
- self._openai_client = OpenAI(api_key=api_key,
- base_url=base_url)
- self._file: ExcelFile
- # 评分方法
- def from_excel(self, file_path: str):
- # 获取表头索引
- self._file = ExcelFile(file_path)
- header_index = self._get_header_index()
- df_subset = self._file.file
- for index, row in df_subset.iterrows():
- chat_history = row.iloc[header_index["chat_history"]]
- unmatched = row.iloc[header_index["unmatched"]]
- result = self.single_record(chat_history, unmatched)
- self._file.new_value(index, "客户意图", result["user_intent"])
- self._file.new_value(index, "相似回复", json.dumps(result["similar_reply"], ensure_ascii=False))
- self._file.new_value(index, "关键词", json.dumps(result["keywords"], ensure_ascii=False))
- self._file.new_value(index, "正则表达式", json.dumps(result["regular"], ensure_ascii=False))
- def single_record(self, chat_history: str, unmatched: str):
- result = {}
- completion = self._openai_client.beta.chat.completions.parse(
- model=self.model,
- messages=[
- {"role": "system", "content": f"""# 任务介绍
- 公司在用程序巡检电话通话记录时,有些用户的回复内容没有被关键词库识别到,请根据以下通话记录,给出一些类似的回复,以及对关键词库的具体建议,非常感谢!
- # 输出要求
- 1. 用户意图:结合上下文分析未识别内容的根本意图,用户说这句话的背后真实目的是什么,结合上下文挖掘用户最深的意图,请不要停留在表面的意思。
- 2. 类似回复:首先应包含未识别的内容原文:{unmatched}。其次生成尽可能多的类似意图的回复。
- 2. 关键词库:从类似回复中抽取特征词,要求有两点:一是特征词应尽可能的准确,即要覆盖住此类问题,又要尽可能避免和其他语境相冲突。二是需要注重通用性,一些专有名词、人名、地名、产品名、公司名等需要排除在外。
- 3. 正则表达式:对关键词词进行解耦,用正则表达式进行表示,专注于主要内容,排除次要内容
- # 注意事项
- 1. 应贴近真实的外呼场景,用户的素质参差不齐,请避免使用任何浮夸的用词,避免使用高级词汇,避免使用任何的礼貌用语或敬语,适当的低素质些,请至少给出20条结果
- 2. 通话记录为录音转译,因此可能有错别字或音同字不同的情况(例如:借和接),请根据上下文分析后就成可能的错字错误
- 3. 正则关键词库和正则表达式中也应该考虑到音同字不同的情况,且避免使用匹配次数相关的语法如{0,2}"""},
- {
- "role": "user",
- "content": f"""# 通话记录
- {chat_history}
- # 其中未识别到的内容为:{unmatched}
- """
- }],
- response_format=Keyword
- # response_format={"type": "json_object"}
- )
- user_intent = json.loads(completion.choices[0].message.content)["user_intent"]
- similar_reply = json.loads(completion.choices[0].message.content)["similar_reply"]
- keywords = json.loads(completion.choices[0].message.content)["keywords"]
- regular = json.loads(completion.choices[0].message.content)["regular"]
- result["user_intent"] = user_intent
- result["similar_reply"] = similar_reply
- result["keywords"] = keywords
- result["regular"] = regular
- print(f"result: {result}")
- return result
- def _get_header_index(self):
- header_index = {}
- for index, column in enumerate(self._file.file.columns):
- if "通话记录" == column:
- header_index["chat_history"] = index
- elif "客户侧未命中" == column:
- header_index["unmatched"] = index
- elif "客户意图" == column:
- header_index["user_intent"] = index
- elif "相似回复" == column:
- header_index["similar_reply"] = index
- elif "关键词" == column:
- header_index["keywords"] = index
- elif "正则表达式" == column:
- header_index["regular"] = index
- return header_index
|