|
import os |
|
|
|
import gradio as gr |
|
from gradio.themes.base import Base |
|
from gradio.themes.utils import colors, fonts, sizes |
|
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_URL = os.environ['NEO4J_URL'] |
|
NEO4J_USERNAME = os.environ['NEO4J_USERNAME'] |
|
NEO4J_PASSWORD = os.environ['NEO4J_PASSWORD'] |
|
NEO4J_DATABASE = os.environ['NEO4J_DATABASE'] |
|
|
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
class CustomTheme(Base): |
|
def __init__( |
|
self, |
|
*, |
|
primary_hue: colors.Color | str = colors.blue, |
|
secondary_hue: colors.Color | str = colors.gray, |
|
neutral_hue: colors.Color | str = colors.gray, |
|
spacing_size: sizes.Size | str = sizes.spacing_md, |
|
radius_size: sizes.Size | str = sizes.radius_md, |
|
text_size: sizes.Size | str = sizes.text_lg, |
|
font: fonts.Font |
|
| str |
|
| list[fonts.Font | str] = ( |
|
fonts.GoogleFont("IBM Plex Sans"), |
|
"Arial", |
|
"sans-serif", |
|
), |
|
font_mono: fonts.Font |
|
| str |
|
| list[fonts.Font | str] = ( |
|
fonts.GoogleFont("IBM Plex Mono"), |
|
"Courier", |
|
"monospace", |
|
), |
|
): |
|
super().__init__( |
|
primary_hue=primary_hue, |
|
secondary_hue=secondary_hue, |
|
neutral_hue=neutral_hue, |
|
spacing_size=spacing_size, |
|
radius_size=radius_size, |
|
text_size=text_size, |
|
font=font, |
|
font_mono=font_mono, |
|
) |
|
|
|
|
|
theme = CustomTheme() |
|
|
|
CSS =""" |
|
.contain { display: flex; flex-direction: column; } |
|
.gradio-container { min-height: 100vh !important; } |
|
#component-0 { height: 100%; } |
|
#textbox { flex-grow: 1; overflow: auto; resize: vertical;} |
|
.secondary {background-color: #6366f1; } |
|
#full-width-button { width: 100%; } |
|
#search-result { overflow-y: scroll !important; font-size:18px !important; font-weight:500 !important;} |
|
#question-box { font-size:18px !important; font-weight:500 !important; } |
|
""" |
|
|
|
with gr.Blocks(theme=theme, css=CSS) as demo: |
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown(f""" |
|
### ・非公式サイトです |
|
### ・デモでしかないので速度・精度・動作は保証しないし新しい裁定にも対応しません。突然消す可能性もあり |
|
### ・ですます調で質問をすると精度が上がるかも\n\n |
|
""") |
|
|
|
|
|
with gr.Row(): |
|
gr.Markdown("<br><br>", elem_id="spacer", visible=True) |
|
|
|
with gr.Row(): |
|
gr.Markdown("# 裁定検索") |
|
with gr.Row(): |
|
output = gr.TextArea( |
|
elem_id="search-result", |
|
label="検索結果", |
|
) |
|
with gr.Row(): |
|
input = gr.Textbox( |
|
elem_id="question-box", |
|
label="質問", |
|
placeholder="カードを指定して破壊する能力でクリーチャーの下にあるカードを指定できますか", |
|
lines=3, |
|
) |
|
with gr.Row(): |
|
submit = gr.Button(value="検索", variant="huggingface", 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() |