Simplifier Makers ClubSimplifier Makers Club
  • Docs
  • Knowledge
  • F.A.Q
  • Forum
  • Courses
  • Marketplace
  • Login
  • Try for free
  • German
  • English
  • Try for free
  • Docs
  • Knowledge
  • F.A.Q
  • Forum
  • Courses
  • Marketplace
  • Login
  • Try for free
  • German
  • English
  • Try for free
home/Knowledge Base/How to's/Building an AI Agent in Simplifier

Building an AI Agent in Simplifier

Written by Christian Kleinschroth
March 2, 2026

Overview

This guide walks you through building a fully functional AI Agent in Simplifier that connects to the Anthropic Claude API (claude-sonnet-4-6). You will learn how to:

  • Set up a REST connector to the Claude API
  • Create a reusable Business Object with multiple AI-powered functions
  • Define proper custom datatypes for structured output
  • Build a real-world agent function:
    • A material price search agent that finds the cheapest offers for a product EAN code

By the end of this guide, your app builders can call Claude directly from any Simplifier workflow, UI event, or process — and receive clean, typed, mappable JSON back

Prerequisites

  • Access to a Simplifier instance
  • An Anthropic API key (get one at console.anthropic.com)
  • Basic familiarity with Simplifier Business Objects and Connectors

Architecture Overview

Step 1 – Create the Login Method

The Anthropic API authenticates via a custom HTTP header x-api-key Simplifier’s Token login method with a custom header target handles this perfectly.

  1. Go to Settings → Login Methods → New
  2. Configure as follows:
Field Value
Name ClaudeApiKey
Type Token
Source Provided
Token value sk-ant-api03-... (your Anthropic API key)
Target Custom Header
Header name x-api-key
  1. Save the login method.

Security tip: Never hard-code the API key directly in Business Object function code. Always use a Login Method so the key is stored securely and centrally managed.

Step 2 – Create the Claude REST Connector

  1. Go to Connectors → New Connector
  2. Set the connector type to REST
  3. Configure:
Field Value
Name Claude
Description Anthropic Claude API connector
Timeout 60s
Tags AI, Claude, Anthropic, LLM
  1. In the Endpoint Configuration:
Field Value
Endpoint Default (your active Simplifier instance)
Base URL https://api.anthropic.com/v1
Login Method ClaudeApiKey
SSL Trust System certificates
  1. Save the connector.

Step 3 – Create the Connector Call: SendMessage

This is the single reusable call that both agent functions will use.

  1. Inside the Claude connector, add a new call named SendMessage
  2. Add the following input parameters:
Parameter Type Fixed Value Notes
verb String POST HTTP method
postFormat String JSON Body format
pathParams[0] String messages Appended to base URL → /v1/messages
headParams/anthropic-version String 2023-06-01 Required by Anthropic API
postBody/model String (dynamic) Model name, e.g. claude-sonnet-4-6
postBody/max_tokens Integer (dynamic) Max response tokens
postBody/system String (dynamic) System prompt (optional)
postBody/messages Any (dynamic) Array of message objects
  1. Add the following output parameters:
Parameter Type
content Any
usage Any
model String
stop_reason String
  1. Set validateIn to true, validateOut to true
  2. Save the call.

Step 4 – Create the Business Object: Ai_Agent

  1. Go to Business Objects → New
  2. Configure:
Field Value
Name Ai_Agent
Description AI Agent using Claude claude-sonnet-4-6
Tags AI, Agent, Claude, LLM
  1. Add a dependency on the Claude connector — this is required for the BO functions to call Simplifier.Connector.Claude.*
  2. Save the Business Object.

Struct Types

Datatype Fields
SellerRating score (Float), scale (Float), ratings_count (Integer)
MetaError code (String), message (String), details (String)
QueryPreferences priority (String), currency (String)
Offer match_type, seller_name, seller_domain, url (String), item_price, shipping_price, total_cost, unit_price (Float), currency, unit, region, availability, delivery_estimate, last_checked_utc, raw_source (String), pack_size (Float), seller_rating → SellerRating
EanResult ean, product_name, product_description, status (String), exact_match_found (Boolean), cheapest_offer → Offer, cheapest_unit_offer → Offer, offers → OfferList
PriceSearchResponse Same fields as EanResult — flat, no query/meta wrapper

Collection Types

Datatype Element Type
OfferList Offer
MetaErrorList MetaError
EanResultList EanResult

Tip: Always create struct types before the collection types that reference them. Create referenced types (e.g. SellerRating before types that embed them (e.g. Offer).

Step 6 – Create Function: GetCheapestOffers (EAN Price Search Agent)

This function asks Claude to act as a web-searching price comparison agent. Given a single EAN code, it returns the cheapest available offers in a fully typed, flat structure.

Input Parameters

Name Type Optional Default
ean String ✅ 4006381333931
userRegion String ✅ DE
currency String ✅ EUR
priority String ✅ lowest_total_cost

Output Parameters

Name Type Description
priceSearchResponse PriceSearchResponse Flat typed result with product info and offers
rawText String Raw Claude response
usage Any Token usage

Function Code

// ── System Prompt ────────────────────────────────────────────────────────────
const SYSTEM_PROMPT = `You are an AI agent whose primary task is to find the
cheapest available offer for products identified by their EAN code.

Output ONLY a single flat valid JSON object with exactly these fields:
{
  "ean": "",
  "product_name": null,
  "product_description": null,
  "status": "found",
  "exact_match_found": true,
  "cheapest_offer": { ...offer object... },
  "cheapest_unit_offer": { ...offer object... },
  "offers": [ ...up to 3 offer objects... ]
}

Each offer must contain: match_type, seller_name, seller_domain, url,
item_price, shipping_price, total_cost, currency, pack_size, unit,
unit_price, seller_rating { score, scale, ratings_count }, region,
availability, delivery_estimate, last_checked_utc, raw_source, notes.

No wrapping query or meta object. No text outside the JSON. No markdown fences.`;

// ── Default / Sample values ──────────────────────────────────────────────────
const DEFAULT_EAN      = "4006381333931";
const DEFAULT_REGION   = "DE";
const DEFAULT_CURRENCY = "EUR";
const DEFAULT_PRIORITY = "lowest_total_cost";

// ── Resolve inputs ───────────────────────────────────────────────────────────
const ean      = (input.ean        && input.ean.trim())        ? input.ean.trim()        : DEFAULT_EAN;
const region   = (input.userRegion && input.userRegion.trim()) ? input.userRegion.trim() : DEFAULT_REGION;
const currency = (input.currency   && input.currency.trim())   ? input.currency.trim()   : DEFAULT_CURRENCY;
const priority = (input.priority   && input.priority.trim())   ? input.priority.trim()   : DEFAULT_PRIORITY;

// ── Build user message ───────────────────────────────────────────────────────
const userMessage = `Search for the cheapest offers for this EAN code:
EAN: ${ean}
User region: ${region}
Preferred currency: ${currency}
Priority: ${priority}

Limit to 3 offers. Return ONLY a single flat JSON object. No text outside the JSON, no markdown fences.`;

// ── Call Claude via the connector ────────────────────────────────────────────
const response = Simplifier.Connector.Claude.SendMessage({
  "postBody/model":      "claude-sonnet-4-6",
  "postBody/max_tokens": 8000,
  "postBody/system":     SYSTEM_PROMPT,
  "postBody/messages":   [{ role: "user", content: userMessage }]
});

// ── Extract raw text ─────────────────────────────────────────────────────────
let rawText = "";
if (response && response.content && Array.isArray(response.content)) {
  for (const block of response.content) {
    if (block.type === "text") { rawText = block.text; break; }
  }
} else if (response && response.content) {
  rawText = String(response.content);
}

output.rawText = rawText;
output.usage   = response ? response.usage : null;

// ── Robust JSON extraction ───────────────────────────────────────────────────
// Strip markdown fences if present
let cleaned = rawText.replace(/^"`(?:json)?\s*/i, "").replace(/\s*"`$/i, "").trim();

// If Claude prefixed the JSON with prose, skip to the first {
if (!cleaned.startsWith("{")) {
  const firstBrace = cleaned.indexOf("{");
  if (firstBrace !== -1) cleaned = cleaned.substring(firstBrace).trim();
}

try {
  const parsed = JSON.parse(cleaned);
  // If Claude still wrapped the result in a results array, unwrap first entry
  output.priceSearchResponse = (parsed.results && Array.isArray(parsed.results))
    ? parsed.results[0]
    : parsed;
} catch (e) {
  output.priceSearchResponse = {
    ean:                 ean,
    product_name:        null,
    product_description: null,
    status:              "error",
    exact_match_found:   false,
    cheapest_offer:      null,
    cheapest_unit_offer: null,
    offers:              []
  };
}

Test the GetCheapestOffers Function

Input:

{
  "ean": "4006381333931",
  "userRegion": "DE",
  "currency": "EUR"
}

Expected output shape:

{
  "ean": "4006381333931",
  "product_name": "Stabilo Boss Original Textmarker",
  "product_description": "Classic highlighter pen...",
  "status": "found",
  "exact_match_found": true,
  "cheapest_offer": {
    "seller_domain": "amazon.de",
    "item_price": 0.79,
    "shipping_price": 0.00,
    "total_cost": 0.79,
    "currency": "EUR"
  },
  "offers": [ ... ]
}

Tips & Best Practices

Prompt Engineering

  • Always instruct Claude to return only JSON — no prose, no markdown fences
  • Embed the desired output schema directly in the user message for the Run function
  • Keep the system prompt concise but explicit about the output format

Token Budget

  • Use max_tokens: 2048 for simple structured responses
  • Use max_tokens: 8000 for agents that do tool calls or search like GetCheapestOffers
  • Test with 1 EAN at a time — multiple EANs can exhaust the token limit and truncate the response

JSON Robustness

  • Always strip markdown code fences (“`json) before parsing
  • Always scan for the first { in case Claude prefixes the JSON with a sentence
  • Provide a meaningful fallback error object in the catch block so callers always get a valid typed response

Datatypes

  • Define all datatypes in the bo/<BusinessObjectName>/ namespace to keep them organized
  • Create referenced types first (e.g. SellerRating before Offer)
  • Use Any only as a last resort — proper typing enables full UI mapping in Simplifier
  • Flatten your output types where possible — consumers should not need to navigate deep nesting

Connector Design

  • One connector (Claude) + one call (SendMessage) is enough — keep it reusable across all BO functions
  • The anthropic-version header must be set via headParams/anthropic-version — it cannot be sent via the Login Method
  • The x-api-key header is best handled via the Login Method, not hardcoded in the call parameters

Summary

Resource Name Purpose
Login Method ClaudeApiKey Securely injects x-api-key header
Connector Claude REST connector to https://api.anthropic.com/v1
Connector Call SendMessage Reusable POST to /messages
Business Object Ai_Agent Container for all AI agent functions
BO Function GetCheapestOffers EAN-based price search agent
Datatypes (11x) bo/Ai_Agent/* Fully typed output for UI mapping

What’s Next?

  • Connect to a UI: Bind the GetCheapestOffers output to a Simplifier List component to display price comparisons in your app
  • Add more agents: Use the same Claude connector to add new BO functions for different tasks (e.g. document summarization, SAP data enrichment, translation)
  • Chain agents: Call Ai_Agent from within another BO function to build multi-step AI pipelines
  • Use a different model: Simply change postBody/model to switch between Claude models (e.g. claude-haiku-4-5 for faster/cheaper responses)
Tags:ai

Was this article helpful?

1 Yes  No
Related Articles
  • How to integrate value help and suggestions in user inputs
  • How to handle files selected with the FileUploader
  • Fine-tuning and Running Custom AI Models in Simplifier
  • Using the Simplifier Teams App
  • How to integrate Simplifier in CI/CD pipelines
  • How to use Google reCAPTCHA v3 Essentials
Leave A Comment Cancel reply

You must be logged in to post a comment.

How to's
  • Building an AI Agent in Simplifier
  • How to integrate and use external libraries in Simplifier Apps
  • Working with Drag and Drop
  • Create Test Cases With The UI5 Test Recorder
  • Full-Text Search For PDF Documents
  • Full-Text Search For Excel Files
  • How to Implement an Approval App in Simplifier
  • Create a PDF Template via Plugin
  • Generating a PDF with Simplifier via Plugin
  • How to use Query Options in ODataV2 Connector
  • How to use TimePicker widget
  • How to set Simplifier environment variables in Open Shift
  • How to send and receive Push Notifications
  • Dynamic where-clause and repeatable statement
  • Version and Release Management in Simplifier
  • Logs and Monitoring in Simplifier
  • Use the Adobe PDF Embed API in your Simplifier Application
  • PDF Templates: make the Header/Footer content dynamic
  • Converting Text to Speech with the Google TTS Connector
  • Authentication through another window
  • Creating a ChatBot Client for ChatGPT
  • How to use Simplifier Content Repository Plugin
  • How to use Google reCAPTCHA v3 Essentials
  • How to integrate Simplifier in CI/CD pipelines
  • Using the Simplifier Teams App
  • Fine-tuning and Running Custom AI Models in Simplifier
  • How to handle files selected with the FileUploader
  • How to integrate value help and suggestions in user inputs
Knowledgebase Categories
  • Getting Started 4
  • Best Practices 4
  • How to's 28
  • Layout & Design 4
  • Widgets 8
  • Cloud Services 6
  • Database Handling 1
  • Integrations 9
  • Plugins 6
  • Mobile Client 2

How to integrate value help and suggestions in user inputs  

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.