def _select_atom_question(
        self, question: str, atom_info_candidates: List[AtomRetrievalInfo], chosen_atom_infos: List[AtomRetrievalInfo],
    ) -> Tuple[bool, str, AtomRetrievalInfo]:
        """Given the original question to be answered and the atom information we already have, let the LLM select the
        atom information that can best help the question answering.
        """
        assert len(atom_info_candidates) > 0, "Info candidate list is empty!"
        messages = self._retrieval_info_selection_protocol.process_input(
            content=question,
            atom_info_candidates=atom_info_candidates,
            chosen_atom_infos=chosen_atom_infos,
        )
        content = self._client.generate_content_with_messages(messages, **self.llm_config)
        selected, thinking, chosen_atom = self._retrieval_info_selection_protocol.parse_output(content)

        if not selected and self._backup_retrieval_info_selection_protocol is not None:
            messages = self._backup_retrieval_info_selection_protocol.process_input(
                content=question,
                atom_info_candidates=atom_info_candidates,
                chosen_atom_infos=chosen_atom_infos,
            )
            content = self._client.generate_content_with_messages(messages, **self.llm_config)
            selected, thinking2, chosen_atom = self._backup_retrieval_info_selection_protocol.parse_output(content)
            thinking += "\n" + thinking2

        return selected, thinking, chosen_atom
Given the original question to be answered and the atom information we already have, let the LLM select the
        atom information that can best help the question answering.
        
pikerag/workflows/qa_decompose.py