Browse Source

第一次提交全部代码

yulongyan_citu 10 months ago
parent
commit
03a7943168
42 changed files with 2275 additions and 0 deletions
  1. 3 0
      .idea/.gitignore
  2. 21 0
      .idea/inspectionProfiles/Project_Default.xml
  3. 6 0
      .idea/inspectionProfiles/profiles_settings.xml
  4. 7 0
      .idea/misc.xml
  5. 8 0
      .idea/modules.xml
  6. 8 0
      .idea/rag_project.iml
  7. 6 0
      .idea/vcs.xml
  8. 178 0
      app.py
  9. 19 0
      chat/file_chat.py
  10. 23 0
      database/chormadb.py
  11. 135 0
      database/create_db.py
  12. 27 0
      embedding/embedding.py
  13. 151 0
      graph/graph_retrieval.py
  14. 91 0
      knowledge_db/个人住房贷款.txt
  15. 42 0
      knowledge_db/全产品专业积分.txt
  16. 24 0
      knowledge_db/全产品积分产品汇总.txt
  17. 48 0
      knowledge_db/员工全产品积分.txt
  18. 42 0
      knowledge_db/大中小微企业.txt
  19. 20 0
      knowledge_db/学术论文基本模版.txt
  20. 144 0
      knowledge_db/客户经理专业积分.txt
  21. 32 0
      knowledge_db/客户经理专业积分手工记录.txt
  22. 32 0
      knowledge_db/客户经理专业积分项.txt
  23. 54 0
      knowledge_db/客户经理专业系统计算积分项(含手工补录).txt
  24. 52 0
      knowledge_db/客户经理全产品专业积分对比.txt
  25. 40 0
      knowledge_db/对公客户经理考核期积分.txt
  26. 7 0
      knowledge_db/小额贷款.txt
  27. 84 0
      knowledge_db/工商银行企业手机银行.txt
  28. 44 0
      knowledge_db/支行全产品积分.txt
  29. 34 0
      knowledge_db/支行对公客户经理考核期积分汇总.txt
  30. 124 0
      knowledge_db/数字人民币.txt
  31. 107 0
      knowledge_db/融e借.txt
  32. 44 0
      knowledge_db/部室全产品积分.txt
  33. 36 0
      llm/llm.py
  34. 414 0
      qa_chain/Chat_QA_chain_self.py
  35. 34 0
      qa_chain/get_vectordb.py
  36. 12 0
      qa_chain/result.py
  37. 122 0
      requirements.txt
  38. BIN
      vector_db/chroma/chroma.sqlite3
  39. BIN
      vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/data_level0.bin
  40. BIN
      vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/header.bin
  41. BIN
      vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/length.bin
  42. 0 0
      vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/link_lists.bin

+ 3 - 0
.idea/.gitignore

@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml

+ 21 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,21 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="ignoredPackages">
+        <value>
+          <list size="1">
+            <item index="0" class="java.lang.String" itemvalue="psycopg2" />
+          </list>
+        </value>
+      </option>
+    </inspection_tool>
+    <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <option name="ignoredErrors">
+        <list>
+          <option value="N806" />
+        </list>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 7 - 0
.idea/misc.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (RAG)" project-jdk-type="Python SDK" />
+  <component name="PyCharmProfessionalAdvertiser">
+    <option name="shown" value="true" />
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/RAG_project.iml" filepath="$PROJECT_DIR$/.idea/RAG_project.iml" />
+    </modules>
+  </component>
+</project>

+ 8 - 0
.idea/rag_project.iml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="Python 3.9 (RAG)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 178 - 0
app.py

@@ -0,0 +1,178 @@
+import os
+from fastapi import  Request
+from fastapi.responses import JSONResponse
+from langchain_community.document_loaders import TextLoader
+from langchain_text_splitters import RecursiveCharacterTextSplitter
+from chat.file_chat import allowed_file, UPLOAD_FOLDER
+from qa_chain.Chat_QA_chain_self import Chat_QA_chain_self  # 替换为你的模块名
+from qa_chain.get_vectordb import get_vectordb
+from qa_chain.result import success,failed
+from fastapi.middleware.cors import CORSMiddleware
+from fastapi import FastAPI, File, UploadFile
+
+
+app = FastAPI()
+app.add_middleware(
+    CORSMiddleware,
+    # 允许跨域的源列表,例如 ["http://www.example.org"] 等等,["*"] 表示允许任何源
+    allow_origins=["*"],
+    # 跨域请求是否支持 cookie,默认是 False,如果为 True,allow_origins 必须为具体的源,不可以是 ["*"]
+    allow_credentials=False,
+    # 允许跨域请求的 HTTP 方法列表,默认是 ["GET"]
+    allow_methods=["GET",'POST','PUT','PATCH','DELETE','HEAD','OPTIONS'],
+    # 允许跨域请求的 HTTP 请求头列表,默认是 [],可以使用 ["*"] 表示允许所有的请求头
+    # 当然 Accept、Accept-Language、Content-Language 以及 Content-Type 总之被允许的
+    allow_headers=["*"],
+    # 可以被浏览器访问的响应头, 默认是 [],一般很少指定
+    # expose_headers=["*"]
+    # 设定浏览器缓存 CORS 响应的最长时间,单位是秒。默认为 600,一般也很少指定
+    # max_age=1000
+)
+
+# 初始化你的Chat_QA_chain_self实例
+chat_qa_chain = Chat_QA_chain_self(file_path="./knowledge_db", persist_path="./vector_db/chroma")
+
+@app.post('/clear/history')
+async def clear_history():
+    try:
+        chat_qa_chain.clear_chat_history()
+        res = success({"message": "Chat history has been cleared."}, "success")
+        return JSONResponse(res)
+    except Exception as e:
+        res = failed({}, {"error": f"{e}"})
+        return JSONResponse(res)
+
+@app.post('/view/history')
+async def view_history():
+    try:
+        history = chat_qa_chain.get_chat_history()
+        formatted_history = []
+        for item in history:
+            formatted_item = {
+                "Question": item[0],
+                "Answer": item[1]
+            }
+            formatted_history.append(formatted_item)
+        res = success({"history": formatted_history}, "success")
+        return JSONResponse(res)
+    except Exception as e:
+        res = failed({}, {"error": f"{e}"})
+        return JSONResponse(res)
+
+# @app.post('/ask')
+# async def ask(request: Request):
+#     try:
+#         data = await request.json()
+#         question = data.get('question')
+#         chat_history = data.get('chat_history', [])
+#         response = chat_qa_chain.build_chain(question,chat_history)
+#         # response = chain.invoke({"question": question, "chat_history": chat_history})
+#         # 添加新的聊天记录到历史记录中
+#         chat_qa_chain.add_to_chat_history(question, response)
+#         res = success({"response": response}, "success")
+#         return JSONResponse(res)
+#     except Exception as e:
+#         res = failed({}, {"error": f"{e}"})
+#         return JSONResponse(res)
+
+@app.post('/ask')
+async def ask(request: Request):
+    try:
+        data = await request.json()
+        question = data.get('question')
+        chat_history = data.get('chat_history', [])
+        if question:
+            if '你好' in question:
+                response = '你好!请提出相应问题'
+            else:
+                chain = chat_qa_chain.build_chain()
+                response = chain.invoke({"question": question, "chat_history": chat_history})
+        # 添加新的聊天记录到历史记录中
+        chat_qa_chain.add_to_chat_history(question, response)
+        res = success({"response": response}, "success")
+        return JSONResponse(res)
+    except Exception as e:
+        res = failed({}, {"error": f"{e}"})
+        return JSONResponse(res)
+
+@app.post('/ask/rag')
+async def ask_rag(request: Request):
+    try:
+        data = await request.json()
+        question = data.get('question')
+        chat_history = data.get('chat_history', [])
+        chain = chat_qa_chain.build_rag_chain()
+        response = chain.invoke({"question": question, "chat_history": chat_history})
+        # 添加新的聊天记录到历史记录中
+        chat_qa_chain.add_to_chat_history(question, response)
+        res = success({"response": response}, "success")
+        return JSONResponse(res)
+    except Exception as e:
+        res = failed({}, {"error": f"{e}"})
+        return JSONResponse(res)
+
+# build_text_chain
+@app.post('/ask/unstructure/rag')
+async def ask_rag(request: Request):
+    try:
+        data = await request.json()
+        question = data.get('question')
+        chat_history = data.get('chat_history', [])
+        chain = chat_qa_chain.build_text_chain()
+        response = chain.invoke({"question": question, "chat_history": chat_history})
+        # 添加新的聊天记录到历史记录中
+        chat_qa_chain.add_to_chat_history(question, response)
+        res = success({"response": response}, "success")
+        return JSONResponse(res)
+    except Exception as e:
+        res = failed({}, {"error": f"{e}"})
+        return JSONResponse(res)
+
+@app.post('/file/list')
+async def file_list():
+    try:
+        file_path="./knowledge_db"
+        # 检查文件夹路径是否存在
+        if not os.path.isdir(file_path):
+            res = failed({}, {"error": "Folder does not exist"})
+            return JSONResponse(res)
+
+        # 获取文件夹中的文件列表
+        files = os.listdir(file_path)
+        res = success({"files": files}, "success")
+        return JSONResponse(res)
+
+    except Exception as e:
+        res = failed({}, {"error": f"{e}"})
+        return JSONResponse(res)
+
+
+@app.post("/file/upload")
+async def upload_file(file: UploadFile = File(...)):
+    try:
+        if not allowed_file(file.filename):
+            return JSONResponse(failed({}, {"error": "File type not allowed"}))
+
+        # Ensure the upload folder exists
+        os.makedirs(UPLOAD_FOLDER, exist_ok=True)
+
+        file_path = os.path.join(UPLOAD_FOLDER, file.filename)
+        with open(file_path, "wb") as buffer:
+            buffer.write(await file.read())
+
+        data = []
+        loader = TextLoader(f'{UPLOAD_FOLDER}/{file.filename}', encoding='utf8')
+        data.extend(loader.load())
+        text_splitter = RecursiveCharacterTextSplitter(
+            chunk_size=500, chunk_overlap=150)
+        split_docs = text_splitter.split_documents(data)
+        vector_db = get_vectordb(file_path="./knowledge_db", persist_path="./vector_db/chroma",embedding="m3e")
+        vector_db.add_documents(split_docs)
+
+        return JSONResponse(success({"response": "File uploaded successfully"}, "success"))
+    except Exception as e:
+        return JSONResponse(failed({}, {"error": str(e)}))
+
+if __name__ == '__main__':
+    import uvicorn
+    uvicorn.run(app, host='0.0.0.0', port=3004)

+ 19 - 0
chat/file_chat.py

@@ -0,0 +1,19 @@
+import logging
+# import chroma
+import os
+
+logger = logging.getLogger(__name__)
+
+# 配置文件上传的目录
+UPLOAD_FOLDER = "./knowledge_db"
+if not os.path.exists(UPLOAD_FOLDER):
+    os.makedirs(UPLOAD_FOLDER)
+
+# 允许的文件扩展名
+ALLOWED_EXTENSIONS = {'txt', 'pdf', 'docx'}
+# 检查扩展名是否允许
+def allowed_file(filename):
+    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
+
+
+

+ 23 - 0
database/chormadb.py

@@ -0,0 +1,23 @@
+import chromadb
+from embedding.embedding import get_embedding
+from langchain.text_splitter import RecursiveCharacterTextSplitter
+from database.create_db import load_txt_from_dir
+
+DEFAULT_DB_PATH = r"../knowledge_db"
+DEFAULT_PERSIST_PATH = '../vector_db/chroma'
+# 创建一个客户端
+chroma_client = chromadb.Client()
+# 创建一个集合/传统数据库中的一张表
+embeddings = get_embedding(embedding='m3e')
+collection = chroma_client.get_or_create_collection(name="my_collection",embedding_function=embeddings)
+
+all_docs = load_txt_from_dir(DEFAULT_DB_PATH)
+
+# 切分文档
+text_splitter = RecursiveCharacterTextSplitter(
+    chunk_size=500, chunk_overlap=150)
+split_docs = text_splitter.split_documents(all_docs)
+
+
+
+

+ 135 - 0
database/create_db.py

@@ -0,0 +1,135 @@
+import sys
+import os
+from embedding.embedding import get_embedding
+from langchain_community.document_loaders import PyMuPDFLoader,Docx2txtLoader,TextLoader,DirectoryLoader
+from langchain_chroma import Chroma
+from langchain.text_splitter import RecursiveCharacterTextSplitter
+sys.path.append(os.path.dirname(os.path.dirname(__file__)))
+# 首先实现基本配置
+DEFAULT_DB_PATH = r"../knowledge_db"
+DEFAULT_PERSIST_PATH = '../vector_db/chroma'
+
+# 目录下保存不同的文件
+# def get_files(dir_path):
+#     file_list = []
+#     for filepath, dirnames, filenames in os.walk(dir_path):
+#         for filename in filenames:
+#             file_list.append(os.path.join(filepath, filename))
+#     return file_list
+
+def get_files(dir_path):
+    file_list = []
+    for filepath, dirnames, filenames in os.walk(dir_path):
+        for filename in filenames:
+            file_list.append(os.path.join(filepath, filename))
+    return file_list
+
+
+def file_loader(file_list, loaders):
+    for file in file_list:
+        file_type = file.split('.')[-1]
+        if file_type == 'pdf':
+            loaders.append(PyMuPDFLoader(file))
+        elif file_type == 'txt':
+            l = DirectoryLoader(file, glob="**/*.txt", loader_cls=TextLoader)
+            # loaders.append(TextLoader(file))
+            loaders.append(l)
+        elif file_type == 'docx':
+            loaders.append(Docx2txtLoader(file))
+    return loaders
+
+
+def load_txt_from_dir(directory_path):
+    data = []
+    for filename in os.listdir(directory_path):
+        if filename.endswith(".txt"):
+            # print(filename)
+            loader = TextLoader(f'{directory_path}/{filename}',encoding='utf8')
+            data.extend(loader.load())
+    return data
+
+def create_db_info(files=DEFAULT_DB_PATH, embeddings="openai", persist_directory=DEFAULT_PERSIST_PATH):
+    if embeddings in ['openai', 'm3e', 'zhipuai']:
+        vectordb = create_db(files, persist_directory, embeddings)
+    return ""
+
+
+def create_db(files=DEFAULT_DB_PATH, persist_directory=DEFAULT_PERSIST_PATH, embeddings="m3e"):
+    """
+    该函数用于加载 PDF 文件,切分文档,生成文档的嵌入向量,创建向量数据库。
+
+    参数:
+    file: 存放文件的路径。
+    embeddings: 用于生产 Embedding 的模型
+
+    返回:
+    vectordb: 创建的数据库。
+    """
+    if files is None:
+        return "can't load empty file"
+
+    # directory_path = files
+    # file_list = get_files(directory_path)
+
+    # 加载文件
+    loaders = []
+    # loaders = file_loader(file_list, loaders)
+    # # 加载文档
+    # all_docs = []
+    # for loader in loaders:
+    #     docs = loader.load()
+    #     all_docs.extend(docs)
+
+    all_docs = load_txt_from_dir(files)
+
+    # 切分文档
+    text_splitter = RecursiveCharacterTextSplitter(
+        chunk_size=500, chunk_overlap=150)
+    split_docs = text_splitter.split_documents(all_docs)
+
+    if isinstance(embeddings, str):
+        embeddings = get_embedding(embedding=embeddings)
+
+    # 定义持久化路径
+    persist_directory = DEFAULT_PERSIST_PATH
+
+    # 加载数据库
+    vectordb = Chroma.from_documents(
+        documents=split_docs,
+        embedding=embeddings,
+        persist_directory=persist_directory  # 允许我们将persist_directory目录保存到磁盘上
+    )
+    vectordb.persist()
+    return vectordb
+
+
+def presit_knowledge_db(vectordb):
+    """
+    该函数用于持久化向量数据库。
+
+    参数:
+    vectordb: 要持久化的向量数据库。
+    """
+    vectordb.persist()
+
+
+def load_knowledge_db(path, embeddings):
+    """
+    该函数用于加载向量数据库。
+
+    参数:
+    path: 要加载的向量数据库路径。
+    embeddings: 向量数据库使用的 embedding 模型。
+
+    返回:
+    vectordb: 加载的数据库。
+    """
+    vectordb = Chroma(
+        persist_directory=path,
+        embedding_function=embeddings
+    )
+    return vectordb
+
+
+if __name__ == "__main__":
+    create_db(embeddings="m3e")

+ 27 - 0
embedding/embedding.py

@@ -0,0 +1,27 @@
+from langchain_community.embeddings import DashScopeEmbeddings
+from langchain_community.embeddings  import OpenAIEmbeddings
+import os
+
+
+def get_embedding(embedding: str):
+
+
+    # if embedding == "m3e":
+        # embedding = OpenAIEmbeddings(
+        #     model="m3e",
+        #     api_key="sk-ZcS0IOaaR5FxEXAO2aEb9a37A7Cd41Fd9a70C74a854c20Af",
+        #     base_url="http://192.168.3.233:3001/v1",
+        #     headers={'content-type': 'application/json'}
+        # )
+        # try:
+        #     response = embedding.client.create(
+        #         model="m3e",
+        #         input=["Sample text for embedding"]
+        #     )
+        #     print("Response:", response)
+    return DashScopeEmbeddings(dashscope_api_key="sk-86d4622141d74e9a8d7c38ee873c4d91")
+        # except Exception as e:
+        #     print(f"Error: {e}")
+        #     raise
+    # else:
+    #     raise ValueError(f"embedding {embedding} not support ")

+ 151 - 0
graph/graph_retrieval.py

@@ -0,0 +1,151 @@
+#!/usr/bin/python
+# -*- coding: <utf-8> -*-
+import json
+import os
+from langchain_community.vectorstores.neo4j_vector import remove_lucene_chars
+from langchain.prompts import (
+        PromptTemplate,
+)
+from typing import List
+from langchain.output_parsers import ResponseSchema,StructuredOutputParser
+from langchain_community.graphs import Neo4jGraph
+from langchain.schema import AIMessage
+
+
+def connect():
+    os.environ["NEO4J_URI"] = "bolt://192.168.3.91:27687"
+    os.environ["NEO4J_USERNAME"] = "neo4j"
+    os.environ["NEO4J_PASSWORD"] = "123456"
+
+    graph = Neo4jGraph()
+    return graph
+
+def extract_question_info(question:str,llm)->List[str]:
+    # 定义要接收的响应模式
+    response_schemas = [
+        ResponseSchema(name="entity", description="All the person, organization, or business entities that"""
+                                                  "appear in the text")
+    ]
+    # 创建输出解析器
+    output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
+    # 获取格式指示
+    format_instructions = output_parser.get_format_instructions()
+    # 根据模板创建提示,同时在提示中加入输出解析器的说明
+    prompt_template = PromptTemplate(
+        template="Answer the user query.\n{format_instructions}\n{query}\n",
+        input_variables=["query"],
+        partial_variables={"format_instructions": format_instructions},
+    )
+    # 根据提示准备模型的输入
+    inputData = prompt_template.format(query=question)
+
+    # 获取模型的输出
+    output = llm.invoke(inputData)
+
+    # 去掉 JSON 内容前后的 ```json 和 ``` 标记
+    if isinstance(output, AIMessage):
+        # 从 AIMessage 对象中提取内容
+        json_content = output.content.strip('```json').strip('```').strip()
+    else:
+        raise TypeError("Expected an AIMessage object")
+
+    # 解析 JSON 内容
+    data = json.loads(json_content)
+
+    # 获取 names 列表
+    names = data.get('entity',[])
+    # 用户问题的实体输出
+    # print(names)
+
+    if isinstance(names, str):
+        names = [names]
+    return names
+
+def generate_full_text_query(input: str) -> str:
+    """
+    Generate a full-text search query for a given input string.
+
+    This function constructs a query string suitable for a full-text search.
+    It processes the input string by splitting it into words and appending a
+    similarity threshold (~2 changed characters) to each word, then combines
+    them using the AND operator. Useful for mapping entities from user questions
+    to database values, and allows for some misspelings.
+    """
+    full_text_query = ""
+    words = [el for el in remove_lucene_chars(input).split() if el]
+    for word in words[:-1]:
+        full_text_query += f" {word}~2 AND"
+    full_text_query += f" {words[-1]}~2"
+    return full_text_query.strip()
+
+# Fulltext index query
+def structured_retriever(llm,graph,question: str) -> str:
+    """
+    Collects the neighborhood of entities mentioned
+    in the question
+    """
+    result = ""
+    # 前面提取到的实体
+    names = extract_question_info(question,llm)
+    for entity in names:
+        # 图谱中匹配到的节点限制返回相似度不得低于0.5
+        # query = generate_full_text_query(entity)
+        # print(f"Query:{query}")
+        response = graph.query(
+            """CALL db.index.fulltext.queryNodes('dataops', $query, {limit:2})
+            YIELD node, score
+            WHERE score >= 0.5
+            // score 判断
+            CALL {
+              WITH node
+              MATCH (node)-[r]->(neighbor)
+              RETURN node.name + ' - ' + type(r) + ' -> ' + neighbor.name AS output
+              UNION ALL
+              WITH node
+              MATCH (node)<-[r]-(neighbor)
+              RETURN neighbor.name + ' - ' + type(r) + ' -> ' +  node.name AS output
+            }
+            RETURN output LIMIT 50
+            """,
+            {"query": entity},
+        )
+        result += "\n".join([el['output'] for el in response])
+    return result
+
+# 非结构化的全文索引
+def text_structured_retriever(llm,graph,question: str) -> str:
+    """
+    Collects the neighborhood of entities mentioned
+    in the question
+    """
+    result = ""
+    # 前面提取到的实体
+    names = extract_question_info(question,llm)
+    for entity in names:
+        # 图谱中匹配到的节点限制返回相似度不得低于0.5
+        # query = generate_full_text_query(entity)
+        # print(f"Query:{query}")
+        response = graph.query(
+            """CALL db.index.fulltext.queryNodes('unstructure', $query, {limit:4})
+            YIELD node, score
+            WHERE score >= 0.2
+            // score 判断
+            CALL {
+              WITH node
+              MATCH (node)-[r]->(neighbor)
+              RETURN node.name + ' - ' + type(r) + ' -> ' + neighbor.name AS output
+              UNION ALL
+              WITH node
+              MATCH (node)<-[r]-(neighbor)
+              RETURN neighbor.name + ' - ' + type(r) + ' -> ' +  node.name AS output
+            }
+            RETURN output LIMIT 50
+            """,
+            {"query": entity},
+        )
+        result += "\n".join([el['output'] for el in response])
+    return result
+
+
+
+

+ 91 - 0
knowledge_db/个人住房贷款.txt

@@ -0,0 +1,91 @@
+中国工商银行(工行)的个人住房贷款主要是指向借款人发放的,用于购买房地产开发企业依法建造、销售(预售)住房的贷款。适用于有购房需求的个人客户。
+
+一手个人住房贷款的适用对象主要包括以下几类:
+
+1. **中国公民**:有合法身份的中国公民,包括在境内工作的外籍人员,且在工行开立了相关账户。
+
+2. **购房者**:购买在中国境内合法开发和销售的一手住房,例如新建商品房。
+
+3. **满足资信要求的借款人**:需要提供稳定的收入证明和良好的信用记录,证明有能力按时还款。
+
+4. **符合相关政策要求的人群**:如首次购房者、改善性需求购房者等,具体政策可能因地区和时点而异。
+
+5. **年龄符合要求**:借款人年龄一般需在18岁到65岁之间,某些地区可能会有不同的规定。
+
+申请时,借款人通常需要提供身份证明、收入证明、购房合同等相关材料。建议前往工行官网或咨询当地网点获取最新的贷款政策和具体要求。
+
+中国工商银行(工行)个人住房贷款的还款方式一般包括以下几种:
+
+1. **等额本息**:每月偿还相同金额的金额,包括本金和利息。适合希望每个月还款金额相对稳定的借款人。
+
+2. **等额本金**:每月偿还固定金额的本金,加上当期的利息。前期还款压力相对较大,但总利息支出较少,适合希望节省利息的借款人。
+
+3. **一次性还本付息**:在贷款到期时一次性偿还本金和利息,适合短期内没有还款压力的借款人。
+
+4. **按月付息到期还本**:每月只支付利息,到期时一次性偿还本金。
+
+具体的还款方式和条件可能会根据个人情况、贷款类型及银行政策等有所不同,建议在申请贷款前与工行工作人员咨询确认,选择适合自己的还款方式。
+
+在中国工商银行(工行)手机银行申请一手个人住房贷款,通常可以按照以下步骤进行:
+
+1. **下载并安装工行手机银行**:如果尚未安装,您可以在应用商店搜索“工行”下载并安装。
+
+2. **登录账户**:打开手机银行应用,使用您的工行账户进行登录。如果您还没有注册,可以先进行注册。
+
+3. **进入贷款申请界面**:
+   - 在主界面上,找到并点击“贷款”或“我的贷款”选项。
+   - 在贷款页面中,寻找“个人住房贷款”或相应的链接。
+
+4. **选择贷款类型**:选择“个人住房贷款”或“一手房贷款”选项,以便获取相关信息。
+
+5. **填写申请信息**:根据系统提示,填写个人信息、贷款金额、贷款期限、购房信息等相关申请内容。
+
+6. **提交资料**:上传所需的申请资料,如身份证、购房合同、收入证明等相关文件。系统会提示您需要准备哪些材料。
+
+7. **确认信息**:仔细核对您填写的所有信息和上传的文件,确保准确无误。
+
+8. **提交申请**:确认无误后,提交您的贷款申请。
+
+9. **等待审核**:提交后,工行会对您的申请进行审核,您可以在手机银行上查看申请状态。
+
+10. **签约与放款**:审核通过后,工行会与您联系进行贷款合同签署,签约完成后,贷款金额将会按照协议发放。
+
+### 注意事项
+- 不同特点的房屋和个人财务状况可能会影响贷款的审核结果。
+- 建议提前准备相关文件,以加快申请过程。
+- 在申请过程中,如有疑问,可以直接拨打工行客服热线进行咨询。
+
+请注意,不同时间和地区可能会有政策变化,建议根据实际情况查看工行官方网站或联系银行客服获取最新信息。
+
+
+### 摘要
+中国工商银行于2023年9月7日公告,将从2023年9月25日起对存量首套个人住房贷款利率进行调整,以响应国家政策并支持客户。这一调整适用于符合特定条件的个人住房贷款,旨在为客户提供更低的利率和便利的操作方式。具体的调整规则、申请方式和相关服务将通过线上及线下渠道向客户实施与公告说明。
+
+### 关键要点
+- 自2023年9月25日起,中国工商银行将启动存量首套个人住房贷款利率的协商调整。
+- 调整适用于贷款发放时间在2023年8月31日及之前的贷款,且为购买住宅的个人住房贷款。
+- 只有符合首套住房贷款条件的客户才能进行利率调整,包括还清不良贷款的情况。
+- 调整后最低利率可降至原合同利率政策下限,具体依据贷款发放时间和市场利率情况。
+- 客户可通过手机银行一键申请利率调整,原贷款服务行也提供协助。
+- 针对“二套转首套”的客户,需提出申请并经过审核才能调整利率。
+- 所有的利率调整不收取任何费用,客户需警惕外部误导信息。
+
+
+要判断您的贷款是否符合存量个人住房贷款利率调整的条件,请参考以下几点:
+
+1. **贷款发放时间**:您的贷款发放时间或合同签订时间必须在2023年8月31日(含当日)之前。
+
+2. **贷款用途**:贷款必须是用于购买住宅的商业性个人住房贷款,包括普通纯商业性个人住房贷款和公积金组合贷款中的商业性个人住房贷款。
+
+3. **首套住房贷款**:您的贷款必须为首套个人住房贷款,具体包括以下情形:
+   - 原贷款发放时满足所在城市首套房贷利率标准的房贷。
+   - 房屋购买时家庭在当地没有其他成套住房,但因当地政府政策导致该套住房按照二套房贷利率标准办理房贷,现在当地政府执行“认房不认贷”政策的。
+   - 房屋购买时不是家庭在当地唯一成套住房,但后期通过交易等方式出售了其他成套住房,本住房成为家庭在当地唯一成套住房且当地政府执行“认房不认贷”政策的。
+   - 其他满足所在城市首套房贷利率标准的存量房贷。
+
+4. **贷款状态**:原则上,您的贷款应为按月足额偿还本息的正常类个人住房贷款。如果贷款当前处于不良状态,需在归还积欠本金及利息后再申请调整利率。
+
+如果您的贷款符合以上条件,您可以申请利率调整。如有疑问,建议联系您的贷款服务行进行确认。
+
+
+

+ 42 - 0
knowledge_db/全产品专业积分.txt

@@ -0,0 +1,42 @@
+全产品专业积分是一个数据库表,这个数据库表的英文名称为 t_raw_general_products_professional_volume。
+全产品专业积分包含了以下的字段内容:
+ 专业  
+ 额度合计  
+ 分行负担额度  
+ 专业负担额度  
+ 超序时进度  
+ 剩余可用额度  
+ 当月变动备注  
+ 延迟发放金额  
+ 主要计价产品  
+ uuid 全局唯一标识  
+ 删除标识  
+ 数据修改时间  
+ 数据创建时间  
+ 租户标识  
+ 月累计计价  
+ 比上月  
+ 当年累计计价  
+ 月份  
+ 积分类别  
+
+为了方便识别全产品专业积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 专业的英文名称是major  
+ 额度合计的英文名称是total_limit  
+ 分行负担额度的英文名称是branch_burden_quota  
+ 专业负担额度的英文名称是professional_burden_limit  
+ 超序时进度的英文名称是overtime_progress  
+ 剩余可用额度的英文名称是remaining_available_limit  
+ 当月变动备注的英文名称是current_month_tag  
+ 延迟发放金额的英文名称是delayed_payment_amount  
+ 主要计价产品的英文名称是main_priced_products  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  
+ 月累计计价的英文名称是month_pricing  
+ 比上月的英文名称是than_last_month  
+ 当年累计计价的英文名称是year_total_score  
+ 月份的英文名称是month  
+ 积分类别的英文名称是score_category  

+ 24 - 0
knowledge_db/全产品积分产品汇总.txt

@@ -0,0 +1,24 @@
+全产品积分产品汇总是一个数据库表,这个数据库表的英文名称为 t_raw_full_product_score_product_statistics。
+全产品积分产品汇总包含了以下的字段内容:
+ 月份  
+ 产品  
+ 大类别  
+ 金额  
+ 积分类别  
+ uuid 全局唯一标识  
+ 删除标识  
+ 数据修改时间  
+ 数据创建时间  
+ 租户标识  
+
+为了方便识别客户经理专业积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 月份的英文名称是month  
+ 产品的英文名称是product_name  
+ 大类别的英文名称是large_class  
+ 金额的英文名称是amount  
+ 积分类别的英文名称是score_category  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  

+ 48 - 0
knowledge_db/员工全产品积分.txt

@@ -0,0 +1,48 @@
+员工全产品积分是一个数据库表,这个数据库表的英文名称为t_raw_employee_full_product_score。
+员工全产品积分包含了以下的字段内容:
+ 月份  
+ 姓名1  
+ 统一认证号  
+ 全产品计价积分  
+ 网点号  
+ uuid 全局唯一标识  
+ 删除标识  
+ 数据修改时间  
+ 数据创建时间  
+ 租户标识  
+ 人员编码  
+ 主要计奖产品/原因  
+ 上月累计计价  
+ 比上月  
+ 机构编号  
+ 延迟发放金额  
+ 待发放奖金  
+ 积分类别  
+ 上级机构编码  
+ 上级机构名称  
+ 机构名称  
+ 岗位名称  
+
+为了方便识别员工全产品积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 月份的英文名称是month  
+ 姓名1的英文名称是employee_name  
+ 统一认证号的英文名称是unified_certification_number  
+ 全产品计价积分的英文名称是full_product_pricing_score  
+ 网点号的英文名称是network_no  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  
+ 人员编码的英文名称是personnel_code  
+ 主要计奖产品/原因的英文名称是reward_products_reasons  
+ 上月累计计价的英文名称是last_month_pricing  
+ 比上月的英文名称是than_last_month  
+ 机构编号的英文名称是organization_no  
+ 延迟发放金额的英文名称是delayed_payment_amount  
+ 待发放奖金的英文名称是wait_send_bonus  
+ 积分类别的英文名称是score_category  
+ 上级机构编码的英文名称是parent_organization_no  
+ 上级机构名称的英文名称是parent_organization_name  
+ 机构名称的英文名称是organization_name  
+ 岗位名称的英文名称是post_name  

+ 42 - 0
knowledge_db/大中小微企业.txt

@@ -0,0 +1,42 @@
+大中小微型企业划分标准是什么
+、划分方法简介
+
+ 
+
+(一)主要方法。
+
+ 
+
+现行办法选取从业人员、营业收入、资产总额等指标或替代指标,并结合行业特点制定具体划分标准,将在我国境内依法设立的各种组织形式的法人企业或单位的规模划分为大型、中型、小型和微型。个体工商户参照该办法进行划分。
+
+ 
+
+(二)行业范围。
+
+ 
+
+现行办法适用的行业范围 3 包括:农、林、牧、渔业,采矿业,制造业,电力、热力、燃气及水生产和供应业,建筑业,批发和零售业,交通运输、仓储和邮政业, 住宿和餐饮业,信息传输、软件和信息技术服务业,房地产业,租赁和商务服务业, 科学研究和技术服务业,水利、环境和公共设施管理业,居民服务、修理和其他服务业,文化、体育和娱乐业等 15 个行业门类以及社会工作行业大类。
+
+ 
+
+(三)应用领域。
+
+ 
+
+相较于国家统计局2003 年制定的暂行办法,现行办法不仅设置了“微型企业”,使得层次划分更细致,而且行业范围更全面、指标选取更合理、阈值设置更符合当前实际。现行办法的出台,为按企业规模统计以及对中小企业(特别是微型企业)在财税支持、融资促进、创业扶持、创新支持、市场开拓、服务措施、权益保护等全方面促进奠定了基础。
+
+ 
+
+(四)注意事项。
+
+ 
+
+在实际判断企业(单位)的规模时,需注意两点:
+
+ 
+
+1. 企业划分指标以现行统计制度为准。其中:(1)从业人员,是指期末从业人员数,没有期末从业人员数的,采用全年平均人员数代替。(2)营业收入, 工业、建筑业、限额以上批发和零售业、限额以上住宿和餐饮业以及其他设置主营业务收入指标的行业,采用主营业务收入;限额以下批发与零售业企业采用商品销售额代替;限额以下住宿与餐饮业企业采用营业额代替;农、林、牧、渔业企业采用营业总收入代替;其他未设置主营业务收入的行业,采用营业收入指标。(3)资产总额,采用资产总计代替。
+
+ 
+
+2. 指标条件的满足情况略有不同。其中:大型、中型和小型企业,须同时满足所列指标的下限,否则下划一档;微型企业只须满足所列指标中的一项即可。

+ 20 - 0
knowledge_db/学术论文基本模版.txt

@@ -0,0 +1,20 @@
+学术论文的基本模板
+
+论文题目
+
+学术论文的基本格式通常包括以下部分:
+
+封面:包括论文标题、作者姓名、所属机构、提交日期等。
+摘要:简要概括论文的主要内容和研究方法,通常不超过300字。
+关键词:列出5-8个与论文主题密切相关的关键词。
+中图分类号:
+
+引言:介绍研究背景、研究问题和研究目的,引出本文的研究内容。
+文献综述:对相关领域的研究成果进行总结和分析,阐述本文的研究意义和创新点。
+
+材料与方法:详细描述实验材料、实验方法和技术手段。
+结果与讨论:呈现实验结果,对其进行解释和讨论,阐述研究结果的意义。
+结论:总结全文,强调本文的主要发现和创新点。
+致谢:感谢给予帮助和支持的个人和机构。
+
+参考文献:按照规范的格式列出所有引用的文献。

+ 144 - 0
knowledge_db/客户经理专业积分.txt

@@ -0,0 +1,144 @@
+客户经理专业积分是一个数据库表,这个数据库表的英文名称为 t_raw_account_managers_professional_score。
+客户经理专业积分包含了以下的字段内容:
+  所属机构,
+  客户经理,
+  统一认证号,
+  积分时间,
+  A,
+  B,
+  C,
+  D,
+  E,
+  F,
+  G,
+  H,
+  I,
+  J,
+  K,
+  L,
+  M,
+  N,
+  O,
+  P,
+  Q,
+  R,
+  S,
+  T,
+  U,
+  V,
+  W,
+  X,
+  Y,
+  Z,
+  AA,
+  AB,
+  AC,
+  AD,
+  AE,
+  AF,
+  AG,
+  AH,
+  AI,
+  AJ,
+  AK,
+  AL,
+  AM,
+  AN,
+  AO,
+  AP,
+  AQ,
+  AR,
+  AS,
+  AT,
+  AU,
+  AV,
+  AW,
+  AX,
+  AY,
+  AZ,
+  BA,
+  uuid全局唯一标识,
+  删除标识,
+  数据修改时间,
+  数据创建时间,
+  租户标识,
+  积分时间,
+  BB,
+  BC,
+  BF,
+  BE,
+  BG,
+  BH,
+  BD
+
+为了方便识别客户经理专业积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 所属机构的英文名称是organization  
+ 客户经理的英文名称是customer_manage  
+ 统一认证号的英文名称是unified_certification_number  
+ 积分时间的英文名称是score_date  
+ A的英文名称是a  
+ B的英文名称是b  
+ C的英文名称是c  
+ D的英文名称是d  
+ E的英文名称是e  
+ F的英文名称是f  
+ G的英文名称是g  
+ H的英文名称是h  
+ I的英文名称是i  
+ J的英文名称是j  
+ K的英文名称是k  
+ L的英文名称是l  
+ M的英文名称是m  
+ N的英文名称是n  
+ O的英文名称是o  
+ P的英文名称是p  
+ Q的英文名称是q  
+ R的英文名称是r  
+ S的英文名称是s  
+ T的英文名称是t  
+ U的英文名称是u  
+ V的英文名称是v  
+ W的英文名称是w  
+ X的英文名称是x  
+ Y的英文名称是y  
+ Z的英文名称是z  
+ AA的英文名称是aa  
+ AB的英文名称是ab  
+ AC的英文名称是ac  
+ AD的英文名称是ad  
+ AE的英文名称是ae  
+ AF的英文名称是af  
+ AG的英文名称是ag  
+ AH的英文名称是ah  
+ AI的英文名称是ai  
+ AJ的英文名称是aj  
+ AK的英文名称是ak  
+ AL的英文名称是al  
+ AM的英文名称是am  
+ AN的英文名称是an  
+ AO的英文名称是ao  
+ AP的英文名称是ap  
+ AQ的英文名称是aq  
+ AR的英文名称是ar  
+ AS的英文名称是as  
+ AT的英文名称是at  
+ AU的英文名称是au  
+ AV的英文名称是av  
+ AW的英文名称是aw  
+ AX的英文名称是ax  
+ AY的英文名称是ay  
+ AZ的英文名称是az  
+ BA的英文名称是ba  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  
+ 数据月份的英文名称是date_title  
+ BB的英文名称是bb  
+ BC的英文名称是bc  
+ BF的英文名称是bf  
+ BE的英文名称是be  
+ BG的英文名称是bg  
+ BH的英文名称是bh  
+ BD的英文名称是bd  

+ 32 - 0
knowledge_db/客户经理专业积分手工记录.txt

@@ -0,0 +1,32 @@
+客户经理专业积分手工记录是一个数据库表,这个数据库表的英文名称为 t_raw_account_managers_professional_manual_score
+客户经理专业积分手工记录包含了以下的字段内容:
+ 申请调整部门
+ 支行
+ 网点
+ 客户经理
+ 统一认证号
+ 调整项目内容
+ 调整产品数量
+ 调整奖励金额
+ uuid 全局唯一标识
+ 删除标识
+ 数据修改时间
+ 数据创建时间
+ 租户标识
+ 月份
+
+为了方便识别客户经理专业积分手工记录数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 申请调整部门的英文名称是applying_department_adjustment
+ 支行的英文名称是sub_branch
+ 网点的英文名称是network
+ 客户经理的英文名称是customer_manage
+ 统一认证号的英文名称是unified_certification_number
+ 调整项目内容的英文名称是adjusting_project_content
+ 调整产品数量的英文名称是adjusting_product_num
+ 调整奖励金额的英文名称是adjusting_reward_amount
+ uuid 全局唯一标识的英文名称是sys_uuid
+ 删除标识的英文名称是sys_deleted
+ 数据修改时间的英文名称是sys_update_time
+ 数据创建时间的英文名称是sys_create_time
+ 租户标识的英文名称是sys_tenant_code
+ 月份的英文名称是month

+ 32 - 0
knowledge_db/客户经理专业积分项.txt

@@ -0,0 +1,32 @@
+客户经理专业积分项是一个数据库表,这个数据库表的英文名称为 t_raw_account_managers_professional_score_vertical。
+客户经理专业积分项包含了以下的字段内容:
+CREATE TABLE t_raw_account_managers_professional_score_vertical (
+  所属机构,
+  客户经理,
+  统一认证号,
+  积分时间,
+  指标类型,
+  指标值,
+  日期,
+  uuid 全局唯一标识,
+  删除标识,
+  数据修改时间,
+  数据创建时间,
+  租户标识,
+  人员编码
+
+为了方便识别客户经理专业积分项数据表的内容,对这个数据表的字段定义了一些别名如下:
+以下是将您提供的英文名称转换为所需结构的中文表述:
+ 所属机构的英文名称是organization  
+ 客户经理的英文名称是customer_manage  
+ 统一认证号的英文名称是unified_certification_number  
+ 积分时间的英文名称是score_date  
+ 指标类型的英文名称是index_type  
+ 指标值的英文名称是index_val  
+ 日期的英文名称是date  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  
+ 人员编码的英文名称是personnel_code  

+ 54 - 0
knowledge_db/客户经理专业系统计算积分项(含手工补录).txt

@@ -0,0 +1,54 @@
+客户经理专业系统计算积分项(含手工补录)是一个数据库表,这个数据库表的英文名称为t_raw_account_managers_professiona_calculatel_score_vertical。
+客户经理专业系统计算积分项(含手工补录)包含了以下的字段内容:
+ 所属机构  
+ 客户经理  
+ 统一认证号  
+ 积分时间  
+ 指标类型  
+ 指标值  
+ 日期  
+ 人员编码  
+ uuid 全局唯一标识  
+ 删除标识  
+ 数据修改时间  
+ 数据创建时间  
+ 租户标识  
+ 计价单位  
+ 计价标准  
+ 大类别  
+ 指标数量  
+ 手工指标数量  
+ 分行负担比例  
+ 分行负担额度  
+ 状态  
+ 积分类别  
+ 积分操作月份  
+ 上级机构编码  
+ 支行名称  
+
+为了方便识别客户经理专业系统计算积分项(含手工补录)数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 所属机构的英文名称是organization  
+ 客户经理的英文名称是customer_manage  
+ 统一认证号的英文名称是unified_certification_number  
+ 积分时间的英文名称是score_date  
+ 指标类型的英文名称是index_type  
+ 指标值的英文名称是index_val  
+ 日期的英文名称是date  
+ 人员编码的英文名称是personnel_code  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  
+ 计价单位的英文名称是pricing_unit  
+ 计价标准的英文名称是pricing_standard  
+ 大类别的英文名称是large_class  
+ 指标数量的英文名称是metric_num  
+ 手工指标数量的英文名称是manual_metric_num  
+ 分行负担比例的英文名称是branch_burden_ratio  
+ 分行负担额度的英文名称是branch_burden_quota  
+ 状态的英文名称是state  
+ 积分类别的英文名称是score_category  
+ 积分操作月份的英文名称是operation_month  
+ 上级机构编码的英文名称是parent_organization_no  
+ 支行名称的英文名称是branch_name  

+ 52 - 0
knowledge_db/客户经理全产品专业积分对比.txt

@@ -0,0 +1,52 @@
+客户经理全产品专业积分对比是一个数据库表,这个数据库表的英文名称为t_raw_employee_full_product_major_score_contrast。
+客户经理全产品专业积分对比包含了以下的字段内容:
+ 姓名1  
+ 人员编码  
+ 机构名称  
+ 机构编号  
+ 积分时间  
+ uuid 全局唯一标识  
+ 删除标识  
+ 数据修改时间  
+ 数据创建时间  
+ 租户标识  
+ 手工追加积分  
+ 指标计算总积分  
+ 指标类型  
+ 指标值  
+ 指标数量  
+ 手工指标数量  
+ 系统累计总积分  
+ 大类别  
+ 计价标准  
+ 计价单位  
+ 积分差异  
+ 支行名称  
+ 支行号  
+ 统一认证号  
+
+为了方便识别客户经理全产品专业积分对比数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 姓名1的英文名称是employee_name  
+ 人员编码的英文名称是personnel_code  
+ 机构名称的英文名称是organization_name  
+ 机构编号的英文名称是organization_no  
+ 积分时间的英文名称是score_date  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  
+ 手工追加积分的英文名称是manual_add_score  
+ 指标计算总积分的英文名称是metric_calculation_total_score  
+ 指标类型的英文名称是index_type  
+ 指标值的英文名称是index_val  
+ 指标数量的英文名称是metric_num  
+ 手工指标数量的英文名称是manual_metric_num  
+ 系统累计总积分的英文名称是program_cumulative_total_score  
+ 大类别的英文名称是large_class  
+ 计价标准的英文名称是pricing_standard  
+ 计价单位的英文名称是pricing_unit  
+ 积分差异的英文名称是score_diff  
+ 支行名称的英文名称是branch_name  
+ 支行号的英文名称是sub_branch_no  
+ 统一认证号的英文名称是unified_certification_number  

+ 40 - 0
knowledge_db/对公客户经理考核期积分.txt

@@ -0,0 +1,40 @@
+对公客户经理考核期积分是一个数据库表,这个数据库表的英文名称为 t_raw_corporate_customer_managers_assessment_score。
+对公客户经理考核期积分包含了以下的字段内容:
+  存款存量净收益率,
+  贷款净收益,
+  中间业务收入,
+  信贷资产质量扣减分,
+  客户经理,
+  支行,
+  日期,
+  uuid全局唯一标识,
+  删除标识,
+  数据修改时间,
+  数据创建时间,
+  租户标识,
+  客户经理考核积分,
+  人员编码,
+  上级机构编码,
+  上级机构名称,
+  机构编码,
+  机构名称
+
+为了方便识别对公客户经理考核期积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+存款存量净收益率的英文名称是deposit_stock_net_proceeds_ratio,
+  贷款净收益的英文名称是net_loan_income,
+  中间业务收入的英文名称是intermediate_business_income,
+  信贷资产质量扣减分的英文名称是credit_asset_quality_deduction_points,信贷资产质量扣减分的中文别名是信贷质量扣分,
+  客户经理的英文名称是account_manage,
+  支行的英文名称是sub_branch,
+  日期的英文名称是date,
+  uuid全局唯一标识的英文名称是sys_uuid,
+  删除标识的英文名称是sys_deleted,
+  数据修改时间的英文名称是sys_update_time,
+  数据创建时间的英文名称是sys_create_time,
+  租户标识的英文名称是sys_tenant_code,
+  客户经理考核积分的英文名称是corporate_customer_managers_assessment_score,
+  人员编码的英文名称是personnel_code,
+  上级机构编码的英文名称是parent_organization_no,
+  上级机构名称的英文名称是parent_organization_name,
+  机构编码的英文名称是organization_no,
+  机构名称的英文名称是organization_name

+ 7 - 0
knowledge_db/小额贷款.txt

@@ -0,0 +1,7 @@
+中国银行余杭支行和华盈小额贷款股份有限公司协同完成数字人民币在线上小额贷款场景的试点应用,华盈小额贷款公司通过数字人民币向一位自然人发放2万元小额贷款。这是数字人民币首次在杭州市金融机构小额融资场景中闭环应用,是余杭助力数字普惠金融发展的一次突破性探索。
+
+此次小额贷款的成功发放,将数字人民币与互联网科技相结合,为受疫情影响的个人和企业提供线上数字人民币融资服务,切实解决了居民临时性资金紧张问题。中国银行余杭支行副行长李丹告诉记者:“这次发放过程非常快。当时这位自然人客户向华盈小贷申请贷款,申请第一时间获批通过,随即他就通过设立在中行账户上的数字人民币钱包收款。还款时,客户同样也可将该笔贷款通过数字人民币形式归还到华盈小贷的对公数字钱包中。”对小额贷款公司方面来说,数字人民币应用于小额贷款场景,有望节省原来通过第三方产生的渠道费用。对终端客户而言,申请使用线上数字人民币贷款,意味着增加了收付款新渠道,速度快、效率高。
+
+数字人民币具备可编程性,可以加载智能合约用于条件支付、担保支付等比较复杂的支付功能,为普惠金融和绿色金融创新赋能。当前,余杭数字人民币应用场景不断扩展,并逐步渗透到B端和更多创新领域。不久前,余杭区出台稳经济一揽子政策,其中就明确要积极拓展数字化人民币应用场景。
+
+下阶段,余杭金融监管部门将继续紧跟省、市部署,着力推进数字人民币在普惠便民上的应用,深挖政务、交通、医疗、消费等民生领域生态构建前景,体现服务民生经济的社会责任担当。

+ 84 - 0
knowledge_db/工商银行企业手机银行.txt

@@ -0,0 +1,84 @@
+工商银行的企业手机银行是一款集业务、信息、交易、购物、互动于一体的综合性金融服务应用。它不仅提供全面的投资理财信息,还支持在线交易,满足了客户专业化、多元化、人性化的金融服务需求。此外,工商银行还与京东集团合作,紧扣“快递小哥”等新市民群体,依托开放银行,强化平台生态合作,创新金融产品和服务渠道。
+
+工商银行企业手机银行的主要功能包括:
+
+1. **账户管理**:方便企业随时查阅账户余额、交易明细及银行流水,支持多账户管理。
+
+2. **资金转账**:支持企业之间、个人与企业账户的转账功能,包括实时到账和预约转账。
+
+3. **支付服务**:提供便捷的支付功能,包括账单支付、工资发放、税务支付等。
+
+4. **融资服务**:为企业提供信贷申请、融资方案查询等服务。
+
+5. **投资理财**:提供各种投资理财产品信息,包括基金、定期存款及其他理财产品的购买与管理。
+
+6. **信息查询**:实时提供最新的金融市场动态、利率信息等,帮助企业做出更好的决策。
+
+7. **风险管理**:提供多种风险管理工具和服务,帮助企业识别和控制财务风险。
+
+8. **便捷客服**:支持在线客服,方便随时解决在使用中遇到的问题。
+
+9. **电子合同**:支持在线签署和管理电子合同,提高业务处理效率。
+
+10. **数据分析**:提供企业财务数据分析工具,帮助企业了解自身财务状况及历史交易模式。
+
+这些功能旨在提高企业的金融服务效率,满足企业在日常经营中的多种需求。
+
+
+
+工商银行的企业手机银行通常会推出多种优惠活动,旨在为企业客户提供更好的服务和金融支持。常见的优惠活动包括:
+
+1. **手续费优惠**:部分交易(如资金转账、支付等)可能享有手续费减免或返还的政策。
+
+2. **贷款优惠利率**:在申请企业贷款时,可能享有利率优惠,尤其是对小微企业和信贷新客户。
+
+3. **财富管理产品优惠**:针对在企业手机银行内购买的理财产品,可能会有额外的收益或者优惠利率。
+
+4. **活动奖励**:企业用户在特定时间内使用手机银行进行交易,可能会获得积分、优惠券等奖励,积分可用于兑换礼品或抵扣手续费。
+
+5. **新客户促销**:新注册用户可能会获得首年免费服务、增加额度或其他相关的优惠政策。
+
+6. **定期活动**:工商银行可能会定期推出一些促销活动,比如节假日活动、周年庆典等,涵盖的内容包括限时交易优惠、产品折扣等。
+
+为了了解最新的优惠活动,建议访问工商银行的官方网站或通过企业手机银行的公告页面进行确认。
+
+
+使用工商银行企业手机银行进行投资理财的步骤如下:
+
+### 1. 下载并安装应用
+- 在手机应用商店(如Apple App Store或Google Play)搜索“工商银行”并下载“工商银行企业手机银行”应用。
+  
+### 2. 注册并登录
+- 打开应用,选择注册账户或使用已注册的账户进行登录。企业账户可能需要输入企业相关信息。
+
+### 3. 身份验证
+- 根据系统提示,进行身份验证,通常包括输入企业用户的相关信息和安全密码。
+
+### 4. 进入理财模块
+- 登录后,查找“投资理财”或类似的功能模块。通常在主界面或“理财”选项中可以找到。
+
+### 5. 选择投资产品
+- 浏览可供选择的投资理财产品,例如定期存款、货币市场基金、债券等。工商银行通常提供多种投资产品供企业选择。
+
+### 6. 查看产品详情
+- 点击感兴趣的产品,查看相关信息和风险评级,包括投资周期、预期收益、历史收益等。
+
+### 7. 下单投资
+- 确认选择的产品后,输入投资金额,按照提示完成投资操作。确保仔细阅读相关条款和风险提示。
+
+### 8. 管理投资
+- 投资完成后,可以在“我的投资”或“资产管理”中查看、管理和跟踪投资的表现。
+
+### 9. 提现和赎回
+- 如需提现或赎回投资,按照应用中的相关步骤进行操作,系统会提示您完成这些操作的程序和费用信息。
+
+### 10. 客服和支持
+- 如果在使用过程中有任何疑问或遇到问题,可以联系工商银行的客服支持获取帮助。
+
+### 注意事项
+- 了解各类投资产品的风险和收益,合理规划企业的投资策略。
+- 定期检查投资组合,以适应市场变化和企业财务需求。
+
+通过这些步骤,您可以有效地利用工商银行企业手机银行进行投资理财。
+
+

+ 44 - 0
knowledge_db/支行全产品积分.txt

@@ -0,0 +1,44 @@
+支行全产品积分是一个数据库表,这个数据库表的英文名称为 t_raw_branch_full_product_score。
+支行全产品积分包含了以下的字段内容:
+  月份,
+  支行,
+  全产品计价积分,
+  uuid 全局唯一标识,
+  删除标识,
+  数据修改时间,
+  数据创建时间,
+  租户标识,
+  比上月,
+  比月均,
+  增降幅,
+  计价人数,
+  总人数,
+  计价人员占比,
+  本月积分人均,
+  全年计价人均,
+  当年累计计价,
+  当月主要变动备注,
+  机构编号,
+  积分类别
+
+为了方便识别客户经理专业积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 月份的英文名称是month  
+ 支行的英文名称是branch  
+ 全产品计价积分的英文名称是full_product_pricing_score  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  
+ 比上月的英文名称是than_last_month  
+ 比月均的英文名称是than_avge_month  
+ 增降幅的英文名称是increase_decrease_amplitude  
+ 计价人数的英文名称是pricing_personnel_num  
+ 总人数的英文名称是total_personnel_num  
+ 计价人员占比的英文名称是pricing_personnel_ratio  
+ 本月积分人均的英文名称是month_score_personnel_avge  
+ 全年计价人均的英文名称是year_score_personnel_avge  
+ 当年累计计价的英文名称是year_total_score  
+ 当月主要变动备注的英文名称是month_changes_tag  
+ 机构编号的英文名称是organization_no  
+ 积分类别的英文名称是score_category  

+ 34 - 0
knowledge_db/支行对公客户经理考核期积分汇总.txt

@@ -0,0 +1,34 @@
+支行对公客户经理考核期积分汇总是一个数据库表,这个数据库表的英文名称为 t_raw_sub_corporate_customer_managers_assessment_score
+支行对公客户经理考核期积分汇总包含了以下的字段内容:
+ 支行
+ 存款存量净收益率汇总
+ 存款增量净收益率汇总
+ 贷款净收益汇总
+ 中间业务收入汇总
+ 信贷资产质量扣减分汇总
+ 客户经理考核积分汇总
+ 客户经理人数汇总
+ 日期
+ uuid 全局唯一标识
+ 删除标识
+ 数据修改时间
+ 数据创建时间
+ 租户标识
+ 人员编码
+
+为了方便识别对公客户经理考核期积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 支行的英文名称是sub_branch
+ 存款存量净收益率汇总的英文名称是total_deposit_stock_net_proceeds_ratio
+ 存款增量净收益率汇总的英文名称是total_deposit_increment_net_proceeds_ratio
+ 贷款净收益汇总的英文名称是total_net_loan_income
+ 中间业务收入汇总的英文名称是total_intermediate_business_income
+ 信贷资产质量扣减分汇总的英文名称是total_credit_asset_quality_deduction_points
+ 客户经理考核积分汇总的英文名称是total_corporate_customer_managers_assessment_score
+ 客户经理人数汇总的英文名称是total_account_manage
+ 日期的英文名称是date
+ uuid 全局唯一标识的英文名称是sys_uuid
+ 删除标识的英文名称是sys_deleted
+ 数据修改时间的英文名称是sys_update_time
+ 数据创建时间的英文名称是sys_create_time
+ 租户标识的英文名称是sys_tenant_code
+ 人员编码的英文名称是personnel_code

+ 124 - 0
knowledge_db/数字人民币.txt

@@ -0,0 +1,124 @@
+中国工商银行数字人民币app是一款电子钱包类软件,它支持多家银行的电子钱包功能,包括中国工商银行。该app由中国人民银行发行,是数字人民币的官方应用,数字人民币是一种由中国人民银行发行的法定货币,等同于纸币和硬币,不计付利息。通过该app,用户可以无需持有工行银行卡即可开立钱包,并执行相关交易。
+
+要在中国工商银行开通数字人民币钱包,您可以按照以下步骤进行操作:
+
+1. **下载应用**:首先,下载并安装中国工商银行的官方手机银行应用或数字人民币专用的应用(如果有的话),一般可以在应用商店中找到。
+
+2. **注册账户**:打开应用后,您需要使用手机号进行注册,按照提示填写相关信息并完成实名认证。
+
+3. **开通数字人民币钱包**:在应用中查找“数字人民币”或“数字钱包”相关选项,点击进入后,按照指引完成钱包的开通。
+
+4. **绑定身份证**:根据要求,可能需要绑定您的身份证信息,以确保安全和合规。
+
+5. **设置支付密码**:您在开通钱包的过程中可能需要设置支付密码,以保护您的钱包安全。
+
+6. **充值和使用**:开通后,您可以通过链接银行账户或其他方式为您的数字人民币钱包充值,然后就可以在支持数字人民币支付的商户进行消费了。
+
+### 注意事项:
+- 请确保您使用的是官方渠道下载的应用程序,避免使用非官方的软件以保护个人信息安全。
+- 数字人民币的使用场景逐渐增加,但在某些地区和商户可能尚未普及。
+- 具体的操作界面和步骤可能会因应用版本或更新而有所不同,请根据实际情况进行调整。
+
+如果在过程中遇到问题,可以联系工商银行的客服寻求帮助。
+
+
+数字人民币与传统货币(如纸币和硬币)之间有几个关键的区别:
+
+1. **形式**:
+   - **数字人民币**:以数字形式存在,没有物理实体,用户通过手机等电子设备进行交易。
+   - **传统货币**:以纸币和硬币的形式存在。
+
+2. **发行和监管**:
+   - **数字人民币**:由中国人民银行直接发行和监管,是法定数字货币。
+   - **传统货币**:也是由中央银行发行,但其流通和管理主要依赖于银行体系。
+
+3. **交易方式**:
+   - **数字人民币**:可以通过手机银行、数字人民币钱包等进行转账、支付,支持线上和线下的无接触支付。
+   - **传统货币**:通常通过现金交易,或者通过银行卡等传统方式进行支付。
+
+4. **隐私性**:
+   - **数字人民币**:交易记录可被监管,但用户的身份信息可以在一定程度上保护,提供了较高的隐私安全性。
+   - **传统货币**:现金交易相对匿名,难以追踪,但电子支付方式需提供个人信息。
+
+5. **交易速度**:
+   - **数字人民币**:能够实现即时结算,无需通过中介机构。
+   - **传统货币**:电子转账可能需要时间,尤其在跨行或跨境交易时。
+
+6. **成本和效率**:
+   - **数字人民币**:降低了纸币印刷、流通和管理成本,有助于提高支付系统的效率。
+   - **传统货币**:涉及到现金管理、运输和安全等成本。
+
+7. **适用场景**:
+   - **数字人民币**:适用于各种场景,包括无接触支付、线上购物、跨境支付等。
+   - **传统货币**:主要用于面对面的现金交易。
+
+总体而言,数字人民币旨在利用现代科技提升支付效率和便利性,同时保持货币体系的稳定性和安全性。
+
+
+使用中国工商银行数字人民币APP的优势包括:
+
+1. **安全性高**:数字人民币是由中国人民银行发行的法定货币,具备国家信用保障,并采用多种技术手段确保交易安全。
+
+2. **支付便利**:用户可以通过APP进行快速支付,支持扫码付款、转账等功能,操作简单便捷。
+
+3. **隐私保护**:数字人民币在保护用户隐私方面做了设计,通过“可控匿名”机制,确保用户的交易信息不被随意泄露。
+
+4. **无手续费**:使用数字人民币进行交易通常不收取手续费,能有效降低用户的交易成本。
+
+5. **多场景应用**:数字人民币可以用于日常生活中的多种场景,如购物、缴费、交通出行等,提升了消费体验。
+
+6. **支持离线支付**:在某些情况下,数字人民币支持离线支付,即使没有网络,也能完成交易。
+
+7. **跨行转账便利**:用户可以方便地向其他银行的用户进行转账,促进小额支付与个人之间的资金流通。
+
+8. **与银行业务集成**:数字人民币APP与中国工商银行的其他金融服务相结合,用户可以便捷地管理自己的资产和账户。
+
+9. **实时交易记录**:APP提供详细的交易记录,帮助用户随时了解自己的消费情况,提高财务管理的透明度。
+
+数字人民币的推广和使用,对于提高支付的便捷性、安全性及效率具有重要意义。
+
+中国工商银行数字人民币红包的使用步骤:
+
+在手机上打开中国工商银行的APP。
+进入“我的”或者“卡包”界面,找到数字人民币红包的入口。
+点击红包,进入使用界面。
+根据提示选择支付方式,如扫码支付或付款码支付等。
+按照操作指引完成支付即可。
+请注意,不同情况可能略有差异,具体操作时请参照中国工商银行的最新指引。
+
+数字人民币红包在使用时可能会受到以下一些限制:
+
+1. **使用范围**:数字人民币红包通常只能在支持数字人民币的商家和平台上使用,可能不适用于所有场所。
+
+2. **有效期**:红包一般会有有效期,过期后无法使用,需要在规定时间内消费。
+
+3. **金额限制**:每个红包的金额可能会有所限制,可能有单个红包和累计红包的总额上限。
+
+4. **提现限制**:红包通常不支持直接提现,只能用于支付,因此不能将红包金额转回到银行账户。
+
+5. **活动限制**:一些特定的红包活动可能有使用条件,例如只能用于特定商品或服务,或者只能在特定时间段内使用。
+
+6. **用户身份限制**:有些红包可能只面向特定用户群体,例如新用户或者参与某些活动的用户。
+
+建议在使用数字人民币红包前,仔细阅读相关条款和条件,确保符合使用要求。
+
+给中国工商银行的数字人民币红包充值一般可以按照以下步骤进行:
+
+1. **打开中国工商银行APP**:确保您的手机上已经安装了最新版本的中国工商银行手机银行APP。
+
+2. **登录账户**:使用您的账号和密码登录到您的个人银行账户。
+
+3. **进入数字人民币钱包**:在主界面中,找到“数字人民币”或“数字钱包”的选项,点击进入。
+
+4. **选择充值功能**:在数字人民币钱包界面中,找到充值或加红包的选项,然后点击进入。
+
+5. **选择充值方式**:根据系统提示,选择您希望使用的充值方式(如银行转账、银行卡等)。
+
+6. **输入充值金额**:输入您希望充值到红包的金额,然后确认。
+
+7. **完成操作**:根据系统提示完成后续操作,确认充值。
+
+8. **检查余额**:充值完成后,您可以在红包页面查看您的余额是否已经更新。
+
+请注意,具体的步骤可能会根据APP的版本更新而有所不同。如果遇到任何问题,建议查看工商银行的官方指导或联系客服以获取帮助。
+

+ 107 - 0
knowledge_db/融e借.txt

@@ -0,0 +1,107 @@
+工银融e借是工商银行推出的一款个人信用贷款产品,专门针对符合特定条件的借款人提供无担保、无抵押的人民币贷款,用于个人合法合规的消费用途。该贷款的借款额度最高可达80万,利息从4.2%起,借款期限最长可达5年,还款方式多样。
+
+工银融e借的申请条件一般包括以下几个方面,但具体要求可能会有所不同,建议在申请前查看工商银行的官方网站或者咨询客服获取最新信息:
+
+1. **年龄要求**:通常要求借款人年满18岁,且不超过65岁。
+2. **信用记录**:申请人需拥有良好的个人信用记录,无不良信用记录。
+3. **收入状况**:需要有稳定的收入来源,通常会要求提供收入证明,例如工资单、银行流水等。
+4. **工作状况**:一般要求在工作单位持续工作一定时间,享有稳定的职业及收入。
+5. **居住状况**:需要在中国大陆有合法的居留证明,且居住地通常需在可以办理贷款的范围内。
+
+具体的申请条件可能会由于不同的地区和政策有所不同,建议在申请前详细咨询当地的工商银行或者查看其官方网站。
+
+工银融e借的还款方式一般包括以下几种:
+
+1. **等额本息还款**:每月偿还相同的金额,包括本金和利息。
+
+2. **按月还息到期还本**:借款人在贷款期限内每月只支付利息,到期时一次性偿还本金。
+
+3. **等额本金还款**:每月偿还固定金额的本金,利息则根据剩余本金计算,因此每月还款金额逐渐减少。
+
+具体的还款方式和细节可能会因个人情况及工商银行的规定而有所不同,建议在申请前咨询工商银行的客服或查阅相关信息以获得最新和最准确的还款政策。
+
+工银融e借的贷款利率通常是根据借款人的信用等级、贷款额度和期限等因素来确定的。一般情况下,利率可能在4.2%起步,但具体利率可能会有所不同,建议您在申请时查看工商银行的官方网站或直接咨询相关工作人员,以获取最新和准确的信息。实际利率可能会受到市场利率变化及借款人个人信用状况的影响。
+
+融e借(个人信用消费贷款)的额度是根据您提交申请时的综合情况核算出来的,自助申请额度最高不超过30万元。您可在申请时查看可贷额度。
+  温馨提示:融e借额度与信用卡额度均纳入个人信用总额度,申请融e借后,您所持有的信用卡可用额度会被占用。
+  注:1、问答中未表明仅针对企业单位的,通常指个人业务。2、大连、宁波、青岛、深圳、厦门为我行独立分行,执行独立业务规定;本页面内容供您参考,实际情况请以当地分行公告与具体规定为准。
+
+还款宽限期的定义与意义
+
+2.1 还款宽限期的定义
+
+还款宽限期是指借款人在贷款到期日后,银行允许其延迟还款的一段时间。在这段时间内,借款人不需要支付罚息或违约金,仍可以进行正常的还款。工行的融e借产品通常设置了一定的宽限期,以方便借款人。
+
+2.2 还款宽限期的意义
+
+缓解经济压力:对于一些在还款期内突发经济困难的借款人,宽限期能够有效减轻其还款压力。
+
+提高客户满意度:设置宽限期可以提升客户对银行的满意度,增强客户黏性。
+
+降低逾期风险:通过给予宽限期,银行能够降低借款人因逾期而产生的违约风险,维护自身的信贷资产质量。
+
+三、工行融e借的还款宽限期政策
+
+3.1 宽限期的适用范围
+
+工行融e借的还款宽限期政策适用于所有符合条件的借款人。具体的宽限期天数可能会根据借款人的信用评级、贷款金额及期限等因素有所不同。
+
+3.2 宽限期的时长
+
+融e借的还款宽限期为3天至7天不等。在宽限期内,借款人可以选择全额还款或部分还款,具体情况应以借款合同为准。
+
+3.3 申请宽限期的流程
+
+1. 提前咨询:借款人应在还款到期日前,提前与工行客服或信贷经理进行咨询,确认自己是否符合申请宽限期的条件。
+
+2. 提交申请:借款人需填写相关申请表,并提供必要的身份证明和贷款合同复印件。
+
+3. 等待审批:银行将在收到申请后进行审批,通常会在13个工作日内给予回复。
+
+4. 确认结果:借款人应及时关注申请结果,并按照银行的要求进行后续还款。
+
+四、注意事项
+
+4.1 宽限期不等于免息
+
+需要明确的是,宽限期并不意味着借款人在此期间可以免息。虽然在宽限期内不会产生罚息,但借款人仍需按合同约定支付利息。因此,借款人应在宽限期内尽快还款,以减少利息支出。
+
+4.2 不可频繁申请
+
+虽然宽限期为借款人提供了便利,但频繁申请宽限期可能会对个人信用产生负面影响。银行在审核借款人申请时,会考虑其信用记录。因此,借款人应合理规划还款,避免频繁申请宽限期。
+
+4.3 提前沟通
+
+如果借款人预计在还款日无法按时还款,应提前与银行进行沟通,争取获得宽限期的批准,以免造成逾期。
+
+五、宽限期对借款人的影响
+
+5.1 正面影响
+
+减轻还款压力:宽限期能够有效减轻借款人因经济波动而带来的还款压力,帮助其更好地管理个人财务。
+
+增强信贷可持续性:宽限期的存在使得借款人可以在面对突发情况时仍能保持良好的信用记录,从而增强信贷的可持续性。
+
+5.2 负面影响
+
+可能导致依赖:一些借款人可能会因宽限期的存在而产生依赖心理,导致不良的借款习惯,进而影响其未来的信用状况和借款能力。
+
+增加财务成本:虽然宽限期内不产生罚息,但借款人在宽限期后仍需支付利息,如果未能及时还款,可能会导致整体财务成本增加。
+
+如何与工商银行协商还款?
+
+小编答:借款人可以通过电话、邮件或到银行柜台等方式与工商银行进行还款协商。在协商还款时,借款人需如实向银行说明还款困难的原因,并提供相关证明材料。
+
+问:银行会如何处理借款人的还款困难?
+
+小编答:银行会根据借款人提供的情况进行评估,制定合理的还款方案。可能会延长还款期限、调整还款金额或利率等方式来帮助借款人渡过难关。
+
+问:协商还款会对信用记录造成影响吗?
+
+小编答:一般情况下,协商还款不会对信用记录造成太大影响。但如果借款人一直无法按协商还款方案履行,可能会对信用记录产生负面影响。
+
+问:有没有成功的协商还款案例?
+
+小编答:有的。有些借款人通过与银行积极沟通,成功达成协商还款方案,最终顺利还清贷款。这些案例表明,与银行进行协商还款是一种解决还款困难的有效途径。
+
+工商银行融e贷协商还款是一种解决还款困难的有效方式,借款人在遇到还款困难时不要慌张,应该及时与银行进行沟通,寻求合理的解决方案。银行也会根据借款人的实际情况制定合适的还款方案,帮助借款人尽快摆脱还款困境。希望以上内容可以帮助大家更好地了解工商银行融e贷协商还款相关问题。

+ 44 - 0
knowledge_db/部室全产品积分.txt

@@ -0,0 +1,44 @@
+部室全产品积分是一个数据库表,这个数据库表的英文名称为t_raw_organization_full_product_score。
+部室全产品积分包含了以下的字段内容:
+ 机构编号  
+ 机构名称  
+ 月份  
+ 全产品计价积分  
+ 比上月  
+ 比月均  
+ 增降幅  
+ 计价人数  
+ 总人数  
+ 计价人员占比  
+ 本月积分人均  
+ 全年计价人均  
+ 当年累计计价  
+ 当月主要变动备注  
+ 积分类别  
+ uuid 全局唯一标识  
+ 删除标识  
+ 数据修改时间  
+ 数据创建时间  
+ 租户标识  
+
+为了方便识别部室全产品积分数据表的内容,对这个数据表的字段定义了一些别名如下:
+ 机构编号的英文名称是organization_no  
+ 机构名称的英文名称是organization_name  
+ 月份的英文名称是month  
+ 全产品计价积分的英文名称是full_product_pricing_score  
+ 比上月的英文名称是than_last_month  
+ 比月均的英文名称是than_avge_month  
+ 增降幅的英文名称是increase_decrease_amplitude  
+ 计价人数的英文名称是pricing_personnel_num  
+ 总人数的英文名称是total_personnel_num  
+ 计价人员占比的英文名称是pricing_personnel_ratio  
+ 本月积分人均的英文名称是month_score_personnel_avge  
+ 全年计价人均的英文名称是year_score_personnel_avge  
+ 当年累计计价的英文名称是year_total_score  
+ 当月主要变动备注的英文名称是month_changes_tag  
+ 积分类别的英文名称是score_category  
+ uuid 全局唯一标识的英文名称是sys_uuid  
+ 删除标识的英文名称是sys_deleted  
+ 数据修改时间的英文名称是sys_update_time  
+ 数据创建时间的英文名称是sys_create_time  
+ 租户标识的英文名称是sys_tenant_code  

+ 36 - 0
llm/llm.py

@@ -0,0 +1,36 @@
+import os
+# from langchain_community.chat_models import ChatOpenAI
+from langchain_openai import ChatOpenAI
+from langchain_community.llms import Tongyi
+from langchain_community.chat_models.tongyi import ChatTongyi
+
+
+class LLM():
+    def __init__(self, model_name='qwen'):
+        if model_name == 'deepseek':
+            self.llm = self.deepseek_llm()
+        elif model_name == 'qwen':
+            self.llm = self.qwen_llm()
+        else:
+            raise ValueError("Unsupported model name")
+
+    def deepseek_llm(self):
+        llm = ChatOpenAI(
+            model='deepseek-coder',
+            openai_api_key='sk-7a15d12a3e254dd0a3408f1544c72da5',
+            openai_api_base='https://api.deepseek.com',
+            max_tokens=1024
+        )
+        return llm
+
+    def qwen_llm(self):
+        os.environ["DASHSCOPE_API_KEY"] = "sk-86d4622141d74e9a8d7c38ee873c4d91"
+        llm = ChatTongyi(model='qwen-turbo')
+        return llm
+
+
+    def get_llm(self):
+        return self.llm
+
+class QwenTurboTongyi(Tongyi):
+    mode_name = 'qwen-plus'

+ 414 - 0
qa_chain/Chat_QA_chain_self.py

@@ -0,0 +1,414 @@
+# from langchain_core.runnables import (
+#     RunnableBranch,
+#     RunnableLambda,
+# )
+# from langchain_core.output_parsers import StrOutputParser
+# from langchain_core.runnables import RunnableParallel, RunnablePassthrough
+# from langchain.prompts import (
+#         ChatPromptTemplate,
+# )
+# from typing import List, Tuple
+# from langchain.prompts import PromptTemplate
+# from langchain_core.messages import AIMessage, HumanMessage
+# from qa_chain.get_vectordb import get_vectordb
+# from graph.graph_retrieval import connect, structured_retriever
+# from llm.llm import deepseek_llm
+# # from llm.llm import qwen_llm
+#
+#
+# class Chat_QA_chain_self:
+#     """
+#     带历史记录的问答链
+#     - model:调用的模型名称
+#     - temperature:温度系数,控制生成的随机性
+#     - top_k:返回检索的前k个相似文档
+#     - chat_history:历史记录,输入一个列表,默认是一个空列表
+#     - file_path:建库文件所在路径
+#     - persist_path:向量数据库持久化路径
+#     - embeddings:使用的embedding模型
+#     """
+#
+#     def __init__(self, temperature: float = 0.0, top_k: int = 4, chat_history: List[Tuple[str, str]] = [],
+#                  file_path: str = None, persist_path: str = None, embedding: str = "m3e"):
+#         self.temperature = temperature
+#         self.top_k = top_k
+#         self.chat_history = chat_history
+#         self.file_path = file_path
+#         self.persist_path = persist_path
+#         self.embedding = embedding
+#         self.llm = deepseek_llm
+#         self.vectordb = get_vectordb(self.file_path, self.persist_path, self.embedding)
+#         self.graph = connect()
+#
+#     def clear_chat_history(self):
+#         """
+#         清空历史记录
+#         :return:
+#         """
+#         self.chat_history = []
+#         # print("Chat history has been cleared.")
+#
+#     def add_to_chat_history(self, human_message: str, ai_message: str):
+#         """
+#         添加一条聊天记录到历史记录中
+#         :param human_message: 人类用户的消息
+#         :param ai_message: AI的回复消息
+#         :return:
+#         """
+#         self.chat_history.append((human_message, ai_message))
+#
+#     def get_chat_history(self):
+#         """
+#         获取所有的聊天历史记录
+#         :return: 聊天历史记录列表
+#         """
+#         return self.chat_history
+#
+#     # 原来的函数
+#     # def _format_chat_history(self, chat_history: List[Tuple[str, str]]) -> List:
+#     #     buffer = []
+#     #     for human, ai in chat_history:
+#     #         buffer.append(HumanMessage(content=human))
+#     #         buffer.append(AIMessage(content=ai))
+#     #     buffer.append(chat_history)
+#     #     return buffer
+#
+#     def _format_chat_history(self, chat_history: List[Tuple[str, str]]) -> List:
+#         buffer = []
+#         for human, ai in chat_history:
+#             buffer.append(HumanMessage(content=human))
+#             buffer.append(AIMessage(content=ai))
+#         return buffer
+#
+#     def retriever(self, question: str):
+#         # print(f"Search query: {question}")
+#         structured_data = structured_retriever(self.llm, self.graph, question)
+#         unstructured_data = self.vectordb.as_retriever(search_type="similarity",
+#                                                        search_kwargs={'k': self.top_k})  # 默认similarity,k=4
+#         final_data = f"""Unstructured data:{unstructured_data}\n
+#                          Structured data:{structured_data}
+#                         """
+#         # final_data = f"""Unstructured data:{unstructured_data}\n"""
+#         # print(f"unstructured_data:{unstructured_data}")
+#         return final_data
+#
+#     # # def build_chain(self, question: str):
+#     def build_chain(self):
+#         llm = self.llm
+#
+#         # Condense a chat history and follow-up question into a standalone question
+#         _template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question,
+#         in its original language.
+#         Chat History:
+#         {chat_history}
+#         Follow Up Input: {question}
+#         Standalone question:"""  # noqa: E501
+#         CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template)
+#
+#         _search_query = RunnableBranch(
+#             # If input includes chat_history, we condense it with the follow-up question
+#             (
+#                 RunnableLambda(lambda x: bool(x.get("chat_history"))).with_config(
+#                     run_name="HasChatHistoryCheck"
+#                 ),  # Condense follow-up question and chat into a standalone_question
+#                 RunnablePassthrough.assign(
+#                     chat_history=lambda x: self._format_chat_history(x["chat_history"])
+#                 )
+#                 | CONDENSE_QUESTION_PROMPT
+#                 | llm
+#                 | StrOutputParser(),
+#             ),
+#             # Else, we have no chat history, so just pass through the question
+#             RunnableLambda(lambda x: x["question"]),
+#         )
+#
+#         template = """Answer the question based only on the following context:
+#         {context}
+#
+#         Question: {question}
+#         Use natural language and be concise.
+#         Answer:"""
+#         prompt = ChatPromptTemplate.from_template(template)
+#
+#         chain = (
+#             RunnableParallel(
+#                 {
+#                     "context": _search_query | self.retriever,
+#                     "question": RunnablePassthrough(),
+#                 }
+#             )
+#             | prompt
+#             | llm
+#             | StrOutputParser()
+#         )
+#         return chain
+
+
+from langchain_core.runnables import (
+    RunnableBranch,
+    RunnableLambda,
+)
+from langchain_core.output_parsers import StrOutputParser
+from langchain_core.runnables import RunnableParallel, RunnablePassthrough
+from langchain.prompts import (
+        ChatPromptTemplate,
+)
+from typing import List, Tuple
+from langchain.prompts import PromptTemplate
+from langchain_core.messages import AIMessage, HumanMessage
+
+from embedding.embedding import get_embedding
+from qa_chain.get_vectordb import get_vectordb
+from graph.graph_retrieval import connect, structured_retriever, text_structured_retriever
+from llm.llm import LLM
+
+
+class Chat_QA_chain_self:
+    """
+    带历史记录的问答链
+    - model:调用的模型名称
+    - temperature:温度系数,控制生成的随机性
+    - top_k:返回检索的前k个相似文档
+    - chat_history:历史记录,输入一个列表,默认是一个空列表
+    - file_path:建库文件所在路径
+    - persist_path:向量数据库持久化路径
+    - embeddings:使用的embedding模型
+    """
+
+    def __init__(self, temperature: float = 0.0, top_k: int = 2, chat_history: List[Tuple[str, str]] = [],
+                 file_path: str = None, persist_path: str = None, embedding: str = "m3e"):
+        self.temperature = temperature
+        self.top_k = top_k
+        self.chat_history = chat_history
+        self.file_path = file_path
+        self.persist_path = persist_path
+        self.embedding = get_embedding(embedding)
+        self.llm_instance = LLM(model_name='qwen')
+        self.llm = self.llm_instance.get_llm()
+        self.vectordb = get_vectordb(self.file_path, self.persist_path, self.embedding)
+        self.graph = connect()
+
+    def clear_chat_history(self):
+        """
+        清空历史记录
+        :return:
+        """
+        self.chat_history = []
+        # print("Chat history has been cleared.")
+
+    def add_to_chat_history(self, human_message: str, ai_message: str):
+        """
+        添加一条聊天记录到历史记录中
+        :param human_message: 人类用户的消息
+        :param ai_message: AI的回复消息
+        :return:
+        """
+        self.chat_history.append((human_message, ai_message))
+
+    def get_chat_history(self):
+        """
+        获取所有的聊天历史记录
+        :return: 聊天历史记录列表
+        """
+        return self.chat_history
+
+    def _format_chat_history(self, chat_history: List[Tuple[str, str]]) -> List:
+        buffer = []
+        for human, ai in chat_history:
+            buffer.append(HumanMessage(content=human))
+            buffer.append(AIMessage(content=ai))
+        return buffer
+
+    def retriever(self, question: str):
+        # print(f"Search query: {question}")
+        structured_data = structured_retriever(self.llm, self.graph, question)
+        # unstructured_data = self.vectordb.as_retriever(search_type="similarity",
+        #                                                search_kwargs={'k': self.top_k})  # 默认similarity,k=4
+        unstructured_data = self.rag_retriever(question)
+        final_data = f"""Unstructured data:{unstructured_data}\n
+                         Structured data:{structured_data}
+                        """
+        # final_data = f"""Unstructured data:{unstructured_data}\n"""
+        # print(f"unstructured_data:{unstructured_data}")
+        return final_data
+
+    # 非结构化文本图谱+rag
+    def text_retriever(self, question: str):
+        # print(f"Search query: {question}")
+        structured_data = text_structured_retriever(self.llm, self.graph, question)
+        # unstructured_data = self.vectordb.as_retriever(search_type="similarity",
+        #                                                search_kwargs={'k': self.top_k})  # 默认similarity,k=4
+        unstructured_data = self.rag_retriever(question)
+        final_data = f"""Structured data:{structured_data}\n
+                         Unstructured data:{unstructured_data}\n
+                        """
+        # final_data = f"""Unstructured data:{unstructured_data}\n"""
+        print(f"final_data:{final_data}")
+        return final_data
+
+    # 单纯的rag
+    def rag_retriever(self, question: str):
+        # 获取与查询问题最相似的文档
+        # docs = self.vectordb.similarity_search(question, k=self.top_k)
+        # docs = self.vectordb.max_marginal_relevance_search_by_vector(question)
+        # 将文档内容拼接成一个字符串
+        # final_data = "\n".join([doc.page_content for doc in docs])
+        # print(f"unstructured_data:{final_data}")
+
+        retriever = self.vectordb.as_retriever(search_type = 'mmr',search_kwargs = {'k':self.top_k})
+        docs = retriever.get_relevant_documents(question)
+        final_data = "\n".join([doc.page_content for doc in docs])
+        return final_data
+
+    def build_chain(self):
+        llm = self.llm
+
+        # Condense a chat history and follow-up question into a standalone question
+        _template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question,
+        in its original language.
+        Chat History:
+        {chat_history}
+        Follow Up Input: {question}
+        Standalone question:"""  # noqa: E501
+        CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template)
+
+        _search_query = RunnableBranch(
+            # If input includes chat_history, we condense it with the follow-up question
+            (
+                RunnableLambda(lambda x: bool(x.get("chat_history"))).with_config(
+                    run_name="HasChatHistoryCheck"
+                ),  # Condense follow-up question and chat into a standalone_question
+                RunnablePassthrough.assign(
+                    chat_history=lambda x: self._format_chat_history(x["chat_history"])
+                )
+                | CONDENSE_QUESTION_PROMPT
+                | llm
+                | StrOutputParser(),
+            ),
+            # Else, we have no chat history, so just pass through the question
+            RunnableLambda(lambda x: x["question"]),
+        )
+
+        template = """Answer the question based only on the following context:
+        {context}
+
+        Question: {question}
+        Use natural language and be concise.
+        Answer:"""
+        prompt = ChatPromptTemplate.from_template(template)
+
+        chain = (
+            RunnableParallel(
+                {
+                    "context": _search_query | self.retriever,
+                    "question": RunnablePassthrough(),
+                }
+            )
+            | prompt
+            | llm
+            | StrOutputParser()
+        )
+        return chain
+
+
+    def build_rag_chain(self):
+        llm = self.llm
+
+        # Condense a chat history and follow-up question into a standalone question
+        _template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question,
+        in its original language.
+        Chat History:
+        {chat_history}
+        Follow Up Input: {question}
+        Standalone question:"""  # noqa: E501
+        CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template)
+
+        _search_query = RunnableBranch(
+            # If input includes chat_history, we condense it with the follow-up question
+            (
+                RunnableLambda(lambda x: bool(x.get("chat_history"))).with_config(
+                    run_name="HasChatHistoryCheck"
+                ),  # Condense follow-up question and chat into a standalone_question
+                RunnablePassthrough.assign(
+                    chat_history=lambda x: self._format_chat_history(x["chat_history"])
+                )
+                | CONDENSE_QUESTION_PROMPT
+                | llm
+                | StrOutputParser(),
+            ),
+            # Else, we have no chat history, so just pass through the question
+            RunnableLambda(lambda x: x["question"]),
+        )
+
+        template = """Answer the question based only on the following context:
+        {context}
+
+        Question: {question}
+        Use natural language and be concise.
+        Answer:"""
+        prompt = ChatPromptTemplate.from_template(template)
+
+        chain = (
+            RunnableParallel(
+                {
+                    "context": _search_query | self.rag_retriever,
+                    "question": RunnablePassthrough(),
+                }
+            )
+            | prompt
+            | llm
+            | StrOutputParser()
+        )
+        return chain
+
+
+    # 非结构化+图谱
+    def build_text_chain(self):
+        llm = self.llm
+
+        # Condense a chat history and follow-up question into a standalone question
+        _template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question,
+        in its original language.
+        Chat History:
+        {chat_history}
+        Follow Up Input: {question}
+        Standalone question:"""  # noqa: E501
+        CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template)
+
+        _search_query = RunnableBranch(
+            # If input includes chat_history, we condense it with the follow-up question
+            (
+                RunnableLambda(lambda x: bool(x.get("chat_history"))).with_config(
+                    run_name="HasChatHistoryCheck"
+                ),  # Condense follow-up question and chat into a standalone_question
+                RunnablePassthrough.assign(
+                    chat_history=lambda x: self._format_chat_history(x["chat_history"])
+                )
+                | CONDENSE_QUESTION_PROMPT
+                | llm
+                | StrOutputParser(),
+            ),
+            # Else, we have no chat history, so just pass through the question
+            RunnableLambda(lambda x: x["question"]),
+        )
+
+        template = """Answer the question based only on the following context:
+        {context}
+
+        Question: {question}
+        Use natural language and be concise.
+        Answer:"""
+        prompt = ChatPromptTemplate.from_template(template)
+
+        chain = (
+            RunnableParallel(
+                {
+                    "context": _search_query | self.text_retriever,
+                    "question": RunnablePassthrough(),
+                }
+            )
+            | prompt
+            | llm
+            | StrOutputParser()
+        )
+        return chain

+ 34 - 0
qa_chain/get_vectordb.py

@@ -0,0 +1,34 @@
+import os
+from database.create_db import create_db, load_knowledge_db
+from embedding.embedding import get_embedding
+
+# 定义默认路径
+DEFAULT_DB_PATH = os.path.join("..", "knowledge_db")
+DEFAULT_PERSIST_PATH = os.path.join("..", "vector_db", "chroma")
+
+def get_vectordb(file_path=DEFAULT_DB_PATH, persist_path=DEFAULT_PERSIST_PATH, embedding="m3e"):
+    """
+    返回向量数据库对象
+    输入参数:
+    question:
+    llm:
+    vectordb:向量数据库(必要参数),一个对象
+    embedding:qwen
+    """
+    embedding = get_embedding(embedding=embedding)
+    if os.path.exists(persist_path):  # 持久化目录存在
+        contents = os.listdir(persist_path)
+        if len(contents) == 0:  # 但是下面为空
+            # print("目录为空")
+            create_db(file_path, persist_path, embedding)
+            # presit_knowledge_db(vectordb)
+            vectordb = load_knowledge_db(persist_path, embedding)
+        else:
+            # print("目录不为空")
+            vectordb = load_knowledge_db(persist_path, embedding)
+    else:  # 目录不存在,从头开始创建向量数据库
+        create_db(file_path, persist_path, embedding)
+        # presit_knowledge_db(vectordb)
+        vectordb = load_knowledge_db(persist_path, embedding)
+
+    return vectordb

+ 12 - 0
qa_chain/result.py

@@ -0,0 +1,12 @@
+import logging
+SUCCESS_CODE=20000
+FAILED_CODE=50000
+logger = logging.getLogger('app')
+
+def success(data, msg):
+    return {"code": SUCCESS_CODE, "data": data, "level": 0, "msg": msg}
+
+
+def failed(data, msg):
+    return {"code": FAILED_CODE, "data": data, "level": 1, "msg": msg}
+

+ 122 - 0
requirements.txt

@@ -0,0 +1,122 @@
+aiohttp==3.9.5
+aiosignal==1.3.1
+annotated-types==0.7.0
+anyio==4.4.0
+asgiref==3.8.1
+async-timeout==4.0.3
+attrs==23.2.0
+backoff==2.2.1
+bcrypt==4.1.3
+build==1.2.1
+cachetools==5.4.0
+certifi==2024.7.4
+charset-normalizer==3.3.2
+chroma-hnswlib==0.7.5
+chromadb==0.5.4
+click==8.1.7
+coloredlogs==15.0.1
+dashscope==1.20.1
+dataclasses-json==0.6.7
+Deprecated==1.2.14
+distro==1.9.0
+dnspython==2.6.1
+email_validator==2.2.0
+exceptiongroup==1.2.1
+fastapi==0.111.1
+fastapi-cli==0.0.4
+filelock==3.15.4
+flatbuffers==24.3.25
+frozenlist==1.4.1
+fsspec==2024.6.1
+google-auth==2.32.0
+googleapis-common-protos==1.63.2
+greenlet==3.0.3
+grpcio==1.64.1
+h11==0.14.0
+httpcore==1.0.5
+httptools==0.6.1
+httpx==0.27.0
+huggingface-hub==0.23.4
+humanfriendly==10.0
+idna==3.7
+importlib_metadata==7.1.0
+importlib_resources==6.4.0
+Jinja2==3.1.4
+jsonpatch==1.33
+jsonpointer==3.0.0
+kubernetes==30.1.0
+langchain==0.2.7
+langchain-community==0.2.7
+langchain-core==0.2.16
+langchain-experimental==0.0.62
+langchain-openai==0.1.15
+langchain-text-splitters==0.2.2
+langsmith==0.1.85
+markdown-it-py==3.0.0
+MarkupSafe==2.1.5
+marshmallow==3.21.3
+mdurl==0.1.2
+mmh3==4.1.0
+monotonic==1.6
+mpmath==1.3.0
+multidict==6.0.5
+mypy-extensions==1.0.0
+neo4j==5.22.0
+numpy==1.26.4
+oauthlib==3.2.2
+onnxruntime==1.18.1
+openai==1.35.13
+opentelemetry-api==1.25.0
+opentelemetry-exporter-otlp-proto-common==1.25.0
+opentelemetry-exporter-otlp-proto-grpc==1.25.0
+opentelemetry-instrumentation==0.46b0
+opentelemetry-instrumentation-asgi==0.46b0
+opentelemetry-instrumentation-fastapi==0.46b0
+opentelemetry-proto==1.25.0
+opentelemetry-sdk==1.25.0
+opentelemetry-semantic-conventions==0.46b0
+opentelemetry-util-http==0.46b0
+orjson==3.10.6
+overrides==7.7.0
+packaging==24.1
+posthog==3.5.0
+protobuf==4.25.3
+pyasn1==0.6.0
+pyasn1_modules==0.4.0
+pydantic==2.8.2
+pydantic_core==2.20.1
+Pygments==2.18.0
+PyPika==0.48.9
+pyproject_hooks==1.1.0
+python-dateutil==2.9.0.post0
+python-dotenv==1.0.1
+python-multipart==0.0.9
+pytz==2024.1
+PyYAML==6.0.1
+regex==2024.5.15
+requests==2.32.3
+requests-oauthlib==2.0.0
+rich==13.7.1
+rsa==4.9
+shellingham==1.5.4
+six==1.16.0
+sniffio==1.3.1
+SQLAlchemy==2.0.31
+starlette==0.37.2
+sympy==1.13.0
+tenacity==8.5.0
+tiktoken==0.7.0
+tokenizers==0.19.1
+tomli==2.0.1
+tqdm==4.66.4
+typer==0.12.3
+typing-inspect==0.9.0
+typing_extensions==4.12.2
+urllib3==2.2.2
+uvicorn==0.30.1
+watchfiles==0.22.0
+websocket-client==1.8.0
+websockets==12.0
+wrapt==1.16.0
+yarl==1.9.4
+zipp==3.19.2

BIN
vector_db/chroma/chroma.sqlite3


BIN
vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/data_level0.bin


BIN
vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/header.bin


BIN
vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/length.bin


+ 0 - 0
vector_db/chroma/f3df0d61-78b4-4055-be23-df75e298b637/link_lists.bin