Spaces:
Running
Running
| # References: | |
| # https://docs.crewai.com/introduction | |
| # https://ai.google.dev/gemini-api/docs | |
| import os | |
| from crewai import Agent, Crew, Task | |
| from crewai.agents.agent_builder.base_agent import BaseAgent | |
| from crewai.project import CrewBase, agent, crew, task | |
| from google import genai | |
| from openinference.instrumentation.crewai import CrewAIInstrumentor | |
| from phoenix.otel import register | |
| from tools.ai_tools import AITools | |
| from tools.arithmetic_tools import ArithmeticTools | |
| from typing import List | |
| from utils import read_file_json, is_ext | |
| ## LLMs | |
| MANAGER_MODEL = "gpt-4.5-preview" | |
| AGENT_MODEL = "gpt-4.1-mini" | |
| FINAL_ANSWER_MODEL = "gemini-2.5-pro-preview-03-25" | |
| # LLM evaluation | |
| PHOENIX_API_KEY = os.environ["PHOENIX_API_KEY"] | |
| os.environ["PHOENIX_CLIENT_HEADERS"] = f"api_key={PHOENIX_API_KEY}" | |
| os.environ["PHOENIX_COLLECTOR_ENDPOINT"] = "https://app.phoenix.arize.com" | |
| tracer_provider = register( | |
| auto_instrument=True, | |
| project_name="gaia" | |
| ) | |
| #CrewAIInstrumentor().instrument(tracer_provider=tracer_provider) | |
| class GAIACrew(): | |
| agents: List[BaseAgent] | |
| tasks: List[Task] | |
| def web_search_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["web_search_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=2, | |
| tools=[AITools.web_search_tool], | |
| verbose=True | |
| ) | |
| def web_browser_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["web_browser_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=3, | |
| tools=[AITools.web_browser_tool], | |
| verbose=True | |
| ) | |
| def image_analysis_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["image_analysis_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=2, | |
| tools=[AITools.image_analysis_tool], | |
| verbose=True | |
| ) | |
| def audio_analysis_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["audio_analysis_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=2, | |
| tools=[AITools.audio_analysis_tool], | |
| verbose=True | |
| ) | |
| def video_analysis_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["video_analysis_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=2, | |
| tools=[AITools.video_analysis_tool], | |
| verbose=True | |
| ) | |
| def youtube_analysis_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["youtube_analysis_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=2, | |
| tools=[AITools.youtube_analysis_tool], | |
| verbose=True | |
| ) | |
| def document_analysis_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["document_analysis_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=2, | |
| tools=[AITools.document_analysis_tool], | |
| verbose=True | |
| ) | |
| def arithmetic_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["document_analysis_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=2, | |
| tools=[ArithmeticTools.add, ArithmeticTools.subtract, ArithmeticTools.multiply, ArithmeticTools.divide, ArithmeticTools.modulus], | |
| verbose=True | |
| ) | |
| def code_generation_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["code_generation_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=3, | |
| tools=[AITools.code_generation_tool], | |
| verbose=True | |
| ) | |
| def code_execution_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["code_execution_agent"], | |
| allow_delegation=False, | |
| llm=AGENT_MODEL, | |
| max_iter=3, | |
| tools=[AITools.code_execution_tool], | |
| verbose=True | |
| ) | |
| def manager_agent(self) -> Agent: | |
| return Agent( | |
| config=self.agents_config["manager_agent"], | |
| allow_delegation=True, | |
| llm=MANAGER_MODEL, | |
| max_iter=5, | |
| verbose=True | |
| ) | |
| def manager_task(self) -> Task: | |
| return Task( | |
| config=self.tasks_config["manager_task"] | |
| ) | |
| def crew(self) -> Crew: | |
| return Crew( | |
| agents=self.agents, | |
| tasks=self.tasks, | |
| verbose=True | |
| ) | |
| def run_crew(question, file_path): | |
| final_question = question | |
| if file_path: | |
| if is_ext(file_path, ".csv") or is_ext(file_path, ".xls") or is_ext(file_path, ".xlsx") or is_ext(file_path, ".json") or is_ext(file_path, ".jsonl"): | |
| json_data = read_file_json(file_path) | |
| final_question = f"{question} JSON data:\n{json_data}." | |
| else: | |
| final_question = f"{question} File path: {file_path}." | |
| answer = GAIACrew().crew().kickoff(inputs={"question": final_question}) | |
| final_answer = get_final_answer(FINAL_ANSWER_MODEL, question, str(answer)) | |
| print(f"=> Initial question: {question}") | |
| print(f"=> Final question: {final_question}") | |
| print(f"=> Initial answer: {answer}") | |
| print(f"=> Final answer: {final_answer}") | |
| return final_answer | |
| def get_final_answer(model, question, answer): | |
| prompt_template = """ | |
| You are an expert question answering assistant. Given a question and an initial answer, your task is to provide the final answer. | |
| Your final answer must be a number and/or string OR as few words as possible OR a comma-separated list of numbers and/or strings. | |
| If you are asked for a number, don't use comma to write your number neither use units such as USD, $, percent, or % unless specified otherwise. | |
| If you are asked for a string, don't use articles, neither abbreviations (for example cities), and write the digits in plain text unless specified otherwise. | |
| If you are asked for a comma-separated list, apply the above rules depending of whether the element to be put in the list is a number or a string. | |
| If the final answer is a number, use a number not a word. | |
| If the final answer is a string, start with an uppercase character. | |
| If the final answer is a comma-separated list of numbers, use a space character after each comma. | |
| If the final answer is a comma-separated list of strings, use a space character after each comma and start with a lowercase character. | |
| Do not add any content to the final answer that is not in the initial answer. | |
| **Question:** """ + question + """ | |
| **Initial answer:** """ + answer + """ | |
| **Example 1:** What is the biggest city in California? Los Angeles | |
| **Example 2:** How many 'r's are in strawberry? 3 | |
| **Example 3:** What is the opposite of black? White | |
| **Example 4:** What are the first 5 numbers in the Fibonacci sequence? 0, 1, 1, 2, 3 | |
| **Example 5:** What is the opposite of bad, worse, worst? good, better, best | |
| **Final answer:** | |
| """ | |
| client = genai.Client(api_key=os.environ["GEMINI_API_KEY"]) | |
| response = client.models.generate_content( | |
| model=model, | |
| contents=[prompt_template] | |
| ) | |
| return response.text |