File size: 3,581 Bytes
8484b88
 
 
 
 
 
e356033
8484b88
 
 
 
 
 
 
 
 
 
 
f043058
 
 
 
8362db1
4beb684
8484b88
 
f043058
8484b88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d673ffd
8484b88
 
 
 
 
 
4bcd4f5
8484b88
4fea8bc
4bcd4f5
8484b88
 
 
9adfcb4
 
 
 
 
 
 
8484b88
 
 
 
c14ffd8
8484b88
 
 
 
 
d360af7
8484b88
 
 
4fea8bc
8484b88
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import os

import gradio as gr
from transformers.utils import logging

from langchain_ollama import OllamaEmbeddings
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import Neo4jVector

logging.set_verbosity_info()
logger = logging.get_logger("transformers")

# Neo4jへの接続情報
NEO4J_URL = os.environ['NEO4J_URL']
NEO4J_USERNAME = os.environ['NEO4J_USERNAME']
NEO4J_PASSWORD = os.environ['NEO4J_PASSWORD']
NEO4J_DATABASE = os.environ['NEO4J_DATABASE']

# EMBEDDINGS = OllamaEmbeddings(
#    model="mxbai-embed-large",
# )

EMBEDDINGS = HuggingFaceEmbeddings(
    model_name="mixedbread-ai/mxbai-embed-large-v1"
)


def hybrid_search(input_text, top_k):

    # グラフからノード検索用インデックスを取得
    index = Neo4jVector.from_existing_graph(
        embedding=EMBEDDINGS,
        url=NEO4J_URL,
        username=NEO4J_USERNAME,
        password=NEO4J_PASSWORD,
        database=NEO4J_DATABASE,
        node_label="Document", # 検索対象ノード
        text_node_properties=["id", "text"], # 検索対象プロパティ
        embedding_node_property="embedding", # ベクトルデータの保存先プロパティ
        index_name="vector_index", # ベクトル検索用のインデックス名
        keyword_index_name="fulltext_index", # 全文検索用のインデックス名
        search_type="hybrid" # 検索タイプに「ハイブリッド」を設定(デフォルトは「ベクター」)
    )

    all_answers = []
    # クエリを設定して検索を実行
    query = input_text
    docs_with_score = index.similarity_search_with_score(query, k=top_k)
    for i in docs_with_score:
        doc, score = i
        all_answers.append(doc.metadata["source"])

    return "\n\n************************************************************\n\n".join(all_answers)


CSS ="""
.contain { display: flex; flex-direction: column; }
.gradio-container { height: 100vh !important; }
#component-0 { height: 100%; }
#textbox { flex-grow: 1; overflow: auto; resize: vertical; font-size:18px !important; font-weight:500 !important; }
.secondary {background-color: #6366f1; }
#full-width-button { width: 100%; }
#search-result { overflow-y: auto !important; font-size:18px !important; font-weight:500 !important; }
"""
#with gr.Blocks() as demo:
with gr.Blocks(theme=gr.themes.Monochrome(radius_size=gr.themes.sizes.radius_sm)) as demo:
    with gr.Row():
        with gr.Column():
            gr.Markdown(f"""
                    ### ・非公式サイトです  
                    ### ・デモでしかないので速度・精度・動作は保証しないし新しい裁定にも対応しません。突然消す可能性もあり
                    ### ・ですます調で質問をすると精度が上がるかも
                    """)
    with gr.Row():
        gr.Markdown("# 裁定検索")
    with gr.Row():
        output = gr.TextArea(
            elem_id="search-result",
            label="検索結果",
        )
    with gr.Row():
        input = gr.Textbox(
            label="質問",
            placeholder="カードを指定して破壊する能力でクリーチャーの下にあるカードを指定できますか",
            lines=3,
        )
    with gr.Row():
        submit = gr.Button(value="検索", variant="secondary", elem_id="full-width-button")
        top_k = gr.Slider(1, 10, label="表示数", step=1, value=5, interactive=True)

    submit_click_event = submit.click(fn=hybrid_search, inputs=[input, top_k], outputs=output)

demo.launch()