I_base_chat_pipeline.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # coding=utf-8
  2. """
  3. @project: maxkb
  4. @Author:虎
  5. @file: I_base_chat_pipeline.py
  6. @date:2024/1/9 17:25
  7. @desc:
  8. """
  9. import time
  10. from abc import abstractmethod
  11. from typing import Type
  12. import uuid_utils.compat as uuid
  13. from rest_framework import serializers
  14. from knowledge.models import Paragraph
  15. class ParagraphPipelineModel:
  16. def __init__(self, _id: str, document_id: str, knowledge_id: str, content: str, title: str, status: str,
  17. is_active: bool, comprehensive_score: float, similarity: float, knowledge_name: str,
  18. document_name: str,
  19. hit_handling_method: str, directly_return_similarity: float, knowledge_type, meta: dict = None):
  20. self.id = _id
  21. self.document_id = document_id
  22. self.knowledge_id = knowledge_id
  23. self.content = content
  24. self.title = title
  25. self.status = status,
  26. self.is_active = is_active
  27. self.comprehensive_score = comprehensive_score
  28. self.similarity = similarity
  29. self.knowledge_name = knowledge_name
  30. self.document_name = document_name
  31. self.hit_handling_method = hit_handling_method
  32. self.directly_return_similarity = directly_return_similarity
  33. self.meta = meta
  34. self.knowledge_type = knowledge_type
  35. def to_dict(self):
  36. return {
  37. 'id': self.id,
  38. 'document_id': self.document_id,
  39. 'knowledge_id': self.knowledge_id,
  40. 'content': self.content,
  41. 'title': self.title,
  42. 'status': self.status,
  43. 'is_active': self.is_active,
  44. 'comprehensive_score': self.comprehensive_score,
  45. 'similarity': self.similarity,
  46. 'knowledge_name': self.knowledge_name,
  47. 'document_name': self.document_name,
  48. 'knowledge_type': self.knowledge_type,
  49. 'meta': self.meta,
  50. }
  51. class builder:
  52. def __init__(self):
  53. self.similarity = None
  54. self.paragraph = {}
  55. self.comprehensive_score = None
  56. self.document_name = None
  57. self.knowledge_name = None
  58. self.knowledge_type = None
  59. self.hit_handling_method = None
  60. self.directly_return_similarity = 0.9
  61. self.meta = {}
  62. def add_paragraph(self, paragraph):
  63. if isinstance(paragraph, Paragraph):
  64. self.paragraph = {'id': paragraph.id,
  65. 'document_id': paragraph.document_id,
  66. 'knowledge_id': paragraph.knowledge_id,
  67. 'content': paragraph.content,
  68. 'title': paragraph.title,
  69. 'status': paragraph.status,
  70. 'is_active': paragraph.is_active,
  71. }
  72. else:
  73. self.paragraph = paragraph
  74. return self
  75. def add_knowledge_name(self, knowledge_name):
  76. self.knowledge_name = knowledge_name
  77. return self
  78. def add_knowledge_type(self, knowledge_type):
  79. self.knowledge_type = knowledge_type
  80. return self
  81. def add_document_name(self, document_name):
  82. self.document_name = document_name
  83. return self
  84. def add_hit_handling_method(self, hit_handling_method):
  85. self.hit_handling_method = hit_handling_method
  86. return self
  87. def add_directly_return_similarity(self, directly_return_similarity):
  88. self.directly_return_similarity = directly_return_similarity
  89. return self
  90. def add_comprehensive_score(self, comprehensive_score: float):
  91. self.comprehensive_score = comprehensive_score
  92. return self
  93. def add_similarity(self, similarity: float):
  94. self.similarity = similarity
  95. return self
  96. def add_meta(self, meta: dict):
  97. self.meta = meta
  98. return self
  99. def build(self):
  100. return ParagraphPipelineModel(str(self.paragraph.get('id')), str(self.paragraph.get('document_id')),
  101. str(self.paragraph.get('knowledge_id')),
  102. self.paragraph.get('content'), self.paragraph.get('title'),
  103. self.paragraph.get('status'),
  104. self.paragraph.get('is_active'),
  105. self.comprehensive_score, self.similarity, self.knowledge_name,
  106. self.document_name, self.hit_handling_method, self.directly_return_similarity,
  107. self.knowledge_type,
  108. self.meta)
  109. class IBaseChatPipelineStep:
  110. def __init__(self):
  111. # 当前步骤上下文,用于存储当前步骤信息
  112. self.context = {}
  113. self.status = 200
  114. self.err_message = ''
  115. @abstractmethod
  116. def get_step_serializer(self, manage) -> Type[serializers.Serializer]:
  117. pass
  118. def valid_args(self, manage):
  119. step_serializer_clazz = self.get_step_serializer(manage)
  120. step_serializer = step_serializer_clazz(data=manage.context)
  121. step_serializer.is_valid(raise_exception=True)
  122. self.context['step_args'] = step_serializer.data
  123. def run(self, manage):
  124. """
  125. :param manage: 步骤管理器
  126. :return: 执行结果
  127. """
  128. try:
  129. start_time = time.time()
  130. self.context['start_time'] = start_time
  131. # 校验参数,
  132. self.valid_args(manage)
  133. self._run(manage)
  134. self.context['run_time'] = time.time() - start_time
  135. except Exception as e:
  136. self.err_message = str(e)
  137. self.status = 500
  138. chat_record_id = manage.context.get('chat_record_id') or str(uuid.uuid7())
  139. manage.context['message_tokens'] = 0
  140. manage.context['answer_tokens'] = 0
  141. end_time = time.time()
  142. manage.context['run_time'] = end_time - (manage.context.get('start_time') or end_time)
  143. post_response_handler = manage.context.get('post_response_handler')
  144. post_response_handler.handler(manage.context.get('chat_id'), chat_record_id,
  145. manage.context.get('paragraph_list') or [],
  146. manage.context.get('problem_text'),
  147. str(e), manage, self, manage.context.get('padding_problem_text'),
  148. reasoning_content='')
  149. raise e
  150. def _run(self, manage):
  151. pass
  152. def execute(self, **kwargs):
  153. pass
  154. def get_details(self, manage, **kwargs):
  155. """
  156. 运行详情
  157. :return: 步骤详情
  158. """
  159. return None