code: # Constants
  from llama_index.indices.postprocessor import MetadataReplacementPostProcessor, SentenceTransformerRerank
  from llama_index.prompts import ChatPromptTemplate
  from llama_index.llms import OpenAI, ChatMessage, MessageRole
  from llama_index import Document, ServiceContext, VectorStoreIndex
  from llama_index.node_parser import SentenceWindowNodeParser
  import os
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
  MODEL = "gpt-4-1106-preview"
  TEMPERATURE = 0.1
  EMBED_MODEL = "local:BAAI/bge-small-zh-v1.5"
  WINDOW_SIZE = 10
  FILE_PATH = "./data/chat.txt"
  RERANK_MODEL = "BAAI/bge-reranker-base"
  TOP_N = 5
  SIMILARITY_TOP_K = 10
  
  
  class Chatbot:
      def __init__(self):
          self.node_parser = self.initialize_node_parser()
          self.llm = OpenAI(model=MODEL, temperature=TEMPERATURE)
          self.service_context = ServiceContext.from_defaults(
              llm=self.llm,
              embed_model=EMBED_MODEL,
              node_parser=self.node_parser,
          )
          self.engine = self.initialize_engine()
  
      @staticmethod
      def initialize_node_parser():
          def split(text):
              return text.split('\n')
  
          return SentenceWindowNodeParser.from_defaults(
              window_size=WINDOW_SIZE,
              window_metadata_key="window",
              original_text_metadata_key="original_text",
              sentence_splitter=split,
          )
  
      def initialize_engine(self):
          text = self.read_text(FILE_PATH)
          sentence_index = VectorStoreIndex.from_documents(
              [Document(text=text)], service_context=self.service_context
          )
  
          postproc = MetadataReplacementPostProcessor(
              target_metadata_key="window")
          rerank = SentenceTransformerRerank(top_n=TOP_N, model=RERANK_MODEL)
  
          wechat_bot_msgs = [
              ChatMessage(
                  role=MessageRole.SYSTEM,
                  content=(
                      "现在你将扮演我的克隆聊天机器人和朋友对话，请使用我的微信历史聊天记录作为参考，模仿这种特定的聊天风格和语气，以及句子回答的长度。注意使用类似的词汇、语句结构和表达方式、emoji的实用习惯。由于这个是微信聊天，请你说话不要太长太啰嗦。目标是使对话感觉自然、连贯，让他以为是在和我本人对话。"
                  ),
              ),
              ChatMessage(
                  role=MessageRole.USER,
                  content=(
                      "我的相关微信历史聊天记录如下\n"
                      "---------------------\n"
                      "{context_str}\n"
                      "---------------------\n"
                      "请你模仿以上的聊天风格，完成以下对话，你的回答只包含回复\n"
                      "{query_str}\n"
                      "我的回复："
                  )
              ),
          ]
          wechat_bot_template = ChatPromptTemplate(wechat_bot_msgs)
  
          engine = sentence_index.as_query_engine(
              similarity_top_k=SIMILARITY_TOP_K, node_postprocessors=[
                  postproc, rerank]
          )
          engine.update_prompts(
              {"response_synthesizer:text_qa_template": wechat_bot_template})
  
          return engine
  
      @staticmethod
      def read_text(file_path):
          with open(file_path) as f:
              return f.read()
  
      def chat(self, input_text):
          query = f"{input_text}"
          response = self.engine.query(query)
          return response.response
  
  
  def main():
      bot = Chatbot()
      print("Chatbot initialized. Start chatting!")
      history = "朋友："
      while True:
          user_input = input("You: ")
          if user_input.lower() in ['exit', 'quit']:
              break
          response = bot.chat(history + user_input)
          history += user_input + "\n" + "我：" + response + "\n" + "朋友："
          print("Bot:", response)
  
  
  if __name__ == "__main__":
      main()
  
apis: llama_index.ServiceContext.from_defaults llama_index.node_parser.SentenceWindowNodeParser.from_defaults llama_index.llms.OpenAI llama_index.llms.ChatMessage llama_index.prompts.ChatPromptTemplate llama_index.indices.postprocessor.MetadataReplacementPostProcessor llama_index.indices.postprocessor.SentenceTransformerRerank llama_index.Document
extract_api: [((744, 788), 'llama_index.llms.OpenAI', 'OpenAI', ([], {'model': 'MODEL', 'temperature': 'TEMPERATURE'}), '(model=MODEL, temperature=TEMPERATURE)\n', (750, 788), False, 'from llama_index.llms import OpenAI, ChatMessage, MessageRole\n'), ((820, 921), 'llama_index.ServiceContext.from_defaults', 'ServiceContext.from_defaults', ([], {'llm': 'self.llm', 'embed_model': 'EMBED_MODEL', 'node_parser': 'self.node_parser'}), '(llm=self.llm, embed_model=EMBED_MODEL,\n    node_parser=self.node_parser)\n', (848, 921), False, 'from llama_index import Document, ServiceContext, VectorStoreIndex\n'), ((1142, 1313), 'llama_index.node_parser.SentenceWindowNodeParser.from_defaults', 'SentenceWindowNodeParser.from_defaults', ([], {'window_size': 'WINDOW_SIZE', 'window_metadata_key': '"""window"""', 'original_text_metadata_key': '"""original_text"""', 'sentence_splitter': 'split'}), "(window_size=WINDOW_SIZE,\n    window_metadata_key='window', original_text_metadata_key=\n    'original_text', sentence_splitter=split)\n", (1180, 1313), False, 'from llama_index.node_parser import SentenceWindowNodeParser\n'), ((1599, 1661), 'llama_index.indices.postprocessor.MetadataReplacementPostProcessor', 'MetadataReplacementPostProcessor', ([], {'target_metadata_key': '"""window"""'}), "(target_metadata_key='window')\n", (1631, 1661), False, 'from llama_index.indices.postprocessor import MetadataReplacementPostProcessor, SentenceTransformerRerank\n'), ((1692, 1750), 'llama_index.indices.postprocessor.SentenceTransformerRerank', 'SentenceTransformerRerank', ([], {'top_n': 'TOP_N', 'model': 'RERANK_MODEL'}), '(top_n=TOP_N, model=RERANK_MODEL)\n', (1717, 1750), False, 'from llama_index.indices.postprocessor import MetadataReplacementPostProcessor, SentenceTransformerRerank\n'), ((2522, 2557), 'llama_index.prompts.ChatPromptTemplate', 'ChatPromptTemplate', (['wechat_bot_msgs'], {}), '(wechat_bot_msgs)\n', (2540, 2557), False, 'from llama_index.prompts import ChatPromptTemplate\n'), ((1792, 1994), 'llama_index.llms.ChatMessage', 'ChatMessage', ([], {'role': 'MessageRole.SYSTEM', 'content': '"""现在你将扮演我的克隆聊天机器人和朋友对话，请使用我的微信历史聊天记录作为参考，模仿这种特定的聊天风格和语气，以及句子回答的长度。注意使用类似的词汇、语句结构和表达方式、emoji的实用习惯。由于这个是微信聊天，请你说话不要太长太啰嗦。目标是使对话感觉自然、连贯，让他以为是在和我本人对话。"""'}), "(role=MessageRole.SYSTEM, content=\n    '现在你将扮演我的克隆聊天机器人和朋友对话，请使用我的微信历史聊天记录作为参考，模仿这种特定的聊天风格和语气，以及句子回答的长度。注意使用类似的词汇、语句结构和表达方式、emoji的实用习惯。由于这个是微信聊天，请你说话不要太长太啰嗦。目标是使对话感觉自然、连贯，让他以为是在和我本人对话。'\n    )\n", (1803, 1994), False, 'from llama_index.llms import OpenAI, ChatMessage, MessageRole\n'), ((2085, 2264), 'llama_index.llms.ChatMessage', 'ChatMessage', ([], {'role': 'MessageRole.USER', 'content': '"""我的相关微信历史聊天记录如下\n---------------------\n{context_str}\n---------------------\n请你模仿以上的聊天风格，完成以下对话，你的回答只包含回复\n{query_str}\n我的回复："""'}), '(role=MessageRole.USER, content=\n    """我的相关微信历史聊天记录如下\n---------------------\n{context_str}\n---------------------\n请你模仿以上的聊天风格，完成以下对话，你的回答只包含回复\n{query_str}\n我的回复："""\n    )\n', (2096, 2264), False, 'from llama_index.llms import OpenAI, ChatMessage, MessageRole\n'), ((1510, 1529), 'llama_index.Document', 'Document', ([], {'text': 'text'}), '(text=text)\n', (1518, 1529), False, 'from llama_index import Document, ServiceContext, VectorStoreIndex\n')]