llm_sensitivity.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # vim:fenc=utf-8
  4. import json
  5. from openai import OpenAI
  6. def request_llm_api(prompt, text):
  7. client = OpenAI(
  8. api_key='sk-c1b18099dadc4dd1b48239bdde184f6c',
  9. base_url="https://api.deepseek.com"
  10. )
  11. chat_completion = client.chat.completions.create(
  12. messages=[
  13. {
  14. "role": "user",
  15. "content": prompt + text,
  16. }
  17. ],
  18. model="deepseek-chat",
  19. temperature=0.2,
  20. response_format={"type": "json_object"}
  21. )
  22. response = chat_completion.choices[0].message.content
  23. return response
  24. def do_check_titles(text):
  25. """
  26. :param text:
  27. :return:
  28. """
  29. text_prompt = """
  30. 你是一位专业的微信公众号内容编辑,公众号的主要读者是中老年群体,主要内容来源为其它公众号发布文章。你需要对公众号待发布的文章标题进行可用性审核,判断其是否适合发布。不可用的情形包括以下7大类,每个大类情形中包括多个小类,以多级序号表示:
  31. 1.违规诱导、对抗平台审查规则
  32. 1.1 使用不完全或擦边的标题诱导用户点击
  33. 1.2 使用了生僻字/绕过字体等形式规避微信审核
  34. 2.违反国家法律法规
  35. 2.1 涉及国内政治敏感人物、敏感政治事件
  36. 3.有煽动、夸大、误导嫌疑
  37. 3.1 涉及国内外时局政治内容,尤其是与中国关系密切的国家的
  38. 3.2 在标题中使用内部、内参、解封等词语,将内容伪装成官方内部流出的
  39. 3.3 非官方通知或者公告,但标题假借官方名义或者暗喻为官方发布的
  40. 3.4 标题滥用“领导”、“主席”等头衔,容易造成曲解的
  41. 3.5 在标题中使用重大消息、通知、紧急提醒等,或以信息来源机密、看完即删来诱导用户的
  42. 3.6 在标题中使用过度夸张的词语,比如含有危害人身安全、恐吓侮辱、惊悚、极端内容,或者以命令式语气强迫用户阅读,煽动诱导的意味较强的
  43. 4.色情低俗内容
  44. 4.1 文字描述男女性隐私部位,或误导用户误以为是隐私部位
  45. 4.2 文字明示或暗示,容易让人联想到性、性行为、不正当性关系的
  46. 4.3 文字出现不正当婚恋观,如出轨、找小三、约炮等
  47. 5.宣扬封建迷信
  48. 5.1 标题捏造神迹或捏造所谓的特殊日子,用于接福、求福的
  49. 5.2 标题涉及民间迷信谚语、民俗,容易宣扬迷信思想的
  50. 6.不适合在非特定时间、向不特定群体发布的
  51. 6.1 具有较强新闻时效性的事件,尤其是包含“突发”、“刚刚”或特定日期的
  52. 6.2 面向特定范围群体(某个省市的居民、企事业单位员工等)的通知、宣传稿、新闻稿等
  53. 7.与中老年人阅读偏好不相关的
  54. 7.1 学习、影视等资源下载
  55. 7.2 其它与一般中老年人偏好不相关的情形
  56. 审核时,请特别注意以下事项:
  57. - 标题是否涉及政治敏感、色情低俗、封建迷信等内容。
  58. - 标题是否适合中老年群体的阅读偏好。
  59. - 标题是否具有时效性或面向特定群体,不适合广泛发布。例如:
  60. - 标题中包含“突破”、“刚刚”等词语时,需注意是否具有时效性(如年初、特定节日等)。
  61. - 标题中包含特定地名、群体名称(如省市区县旗盟乡镇)时,需注意是否面向特定群体,如果包含特定地域或人群但具有传播性和普适性则也可以发布。
  62. 审核结果分为2种:
  63. - 通过:标题未违反规则,适合发布。
  64. - 不通过:标题明确违反规则,不适合发布。
  65. 对于“不通过”的情形,请同时标注命中的规则大类序号(如 1、2、3 等)。
  66. 输出格式必须为 JSON 格式,示例如下:
  67. [
  68. {
  69. "title": "标题",
  70. "status": "不通过",
  71. "hit_rule": 5
  72. }
  73. ]
  74. 现在,请对以下文章标题的可用性进行判断:
  75. """
  76. return request_llm_api(text_prompt, text)
  77. def check_titles(titles, return_map=False):
  78. n_titles = len(titles)
  79. batch_size = 20
  80. n_batches = (n_titles + batch_size - 1) // batch_size
  81. json_data = []
  82. for i in range(0, n_batches):
  83. offset_begin = i * batch_size
  84. offset_end = min(offset_begin + batch_size, n_titles)
  85. current_batch = titles[offset_begin:offset_end]
  86. try:
  87. res = do_check_titles('\n'.join(current_batch))
  88. json_data = json.loads(res)
  89. except Exception as e:
  90. print(e)
  91. if isinstance(json_data, dict):
  92. json_data = [json_data]
  93. if not json_data:
  94. for title in current_batch:
  95. try:
  96. res = do_check_titles(title)
  97. json_res = json.loads(res)
  98. if isinstance(json_res, list):
  99. json_data.append(json_res[0])
  100. elif isinstance(json_res, dict):
  101. json_data.append(json_res)
  102. else:
  103. raise Exception('Invalid Response')
  104. except Exception as e:
  105. print(e)
  106. json_data.append({'title': title, 'status': '通过'})
  107. for item in json_data:
  108. if item['status'] == '不通过':
  109. try:
  110. item['hit_rule'] = int(float(item['hit_rule']))
  111. except Exception as e:
  112. item['hit_rule'] = 99
  113. # 保证不为0 避免LLM返回异常
  114. if item['hit_rule'] == 0:
  115. item['hit_rule'] = 99
  116. else:
  117. item['hit_rule'] = 0
  118. if return_map:
  119. result_map = {}
  120. for item in json_data:
  121. if item['title'] not in result_map:
  122. result_map[item['title']] = item
  123. # 安全起见,保留最后一次不通过的记录
  124. elif item['status'] == '不通过':
  125. result_map[item['title']] = item
  126. return result_map
  127. else:
  128. return json_data