admin管理员组

文章数量:1384701

Hi I am creating a react agent through the Langgraph and Bedrock ApI agent to call a glue api and calculate cost . However the functions is not executing. i am using a local desktop python code to invoke the agent

main.py

import logging
from dotenv import load_dotenv

# Configure logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

load_dotenv()

from langchain_core.agents import AgentFinish
from langgraph.graph import END, StateGraph

from nodes import execute_tools, run_agent_reasoning_engine
from state import AgentState

AGENT_REASON = "agent_reason"
ACT = "act"

logging.debug("Modules imported and constants defined.")

def should_continue(state: AgentState) -> str:
    logging.debug(f"Checking if should continue with state: {state}")
    if isinstance(state["agent_outcome"], AgentFinish):
        logging.debug("Agent outcome is AgentFinish, returning END.")
        return END
    else:
        logging.debug("Agent outcome is not AgentFinish, returning ACT.")
        return ACT

flow = StateGraph(AgentState)
logging.debug("StateGraph initialized.")

flow.add_node(AGENT_REASON, run_agent_reasoning_engine)
logging.debug(f"Node {AGENT_REASON} added to the graph.")

flow.set_entry_point(AGENT_REASON)
logging.debug(f"Entry point set to {AGENT_REASON}.")

flow.add_node(ACT, execute_tools)
logging.debug(f"Node {ACT} added to the graph.")

flow.add_conditional_edges(
    AGENT_REASON,
    should_continue,
)
logging.debug(f"Conditional edges added from {AGENT_REASON} based on should_continue function.")

flow.add_edge(ACT, AGENT_REASON)
logging.debug(f"Edge added from {ACT} to {AGENT_REASON}.")

app = flowpile()
logging.debug("Flow compiled into app.")

app.get_graph().draw_mermaid_png(output_file_path="graph.png")
logging.debug("Graph drawn and saved as graph.png.")

if __name__ == "__main__":
    logging.info("Starting main execution.")
    print("Hello ReAct with LangGraph")
    res = app.invoke(
        input={
            "input": "What is the cost of the jobs latest run test-job",
        }
    )
    logging.debug(f"Invocation result: {res}")
    print(res["agent_outcome"].return_values["output"])
    logging.info("Execution finished.")

The react agent is react.py

import os
import boto3
import logging
from dotenv import load_dotenv
from langchain import hub
from langchain.agents import create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain_core.tools import tool
from langchain_aws import ChatBedrock

# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

# Load environment variables from .env file
logger.debug("Loading environment variables from .env file")
load_dotenv()

# Set the region, defaulting to 'us-east-1' if not found
aws_region = os.getenv("AWS_REGION", "us-east-1")
logger.debug(f"AWS region set to: {aws_region}")

# Initialize the session with the specified profile for Glue
logger.debug("Initializing boto3 session with profile 'profile1'")
glue_session = boto3.Session(profile_name="profile1")

# Create a Glue client
logger.debug("Creating Glue client")
glue_client = glue_session.client("glue", region_name=aws_region)

@tool
def get_latest_glue_job_run_dpu_seconds(job_name: str) -> float:
    """
    Retrieves the DPU seconds of the latest completed run of a Glue job.
    
    :param job_name: The name of the Glue job
    :return: The DPU seconds of the latest completed run, or None if no completed runs are found
    """
    logger.debug(f"Retrieving latest Glue job run DPU seconds for job: {job_name}")
    try:
        response = glue_client.get_job_runs(JobName=job_name, MaxResults=1)
        logger.debug(f"Glue job runs response: {response}")
        if response.get("JobRuns"):
            latest_run = response["JobRuns"][0]
            logger.debug(f"Latest job run: {latest_run}")
            if latest_run.get("JobRunState") == "SUCCEEDED":
                dpu_seconds = latest_run.get("DPUSeconds")
                logger.debug(f"DPU seconds for latest successful run: {dpu_seconds}")
                return dpu_seconds
            else:
                logger.debug("Latest job run did not succeed")
                return None
        else:
            logger.debug("No job runs found")
            return None
    except Exception as e:
        error_message = f"Error retrieving Glue job run DPU seconds: {str(e)}"
        logger.error(error_message)
        return error_message

@tool
def cost(num: float) -> float:
    """
    :param num: a DPU hours to find cost
    :return: the number tripled -> multiplied by 0.44
    """
    logger.debug(f"Calculating cost for DPU hours: {num}")
    calculated_cost = 0.44 * float(num)
    logger.debug(f"Calculated cost: {calculated_cost}")
    return calculated_cost

# Pull the react prompt template
logger.debug("Pulling react prompt template from hub")
react_prompt: PromptTemplate = hub.pull("hwchase17/react")

# Define the tools
logger.debug("Defining tools")
tools = [get_latest_glue_job_run_dpu_seconds, cost]

# Initialize the LLM with the specified profile for Bedrock
logger.debug("Initializing ChatBedrock LLM")
llm = ChatBedrock(
    credentials_profile_name="",
    model_id="",
    model_kwargs={
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 512,
        "temperature": 0.5
    },
    provider="anthropic",
    region_name="us-east-1"
).bind_tools(tools=tools)

# Create the react agent
logger.debug("Creating react agent")
react_agent_runnable = create_react_agent(llm, tools, react_prompt)

The Agent state is in state.py

import operator
import logging
from typing import Annotated, TypedDict, Union

from langchain_core.agents import AgentAction, AgentFinish

# Configure logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

class AgentState(TypedDict):
    input: str
    agent_outcome: Union[AgentAction, AgentFinish, None]
    intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]

# Example usage
if __name__ == "__main__":
    # Example data
    example_input = "example input"
    example_agent_outcome = None  # Replace with an actual AgentAction or AgentFinish instance
    example_intermediate_steps = []  # Replace with actual intermediate steps

    # Create an instance of AgentState
    agent_state = AgentState(
        input=example_input,
        agent_outcome=example_agent_outcome,
        intermediate_steps=example_intermediate_steps
    )

    logging.debug(f"Created AgentState: {agent_state}")

Finally the nodes.py

import logging
from dotenv import load_dotenv
from langchain_core.agents import AgentAction, AgentFinish  # Import AgentAction and AgentFinish
from langgraph.prebuilt import ToolNode

from react import react_agent_runnable, tools
from state import AgentState

# Configure logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

load_dotenv()

def run_agent_reasoning_engine(state: AgentState):
    logging.debug("Starting run_agent_reasoning_engine with state: %s", state)
    agent_outcome = react_agent_runnable.invoke(state)
    logging.debug("Agent outcome: %s", agent_outcome)
    return {"agent_outcome": agent_outcome}

tool_executor = ToolNode(tools)

def execute_tools(state: AgentState):
    logging.debug("Starting execute_tools with state: %s", state)
    agent_action = state["agent_outcome"]
    logging.debug("Agent action: %s", agent_action)
    if isinstance(agent_action, AgentAction):
        try:
            output = tool_executor.invoke(agent_action)
            logging.debug("Tool executor output: %s", output)
            return {"intermediate_steps": [(agent_action, str(output))]}
        except Exception as e:
            logging.error("Error invoking tool executor: %s", e)
            return {"intermediate_steps": state["intermediate_steps"]}
    else:
        logging.error("Agent action is not of type AgentAction")
        return {"intermediate_steps": state["intermediate_steps"]}

The problem i am facing the the Tool invoke is always returning Blank , I have tested the functions separately and works pretty good.

 return_values={'output': 'I cannot determine the cost because I was unable to retrieve the DPU seconds for the specified job. To proceed, you would need to:\n- Verify the exact job name is correct\n- Confirm that the job has completed runs\n- Check if there are any access or permission issues with retrieving the job run information\n\nWould you like to double-check the job name or provide more context about the job?'} log='I apologize, but it seems there might be an issue retrieving the DPU seconds for the specified job. Let me explain my reasoning:\n\nQuestion: What is the cost of the latest run of job test-job\nThought: I attempted to retrieve the DPU seconds, but the response was an empty message list, which suggests either:\n1. The job name might be incorrect\n2. There are no completed runs for this job\n3. There might be an issue with accessing the job run information\n\nFinal Answer: I cannot determine the cost because I was unable to retrieve the DPU seconds for the specified job. To proceed, you would need to:\n- Verify the exact job name is correct\n- Confirm that the job has completed runs\n- Check if there are any access or permission issues with retrieving the job run information\n\nWould you like to double-check the job name or provide more context about the job?'
I cannot determine the cost because I was unable to retrieve the DPU seconds for the specified job. To proceed, you would need to:
- Verify the exact job name is correct
- Confirm that the job has completed runs
- Check if there are any access or permission issues with retrieving the job run information

Issue The problem I'm facing is that the tool invocation (output = tool_executor.invoke(agent_action)) is always returning blank results. Here are the relevant debug logs:

output = tool_executor.invoke(agent_action)

DEBUG:root:Starting execute_tools with state: {'input': 'What is the cost of the lstest run of job test-job', 'agent_outcome': AgentAction(tool='get_latest_glue_job_run_dpu_seconds', tool_input='test-job', log="I'll solve this step by step:\n\n1. First, I need to get the DPU seconds for the latest run of the specified Glue job\n2. Then, I'll convert those DPU seconds to DPU hours\n3. Finally, I'll calculate the cost\n\nThought: I'll first retrieve the DPU seconds for the job\nAction: get_latest_glue_job_run_dpu_seconds\nAction Input: test-job"), 'intermediate_steps': []}
DEBUG:root:Agent action: tool='get_latest_glue_job_run_dpu_seconds' tool_input='test-job' log="I'll solve this step by step:\n\n1. First, I need to get the DPU seconds for the latest run of the specified Glue job\n2. Then, I'll convert those DPU seconds to DPU hours\n3. Finally, I'll calculate the cost\n\nThought: I'll first retrieve the DPU seconds for the job\nAction: get_latest_glue_job_run_dpu_seconds\nAction Input: test-job"
DEBUG:root:Tool executor output: {'messages': []}

I know ite lengthly but unable to point out the issue for quite sometime now. Any insights would help. New to this whole agent wor

本文标签: