Spaces:
Sleeping
Sleeping
| from llama_index.core.tools import FunctionTool | |
| from duckduckgo_search import DDGS | |
| from llama_index.llms.openai import OpenAI | |
| from llama_index.readers.wikipedia.base import WikipediaReader | |
| from llama_index.readers.papers import ArxivReader | |
| from datetime import datetime | |
| from typing import Union, List | |
| import ast | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| # model llm | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| llm = OpenAI(model="gpt-3.5-turbo", temperature=0) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| # 🔎 Outil de recherche web avec DuckDuckGo (remplace Serper) | |
| #-------------------------------------------------------------------------------------------------------------------------------------- | |
| def detect_answer_type(question: str) -> str: | |
| prompt = f""" | |
| You are a classifier. | |
| Your task is to determine the expected type of answer for a given question. | |
| Possible types: | |
| - number: a numerical value like 7 or 3.14 | |
| - list: multiple items (comma separated or array) | |
| - date: a calendar date or year | |
| - boolean: true/false, yes/no | |
| - string: a word, name, or short sentence | |
| Only return the type name. No explanation. | |
| Question: "{question}" | |
| Answer: | |
| """ | |
| response = llm.complete(prompt).text.strip().lower() | |
| return response | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| # 🔎 Outil de recherche web avec DuckDuckGo / WikipediaReader / ArxivReader | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def web_search(query: str) -> str: | |
| """Web search with DuckDuckGo""" | |
| try: | |
| with DDGS() as ddgs: | |
| results = list(ddgs.text(query, max_results=5)) | |
| # Formatage des résultats | |
| formatted_results = [] | |
| for result in results: | |
| formatted_results.append(f"📄 {result.get('title', 'No title')}\n🔗 {result.get('href', 'No link')}\n📝 {result.get('body', 'No description')}\n") | |
| return "\n".join(formatted_results) if formatted_results else "Aucun résultat trouvé." | |
| except Exception as e: | |
| return f"Erreur lors de la recherche: {str(e)}" | |
| # Création du tool de recherche | |
| search_tool = FunctionTool.from_defaults( | |
| fn=web_search, | |
| name="web_search", | |
| description="Searches for information on the web using DuckDuckGo." | |
| ) | |
| def load_arxiv(query: str) -> str: | |
| reader = ArxivReader() | |
| docs = reader.load_data(search_query=query) | |
| return "n\n".join([d.text for d in docs]) | |
| arxiv_tool = FunctionTool.from_defaults( | |
| fn= load_arxiv, | |
| name="arxiv_search", | |
| description="Recherche et chrge des articles scientifiques depuis arXiv" | |
| ) | |
| def load_wikipedia(query: str) -> str: | |
| wiki_loader = WikipediaReader() | |
| docs = wiki_loader.load_data(pages=[query]) | |
| return "\n\n".join([d.text for d in docs]) | |
| wiki_tool = FunctionTool.from_defaults( | |
| fn=load_wikipedia, | |
| name="wikipedia_search", | |
| description="Charge un article Wikipedia en anglais à partir d'un titre" | |
| ) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| # 🔧 Exemple d'outil custom | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def say_hello(name: str) -> str: | |
| """Salue une personne""" | |
| return f"Hello {name}, je suis ton agent GAIA." | |
| hello_tool = FunctionTool.from_defaults( | |
| fn=say_hello, | |
| name="say_hello", | |
| description="Salue une personne avec son nom" | |
| ) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 Résumé de texte | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def summarize_text(text: str) -> str: | |
| prompt = f""" | |
| Summarize the following text clearly, in no more than three key points. Ignore secondary details. | |
| Texte : | |
| {text} | |
| Résumé : | |
| """ | |
| return llm.complete(prompt).text.strip() | |
| summarize_tool = FunctionTool.from_defaults( | |
| fn=summarize_text, | |
| name="summarize_text", | |
| description="Provides a clear and concise summary of a long text." | |
| ) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 Extraction d'entités nommées | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def extract_entities(text: str) -> str: | |
| prompt = f""" | |
| Read the following text and list the named entities found, categorized as: people, locations, organizations, and dates. | |
| Texte : | |
| {text} | |
| Entités : | |
| """ | |
| return llm.complete(prompt).text.strip() | |
| entities_tool = FunctionTool.from_defaults( | |
| fn=extract_entities, | |
| name="extract_entities", | |
| description="Extracts names of people, places, dates, and organizations from a given text." | |
| ) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 Date du jour | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def get_today_date() -> str: | |
| return datetime.now().strftime("%Y-%m-%d") | |
| date_tool = FunctionTool.from_defaults( | |
| fn=get_today_date, | |
| name="get_today_date", | |
| description="Returns the current date in the format YYYY-MM-DD." | |
| ) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 Extraction d'événements | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def extract_events(text: str) -> str: | |
| prompt = f""" | |
| Identify and list the key events described in the following text. Use one short sentence per event. | |
| Texte : | |
| {text} | |
| Événements : | |
| """ | |
| return llm.complete(prompt).text.strip() | |
| events_tool = FunctionTool.from_defaults( | |
| fn=extract_events, | |
| name="extract_events", | |
| description="Lists major events mentioned in a text." | |
| ) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 Question ciblée sur un texte | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def question_answer(text: str, question: str) -> str: | |
| prompt = f""" | |
| You are an agent that answers questions based solely on a given text. | |
| RULES: | |
| - If the answer is clearly present in the text, provide it concisely. | |
| - If the answer is not explicitly in the text, reply: "I don't know." | |
| - Do NOT make assumptions. | |
| - Do NOT repeat the question. | |
| - Always give the shortest possible answer (e.g., a word, a date, a number). | |
| TEXTE : | |
| {text} | |
| QUESTION : | |
| {question} | |
| RÉPONSE : | |
| """ | |
| return llm.complete(prompt).text.strip() | |
| qa_tool = FunctionTool.from_defaults( | |
| fn=question_answer, | |
| name="question_answer", | |
| description="Answers a specific question based on a given text" | |
| ) | |
| def enforce_answer_format(answer: str, expected_type: str) -> Union[str, int, float, bool, List[str]]: | |
| prompt = f""" | |
| You are a formatting assistant. Your task is to extract and return only the value corresponding to the expected type from the given answer. | |
| Respond ONLY with the exact Python value (e.g., 4, "blue", true, ["a", "b"]) and nothing else. | |
| Examples: | |
| Expected type: number | |
| Answer: "There are 4 albums." | |
| Output: 4 | |
| Expected type: list | |
| Answer: "Apples, oranges, and bananas." | |
| Output: ["apples", "oranges", "bananas"] | |
| Expected type: date | |
| Answer: "He died on September 1, 1715." | |
| Output: "1715-09-01" | |
| Expected type: boolean | |
| Answer: "Yes, that's correct." | |
| Output: true | |
| Now process the following: | |
| Expected type: {expected_type} | |
| Answer: {answer} | |
| Output: | |
| """ | |
| raw_output = llm.complete(prompt).text.strip() | |
| # Tentative de parsing Python natif | |
| try: | |
| return ast.literal_eval(raw_output) | |
| except Exception: | |
| return raw_output # Fallback si ce n’est pas une valeur parseable | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 calculator | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| def calculator(expression: str) -> str: | |
| """Évalue une expression mathématique.""" | |
| try: | |
| return str(eval(expression)) | |
| except Exception: | |
| return "Erruer de calcul" | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 Question ciblée sur un texte | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| calculator_tool = FunctionTool.from_defaults( | |
| fn= calculator, | |
| name="calculator", | |
| description = "Effectue des calculs arithmétiques sur des expressions comme comme '2 + 3 * 4'." | |
| ) | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| #🔧 Question ciblée sur un texte | |
| #------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| # Liste exportable | |
| TOOLS = [search_tool, hello_tool, summarize_tool, entities_tool, date_tool, events_tool, qa_tool, calculator_tool, | |
| wiki_tool, arxiv_tool] |