Aurele000 commited on
Commit
54408cb
·
1 Parent(s): 8644d0b

1er essai

Browse files
Files changed (3) hide show
  1. agent.py +154 -0
  2. app.py +6 -5
  3. requirements.txt +6 -1
agent.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_community.document_loaders import WikipediaLoader
2
+ from langchain_community.document_loaders import ArxivLoader
3
+ from langchain_core.tools import tool
4
+ from langgraph_supervisor import create_supervisor
5
+ from langchain.chat_models import init_chat_model
6
+ import os
7
+ from langchain_openai import ChatOpenAI
8
+ from langgraph.prebuilt import create_react_agent
9
+ from openai import OpenAI
10
+ import re
11
+
12
+ api_open_ai_agent_key=os.environ["OPENAI_API_KEY"]
13
+ client = OpenAI(api_key=api_open_ai_agent_key)
14
+ llm_4o = ChatOpenAI(
15
+ model_name="gpt-4o",
16
+ openai_api_key=api_open_ai_agent_key, # ou variable d’environnement
17
+ )
18
+
19
+
20
+ @tool
21
+ def wiki_search(query: str) -> str:
22
+ """Search Wikipedia for a query and return maximum 2 results.
23
+
24
+ Args:
25
+ query: The search query."""
26
+ search_docs = WikipediaLoader(query=query, load_max_docs=2).load()
27
+ formatted_search_docs = "\n\n---\n\n".join(
28
+ [
29
+ f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
30
+ for doc in search_docs
31
+ ])
32
+ return {"wiki_results": formatted_search_docs}
33
+
34
+
35
+ @tool
36
+ def arvix_search(query: str) -> str:
37
+ """Search Arxiv for a query and return maximum 3 result.
38
+
39
+ Args:
40
+ query: The search query."""
41
+ search_docs = ArxivLoader(query=query, load_max_docs=3).load()
42
+ formatted_search_docs = "\n\n---\n\n".join(
43
+ [
44
+ f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content[:1000]}\n</Document>'
45
+ for doc in search_docs
46
+ ])
47
+ return {"arvix_results": formatted_search_docs}
48
+
49
+
50
+ @tool
51
+ def web_search_openai_tool(query: str) -> str:
52
+ """Call web search and the output is a structured text answering the query)
53
+
54
+ Args:
55
+ query: The search query."""
56
+ response = client.responses.create(
57
+ model="gpt-4o",
58
+ tools=[{"type": "web_search_preview"}],
59
+ input=prompt + query
60
+ )
61
+
62
+ return {"web_results": response.output_text}
63
+ @tool
64
+ def add(a: float, b: float):
65
+ """Add two numbers."""
66
+ return a + b
67
+
68
+ @tool
69
+ def multiply(a: float, b: float):
70
+ """Multiply two numbers."""
71
+ return a * b
72
+
73
+ @tool
74
+ def divide(a: float, b: float):
75
+ """Divide two numbers."""
76
+ return a / b
77
+
78
+ research_agent = create_react_agent(
79
+ model=llm_4o,
80
+ tools=[wiki_search, arvix_search],
81
+ prompt=(
82
+ "You are a research agent.\n\n"
83
+ "INSTRUCTIONS:\n"
84
+ "- Assist ONLY with research-related tasks, DO NOT do any math\n"
85
+ "- After you're done with your tasks, respond to the supervisor directly\n"
86
+ "- Respond ONLY with the results of your work, do NOT include ANY other text."
87
+ "- You only have access to arxiv or wikipedia, no other website"
88
+ ),
89
+ name="research_agent",
90
+ )
91
+
92
+ web_search_openai_agent = create_react_agent(
93
+ model=llm_4o,
94
+ tools=[web_search_openai_tool],
95
+ prompt=(
96
+ "You are a websearch agent.\n\n"
97
+ "INSTRUCTIONS:\n"
98
+ "- Assist ONLY with internet related tasks. DO NOT do any math\n"
99
+ "- After you're done with your tasks, respond to the supervisor directly\n"
100
+ "- Respond ONLY with the results of your work, do NOT include ANY other text."
101
+ "- You can browse the web then give your results to your supervisor "
102
+ ),
103
+ name="web_search_openai_agent",
104
+ )
105
+
106
+
107
+
108
+ math_agent = create_react_agent(
109
+ model=llm_4o,
110
+
111
+ tools=[add, multiply, divide],
112
+ prompt=(
113
+ "You are a math agent.\n\n"
114
+ "INSTRUCTIONS:\n"
115
+ "- Assist ONLY with math-related tasks\n"
116
+ "- After you're done with your tasks, respond to the supervisor directly\n"
117
+ "- Respond ONLY with the results of your work, do NOT include ANY other text."
118
+ ),
119
+ name="math_agent",
120
+ )
121
+
122
+
123
+ supervisor = create_supervisor(
124
+ model=init_chat_model("openai:gpt-4o", api_key = api_open_ai_agent_key),
125
+ agents=[research_agent, math_agent, web_search_openai_agent],
126
+ prompt=(
127
+ "You are a supervisor managing three agents:\n"
128
+ "- research_agent: Specialised in ArXiv and Wikipedia. Assign research-related tasks to this agent.\n"
129
+ "- math_agent: Handles math-related tasks such as solving equations or performing calculations.\n"
130
+ "- web_search_openai_agent: Can browse the web to find up-to-date and relevant information. Assign web-related tasks to this agent.\n"
131
+ "Assign work to one agent at a time. Do not call agents in parallel.\n"
132
+ "When a new question arises, always first consult the research_agent — it may provide useful information.\n"
133
+ "If research_agent yields no results, then delegate the task to web_search_openai_agent.\n"
134
+ "Each time you receive information from an agent, you have to analyze, process it then decide what to do (call an agent or give your final answer)."
135
+ "Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]. YOUR FINAL ANSWER should be a number 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 $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for 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 no punctuation is precised, don't add any. Respect the requested format"
136
+
137
+ ),
138
+ add_handoff_back_messages=True,
139
+ output_mode="full_history",
140
+ ).compile()
141
+ def clean_response(response):
142
+ match = re.search(r'FINAL ANSWER:\s*(.+)', response['supervisor']['messages'][-1].content)
143
+ answer = match.group(1).strip() if match else None
144
+ return answer
145
+ def response_from_agent(question):
146
+
147
+ for chunk in supervisor.stream(
148
+ {"messages": [{"role": "user", "content": question}]}
149
+ ):
150
+ response = chunk
151
+
152
+
153
+ response = clean_response(response)
154
+ return response
app.py CHANGED
@@ -1,22 +1,23 @@
1
  import os
2
  import gradio as gr
3
  import requests
4
- import inspect
5
  import pandas as pd
 
6
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
 
11
  # --- Basic Agent Definition ---
12
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
  class BasicAgent:
14
  def __init__(self):
15
- print("BasicAgent initialized.")
 
16
  def __call__(self, question: str) -> str:
17
  print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "BER"
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
  return fixed_answer
21
 
22
  def run_and_submit_all( profile: gr.OAuthProfile | None):
@@ -45,7 +46,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
45
  print(f"Error instantiating agent: {e}")
46
  return f"Error initializing agent: {e}", None
47
  # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
48
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
49
  print(agent_code)
50
 
51
  # 2. Fetch Questions
 
1
  import os
2
  import gradio as gr
3
  import requests
 
4
  import pandas as pd
5
+ from agent import response_from_agent, supervisor
6
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
+ api_open_ai_agent_key=os.environ["OPENAI_API_KEY"]
12
  # --- Basic Agent Definition ---
13
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
14
  class BasicAgent:
15
  def __init__(self):
16
+
17
+ self.my_agent = supervisor
18
  def __call__(self, question: str) -> str:
19
  print(f"Agent received question (first 50 chars): {question[:50]}...")
20
+ fixed_answer = response_from_agent(question)
 
21
  return fixed_answer
22
 
23
  def run_and_submit_all( profile: gr.OAuthProfile | None):
 
46
  print(f"Error instantiating agent: {e}")
47
  return f"Error initializing agent: {e}", None
48
  # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
49
+ agent_code = 'https://huggingface.co/spaces/Aurele000/Final_Assignment_Template/tree/main'
50
  print(agent_code)
51
 
52
  # 2. Fetch Questions
requirements.txt CHANGED
@@ -1,2 +1,7 @@
1
  gradio
2
- requests
 
 
 
 
 
 
1
  gradio
2
+ requests
3
+ langchain
4
+ langgraph
5
+ langchain-community
6
+ langgraph-supervisor
7
+ langchain-openai