def _retrieve_atom_info_candidates(
        self, atom_queries: List[str], query: str, chosen_atom_infos: List[AtomRetrievalInfo], retrieve_id: str,
    ) -> List[AtomRetrievalInfo]:
        """Retrieve the atom information candidates from vector stores. It's designed to use the `atom_queries` to
        retrieve atom information while the `query` would be used as back-up retrieval methods. It is the second step
        in atom information selection loop.
        """
        assert isinstance(self._retriever, ChunkAtomRetriever)

        # Retrieve atom info through atom storage by atom queries.
        atom_info_candidates = self._retriever.retrieve_atom_info_through_atom(
            queries=atom_queries,
            retrieve_id=retrieve_id,
        )
        atom_info_candidates = self._filter_atom_infos(atom_info_candidates, chosen_atom_infos)

        # Backup retrieval 1: retrieve atom info through atom storage by original query.
        if len(atom_info_candidates) == 0:
            atom_info_candidates = self._retriever.retrieve_atom_info_through_atom(
                queries=query,
                retrieve_id=retrieve_id,
            )
            atom_info_candidates = self._filter_atom_infos(atom_info_candidates, chosen_atom_infos)

        # Backup retrieval 2: retrieve atom info through chunk storage directly by original query.
        if len(atom_info_candidates) == 0:
            atom_info_candidates = self._retriever.retrieve_atom_info_through_chunk(query, retrieve_id)
            atom_info_candidates = self._filter_atom_infos(atom_info_candidates, chosen_atom_infos)

        return atom_info_candidates
Retrieve the atom information candidates from vector stores. It's designed to use the `atom_queries` to
        retrieve atom information while the `query` would be used as back-up retrieval methods. It is the second step
        in atom information selection loop.
        
pikerag/workflows/qa_decompose.py