Your First Agent

Build an AI agent that reasons through a task: register tools, create a workflow with a ReAct loop, execute it, watch the reasoning trace unfold, handle a human escalation, and read the final answer.

Prerequisites

A running Hyphen instance at http://localhost:3009 with an LLM API key configured. All examples use X-Org-Id: tutorial-org.

Store your LLM key if you haven't already:

bash
curl -X POST http://localhost:3009/org-config \
  -H "X-Org-Id: tutorial-org" \
  -H "Content-Type: application/json" \
  -d '{ "key": "api:llm_api_key", "value": "sk-your-openai-key" }'

Step 1: Register Tools

Agents need tools to work with. Register an HTTP action and an LLM action:

bash
# An HTTP action that looks up order details
curl -X POST http://localhost:3009/actions \
  -H "X-Org-Id: tutorial-org" \
  -H "Content-Type: application/json" \
  -d '{
    "action_name": "lookup_order",
    "kind": "http",
    "description": "Look up order details by order ID",
    "url": "https://httpbin.org/anything/orders/{{order_id}}",
    "http_method": "GET",
    "passthrough": true
  }'
bash
# An LLM action that drafts a customer response
curl -X POST http://localhost:3009/actions \
  -H "X-Org-Id: tutorial-org" \
  -H "Content-Type: application/json" \
  -d '{
    "action_name": "draft_response",
    "kind": "llm",
    "description": "Draft a professional customer service response",
    "template": "Draft a professional, empathetic response to this customer issue:\n\nIssue: {{issue}}\nOrder details: {{order_details}}\n\nKeep it under 3 sentences.",
    "model": "gpt-4o-mini",
    "max_tokens": 256
  }'

Step 2: Create the Agent Workflow

Create a workflow with a ReAct loop step. The agent gets an objective, a set of tools, and autonomy to reason through the problem:

bash
curl -X POST http://localhost:3009/workflows \
  -H "X-Org-Id: tutorial-org" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "customer_issue_agent",
    "definition": {
      "actions": [
        {
          "type": "loop",
          "properties": {
            "mode": "react",
            "objective": "Handle this customer issue: {{input.issue}}. Order ID: {{input.order_id}}. Steps: 1) Look up the order details, 2) Draft a response to the customer, 3) If the issue involves a refund over $100, pause for human approval before completing. 4) Complete with your drafted response and a confidence score.",
            "tools": [
              { "type": "action", "name": "lookup_order" },
              { "type": "action", "name": "draft_response" }
            ],
            "model": "gpt-4o",
            "max_iterations": 8,
            "on_stuck": {
              "iterations": 3,
              "action": "escalate"
            },
            "result_key": "agent_result"
          }
        }
      ]
    }
  }'

What this does: The agent receives an objective in natural language and a list of tools. It reasons step by step — thinking about what to do, choosing a tool, observing the result, and repeating until it calls __complete__. If it encounters a refund over $100, it pauses for human approval.


Step 3: Execute with an Objective

bash
curl -X POST http://localhost:3009/workflows/WORKFLOW_ID/execute \
  -H "X-Org-Id: tutorial-org" \
  -H "Content-Type: application/json" \
  -d '{
    "issue": "I was charged twice for my order and I want a refund of $150",
    "order_id": "ORD-12345"
  }'

Step 4: Watch the Reasoning Trace

Check the run status:

bash
curl http://localhost:3009/runs/RUN_ID/status \
  -H "X-Org-Id: tutorial-org"

If the agent is still running, you'll see status: "running". Once it pauses or completes, the reasoning trace shows exactly how it worked through the problem:

json
{
  "status": "paused",
  "reasoning_trace": [
    {
      "iteration": 1,
      "thought": "The customer reports being charged twice and wants a $150 refund. Let me first look up the order details.",
      "action": "lookup_order",
      "action_input": { "order_id": "ORD-12345" },
      "observation": { "url": "https://httpbin.org/anything/orders/ORD-12345", "method": "GET" }
    },
    {
      "iteration": 2,
      "thought": "I have the order details. Now I'll draft a response to the customer.",
      "action": "draft_response",
      "action_input": { "issue": "charged twice, requesting $150 refund", "order_details": "..." },
      "observation": "Dear valued customer, I sincerely apologize for the duplicate charge..."
    },
    {
      "iteration": 3,
      "thought": "The refund is $150, which is over $100. Per my instructions, I need to pause for human approval before completing.",
      "action": "__pause_for_human__",
      "action_input": {
        "question": "Customer requests $150 refund for duplicate charge on order ORD-12345. Approve the refund?",
        "options": ["Approve full refund ($150)", "Approve partial refund", "Deny — investigate further"],
        "context_summary": "Order looked up. Response drafted. Awaiting refund approval.",
        "urgency": "medium"
      }
    }
  ]
}

The agent looked up the order, drafted a response, recognized the refund exceeds $100, and paused for human approval — exactly as instructed.


Step 5: Handle the Pause

The agent is waiting for human input. Provide it:

bash
curl -X POST http://localhost:3009/agents/AGENT_RUN_ID/resume \
  -H "X-Org-Id: tutorial-org" \
  -H "Content-Type: application/json" \
  -d '{
    "human_input": "Approved. Process the full $150 refund. Also add a 10% discount code for their next order as a goodwill gesture.",
    "approved": true
  }'

The agent resumes, incorporating the human's guidance into its next iteration.


Step 6: Read the Final Answer

After resuming, the agent completes:

bash
curl http://localhost:3009/runs/RUN_ID/status \
  -H "X-Org-Id: tutorial-org"
json
{
  "status": "completed",
  "context": {
    "agent_result": {
      "answer": "Refund of $150 approved and processed. Customer response drafted with apology and 10% discount code for next order.",
      "confidence": 0.95,
      "summary": "Looked up order, drafted response, obtained human approval for refund."
    }
  }
}

The confidence score tells you how certain the agent was about its answer. The full reasoning trace is preserved as an audit trail.


Step 7: View the Complete Trace

For the full audit trail including all iterations (before and after the pause):

bash
curl http://localhost:3009/agents/AGENT_RUN_ID/trace \
  -H "X-Org-Id: tutorial-org"

This returns every thought, action, and observation — the complete record of the agent's reasoning and decisions.


What You Built

An AI agent that:

  1. Reasons through a customer issue step by step
  2. Uses tools — looking up order data and drafting responses
  3. Pauses for human approval when a refund exceeds a threshold
  4. Resumes with human guidance incorporated into its reasoning
  5. Completes with a confidence-scored answer and full audit trail

Key concepts demonstrated:

Concept How It Appeared
ReAct loop Agent thinks → acts → observes → repeats
Tool usage lookup_order (HTTP), draft_response (LLM)
Human escalation __pause_for_human__ when refund > $100
Reasoning trace Full chain of thought captured per iteration
Confidence scoring Agent reports 0.95 confidence in final answer
Stuck detection Configured at 3 iterations with escalate fallback

Next: Explore the templates for production-ready patterns, or read the agent deployment patterns guide to learn about agents as workflow triggers and orchestrators.