|
|
| import json |
| import numpy as np |
| from flask import Flask, request, jsonify |
| from sentence_transformers import SentenceTransformer |
| from sklearn.metrics.pairwise import cosine_similarity |
| import os |
|
|
| app = Flask(__name__) |
|
|
| |
| |
| |
| CHUNKS_FILE = 'leemai_all_chunks.json' |
| EMBEDDINGS_FILE = 'leemai_document_embeddings.npy' |
|
|
| |
| |
| print("Loading SentenceTransformer model...") |
| embedding_model = SentenceTransformer('all-MiniLM-L6-v2') |
| print("Model loaded successfully.") |
|
|
| |
| print(f"Loading chunks from {CHUNKS_FILE}...") |
| if not os.path.exists(CHUNKS_FILE): |
| print(f"Error: {CHUNKS_FILE} not found. Please ensure it's in the same directory as app.py or provide the correct path.") |
| all_leemai_chunks = [] |
| else: |
| with open(CHUNKS_FILE, 'r') as f: |
| all_leemai_chunks = json.load(f) |
| print(f"Loaded {len(all_leemai_chunks)} chunks.") |
|
|
| |
| print(f"Loading embeddings from {EMBEDDINGS_FILE}...") |
| if not os.path.exists(EMBEDDINGS_FILE): |
| print(f"Error: {EMBEDDINGS_FILE} not found. Please ensure it's in the same directory as app.py or provide the correct path.") |
| document_embeddings = np.array([]) |
| else: |
| document_embeddings = np.load(EMBEDDINGS_FILE) |
| print(f"Loaded embeddings with shape: {document_embeddings.shape}") |
|
|
|
|
| |
| def get_relevant_chunks(query, model, document_chunks, document_embeddings, top_k=3): |
| """Finds the most semantically similar document chunks to a given query.""" |
| if not document_chunks or document_embeddings.size == 0: |
| return [] |
|
|
| query_embedding = model.encode([query]) |
| similarities = cosine_similarity(query_embedding, document_embeddings)[0] |
| top_k_indices = similarities.argsort()[-top_k:][::-1] |
|
|
| relevant_chunks = [] |
| for i in top_k_indices: |
| relevant_chunks.append({ |
| 'chunk': document_chunks[i], |
| 'similarity': similarities[i] |
| }) |
| return relevant_chunks |
|
|
| def generate_response_from_chunks(relevant_chunks): |
| """Generates a basic response by concatenating relevant chunks with improved formatting.""" |
| if not relevant_chunks: |
| return "I couldn't find relevant information for your query in my knowledge base." |
|
|
| response_text = "Based on the information I have, here are some relevant details:\n\n" |
|
|
| for i, item in enumerate(relevant_chunks): |
| response_text += f"**Information Block {i+1}:**\n" |
| response_text += f"{item['chunk']}\n\n" |
|
|
| response_text += "I hope these details provide a comprehensive answer to your query!" |
| return response_text |
|
|
|
|
| |
| @app.route('/') |
| def home(): |
| return "LeemAI is running! Use the /ask endpoint to query." |
|
|
| @app.route('/ask', methods=['POST']) |
| def ask(): |
| data = request.get_json() |
| user_query = data.get('query') |
|
|
| if not user_query: |
| return jsonify({'error': 'No query provided'}), 400 |
|
|
| if not all_leemai_chunks or document_embeddings.size == 0: |
| return jsonify({'error': 'LeemAI knowledge base not loaded. Check server logs.'}), 500 |
|
|
| relevant_chunks = get_relevant_chunks( |
| user_query, embedding_model, all_leemai_chunks, document_embeddings |
| ) |
| leemai_response = generate_response_from_chunks(relevant_chunks) |
|
|
| return jsonify({'response': leemai_response}) |
|
|
|
|
| |
| if __name__ == '__main__': |
| |
| |
| |
| |
| app.run(debug=False, host='0.0.0.0', port=int(os.environ.get('PORT', 8080))) |
|
|