| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import textwrap |
| from typing import Any |
|
|
| from pydantic import ConfigDict |
|
|
| from camel.agents.programmed_agent_instruction import ( |
| ProgrammableChatAgent, |
| ProgrammedAgentInstructionResult, |
| programmable_capability, |
| ) |
| from camel.datagen.source2synth.models import ( |
| ContextPrompt, |
| MultiHopQA, |
| ) |
| from camel.messages import BaseMessage |
|
|
|
|
| class MultiHopGeneratorAgent(ProgrammableChatAgent): |
| r"""An agent specialized in generating multi-hop question-answer pairs. |
| |
| This agent is designed to create complex questions that require multiple |
| steps of reasoning to answer. It analyzes context to identify related |
| facts and generates questions that require connecting these facts |
| logically. |
| |
| Attributes: |
| model_config (ConfigDict): Configuration for model behavior. |
| system_message (BaseMessage): System message defining agent's role and |
| instructions. |
| """ |
|
|
| model_config = ConfigDict(arbitrary_types_allowed=True) |
|
|
| def __init__(self, **kwargs: Any) -> None: |
| r"""Initialize the MultiHopGeneratorAgent. |
| |
| Args: |
| **kwargs (Any): Additional keyword arguments to pass to parent |
| class. |
| """ |
| super().__init__(**kwargs) |
|
|
| system_text: str = textwrap.dedent( |
| """\ |
| You are an expert at generating |
| multi-hop question-answer pairs. |
| For each context, you should: |
| 1. Identify multiple related facts or pieces of information |
| 2. Create questions that require reasoning across these multiple pieces |
| 3. Ensure the reasoning chain is clear and logical |
| 4. Generate questions that require at least 2-3 steps of reasoning |
| 5. Include the reasoning steps in the answer |
| |
| Give your response with this information: |
| Question: [Complex question requiring multiple reasoning steps] |
| Reasoning Steps: |
| 1. [First reasoning step] |
| 2. [Second reasoning step] |
| 3. [Final reasoning step] |
| Answer: [Final answer] |
| Supporting Facts: [List of relevant text segments used] |
| """ |
| ) |
| self.system_message = BaseMessage.make_assistant_message( |
| role_name='Assistant', content=system_text |
| ) |
|
|
| @programmable_capability |
| def generate_multi_hop_qa( |
| self, context: str |
| ) -> ProgrammedAgentInstructionResult[MultiHopQA]: |
| r"""Generate a multi-hop question-answer pair from given context. |
| |
| Args: |
| context (str): The input text context to generate QA from. |
| |
| Returns: |
| ProgrammedAgentInstructionResult[MultiHopQA]: Result containing the |
| generated question, reasoning steps, answer, and supporting |
| facts. |
| |
| Raises: |
| RuntimeError: If the agent fails to generate a response. |
| """ |
| context_prompt = ContextPrompt( |
| main_context=context, related_contexts=None |
| ) |
|
|
| user_message = BaseMessage.make_user_message( |
| content=context_prompt.model_dump_json(), role_name="User" |
| ) |
| response = self.step( |
| input_message=user_message, response_format=MultiHopQA |
| ) |
| value = MultiHopQA.model_validate_json(response.msgs[0].content) |
|
|
| if response.msgs: |
| return ProgrammedAgentInstructionResult( |
| user_message=user_message, |
| agent_message=response.msgs[0], |
| value=value, |
| ) |
| raise RuntimeError("No response from agent") |
|
|