call_keyword.py 4.9 KB

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