# Simplified pseudo-code of an agentic loop class SimpleAgent: def __init__(self, llm, tools): self.llm = llm self.tools = tools self.memory = [] def run(self, objective): plan = self.llm.generate_plan(objective) self.memory.append(f"Objective: {objective}") while not task_complete: # 1. REASON: Decide next step based on plan and memory action_spec = self.llm.decide_next_action(plan, self.memory, available_tools) # 2. ACT: Execute the chosen tool with the right parameters result = self.execute_tool(action_spec['tool'], action_spec['input']) # 3. OBSERVE: Store the result in memory self.memory.append(f"Action: {action_spec['tool']}. Result: {result}") # 4. LOOP: Check if objective is met or if plan needs adjustment task_complete = self.llm.evaluate_status(objective, self.memory) COMMAND_BLOCK: # Simplified pseudo-code of an agentic loop class SimpleAgent: def __init__(self, llm, tools): self.llm = llm self.tools = tools self.memory = [] def run(self, objective): plan = self.llm.generate_plan(objective) self.memory.append(f"Objective: {objective}") while not task_complete: # 1. REASON: Decide next step based on plan and memory action_spec = self.llm.decide_next_action(plan, self.memory, available_tools) # 2. ACT: Execute the chosen tool with the right parameters result = self.execute_tool(action_spec['tool'], action_spec['input']) # 3. OBSERVE: Store the result in memory self.memory.append(f"Action: {action_spec['tool']}. Result: {result}") # 4. LOOP: Check if objective is met or if plan needs adjustment task_complete = self.llm.evaluate_status(objective, self.memory) COMMAND_BLOCK: # Simplified pseudo-code of an agentic loop class SimpleAgent: def __init__(self, llm, tools): self.llm = llm self.tools = tools self.memory = [] def run(self, objective): plan = self.llm.generate_plan(objective) self.memory.append(f"Objective: {objective}") while not task_complete: # 1. REASON: Decide next step based on plan and memory action_spec = self.llm.decide_next_action(plan, self.memory, available_tools) # 2. ACT: Execute the chosen tool with the right parameters result = self.execute_tool(action_spec['tool'], action_spec['input']) # 3. OBSERVE: Store the result in memory self.memory.append(f"Action: {action_spec['tool']}. Result: {result}") # 4. LOOP: Check if objective is met or if plan needs adjustment task_complete = self.llm.evaluate_status(objective, self.memory) COMMAND_BLOCK: from langchain.tools import tool import requests @tool def get_pr_diff(owner: str, repo: str, pr_number: int) -> str: """Fetches the diff for a GitHub Pull Request.""" url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" headers = {"Accept": "application/vnd.github.v3.diff"} response = requests.get(url, headers=headers) return response.text @tool def get_file_contents(owner: str, repo: str, filepath: str, ref: str = "main") -> str: """Fetches the contents of a specific file in a repo.""" url = f"https://api.github.com/repos/{owner}/{repo}/contents/{filepath}?ref={ref}" response = requests.get(url) content_data = response.json() import base64 return base64.b64decode(content_data['content']).decode('utf-8') COMMAND_BLOCK: from langchain.tools import tool import requests @tool def get_pr_diff(owner: str, repo: str, pr_number: int) -> str: """Fetches the diff for a GitHub Pull Request.""" url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" headers = {"Accept": "application/vnd.github.v3.diff"} response = requests.get(url, headers=headers) return response.text @tool def get_file_contents(owner: str, repo: str, filepath: str, ref: str = "main") -> str: """Fetches the contents of a specific file in a repo.""" url = f"https://api.github.com/repos/{owner}/{repo}/contents/{filepath}?ref={ref}" response = requests.get(url) content_data = response.json() import base64 return base64.b64decode(content_data['content']).decode('utf-8') COMMAND_BLOCK: from langchain.tools import tool import requests @tool def get_pr_diff(owner: str, repo: str, pr_number: int) -> str: """Fetches the diff for a GitHub Pull Request.""" url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" headers = {"Accept": "application/vnd.github.v3.diff"} response = requests.get(url, headers=headers) return response.text @tool def get_file_contents(owner: str, repo: str, filepath: str, ref: str = "main") -> str: """Fetches the contents of a specific file in a repo.""" url = f"https://api.github.com/repos/{owner}/{repo}/contents/{filepath}?ref={ref}" response = requests.get(url) content_data = response.json() import base64 return base64.b64decode(content_data['content']).decode('utf-8') COMMAND_BLOCK: from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # Pull a standard "ReAct" prompt that encourages reasoning and action prompt = hub.pull("hwchase17/react") # Initialize the LLM llm = ChatOpenAI(model="gpt-4-turbo", temperature=0) # Create the agent with our tools tools = [get_pr_diff, get_file_contents] agent = create_react_agent(llm, tools, prompt) # Create the executor, which runs the agentic loop agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True) COMMAND_BLOCK: from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # Pull a standard "ReAct" prompt that encourages reasoning and action prompt = hub.pull("hwchase17/react") # Initialize the LLM llm = ChatOpenAI(model="gpt-4-turbo", temperature=0) # Create the agent with our tools tools = [get_pr_diff, get_file_contents] agent = create_react_agent(llm, tools, prompt) # Create the executor, which runs the agentic loop agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True) COMMAND_BLOCK: from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # Pull a standard "ReAct" prompt that encourages reasoning and action prompt = hub.pull("hwchase17/react") # Initialize the LLM llm = ChatOpenAI(model="gpt-4-turbo", temperature=0) # Create the agent with our tools tools = [get_pr_diff, get_file_contents] agent = create_react_agent(llm, tools, prompt) # Create the executor, which runs the agentic loop agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True) CODE_BLOCK: result = agent_executor.invoke({ "input": "Review pull request #42 in the 'myorg/awesome-api' repository. Focus on security best practices and error handling in the changed files. Provide a summary." }) CODE_BLOCK: result = agent_executor.invoke({ "input": "Review pull request #42 in the 'myorg/awesome-api' repository. Focus on security best practices and error handling in the changed files. Provide a summary." }) CODE_BLOCK: result = agent_executor.invoke({ "input": "Review pull request #42 in the 'myorg/awesome-api' repository. Focus on security best practices and error handling in the changed files. Provide a summary." }) COMMAND_BLOCK: Thought: I need to first examine the PR diff to see what files changed. Action: get_pr_diff Action Input: {"owner": "myorg", "repo": "awesome-api", "pr_number": 42} Observation: [Shows the diff...] Thought: I see changes to `auth/middleware.py`. I should get the full context of this file to understand the changes better. Action: get_file_contents Action Input: {"owner": "myorg", "repo": "awesome-api", "filepath": "auth/middleware.py", "ref": "main"} ... Thought: I have enough context. I will now analyze the security implications... Final Answer:
Code Review Summary for PR #42... COMMAND_BLOCK: Thought: I need to first examine the PR diff to see what files changed. Action: get_pr_diff Action Input: {"owner": "myorg", "repo": "awesome-api", "pr_number": 42} Observation: [Shows the diff...] Thought: I see changes to `auth/middleware.py`. I should get the full context of this file to understand the changes better. Action: get_file_contents Action Input: {"owner": "myorg", "repo": "awesome-api", "filepath": "auth/middleware.py", "ref": "main"} ... Thought: I have enough context. I will now analyze the security implications... Final Answer:
Code Review Summary for PR #42... COMMAND_BLOCK: Thought: I need to first examine the PR diff to see what files changed. Action: get_pr_diff Action Input: {"owner": "myorg", "repo": "awesome-api", "pr_number": 42} Observation: [Shows the diff...] Thought: I see changes to `auth/middleware.py`. I should get the full context of this file to understand the changes better. Action: get_file_contents Action Input: {"owner": "myorg", "repo": "awesome-api", "filepath": "auth/middleware.py", "ref": "main"} ... Thought: I have enough context. I will now analyze the security implications... Final Answer:
Code Review Summary for PR #42... - Perception: It can intake data from its environment (APIs, files, user input). - Planning & Reasoning: It breaks down a high-level goal into a sequence of steps. - Action: It can execute tools (like API calls, shell commands, or database queries) to affect its environment. - Memory: It retains context from previous actions to inform future decisions. - Hallucinated Tool Calls: The LLM might try to use a tool that doesn't exist or with invalid parameters. Fix: Use LLMs with strong structured output (like gpt-4-turbo), implement robust parsing with Pydantic, and build comprehensive error handling into the agent loop. - Fix: Use LLMs with strong structured output (like gpt-4-turbo), implement robust parsing with Pydantic, and build comprehensive error handling into the agent loop. - Infinite Loops: The agent might get stuck in a reasoning loop. Fix: Implement a step counter (max_iterations=15) and a clear termination condition in your prompt (e.g., "When you have a comprehensive answer, respond with FINAL ANSWER."). - Fix: Implement a step counter (max_iterations=15) and a clear termination condition in your prompt (e.g., "When you have a comprehensive answer, respond with FINAL ANSWER."). - Cost & Latency: Each reasoning step is an LLM call. Fix: Use smaller, faster models for simpler reasoning steps (like gpt-3.5-turbo for planning) and reserve powerful models for complex analysis. Cache frequent tool results. - Fix: Use smaller, faster models for simpler reasoning steps (like gpt-3.5-turbo for planning) and reserve powerful models for complex analysis. Cache frequent tool results. - Fix: Use LLMs with strong structured output (like gpt-4-turbo), implement robust parsing with Pydantic, and build comprehensive error handling into the agent loop. - Fix: Implement a step counter (max_iterations=15) and a clear termination condition in your prompt (e.g., "When you have a comprehensive answer, respond with FINAL ANSWER."). - Fix: Use smaller, faster models for simpler reasoning steps (like gpt-3.5-turbo for planning) and reserve powerful models for complex analysis. Cache frequent tool results.