Ask a question and get an LLM-generated answer. Retrieves the most relevant chunks from the vector store, feeds them as context to the LLM, and returns the response. Args: query: The natural-language question. doc_id: Document identifier returned by
(
self, query: str, doc_id, output_parser=None, context_size=4, extraction_schema=None, verbose=False
)
| 292 | self.grobid_processor = GrobidProcessor(grobid_url, ping_server=ping_grobid_server) |
| 293 | |
| 294 | def query_document( |
| 295 | self, query: str, doc_id, output_parser=None, context_size=4, extraction_schema=None, verbose=False |
| 296 | ) -> tuple[Any, str, list]: |
| 297 | """Ask a question and get an LLM-generated answer. |
| 298 | |
| 299 | Retrieves the most relevant chunks from the vector store, feeds |
| 300 | them as context to the LLM, and returns the response. |
| 301 | |
| 302 | Args: |
| 303 | query: The natural-language question. |
| 304 | doc_id: Document identifier returned by create_memory_embeddings`. |
| 305 | output_parser: Optional LangChain output parser. If provided the |
| 306 | raw LLM response is re-processed into structured output. |
| 307 | context_size: Number of chunks to retrieve as context (default 4). |
| 308 | extraction_schema: Optional extraction schema. |
| 309 | verbose: Print debug information. |
| 310 | |
| 311 | Returns: |
| 312 | tuple: ``(parsed_output | None, raw_text_response, coordinates)`` |
| 313 | |
| 314 | - *parsed_output* — structured data if a parser/schema was given, |
| 315 | otherwise ``None``. |
| 316 | - *raw_text_response* — the LLM's raw text answer. |
| 317 | - *coordinates* — list of lists of coordinate strings for each |
| 318 | retrieved chunk (for PDF highlighting). |
| 319 | """ |
| 320 | # self.load_embeddings(self.embeddings_root_path) |
| 321 | |
| 322 | if verbose: |
| 323 | print(query) |
| 324 | |
| 325 | response, coordinates = self._run_query(doc_id, query, context_size=context_size) |
| 326 | response = response["output_text"] if "output_text" in response else response |
| 327 | |
| 328 | if verbose: |
| 329 | print(doc_id, "->", response) |
| 330 | |
| 331 | if output_parser: |
| 332 | try: |
| 333 | return self._parse_json(response, output_parser), response, coordinates |
| 334 | except Exception as oe: |
| 335 | print("Failing to parse the response", oe) |
| 336 | return None, response, coordinates |
| 337 | elif extraction_schema: |
| 338 | try: |
| 339 | chain = create_extraction_chain(extraction_schema, self.llm) |
| 340 | parsed = chain.run(response) |
| 341 | return parsed, response, coordinates |
| 342 | except Exception as oe: |
| 343 | print("Failing to parse the response", oe) |
| 344 | return None, response, coordinates |
| 345 | else: |
| 346 | return None, response, coordinates |
| 347 | |
| 348 | def query_storage(self, query: str, doc_id, context_size=4) -> tuple[List[str], list]: |
| 349 | """Retrieve relevant text passages without calling the LLM. |
no test coverage detected