Sponsored Advertisement
Back to Blog
Originally published on Medium.Read Original Article
2026-05-11
aiai-agentllmpythonagentic-ai

Part 2: The Hands-On Build — Orchestrating Agents with LangGraph

In Part 1 , we defined the “Agentic Mindset.” Now, it’s time to move into production. In this post, we will build a fully autonomous Securit...

Part 2: The Hands-On Build — Orchestrating Agents with LangGraph

In Part 1, we defined the “Agentic Mindset.” Now, it’s time to move into production. In this post, we will build a fully autonomous Security Remediation Agent that scans a Provider Cloud environment, identifies vulnerabilities, and fixes them — all while running a local LLM to ensure maximum data privacy.

To achieve this, we need three distinct layers: The Hands (Tools), The Brain (Local LLM), and The Nervous System (LangGraph).

1. The Hands: Functional Tools with Provider SDKs

An LLM cannot interact with your cloud infrastructure directly. We must provide it with “Tools” — structured Python functions decorated with @tool. These aren't just snippets of code; they include descriptive docstrings that the AI reads to understand when and why to use them.

Using the appropriate Provider SDK, we define our agent’s primary capabilities:

  • The Scanner: list_vulnerable_instances() — Uses the SDK to search for instances with insecure network configurations (e.g., Port 22 open to the public).
  • The Actor: stop_instance(id) — Issues the specific SDK command to shut down or isolate a compromised resource.
@tool
def list_vulnerable_instances():
    """Returns cloud instances with Port 22 open to 0.0.0.0/0."""
    # Logic to call the specific Provider SDK...
    return vulnerable_list

@tool
def stop_instance(instance_id: str):
    """Issues a STOP command to remediate a vulnerable instance."""
    # Logic to call specific provider sdk code
    return f"REMEDIATED: Instance {instance_id} stopped."

Why this is needed: This bridges the gap between high-level reasoning (“I need to secure the perimeter”) and low-level API execution (“Run this specific POST request”).

2. The Brain: Local LLM with LM Studio

For security operations, privacy is paramount. Sending your internal vulnerability logs to a public API is a massive risk. To solve this, we use LM Studio to host a local model (such as Gemma or Llama) on your own hardware.

We connect our agent to this local brain using an OpenAI-compatible endpoint. This architecture ensures that every “thought” and every piece of log data stays within your local perimeter.

# Connecting to local LLM via LM Studio
llm = ChatOpenAI(base_url="http://localhost:1234/v1", api_key="local-server")
llm_with_tools = llm.bind_tools(tools)

3. The Nervous System: The LangGraph Workflow

This is the core of our system. Instead of a linear script, we build a StateGraph. This allows our agent to move through nodes that represent specific states of the audit, enabling it to loop, verify, and reason recursively.

The Graph Architecture:

  • Agent Node: The reasoning engine. It takes the current message history and decides: “Do I need to find vulnerabilities, or is the environment now secure?”
  • Tools Node: The execution engine. It handles the actual Python SDK calls to the Provider Cloud.
  • Notify Node: The reporting engine. Once the audit is complete, it formats the final report and pushes it to a platform like Slack.

The Power of the Loop

Notice the edge workflow.add_edge("tools", "agent"). This is what makes it an agent rather than just a script. After stopping a server, the agent loops back to the reasoning node to verify the fix or identify the next vulnerability.

4. The Logic of the “Route”

How does the graph know when the job is done? We use a Conditional Edge called route. It acts as a traffic cop, inspecting the LLM's last response:

  • If the LLM says “I need to run a tool,” the graph routes to the Tools node.
  • If the LLM says “I have finished the audit,” the graph routes to the Notify node.
def route(state: State):
    last_message = state["messages"][-1]
    if last_message.tool_calls:
        return "tools"
    return "notify"

5. Seeing the “Thinking” in Action (The Logs)

When we run this agent, the logs reveal its internal process. We see it identify a vulnerability, execute the fix via the Provider SDK, and then — crucially — verify that no more work is needed:

10:00:01 - [agent] → Requesting tool: list_vulnerable_instances
10:00:02 - [route] → Executing 1 tool(s) via Provider SDK
10:00:05 - [agent] → Requesting tool: stop_cloud_instance
10:00:10 - [agent] → No tools requested, generating final response
10:00:11 - [route] → Sending notification to Slack...

Detail code and explanation here: https://tech.durgadas.in/security-remediation-agent-using-langgraph-4a7b243906f6?source=friends_link&sk=357d492b20c12e61cbdba4654faddbf9

Conclusion

By the end of Part 2, we have moved beyond a simple chatbot. We have built a system that observes the cloud via real SDK calls, decides on a course of action using local reasoning, and acts autonomously.

Next in Part 3: We will look at the economics of this build — how to manage the “Reasoning Tax” and scale these loops without breaking your compute budget.

Clap, share, comment, and provide your thoughts. Please share your opinions with me! Happy studying! Please follow to receive notifications on new articles.

Image

Sponsored Advertisement