diff --git a/backend/.gitignore b/backend/.gitignore index 2eea525d8..b2cf4cf10 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1 +1,3 @@ -.env \ No newline at end of file +.env +__pycache__/ +bluebook_env/ \ No newline at end of file diff --git a/backend/README.md b/backend/README.md deleted file mode 100644 index 56cccfe39..000000000 --- a/backend/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Flask Backend - -This is the backend for the project, built using Flask. - -## Installation - -1. Install the required dependencies: - - ```bash - conda env create -f environment.yml - conda activate bluebook - ``` - -2. You will need to have your IP address allowlisted from Mongo to query the database. -3. You will also need to create an `.env` file that contains your API keys: - -``` -MONGO_URI="mongodb+srv://xxx" -OPENAI_API_KEY="sk-xxx" -``` - -## Usage - -1. Start the Flask server: - - ```bash - python app.py - ``` - -2. The server will start running on `http://localhost:8000`. - -3. Use your favorite API client (e.g., Postman) to send a POST request to `http://localhost:8000/api/chat` with the following JSON payload: - - ```json - { - "role": "user", - "content": "Tell me some courses about personal finance" - } - ``` - - You should receive a response with the recommended courses like this: - - ```json - { - "courses": [ - { - "course_code": "ECON 436", - "description": "How much should I be saving at age 35? How much of my portfolio should be invested in stocks at age 50? Which mortgage should I choose, and when should I refinance it? How much can I afford to spend per year in retirement? This course covers prescriptive models of personal saving, asset allocation, borrowing, and spending. The course is designed to answer questions facing anybody who manages their own money or is a manager in an organization that is trying to help clients manage their money.", - "title": "Personal Finance" - }, - ... - ], - "response": "To learn more about personal finance, you can start by taking courses or workshops that focus on financial management, budgeting, investing, and retirement planning. Some universities and educational platforms offer online courses on personal finance, such as ECON 436: Personal Finance and ECON 361: Corporate Finance. Additionally, you can explore resources like books, podcasts, and websites dedicated to personal finance advice and tips. It may also be helpful to consult with a financial advisor or planner for personalized guidance on managing your finances effectively." - } - ``` diff --git a/backend/app.py b/backend/app.py index e67011404..72156b228 100644 --- a/backend/app.py +++ b/backend/app.py @@ -7,6 +7,8 @@ from pymongo.mongo_client import MongoClient COURSE_QUERY_LIMIT = 5 +SAFETY_CHECK_ENABLED = False +DATABASE_RELEVANCY_CHECK_ENABLED = False load_dotenv() @@ -40,28 +42,27 @@ def chat(): if message['role'] == 'ai': message['role'] = 'assistant' - print(user_messages) - - # for safety check, not to be included in final response - user_messages_safety_check = user_messages.copy() - user_messages_safety_check.append({ - 'role': 'user', - 'content': 'Am I asking for help with courses or academics? Answer "yes" or "no".' - }) + if SAFETY_CHECK_ENABLED: + # for safety check, not to be included in final response + user_messages_safety_check = user_messages.copy() + user_messages_safety_check.append({ + 'role': 'user', + 'content': 'Am I asking for help with courses or academics? Answer "yes" or "no".' + }) - response_safety_check = chat_completion_request(messages=user_messages_safety_check) - response_safety_check = response_safety_check.choices[0].message.content - - if 'no' in response_safety_check.lower(): - response = 'I am sorry, but I can only assist with questions related to courses or academics at this time.' - json_response = { - 'response': response, - 'courses': [] - } - print('failed safety check') - return jsonify(json_response) - else: - print('passed safety check') + response_safety_check = chat_completion_request(messages=user_messages_safety_check) + response_safety_check = response_safety_check.choices[0].message.content + + if 'no' in response_safety_check.lower(): + response = 'I am sorry, but I can only assist with questions related to courses or academics at this time.' + json_response = { + 'response': response, + 'courses': [] + } + print('failed safety check') + return jsonify(json_response) + else: + print('passed safety check') # adding system message if user message does not include a system message header if user_messages[0]['role'] != 'system': @@ -70,27 +71,28 @@ def chat(): 'content': 'Your name is Eli. You are a helpful assistant for Yale University students to ask questions about courses and academics.' }) - # checking if database query is necessary - user_messages_database_relevancy_check = user_messages.copy() - user_messages_database_relevancy_check.append({ - 'role': 'user', - 'content': 'Will you be able to better answer my questions with information about specific courses related to the user query at Yale University? You should answer "yes" if you need information about courses at Yale that you don\'t have, otherwise you should answer "no".' - }) + if DATABASE_RELEVANCY_CHECK_ENABLED: + # checking if database query is necessary + user_messages_database_relevancy_check = user_messages.copy() + user_messages_database_relevancy_check.append({ + 'role': 'user', + 'content': 'Will you be able to better answer my questions with information about specific courses related to the user query at Yale University? You should answer "yes" if you need information about courses at Yale that you don\'t have, otherwise you should answer "no".' + }) - user_messages_database_relevancy_check = chat_completion_request(messages=user_messages_database_relevancy_check) - response_user_messages_database_relevancy_check = user_messages_database_relevancy_check.choices[0].message.content + user_messages_database_relevancy_check = chat_completion_request(messages=user_messages_database_relevancy_check) + response_user_messages_database_relevancy_check = user_messages_database_relevancy_check.choices[0].message.content - if 'no' in response_user_messages_database_relevancy_check.lower(): - response = chat_completion_request(messages=user_messages) - response = response.choices[0].message.content - json_response = { - 'response': response, - 'courses': [] - } - print('no need to query database for course information') - return jsonify(json_response) - else: - print('need to query database for course information') + if 'no' in response_user_messages_database_relevancy_check.lower(): + response = chat_completion_request(messages=user_messages) + response = response.choices[0].message.content + json_response = { + 'response': response, + 'courses': [] + } + print('no need to query database for course information') + return jsonify(json_response) + else: + print('need to query database for course information') # create embedding for user message to query against vector index query_vector = create_embedding(user_messages[-1]['content']) diff --git a/backend/environment.yml b/backend/environment.yml deleted file mode 100644 index d868718fe..000000000 --- a/backend/environment.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: bluebook -channels: - - defaults -dependencies: - - bzip2=1.0.8=h80987f9_5 - - ca-certificates=2024.3.11=hca03da5_0 - - expat=2.5.0=h313beb8_0 - - libcxx=14.0.6=h848a8c0_0 - - libffi=3.4.4=hca03da5_0 - - ncurses=6.4=h313beb8_0 - - openssl=3.0.13=h1a28f6b_0 - - pip=23.3.1=py312hca03da5_0 - - python=3.12.2=h99e199e_0 - - readline=8.2=h1a28f6b_0 - - setuptools=68.2.2=py312hca03da5_0 - - sqlite=3.41.2=h80987f9_0 - - tk=8.6.12=hb8d0fd4_0 - - tzdata=2024a=h04d1e81_0 - - wheel=0.41.2=py312hca03da5_0 - - xz=5.4.6=h80987f9_0 - - zlib=1.2.13=h5a0b063_0 - - pip: - - annotated-types==0.6.0 - - anyio==4.3.0 - - blinker==1.7.0 - - certifi==2024.2.2 - - click==8.1.7 - - distro==1.9.0 - - dnspython==2.6.1 - - flask==3.0.2 - - h11==0.14.0 - - httpcore==1.0.5 - - httpx==0.27.0 - - idna==3.6 - - itsdangerous==2.1.2 - - jinja2==3.1.3 - - markupsafe==2.1.5 - - openai==1.14.3 - - pydantic==2.6.4 - - pydantic-core==2.16.3 - - pymongo==4.6.3 - - python-dotenv==1.0.1 - - python-env==1.0.0 - - sniffio==1.3.1 - - tenacity==8.2.3 - - tqdm==4.66.2 - - typing-extensions==4.10.0 - - werkzeug==3.0.1 -prefix: /opt/anaconda3/envs/bluebook