ofermend commited on
Commit
834e5f8
β€’
1 Parent(s): 1d1fdde

updated to us vectara-agent

Browse files
Files changed (2) hide show
  1. app.py +102 -92
  2. prompts.py +0 -76
app.py CHANGED
@@ -4,23 +4,14 @@ import streamlit as st
4
  import os
5
  from PIL import Image
6
  import re
7
- from translate import Translator
8
- from pydantic import Field
9
  import sys
 
10
 
11
- from llama_index.indices.managed.vectara import VectaraIndex
12
- from llama_index.core.agent import ReActAgent
13
- from llama_index.llms.openai import OpenAI
14
- from llama_index.core.tools import QueryEngineTool, ToolMetadata
15
- from llama_index.core.utils import print_text
16
- from llama_index.core.agent.react.formatter import ReActChatFormatter
17
 
18
- from llama_index.core.agent import ReActAgent
19
- from llama_index.agent.openai import OpenAIAgent
20
- from llama_index.core.tools import FunctionTool
21
-
22
-
23
- from prompts import prompt_template
24
 
25
  teaching_styles = ['traditional', 'Inquiry-based', 'Socratic']
26
  languages = {'English': 'en', 'Spanish': 'es', 'French': 'fr', 'German': 'de', 'Arabic': 'ar', 'Chinese': 'zh-cn',
@@ -28,76 +19,94 @@ languages = {'English': 'en', 'Spanish': 'es', 'French': 'fr', 'German': 'de', '
28
  initial_prompt = "How can I help you today?"
29
 
30
 
31
- def launch_bot(agent_type: str):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  def reset():
33
  cfg = st.session_state.cfg
34
- llm = OpenAI(model="gpt-4o", temperature=0)
35
- tr_prompt = Translator(to_lang=languages[cfg.language]).translate(initial_prompt)
36
- st.session_state.messages = [{"role": "assistant", "content": tr_prompt, "avatar": "πŸ¦–"}]
37
- st.session_state.thinking_prompt = Translator(to_lang=languages[cfg.language]).translate("Thinking...")
38
- vectara = VectaraIndex(vectara_api_key=cfg.api_key,
39
- vectara_customer_id=cfg.customer_id,
40
- vectara_corpus_id=cfg.corpus_id)
41
-
42
- # Create tool to adapt output to style, age and language
43
- def adjust_response_to_student(
44
- text: str = Field(descrition='the original text'),
45
- age: int = Field(description='the age of the student. An integer'),
46
- style: str = Field(description='teaching style'),
47
- language: str = Field(description='the language')
48
- ) -> str:
49
- """
50
- Rephrase the text to match the student's age, desired teaching style and language
51
- """
52
- llm = OpenAI(model="gpt-4o", temperature=0)
53
- prompt = f'''
54
- The following is response the teacher is planning to provide to a student based on their question.
55
- Please adjust the response to match the student's age of {age}, the {style} teaching style.
56
- For example, in the inquiry-based teaching style, choose to ask questions that encourage the student to think critically instead of repsonding directly with the answer.
57
- Or in the socratic teaching style, choose to ask questions that lead the student to the answer.
58
- Always respond in the {language} language.
59
- original response: {text}
60
- adjusted response:
61
- '''
62
- response = llm.complete(prompt)
63
- return response
64
-
65
-
66
- # Create the Vectara Tool
67
- vectara_tool = QueryEngineTool(
68
- query_engine = vectara.as_query_engine(summary_enabled = True, summary_num_results = 15, summary_response_lang = languages[cfg.language],
69
- summary_prompt_name = "ectara-experimental-summary-ext-2023-12-11-large",
70
- vectara_query_mode = "mmr", rerank_k = 50, mmr_diversity_bias = 0.2,
71
- n_sentence_before = 5, n_sentence_after = 5),
72
- metadata = ToolMetadata(name="vectara",
73
- description="""
74
- A tool that is able to answer questions about the justice, morality, politics and related topics.
75
- Based on transcripts of recordings from the Justice Harvard class that includes a lot of content on these topics.
76
- When using the tool it's best to ask simple short questions.
77
- """),
78
- )
79
-
80
- rephrase_tool = FunctionTool.from_defaults(adjust_response_to_student)
81
-
82
- # Create the agent
83
- prompt = prompt_template.replace("{style}", cfg.style) \
84
- .replace("{language}", cfg.language) \
85
- .replace("{student_age}", str(cfg.student_age))
86
- tools = [vectara_tool, rephrase_tool]
87
- if agent_type == 'react':
88
- st.session_state.agent = ReActAgent.from_tools(
89
- tools=tools, llm=llm, verbose=True,
90
- react_chat_formatter = ReActChatFormatter(system_header=prompt),
91
- max_iterations = 20,
92
- )
93
- elif agent_type == 'openai':
94
- st.session_state.agent = OpenAIAgent.from_tools(
95
- tools=tools, llm=llm, verbose=True,
96
- system_prompt=prompt)
97
- else:
98
- raise ValueError(f"Unknown agent type: {agent_type}")
99
-
100
 
 
101
  if 'cfg' not in st.session_state:
102
  cfg = OmegaConf.create({
103
  'customer_id': str(os.environ['VECTARA_CUSTOMER_ID']),
@@ -106,15 +115,15 @@ def launch_bot(agent_type: str):
106
  'style': teaching_styles[0],
107
  'language': 'English',
108
  'student_age': 18
 
109
  })
110
  st.session_state.cfg = cfg
111
  st.session_state.style = cfg.style
112
  st.session_state.language = cfg.language
113
  st.session_state.student_age = cfg.student_age
114
- reset()
115
 
 
116
  cfg = st.session_state.cfg
117
- st.set_page_config(page_title="Teaching Assistant", layout="wide")
118
 
119
  # left side content
120
  with st.sidebar:
@@ -168,22 +177,23 @@ def launch_bot(agent_type: str):
168
  if prompt := st.chat_input():
169
  st.session_state.messages.append({"role": "user", "content": prompt, "avatar": 'πŸ§‘β€πŸ’»'})
170
  with st.chat_message("user", avatar='πŸ§‘β€πŸ’»'):
171
- print_text(f"Starting new question: {prompt}\n", color='green')
172
  st.write(prompt)
173
 
174
- # Generate a new response if last message is not from assistant
175
  if st.session_state.messages[-1]["role"] != "assistant":
176
  with st.chat_message("assistant", avatar='πŸ€–'):
177
- with st.spinner(st.session_state.thinking_prompt):
 
178
  res = st.session_state.agent.chat(prompt)
179
- cleaned = re.sub(r'\[\d+\]', '', res.response)
180
- st.write(cleaned)
181
  message = {"role": "assistant", "content": cleaned, "avatar": 'πŸ€–'}
182
  st.session_state.messages.append(message)
183
-
 
 
184
  sys.stdout.flush()
185
-
 
186
  if __name__ == "__main__":
187
- print("Starting up...")
188
- launch_bot(agent_type = 'openai')
189
 
 
4
  import os
5
  from PIL import Image
6
  import re
 
 
7
  import sys
8
+ import datetime
9
 
10
+ from pydantic import Field, BaseModel
11
+ from vectara_agent.agent import Agent, AgentType, AgentStatusType
12
+ from vectara_agent.tools import ToolsFactory
13
+ from vectara_agent.tools_catalog import rephrase_text
 
 
14
 
 
 
 
 
 
 
15
 
16
  teaching_styles = ['traditional', 'Inquiry-based', 'Socratic']
17
  languages = {'English': 'en', 'Spanish': 'es', 'French': 'fr', 'German': 'de', 'Arabic': 'ar', 'Chinese': 'zh-cn',
 
19
  initial_prompt = "How can I help you today?"
20
 
21
 
22
+ def create_tools(cfg):
23
+
24
+ def adjust_response_to_student(
25
+ text: str = Field(description='the original text.'),
26
+ age: int = Field(description='the age of the student. An integer'),
27
+ style: str = Field(description='teaching style'),
28
+ language: str = Field(description='the language')
29
+
30
+ ) -> str:
31
+ """
32
+ Rephrase the text to match the student's age, desired teaching style and language
33
+ """
34
+ instructions = f'''
35
+ The following is response the teacher is planning to provide to a student based on their question.
36
+ Please adjust the response to match the student's age of {age}, the {style} teaching style.
37
+ For example, in the inquiry-based teaching style, choose to ask questions that encourage the student to think critically instead of repsonding directly with the answer.
38
+ Or in the socratic teaching style, choose to ask questions that lead the student to the answer.
39
+ Always respond in the {language} language.''' \
40
+ .replace("{style}", cfg.style) \
41
+ .replace("{language}", cfg.language) \
42
+ .replace("{student_age}", str(cfg.student_age))
43
+
44
+ return rephrase_text(text, instructions)
45
+
46
+
47
+ class JusticeHarvardArgs(BaseModel):
48
+ query: str = Field(..., description="The user query.")
49
+
50
+ tools_factory = ToolsFactory(vectara_api_key=cfg.api_key,
51
+ vectara_customer_id=cfg.customer_id,
52
+ vectara_corpus_id=cfg.corpus_id)
53
+ query_tool = tools_factory.create_rag_tool(
54
+ tool_name = "justice_harvard_query",
55
+ tool_description = """
56
+ Given a user query, returns a response (str) based on the content of the Justice Harvard lecture transcripts.
57
+ It can answer questions about the justice, morality, politics and related topics,
58
+ based on transcripts of recordings from the Justice Harvard class that includes a lot of content on these topics.
59
+ When using the tool it's best to ask simple short questions. You can break complex questions into sub-queries.
60
+ """,
61
+ tool_args_schema = JusticeHarvardArgs,
62
+ tool_filter_template = '',
63
+ reranker = "multilingual_reranker_v1", rerank_k = 100,
64
+ n_sentences_before = 2, n_sentences_after = 2, lambda_val = 0.01,
65
+ summary_num_results = 10,
66
+ vectara_summarizer = 'vectara-summary-ext-24-05-med-omni',
67
+ )
68
+
69
+ return (tools_factory.get_tools(
70
+ [
71
+ adjust_response_to_student,
72
+ ]
73
+ ) +
74
+ tools_factory.standard_tools() +
75
+ tools_factory.guardrail_tools() +
76
+ [query_tool]
77
+ )
78
+
79
+ @st.cache_resource
80
+ def initialize_agent(agent_type: AgentType, _cfg):
81
+ date = datetime.datetime.now().strftime("%Y-%m-%d")
82
+ bot_instructions = f"""
83
+ - You are a helpful teacher assistant, with expertise in education in various teaching styles.
84
+ - Today's date is {date}.
85
+ - Response in a concise and clear manner, and provide the most relevant information to the student.
86
+ - Use tools when available instead of depending on your own knowledge.
87
+ """
88
+
89
+ def update_func(status_type: AgentStatusType, msg: str):
90
+ output = f"{status_type.value} - {msg}"
91
+ st.session_state.thinking_placeholder.text(output)
92
+
93
+ agent = Agent(
94
+ agent_type=agent_type,
95
+ tools=create_tools(_cfg),
96
+ topic="An educator with expertise in philosophy",
97
+ custom_instructions=bot_instructions,
98
+ update_func=update_func
99
+ )
100
+ return agent
101
+
102
+ def launch_bot(agent_type: AgentType):
103
  def reset():
104
  cfg = st.session_state.cfg
105
+ st.session_state.messages = [{"role": "assistant", "content": initial_prompt, "avatar": "πŸ¦–"}]
106
+ st.session_state.thinking_message = "Agent at work..."
107
+ st.session_state.agent = initialize_agent(agent_type, cfg)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
+ st.set_page_config(page_title="Justice Harvard Teaching Assistant", layout="wide")
110
  if 'cfg' not in st.session_state:
111
  cfg = OmegaConf.create({
112
  'customer_id': str(os.environ['VECTARA_CUSTOMER_ID']),
 
115
  'style': teaching_styles[0],
116
  'language': 'English',
117
  'student_age': 18
118
+
119
  })
120
  st.session_state.cfg = cfg
121
  st.session_state.style = cfg.style
122
  st.session_state.language = cfg.language
123
  st.session_state.student_age = cfg.student_age
 
124
 
125
+ reset()
126
  cfg = st.session_state.cfg
 
127
 
128
  # left side content
129
  with st.sidebar:
 
177
  if prompt := st.chat_input():
178
  st.session_state.messages.append({"role": "user", "content": prompt, "avatar": 'πŸ§‘β€πŸ’»'})
179
  with st.chat_message("user", avatar='πŸ§‘β€πŸ’»'):
180
+ print(f"Starting new question: {prompt}\n")
181
  st.write(prompt)
182
 
 
183
  if st.session_state.messages[-1]["role"] != "assistant":
184
  with st.chat_message("assistant", avatar='πŸ€–'):
185
+ with st.spinner(st.session_state.thinking_message):
186
+ st.session_state.thinking_placeholder = st.empty()
187
  res = st.session_state.agent.chat(prompt)
188
+ cleaned = re.sub(r'\[\d+\]', '', res).replace('$', '\\$')
 
189
  message = {"role": "assistant", "content": cleaned, "avatar": 'πŸ€–'}
190
  st.session_state.messages.append(message)
191
+ st.session_state.thinking_placeholder.empty()
192
+ st.rerun()
193
+
194
  sys.stdout.flush()
195
+
196
+
197
  if __name__ == "__main__":
198
+ launch_bot(agent_type=AgentType.OPENAI)
 
199
 
prompts.py DELETED
@@ -1,76 +0,0 @@
1
-
2
- prompt_template = """
3
-
4
- You are a helpful teaching assistant in conversation with a {student_age} years old student.
5
- You task is to help the student with a variety of tasks, from answering questions
6
- to providing summaries to other types of analyses.
7
- You specialize in the {style} teaching style and apply it to this conversation.
8
-
9
- The course you are helping the student with
10
- examines fundamental questions of political philosophy and moral reasoning.
11
- It challenges students to think critically about justice, equality, democracy, and citizenship
12
- through the lens of classical and contemporary philosophical arguments.
13
-
14
- ## Tools
15
- You have access to tools. You are responsible for using
16
- the tools in any sequence you deem appropriate to complete the task at hand.
17
- This may require breaking the task into subtasks and using different tools
18
- to complete each subtask.
19
-
20
- The tools must be your main source of information to answer the student's questions.
21
- If you can't answer the question with the provided tools, you must say so.
22
-
23
- You have access to the following tools:
24
- {tool_desc}
25
-
26
- ## Input
27
- The user will specify a task or a question in text.
28
-
29
- ## Output Format
30
- To answer the question, please use the following format.
31
-
32
- ```
33
- Thought: I need to use a tool to help me answer the question.
34
- Action: tool name (one of {tool_names}) if using a tool.
35
- Action Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{"input": "hello world", "num_beams": 5}})
36
- ```
37
-
38
- Please ALWAYS start with a Thought.
39
- Please use a valid JSON format for the Action Input. Do NOT do this {{'input': 'hello world', 'num_beams': 5}}.
40
-
41
- If this format is used, the tool will respond in the following format:
42
- ```
43
- Observation: tool response
44
- ```
45
-
46
- You should keep repeating the above format until you have enough information
47
- to answer the question without using any more tools.
48
-
49
- At that point, you MUST respond
50
-
51
- Respond in the one of the following two formats:
52
-
53
- ```
54
- Thought: I can answer without using any more tools.
55
- Answer: [your answer here]
56
- ```
57
- OR if you cannot answer the question with the provided tools:
58
-
59
- ```
60
- Thought: I cannot answer the question with the provided tools.
61
- Answer: Sorry, I cannot answer your question.
62
- ```
63
-
64
- ADDITIONAL INSTRUCTIONS:
65
- - When using a tool, break down complex questions into a set of shorter questions, and ask the tool about each of them.
66
- - If a tool does not respond with a clear answer or cannot answer the query properly, try to rephrase your query or break it down into sub-queries to help it respond properly.
67
- - You must make at least one use of a tool for each question before responding.
68
- - Make sure your response relies on the tools you have used and the information from those tools.
69
- - Do not base your response on information that was not provided by the tools.
70
- - The tool response may include citations in the form [1], [2], etc. Ignore these citations.
71
- - Always use the rephrase tool at the end in order to ensure it fits the student's age, the desired teaching style and the language {language}
72
-
73
- ## Current Conversation
74
- Below is the current conversation consisting of interleaving student and assistant messages.
75
-
76
- """