Spaces:
Sleeping
Sleeping
Update app.py
Browse files加入chatgpt判斷要用哪個關鍵字搜尋
app.py
CHANGED
|
@@ -9,6 +9,7 @@ from duckduckgo_search import DDGS
|
|
| 9 |
import json
|
| 10 |
from langgraph.graph import StateGraph
|
| 11 |
from typing import TypedDict, Optional
|
|
|
|
| 12 |
|
| 13 |
# (Keep Constants as is)
|
| 14 |
# --- Constants ---
|
|
@@ -41,19 +42,40 @@ def analyze_question(state: QueryState) -> QueryState:
|
|
| 41 |
new_state['query_type'] = "other"
|
| 42 |
return new_state
|
| 43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
def search_wikipedia(state: QueryState) -> QueryState:
|
| 45 |
new_state = state.copy()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
try:
|
| 47 |
-
new_state['wiki_result'] = wikipedia.summary(
|
| 48 |
except Exception as e:
|
| 49 |
new_state['wiki_result'] = f"[Wikipedia無結果] {e}"
|
| 50 |
return new_state
|
| 51 |
|
| 52 |
def search_web(state: QueryState) -> QueryState:
|
| 53 |
new_state = state.copy()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
try:
|
| 55 |
with DDGS() as ddgs:
|
| 56 |
-
results = list(ddgs.text(
|
| 57 |
if results:
|
| 58 |
new_state['web_result'] = results[0]['body']
|
| 59 |
else:
|
|
@@ -64,9 +86,13 @@ def search_web(state: QueryState) -> QueryState:
|
|
| 64 |
|
| 65 |
def search_arxiv(state: QueryState) -> QueryState:
|
| 66 |
new_state = state.copy()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
try:
|
| 68 |
client = arxiv.Client()
|
| 69 |
-
search = arxiv.Search(query=
|
| 70 |
results = list(client.results(search))
|
| 71 |
if results:
|
| 72 |
paper = results[0]
|
|
@@ -79,8 +105,20 @@ def search_arxiv(state: QueryState) -> QueryState:
|
|
| 79 |
|
| 80 |
def synthesize_answer(state: QueryState) -> QueryState:
|
| 81 |
new_state = state.copy()
|
| 82 |
-
|
| 83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
return new_state
|
| 85 |
|
| 86 |
# 條件分支
|
|
|
|
| 9 |
import json
|
| 10 |
from langgraph.graph import StateGraph
|
| 11 |
from typing import TypedDict, Optional
|
| 12 |
+
import openai
|
| 13 |
|
| 14 |
# (Keep Constants as is)
|
| 15 |
# --- Constants ---
|
|
|
|
| 42 |
new_state['query_type'] = "other"
|
| 43 |
return new_state
|
| 44 |
|
| 45 |
+
def extract_query_with_gpt(question: str) -> str:
|
| 46 |
+
prompt = '''You are a search query generator.\nGiven a user question, extract the most relevant and concise English search query or keywords that would help find the answer in Wikipedia or Google.\nOnly output the search query, do not explain or translate.\n\nExamples:\nQuestion: Who won the Nobel Prize in Physics in 2020?\nSearch query: Nobel Prize Physics 2020 winner\n\nQuestion: How many studio albums were published by Mercedes Sosa between 2000 and 2009?\nSearch query: Mercedes Sosa studio albums 2000-2009\n\nQuestion: What is the capital city of Mongolia?\nSearch query: Mongolia capital city\n\nQuestion: {question}\nSearch query:'''.format(question=question)
|
| 47 |
+
try:
|
| 48 |
+
response = openai.ChatCompletion.create(
|
| 49 |
+
model="gpt-4o",
|
| 50 |
+
messages=[{"role": "user", "content": prompt}],
|
| 51 |
+
max_tokens=32,
|
| 52 |
+
temperature=0.2,
|
| 53 |
+
)
|
| 54 |
+
return response.choices[0].message.content.strip()
|
| 55 |
+
except Exception as e:
|
| 56 |
+
return question # fallback: 用原題目
|
| 57 |
+
|
| 58 |
def search_wikipedia(state: QueryState) -> QueryState:
|
| 59 |
new_state = state.copy()
|
| 60 |
+
if new_state['query_type'] != 'fact':
|
| 61 |
+
new_state['wiki_result'] = "Not supported"
|
| 62 |
+
return new_state
|
| 63 |
+
query = extract_query_with_gpt(new_state['question'])
|
| 64 |
try:
|
| 65 |
+
new_state['wiki_result'] = wikipedia.summary(query, sentences=2)
|
| 66 |
except Exception as e:
|
| 67 |
new_state['wiki_result'] = f"[Wikipedia無結果] {e}"
|
| 68 |
return new_state
|
| 69 |
|
| 70 |
def search_web(state: QueryState) -> QueryState:
|
| 71 |
new_state = state.copy()
|
| 72 |
+
if new_state['query_type'] != 'fact':
|
| 73 |
+
new_state['web_result'] = "Not supported"
|
| 74 |
+
return new_state
|
| 75 |
+
query = extract_query_with_gpt(new_state['question'])
|
| 76 |
try:
|
| 77 |
with DDGS() as ddgs:
|
| 78 |
+
results = list(ddgs.text(query, max_results=2))
|
| 79 |
if results:
|
| 80 |
new_state['web_result'] = results[0]['body']
|
| 81 |
else:
|
|
|
|
| 86 |
|
| 87 |
def search_arxiv(state: QueryState) -> QueryState:
|
| 88 |
new_state = state.copy()
|
| 89 |
+
if new_state['query_type'] != 'fact':
|
| 90 |
+
new_state['arxiv_result'] = "Not supported"
|
| 91 |
+
return new_state
|
| 92 |
+
query = extract_query_with_gpt(new_state['question'])
|
| 93 |
try:
|
| 94 |
client = arxiv.Client()
|
| 95 |
+
search = arxiv.Search(query=query, max_results=1, sort_by=arxiv.SortCriterion.Relevance)
|
| 96 |
results = list(client.results(search))
|
| 97 |
if results:
|
| 98 |
paper = results[0]
|
|
|
|
| 105 |
|
| 106 |
def synthesize_answer(state: QueryState) -> QueryState:
|
| 107 |
new_state = state.copy()
|
| 108 |
+
if new_state['query_type'] != 'fact':
|
| 109 |
+
new_state['final_answer'] = "Not supported"
|
| 110 |
+
return new_state
|
| 111 |
+
prompt = f'''You are an expert answer extractor.\nGiven the following search results from Wikipedia, DuckDuckGo, and arXiv, extract and output ONLY the final, most accurate answer to the original question.\nDo not explain, do not repeat the question, do not add any extra text.\nIf the answer is a number, only output the number. If it is a name, only output the name. If the answer is a list, only output the list in the required format. If you cannot find the answer, output None.\n\nExamples:\nOriginal question: How many studio albums were published by Mercedes Sosa between 2000 and 2009?\n[Wikipedia]\nMercedes Sosa released three studio albums between 2000 and 2009.\n[DuckDuckGo]\nMercedes Sosa's discography includes albums released in 2000, 2002, and 2005.\n[arXiv]\nNo relevant results.\nFinal answer: 3\n\nOriginal question: What is the capital city of Mongolia?\n[Wikipedia]\nThe capital city of Mongolia is Ulaanbaatar.\n[DuckDuckGo]\nUlaanbaatar is the capital of Mongolia.\n[arXiv]\nNo relevant results.\nFinal answer: Ulaanbaatar\n\nOriginal question: {new_state['question']}\n[Wikipedia]\n{new_state['wiki_result']}\n[DuckDuckGo]\n{new_state['web_result']}\n[arXiv]\n{new_state['arxiv_result']}\nFinal answer:'''
|
| 112 |
+
try:
|
| 113 |
+
response = openai.ChatCompletion.create(
|
| 114 |
+
model="gpt-4o",
|
| 115 |
+
messages=[{"role": "user", "content": prompt}],
|
| 116 |
+
max_tokens=64,
|
| 117 |
+
temperature=0.2,
|
| 118 |
+
)
|
| 119 |
+
new_state['final_answer'] = response.choices[0].message.content.strip()
|
| 120 |
+
except Exception as e:
|
| 121 |
+
new_state['final_answer'] = "[LLM後處理錯誤]"
|
| 122 |
return new_state
|
| 123 |
|
| 124 |
# 條件分支
|