Spaces:
Sleeping
Sleeping
File size: 5,621 Bytes
68a83b7 922a900 68a83b7 922a900 68a83b7 | 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | import gradio as gr
import cohere
import psycopg2
from psycopg2.extras import RealDictCursor
import os
from dotenv import load_dotenv
load_dotenv()
# 環境変数の設定
os.environ["PYTHONIOENCODING"] = "utf-8"
# --- 設定 ---
COHERE_API_KEY = os.getenv("COHERE_API_KEY")
DB_CONFIG = {
"host": "www.ryhintl.com",
"dbname": "smair",
"user": "smairuser",
"password": "smairuser",
"port": 10629,
"connect_timeout": 15
}
co = cohere.Client(COHERE_API_KEY)
def generate_ai_advice(query, results):
context = ""
for res in results:
context += f"- 事例: {res['title']}\n 現象: {res['phenomenon']}\n 原因: {res['cause']}\n 処置: {res['action']}\n 防止策: {res['prevention']}\n\n"
prompt = f"""
あなたはベテランの工場管理者です。以下の「ユーザーからの相談内容」に対し、提供された「過去の類似事例」を参考にして、現場で今すぐ取るべき行動と、長期的な対策をプロの視点で要約・アドバイスしてください。
# ユーザーからの相談内容:
{query}
# 過去の類似事例:
{context}
# 回答の指針:
1. 過去事例から共通する原因を特定してください。
2. 現場担当者が優先して確認すべき点(チェックポイント)を3つ挙げてください。
3. 再発防止のための改善提案を簡潔に述べてください。
回答は日本語で、現場で読みやすいように箇条書きを活用してください。
"""
# model名を安定した名称に変更(command-r-plusなど)
response = co.chat(
message=prompt,
model='command-a-03-2025'
)
return response.text
def search_troubles(query):
if not query.strip():
return "⚠️ トラブル事象を入力してください。"
conn = None
try:
# 1. ベクトル化
res = co.embed(
texts=[query],
model='embed-multilingual-v3.0',
input_type='search_query'
)
query_embedding = res.embeddings[0]
# 2. DB接続
conn = psycopg2.connect(**DB_CONFIG, client_encoding='utf8')
cur = conn.cursor(cursor_factory=RealDictCursor)
search_query = """
SELECT id, occurrence_date, process_name, equipment_name, title,
phenomenon, cause, action, prevention, severity,
1 - (embedding <=> %s::vector) AS similarity
FROM factory_troubles
ORDER BY similarity DESC
LIMIT 3;
"""
cur.execute(search_query, (query_embedding,))
results = cur.fetchall()
if not results:
return "該当する事例が見つかりませんでした。"
# 3. AIによるアドバイス生成
ai_advice = generate_ai_advice(query, results)
# 4. フォーマット
output = "## 🤖 AIからのトラブルシューティング・アドバイス\n\n"
output += f"{ai_advice}\n\n"
output += "---\n"
output += "## 🔍 参考にした過去の類似事例\n\n"
for i, res in enumerate(results):
output += f"### {i+1}. {res['title']} (類似度: {res['similarity']:.4f})\n"
output += f"**【処置】**: {res['action']}\n\n"
output += f"""
<details>
<summary><b>📄 元のデータ(出典詳細)を表示</b></summary>
<div style="background-color: #f9f9f9; padding: 10px; border-radius: 5px; border: 1px solid #ddd; color: #333;">
<p><b>発生日:</b> {res['occurrence_date']} | <b>工程:</b> {res['process_name']}</p>
<p><b>現象:</b> {res['phenomenon']}</p>
<p><b>原因:</b> {res['cause']}</p>
<p><b>防止策:</b> {res['prevention']}</p>
</div>
</details>\n\n---\n"""
return output
except Exception as e:
return f"### ⚠️ エラーが発生しました\n詳細: `{repr(e)}`"
finally:
if conn: conn.close()
# --- Gradio Blocks UI ---
with gr.Blocks(title="AI工場トラブル・コンシェルジュ", css=".gradio-container {background-color: #f5f7f9}") as demo:
gr.Markdown("# 🛠 AI工場トラブル・コンシェルジュ")
gr.Markdown("過去の知見に基づき、AIが現場の課題解決に向けたアドバイスを生成します。")
with gr.Row():
with gr.Column():
input_text = gr.Textbox(
label="現在のトラブル状況を入力",
info="例: コンベアのモーターが高温になっており、焦げたような臭いがする。 加工面の焼け発生している。 末端のシール部からの液漏れがある。",
lines=3
)
# ボタンクリック時に非活性化するように設定可能
search_btn = gr.Button("🔍 知見を検索してAIアドバイスを受ける", variant="primary")
with gr.Row():
# ステータス表示用のコンポーネント(任意ですが、標準機能で十分カバーされます)
output_markdown = gr.Markdown(value="ここに結果が表示されます。")
# .click の際に、検索中はボタンを無効化し、ローディングを表示する設定
search_btn.click(
fn=search_troubles,
inputs=input_text,
outputs=output_markdown,
show_progress="full", # "full"にすることで画面全体にローディングインジケータを表示
scroll_to_output=True # 完了時に結果へスクロール
)
if __name__ == "__main__":
demo.launch() |