Download _backend/utils/ai.py from IOE-IFAD/test: direct link, hf CLI and curl.
- Browser
- Download file 4.48 kB
-
https://huggingface.co/spaces/IOE-IFAD/test/resolve/main/_backend/utils/ai.py
- Command line
-
hf download hf://spaces/IOE-IFAD/test/_backend/utils/ai.py
-
curl -L -o ai.py https://huggingface.co/spaces/IOE-IFAD/test/resolve/main/_backend/utils/ai.py
4.48 kB
| import re | |
| import json | |
| from openai import OpenAI | |
| from langchain.prompts import ChatPromptTemplate | |
| from langchain.document_loaders import PyPDFLoader | |
| from langchain.embeddings.openai import OpenAIEmbeddings | |
| from langchain.text_splitter import RecursiveCharacterTextSplitter | |
| from langchain_openai import ChatOpenAI | |
| class AiService: | |
| def __init__(self, model="gpt-4.1-mini"): | |
| self.OPENAI_MODEL = model | |
| self.embeddings = OpenAIEmbeddings( | |
| model="text-embedding-3-small" | |
| ) | |
| self.openai = OpenAI() | |
| def generate_response(self, question_history=[], docs = [], extra_context: str = "", json_structure=None, instructions: str = None): | |
| # simplified $SELECTION_PLACEHOLDER$ | |
| original_question = question_history[-1]["content"] | |
| # attach supporting docs | |
| if docs: | |
| print(f"Found {len(docs)} supporting documents") | |
| fragments = [str(d["payload"]) for d in docs] | |
| question_history[-1]["content"] += "\n\nSupporting documents:\n" + "\n\n".join(fragments) | |
| # attach extra context | |
| if extra_context: | |
| question_history[-1]["content"] += "\n\nExtra context:\n" + extra_context | |
| try: | |
| # common parameters | |
| params = { | |
| "instructions": instructions, | |
| "input": question_history, | |
| "model": self.OPENAI_MODEL, | |
| "temperature": 0.0, | |
| "top_p": 0.25 | |
| } | |
| if json_structure: | |
| params["text_format"] = json_structure | |
| result = self.openai.responses.parse(**params) | |
| content = result.output_parsed | |
| else: | |
| result = self.openai.responses.create(**params) | |
| content = re.sub(r"\$", r"\\$", result.output_text) | |
| return content | |
| except Exception as e: | |
| print(f"Error during API request: {e}") | |
| return "" | |
| finally: | |
| # restore original question text | |
| question_history[-1]["content"] = original_question | |
| def generate_single_response(self, query, system_message, json_output=False, json_structure=None): | |
| question_history = [{"role": "system", "content": system_message}, {"role": "user", "content": query}] | |
| return self.generate_response(question_history, json_structure=json_structure) | |
| def json_response_cleaner(self, response): | |
| response = response.replace("\n", "").replace( | |
| "\t", "").replace("\\", "") | |
| return json.loads(response) | |
| def init_messages(self, system_message): | |
| return [{"role": "system", "content": system_message}] | |
| def add_user_message(self, messages, user_message): | |
| messages.append({"role": "user", "content": user_message}) | |
| return messages | |
| def add_assistant_message(self, messages, assistant_message): | |
| messages.append({"role": "assistant", "content": assistant_message}) | |
| return messages | |
| def search_pdf(self, pdf_path, query, schema, output_format): | |
| """ | |
| Search through a PDF document and extract structured information. | |
| Args: | |
| pdf_path (str): Path to the PDF file | |
| query (str): Search query | |
| schema (dict): Schema defining the required output structure | |
| Returns: | |
| dict: Extracted structured information | |
| """ | |
| # Load and split the PDF | |
| loader = PyPDFLoader(pdf_path) | |
| pages = loader.load() | |
| text_splitter = RecursiveCharacterTextSplitter( | |
| chunk_size=1000, | |
| chunk_overlap=100 | |
| ) | |
| splits = text_splitter.split_documents(pages) | |
| combined_content = "\n".join([chunk.page_content for chunk in splits]) | |
| prompt = ChatPromptTemplate.from_template( | |
| """Extract the requested information from the following text, just write the answer to the question do not include that how the document discusses it or some other form of this. DIRECTLY ANSWER THE QUESTION.: | |
| {text} | |
| {schema} | |
| Query: {query}""" | |
| ) | |
| messages = prompt.format_messages( | |
| text=combined_content, | |
| schema=schema, | |
| query=query | |
| ) | |
| llm = ChatOpenAI(temperature=0, model=self.OPENAI_MODEL).with_structured_output(output_format) | |
| response = llm.invoke(messages) | |
| return response |