import os from dotenv import load_dotenv from langchain_groq import ChatGroq from langchain_community.tools import DuckDuckGoSearchRun from langchain_core.tools import tool from langgraph.prebuilt import create_react_agent import gradio as gr import time load_dotenv() GROQ_API_KEY = os.getenv("GROQ_API_KEY") llm = ChatGroq( model="llama-3.1-8b-instant", api_key=GROQ_API_KEY, temperature=0.3 ) search = DuckDuckGoSearchRun() @tool def web_search(query: str) -> str: """Search the web for current information about a topic.""" max_retries = 3 for attempt in range(max_retries): try: results = search.run(query) if results: return results except Exception as e: if attempt < max_retries - 1: time.sleep(2) # tunggu 2 detik sebelum retry else: return f"Search tidak tersedia saat ini, menggunakan pengetahuan model: {query}" return "Search tidak tersedia." @tool def summarize_text(text: str) -> str: """Summarize a given text into key bullet points. Input should be the text to summarize.""" response = llm.invoke(f"Summarize the following text concisely in 3-5 bullet points:\n\n{text}") return response.content tools = [web_search, summarize_text] agent_executor = create_react_agent(llm, tools) def research_topic(topic: str, language: str = "Indonesia") -> str: if not topic.strip(): return "Masukkan topik yang ingin diriset." try: query = f"""Research the following topic comprehensively and provide a detailed report in {language}: Topic: {topic} Please search for recent information at least 2-3 times with different queries, summarize findings, and structure a final report in {language}.""" result = agent_executor.invoke({"messages": [{"role": "user", "content": query}]}) final_answer = result["messages"][-1].content format_prompt = f"""Format the following research findings into a well-structured report in {language}: {final_answer} Structure: # Laporan Riset: {topic} ## Temuan Utama [key findings as bullet points] ## Tren & Perkembangan [trends and developments] ## Insight & Analisis [insights and analysis] ## Kesimpulan [brief conclusion] IMPORTANT: Do NOT add any appendix, references, or lampiran section. Only include the sections above. Write in {language}.""" formatted = llm.invoke(format_prompt) return formatted.content except Exception as e: return f"Error: {str(e)}\n\nTip: Coba topik yang lebih spesifik." css = """ .gradio-container { max-width: 900px !important; margin: 0 auto !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important; } .header-section { text-align: center; padding: 2rem 0 1.5rem; border-bottom: 1px solid #e5e7eb; margin-bottom: 1.5rem; } .header-section h1 { font-size: 1.5rem; font-weight: 600; color: #111827; margin-bottom: 0.5rem; } .header-section p { font-size: 0.9rem; color: #6b7280; margin: 0; } .badge-row { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 0.75rem; } .badge { font-size: 0.75rem; padding: 3px 10px; border-radius: 999px; background: #f3f4f6; color: #374151; border: 1px solid #e5e7eb; } footer { display: none !important; } """ with gr.Blocks(css=css, title="Research Assistant") as demo: gr.HTML("""
Riset topik apapun secara otomatis menggunakan multi-agent AI