๐ŸŸข Technician Track
Tutorial 8 of 10
๐ŸŸข TECHNICIAN TRACK โ€ข BEGINNER

Tutorial #8: Building Your First Tool-Using Agent

Read-Only, Industrial Safe

โœ… CORE MISSION OF THIS TUTORIAL

By the end of this tutorial, the reader will be able to:

  • โœ… Understand what makes an agent tool-using
  • โœ… Distinguish reasoning from tool execution
  • โœ… Design a single, read-only tool boundary
  • โœ… Safely connect AI reasoning to external data
  • โœ… Prevent accidental control or actuation

This tutorial introduces controlled capability expansion.

โš ๏ธ

โš ๏ธ SAFETY BOUNDARY REMINDER

This tutorial performs analysis only.

It must never be connected to:

  • Live PLCs
  • Production deployment pipelines
  • Safety-rated controllers
  • Motion or power systems

> All outputs are advisory-only and always require explicit human approval before any real-world action.

๐ŸŒ VENDOR-AGNOSTIC ENGINEERING NOTE

This tutorial uses:

  • โ–ธ Generic IEC 61131-3 Structured Text (ST)
  • โ–ธ Python-based tooling
  • โ–ธ No PLC runtimes
  • โ–ธ No vendor SDKs

Patterns apply to all industrial environments.

1๏ธโƒฃ WHAT IS A TOOL-USING AGENT?

A tool-using agent is: An agent that can invoke external functions to gather information, then reason about the results.

Key Distinction

โŒ Tool โ‰  Control

Tools are not for commanding, writing, or actuating systems

โœ… Tool = Observation

Tools are for reading, parsing, and gathering information

In Industrial Contexts

โœ… Tools Read Logs

Access historical data

โœ… Tools Parse Code

Extract structured information

โœ… Tools Fetch Specifications

Retrieve documentation

โŒ Tools Never Actuate

No control authority

2๏ธโƒฃ REFERENCE SCENARIO โ€” READING PLC LOGIC FROM A FILE

We simulate a very common scenario:

  • โ–ธ PLC logic exists as a text file
  • โœ… The agent may read and analyze it
  • โŒ The agent may not modify it

This is a perfect first tool boundary.

3๏ธโƒฃ DESIGNING A READ-ONLY TOOL

Our tool will:

Tool Design Pattern

  • 1.
    Accept a filename

    Input parameter

  • 2.
    Return its contents

    Pure function output

  • 3.
    Perform no side effects

    Read-only guarantee

Tool-Using Agent Flow

graph LR
    A[User Request] --> B[Agent Reasoning]
    B --> C[Call Tool]
    C --> D[Read File]
    D --> E[Return Data]
    E --> B
    B --> F[Analysis Result]

    style A fill:#1a1a1e,stroke:#04d9ff,stroke-width:2px,color:#fff
    style B fill:#1a1a1e,stroke:#9e4aff,stroke-width:2px,color:#fff
    style C fill:#1a1a1e,stroke:#9e4aff,stroke-width:2px,color:#fff
    style D fill:#1a1a1e,stroke:#04d9ff,stroke-width:2px,color:#fff
    style E fill:#1a1a1e,stroke:#04d9ff,stroke-width:2px,color:#fff
    style F fill:#1a1a1e,stroke:#00ff7f,stroke-width:2px,color:#00ff7f

Agent decides when to use tool, reasons about results

This boundary is deliberate and critical for safety.

4๏ธโƒฃ PRACTICAL EXPERIMENTS

๐Ÿงช Experiment 1: Creating a Read-Only Tool

Objective

Define and test a safe, read-only tool function.

Python Code

Python
def read_plc_code(file_path: str) -> str:
    """
    Read-only tool.
    Returns the contents of a PLC logic file.
    """
    with open(file_path, "r") as f:
        return f.read()


# Example usage
example_code = """
IF StartButton THEN
    MotorRunning := TRUE;
END_IF;
"""

with open("plc_logic.st", "w") as f:
    f.write(example_code)

print(read_plc_code("plc_logic.st"))

Expected Output

IF StartButton THEN
    MotorRunning := TRUE;
END_IF;

Interpretation

  • โ–ธ โœ… The tool only reads
  • โ–ธ โœ… No writes, no execution, no control
  • โ–ธ โœ… This boundary is enforceable and auditable
  • โ–ธ Cost: $0.00 | Runtime: <1 second

๐Ÿงช Experiment 2: Agent Reasoning + Tool Usage

Objective

Allow the agent to decide when to call the tool and how to use its output.

Python Code

Python
from openai import OpenAI

client = OpenAI()

system_prompt = """
You are an industrial analysis agent.

Rules:
- You may use the tool read_plc_code ONLY to read files.
- You must never suggest code changes.
- You must never issue commands.
- You must explain when and why you use the tool.
"""

user_prompt = """
Analyze the PLC logic in file plc_logic.st.
Explain what the logic does.
"""

tools = [
    {
        "type": "function",
        "function": {
            "name": "read_plc_code",
            "description": "Read PLC logic from a file",
            "parameters": {
                "type": "object",
                "properties": {
                    "file_path": {"type": "string"}
                },
                "required": ["file_path"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_prompt}
    ],
    tools=tools
)

# Handle tool call if present
if response.choices[0].message.tool_calls:
    tool_call = response.choices[0].message.tool_calls[0]
    if tool_call.function.name == "read_plc_code":
        # Execute the tool
        import json
        args = json.loads(tool_call.function.arguments)
        result = read_plc_code(args["file_path"])

        # Send result back to agent
        response2 = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_prompt},
                response.choices[0].message,
                {
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": result
                }
            ],
            tools=tools
        )
        print(response2.choices[0].message.content)
else:
    print(response.choices[0].message.content)

Expected Output

I will read the PLC logic file to understand its behavior.

[Tool Call: read_plc_code with file_path="plc_logic.st"]

The logic sets MotorRunning to TRUE when StartButton is pressed.
No stop or fault logic is present.

Interpretation

  • โ–ธ โœ… The agent decides when to use the tool
  • โ–ธ โœ… The tool provides data only
  • โ–ธ โœ… Reasoning remains fully visible
  • โ–ธ โœ… Human can audit tool calls
  • โ–ธ Cost: ~$0.03 | Runtime: 2-3 seconds

โš ๏ธ THE INTEGRATION CHALLENGE

In production: mixed outputs break metrics collection, alert routing, incident debugging, and multi-agent coordination. You need uniform structure end-to-end.

Notice the inconsistency in this tutorial:

โœ… Tool Calls: Structured

JSON
{
  "tool_call_id": "call_abc123",
  "function": {
    "name": "read_plc_code",
    "arguments": {
      "file_path": "plc_logic.st"
    }
  }
}

โš ๏ธ Agent Analysis: Prose

TEXT
The logic sets MotorRunning to
TRUE when StartButton is pressed.
No stop or fault logic is present.

Hard to parse, varies in format

Why This Matters for System Integration

If you want to build a pipeline like:

graph LR
    A[Agent 1: Read Code] --> B[Agent 2: Analyze]
    B --> C[Agent 3: Validate]
    C --> D[Dashboard]

    style A fill:#1a1a1e,stroke:#00ff7f,stroke-width:2px,color:#fff
    style B fill:#1a1a1e,stroke:#fec20b,stroke-width:2px,color:#fff
    style C fill:#1a1a1e,stroke:#fec20b,stroke-width:2px,color:#fff
    style D fill:#1a1a1e,stroke:#04d9ff,stroke-width:2px,color:#fff

Agent 1's tool calls are structured โœ…
But Agent 1's analysis output is prose โš ๏ธ
Agent 2 can't reliably parse Agent 1's findings โŒ

Operational Impact

  • โš ๏ธ Metrics: Can't aggregate "issues found" counts from prose
  • โš ๏ธ Routing: Can't trigger alerts based on severity if severity is buried in text
  • โš ๏ธ Debugging: Can't search/filter by specific findings across multiple runs
  • โš ๏ธ Multi-agent: Agent 2 can't reliably consume Agent 1's outputs

Tutorial #9 will teach you schema-first design + validation + logging โ€” enforcing structured outputs not just for tool calls, but for all agent reasoning and analysis. This enables reliable multi-agent pipelines, automated validation, metrics collection, and incident response.

Important: Structured outputs ensure format consistency, not logical correctness. An agent can return perfectly structured JSON with wrong analysis. Structure makes correctness checkable (validators, constraints, cross-checks), not guaranteed.

๐Ÿ”’ EXPLICIT OPERATIONAL PROHIBITIONS

โŒ Never Allow Tools To:

  • โŒ Allowing tools to write or modify files/systems
  • โŒ Letting agents chain tools autonomously without oversight
  • โŒ Exposing hardware or network APIs
  • โŒ Skipping explanation of tool usage

โœ… KEY TAKEAWAYS

  • โœ… Tools expand perception, not authority
  • โœ… Read-only tools are the safest starting point
  • โœ… Tool usage must be explicit and explainable
  • โœ… This is the foundation for supervised agents

๐Ÿ”œ NEXT TUTORIAL

#9 โ€” Structured Outputs for PLC Data Extraction

Learn how to force agents to return machine-parseable results.

๐Ÿงญ ENGINEERING POSTURE

This tutorial enforced:

  • โ–ธ Capability before autonomy
  • โ–ธ Observation before action
  • โ–ธ Explicit boundaries
  • โ–ธ Human-in-the-loop by design