kimi.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. """
  2. @author: luojunhui
  3. """
  4. import os
  5. import json
  6. from openai import OpenAI
  7. from applications.functions.chatgpt import OpenAIServer
  8. from applications.config import moon_shot
  9. from applications.config import deep_seek
  10. from applications.log import logging
  11. class KimiServer(object):
  12. """
  13. Kimi Server
  14. """
  15. @classmethod
  16. async def search_kimi_schedule(cls, params, safe_score):
  17. """
  18. 搜索阶段 kimi 操作
  19. :param params:
  20. :param safe_score:
  21. :return:
  22. """
  23. title = params['article_title'].split("@@")[-1]
  24. contents = params['article_text']
  25. trace_id = params['content_id']
  26. try:
  27. kimi_title = await cls.kimi_title(title, ai_model=moon_shot)
  28. # 判断kimi 标题是否安全
  29. title_score = await cls.get_kimi_title_safe_score(kimi_title, ai_model=moon_shot)
  30. kimi_green_title = None
  31. if int(title_score) > safe_score:
  32. kimi_green_title = await cls.make_kimi_title_safer(title, ai_model=moon_shot)
  33. logging(
  34. code="1005",
  35. info="generate_title",
  36. data={
  37. "ori_title": title,
  38. "kimi_title": kimi_title,
  39. "title_score": title_score,
  40. "new_kimi_title": kimi_green_title
  41. },
  42. trace_id=trace_id
  43. )
  44. kimi_title = kimi_green_title if kimi_green_title else kimi_title
  45. except Exception as e:
  46. logging(
  47. code="4002",
  48. info="kimi 挖掘失败--{}, 采用 gpt".format(e),
  49. trace_id=trace_id
  50. )
  51. gpt = OpenAIServer()
  52. kimi_title = gpt.gpt_mining(
  53. text=title,
  54. prompt=gpt.prompt_generate(
  55. prompt_type="title"
  56. )
  57. )
  58. kimi_title = kimi_title.replace("'", "").replace('"', "").replace("\\", "")
  59. try:
  60. kimi_info = await cls.kimi_mining(contents, ai_model=moon_shot)
  61. except Exception as e:
  62. logging(
  63. code="4002",
  64. info="kimi 挖掘失败--{}, 采用 gpt".format(e),
  65. trace_id=trace_id
  66. )
  67. gpt = OpenAIServer()
  68. kimi_info = gpt.gpt_mining(
  69. text=contents,
  70. prompt=gpt.prompt_generate(
  71. prompt_type="text"
  72. )
  73. )
  74. kimi_info = kimi_info.replace('```json', '').replace('```', '')
  75. kimi_info = json.loads(kimi_info)
  76. kimi_info['k_title'] = kimi_title
  77. kimi_info['ori_title'] = title
  78. logging(
  79. code="1005",
  80. info="kimi_mining",
  81. data=kimi_info,
  82. trace_id=trace_id
  83. )
  84. return kimi_info
  85. @classmethod
  86. async def ask_kimi(cls, question):
  87. """
  88. Ask Kimi for information
  89. :param question: tiny text
  90. :return: "{}"
  91. """
  92. single_title_prompt = """
  93. 我会给你一个视频标题,需要你帮我用你所学的知识来帮我分析出以下信息,信息我都写到 json 里面了
  94. {
  95. "key_words": [], # 返回三个关键词
  96. "search_keys": [], # 标题可能的搜索关键词,返回 3 个
  97. "extra_keys": [], # 关心这个视频的用户还会关心哪些关键词, 返回 3 个
  98. "theme": 标题的主题, 用一个词概括
  99. }
  100. 只需要返回一个 json,key 和上面的一样,
  101. 我给你的标题是:
  102. """
  103. client = OpenAI(
  104. api_key='sk-5DqYCa88kche6nwIWjLE1p4oMm8nXrR9kQMKbBolNAWERu7q',
  105. base_url="https://api.moonshot.cn/v1"
  106. )
  107. chat_completion = client.chat.completions.create(
  108. messages=[
  109. {
  110. "role": "user",
  111. "content": single_title_prompt + question,
  112. }
  113. ],
  114. model="moonshot-v1-8k",
  115. )
  116. response = chat_completion.choices[0].message.content.replace('```json', '').replace('```', '')
  117. try:
  118. response = json.loads(response)
  119. return response
  120. except:
  121. return {}
  122. @classmethod
  123. async def ask_kimi_and_save_to_local(cls, info_tuple):
  124. """
  125. save file to local
  126. :return:
  127. """
  128. title, trace_id, save_path = info_tuple[0], info_tuple[1], info_tuple[2]
  129. if os.path.exists(save_path):
  130. logging(
  131. code="2001",
  132. info="该 video 信息已经挖掘完成---{}".format(title),
  133. function="ask_kimi_and_save_to_local",
  134. trace_id=trace_id,
  135. )
  136. else:
  137. os.makedirs(os.path.dirname(save_path), exist_ok=True)
  138. if not title:
  139. result = {}
  140. else:
  141. result = await cls.ask_kimi(title)
  142. logging(
  143. code="2001",
  144. info="kimi-result",
  145. data=result,
  146. trace_id=trace_id,
  147. function="ask_kimi_and_save_to_local"
  148. )
  149. with open(save_path, "w", encoding="utf-8") as f:
  150. f.write(json.dumps(result, ensure_ascii=False))
  151. @classmethod
  152. async def kimi_title(cls, ori_title, ai_model):
  153. """
  154. prompt + kimi + ori_title generate new title
  155. :param ori_title:
  156. :param ai_model:
  157. :return:
  158. """
  159. single_title_prompt = """
  160. 请将以上标题改写成适合小程序点击和传播的小程序标题,小程序标题的写作规范如下,请学习后进行小程序标题的编写。直接输出最终的小程序标题
  161. 小程序标题写作规范:
  162. 1.要点前置:将最重要的信息放在标题的最前面,以快速吸引读者的注意力。例如,“5月一辈子同学,三辈子亲,送给我的老同学,听哭无数人!”中的“5月”和“一辈子同学,三辈子亲”都是重要的信息点。
  163. 2.激发情绪:使用能够触动人心的语言,激发读者的情感共鸣。如“只剩两人同学聚会,看后感动落泪。”使用“感动落泪”激发读者的同情和怀旧情绪。
  164. 3.使用数字和特殊符号:数字可以提供具体性,而特殊符号如“🔴”、“😄”、“🔥”等可以吸引视觉注意力,增加点击率。
  165. 4.悬念和好奇心:创建悬念或提出问题,激发读者的好奇心。例如,“太神奇了!长江水位下降,重庆出现惊奇一幕!”中的“惊奇一幕”就是一个悬念。
  166. 5.名人效应:如果内容与知名人士相关,提及他们的名字可以增加标题的吸引力。
  167. 6.社会价值观:触及读者的文化和社会价值观,如家庭、友情、国家荣誉等。
  168. 7.标点符号的运用:使用感叹号、问号等标点来增强语气和情感表达。
  169. 8.直接的语言:使用直白、口语化的语言,易于理解,如“狗屁股,笑死我了!”。
  170. 9.热点人物或事件:提及当前的热点人物或事件,利用热点效应吸引读者。
  171. 10.字数适中:保持标题在10-20个字之间,既不过长也不过短,确保信息的完整性和吸引力。
  172. 11.适当的紧迫感:使用“最新”、“首次”、“紧急”等词汇,创造一种紧迫感,促使读者立即行动。
  173. 12.情感或价值诉求:使用如“感动”、“泪目”、“经典”等词汇,直接与读者的情感或价值观产生共鸣。
  174. 避免误导:确保标题准确反映内容,避免夸大或误导读者。
  175. """
  176. client = OpenAI(
  177. api_key=ai_model['api_key'],
  178. base_url=ai_model['base_url']
  179. )
  180. chat_completion = client.chat.completions.create(
  181. messages=[
  182. {
  183. "role": "user",
  184. "content": ori_title + "\n" + single_title_prompt,
  185. }
  186. ],
  187. model=ai_model['model'],
  188. )
  189. response = chat_completion.choices[0].message.content
  190. return response.split("\n")[0]
  191. @classmethod
  192. async def kimi_mining(cls, text, ai_model):
  193. """
  194. 通过文章来挖掘出有效的信息
  195. :param text:
  196. :param ai_model:
  197. :return:
  198. """
  199. text_prompt = """
  200. 请从我给你的文章中挖掘出以下信息并且返回如下结果。
  201. 你返回的结果是一个 json, 格式如下:
  202. {
  203. "content_keys": [] # 同时提供三个与文章内容高度相关的关键词,这些关键词将用于网络上搜索相关视频内容,
  204. "content_title": 一个总结性的标题,该标题应简洁并能够反映文章的主要内容
  205. }
  206. 你需要处理的文本是:
  207. """
  208. client = OpenAI(
  209. api_key=ai_model['api_key'],
  210. base_url=ai_model['base_url']
  211. )
  212. chat_completion = client.chat.completions.create(
  213. messages=[
  214. {
  215. "role": "user",
  216. "content": text_prompt + text,
  217. }
  218. ],
  219. model=ai_model['model'],
  220. response_format={"type": "json_object"}
  221. )
  222. content = json.loads(chat_completion.choices[0].message.content)
  223. return content
  224. @classmethod
  225. async def get_kimi_title_safe_score(cls, kimi_title, ai_model):
  226. """
  227. 获取kimi_title的安全分数
  228. """
  229. prompt = f"""
  230. 请你学习一下内容规范,以下标题可能会违反了某条内容规范。请你对标题做一个内容风险评级,1-10分,等级越高内容违规风险越大。
  231. 请直接输出内容风险评级的分数,不要输出你的理由、分析等内容。
  232. 输出:
  233. 只需要输出危险分级分数,不要输出任何其他内容。
  234. 内容规范为:
  235. 4.2 色俗内容
  236. 4.2.1 散布淫秽、色情内容,包括但不限于招嫖、寻找一夜情、性伴侣等。
  237. 4.2.2 发布有色情意味的情色文字、情色视频、情色漫画等内容。
  238. 4.2.3 以投稿/爆料等形式描述约炮经历、性交体验、偷情、涉隐私部位偷拍等伤风败俗的话题内容。
  239. 4.2.4 以低俗的配图引诱用户阅读文章、关注微信公众号。包含性撩拨、性挑逗画面;疑似女性性高潮/性虐场面;偷拍的沐浴/更衣/如厕/亲热等私密画面;女性故意露出敏感部位 (纯裸露的胸、生殖器官)以及敏感部位未打码的真人写真/艺术摄影等。
  240. 4.2.5 文内以低俗类的动图或引导图,诱导用户点击进而跳转至另一篇图文页或关注某个公众号。
  241. 4.2.6 文章主要描述PUA撩妹、撩汉等相关话题,且引导用户关注公众号/加个人微信号/加群。
  242. 4.11 煽动、夸大、误导类内容 平台鼓励创作者提供准确、清晰、能体现文章内容主旨的标题,不允许通过标题噱头诱导用户点击或误导用户。
  243. 包括但不限于以下情况:
  244. 4.11.1 标题含有危害人身安全、恐吓侮辱、惊悚、极端内容,或者以命令式语气强迫用户阅读。
  245. 4.11.2 标题无依据夸大事件严重程度、紧急程度、受影响面以及事件引发的情绪。
  246. 4.11.3 标题以浮夸的描述,反常识强调某种食物/行为对人体健康的影响,煽动人群要/不要去做某行为。
  247. 4.11.4 非官方通知或者公告,但标题假借官方名义煽动获取流量,或以信息来源机密、看完即删来诱导用户。
  248. 4.11.5 标题故意隐藏关键信息,或无中生有部分信息,给用户造成误导。
  249. 4.12 违反国家法律法规禁止的内容
  250. (1)违反宪法确定的基本原则的;
  251. (2)危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;
  252. (3)损害国家荣誉和利益的;
  253. (4)煽动民族仇恨、民族歧视,破坏民族团结的;
  254. (5)破坏国家宗教政策,宣扬邪教和封建迷信的;
  255. (6)散布不实信息,扰乱社会秩序,破坏社会稳定的;
  256. (7)散布淫秽、色情、赌博、暴力、恐怖或者教唆犯罪的;
  257. (8)侮辱或者诽谤他人,侵害他人合法权益的;
  258. (9)煽动非法集会、结社、游行、示威、聚众扰乱社会秩序;
  259. (10)以非法民间组织名义活动的;
  260. (11)不符合《即时通信工具公众信息服务发展管理暂行规定》及遵守法律法规、社会主义制度、国家利益、公民合法利益、公共秩序、社会道德风尚和信息真实性等“七条底线”要求的;
  261. (12)含有法律、行政法规禁止的其他内容的。
  262. 输入的标题是: {kimi_title}
  263. """
  264. client = OpenAI(
  265. api_key=ai_model['api_key'],
  266. base_url=ai_model['base_url']
  267. )
  268. chat_completion = client.chat.completions.create(
  269. messages=[
  270. {
  271. "role": "user",
  272. "content": prompt
  273. }
  274. ],
  275. model=ai_model['model']
  276. )
  277. response = chat_completion.choices[0].message.content
  278. return response
  279. @classmethod
  280. async def make_kimi_title_safer(cls, ori_title, ai_model):
  281. """
  282. 安全化 kimi title
  283. """
  284. prompt = """
  285. 以下每行为一个文章的标题,请用尽量平实的语言对以上标题进行改写,保持在10~15字左右,请注意:
  286. 1. 不要虚构或改变标题的含义。
  287. 2. 不要用笃定的语气描述存疑的可能性,不要将表述可能性的问句改为肯定句。
  288. 直接输出改写后的标题列表。
  289. 在改写完成后,再输出一次,在改写的标题前增加和标题情感、语气匹配的特殊符号,如:“🔴”、“😄”、“🔥”、“😨”等等
  290. 输出:
  291. 输出结果是Dict, 格式为:
  292. {
  293. "title_v1": 请填写第一次输出的标题,
  294. "title_v2": 请填写第二次输出的标题
  295. }
  296. 输入的标题是:
  297. """
  298. client = OpenAI(
  299. api_key=ai_model['api_key'],
  300. base_url=ai_model['base_url']
  301. )
  302. chat_completion = client.chat.completions.create(
  303. messages=[
  304. {
  305. "role": "user",
  306. "content": prompt + ori_title,
  307. }
  308. ],
  309. model=ai_model['model'],
  310. response_format={"type": "json_object"}
  311. )
  312. response = chat_completion.choices[0].message.content
  313. response_json = json.loads(response)
  314. safer_title = response_json["title_v2"]
  315. return safer_title