Portal Community

The AI Agent Node for Enrichment

The AIAgentNodeExecutor (exposed in Flow Studio as the AI Agent Node) is the primary vehicle for AI-driven enrichment. It accepts a prompt template, binds record fields as context variables, calls the configured LLM, and returns a structured JSON response that subsequent workflow nodes can parse and write to SQL.

Node Configuration

{
  "nodeType": "AIAgentNode",
  "nodeId": "classify-lead",
  "agentId": "enrichment-agent",   // Octopus agent configured for enrichment tasks
  "promptTemplate": "You are a B2B sales intelligence AI. Analyze this lead record and classify the lead quality.\n\nLead Details:\n- Name: {{lead.FullName}}\n- Company: {{lead.CompanyName}}\n- Industry: {{lead.Industry}}\n- Annual Revenue: {{lead.EstimatedValue}}\n- Notes: {{lead.Notes}}\n- Source: {{lead.Source}}\n\nRespond with a JSON object only:\n{\n  \"classificationLabel\": \"High Value | Medium Value | Low Value | Unlikely to Convert\",\n  \"confidenceScore\": 0.0-1.0,\n  \"reasoning\": \"One sentence explanation\",\n  \"recommendedAction\": \"Next step for the sales rep\"\n}",
  "responseFormat": "json",
  "modelId": "gpt-4o",
  "temperature": 0.2,   // Low temperature for classification — more deterministic
  "outputVariable": "classificationResult"
}

Parsing the AI Response

// After AIAgentNode, use a Transform Node to map the AI response to variables:
{
  "nodeType": "TransformNode",
  "nodeId": "map-classification",
  "mappings": {
    "classificationLabel": "{{variables.classificationResult.classificationLabel}}",
    "confidenceScore":     "{{variables.classificationResult.confidenceScore}}",
    "recommendedAction":   "{{variables.classificationResult.recommendedAction}}"
  },
  "outputVariable": "enrichmentData"
}

Enrichment Task Reference

1. Classification

Assigns a categorical label from a defined set. Best for routing, prioritization, and segmentation:

Prompt pattern:
"Classify this [RECORD TYPE] into exactly one of these categories:
[Category A | Category B | Category C | Category D]

Record content:
{{record.relevantFields}}

Return JSON: { \"label\": \"\", \"confidence\": 0.0-1.0 }"

Temperature: 0.1-0.2 (deterministic classification). Output: ClassificationLabel nvarchar(200).

2. Summarization

Condenses long-form content into a short, structured summary. Best for notes, email threads, support tickets:

Prompt pattern:
"Summarize the following [CONTENT TYPE] in 2-3 sentences. Focus on key facts, decisions made, and next steps.

Content:
{{record.Notes}}

Return JSON: { \"summary\": \"...\", \"keyPoints\": [\"...\", \"...\"] }"

Temperature: 0.3-0.5 (some creativity acceptable). Output: SummaryText nvarchar(max).

3. Sentiment Analysis

Measures emotional tone on a numeric scale. Best for customer feedback, reviews, support tickets:

Prompt pattern:
"Analyze the sentiment of this text on a scale from -1.0 (very negative) to 1.0 (very positive).

Text:
{{record.CustomerFeedback}}

Return JSON: { \"score\": -1.0 to 1.0, \"label\": \"Positive | Neutral | Negative | Mixed\" }"

Temperature: 0.1 (deterministic). Output: SentimentScore decimal(5,4), ClassificationLabel.

4. Entity Extraction

Identifies and structures named entities from unstructured text:

Prompt pattern:
"Extract named entities from this text. Find: people, companies, products, dates, monetary amounts, and locations.

Text:
{{record.Notes}}

Return JSON:
{
  \"people\": [\"...\"],
  \"companies\": [\"...\"],
  \"products\": [\"...\"],
  \"amounts\": [{ \"value\": 0, \"currency\": \"USD\" }],
  \"dates\": [\"YYYY-MM-DD\"],
  \"locations\": [\"...\"]
}"

Output: ExtractedEntitiesJson nvarchar(max).

Prompt Engineering Guidelines

GuidelineReason
Always specify exact JSON output formatPrevents free-text responses that are harder to parse reliably
Use low temperature (0.1-0.3) for classificationReduces random variation in categorical outputs
Include the category list explicitly in the promptPrevents the model from inventing new categories
Set responseFormat: "json" on the nodeEnables JSON mode on the LLM — eliminates non-JSON output
Keep prompts focused on one task per nodeBetter results, easier debugging, modular pipeline
Include a confidence score requestEnables downstream filtering of low-confidence enrichment
Handle Low-Confidence Results

Add a condition node after each AI enhancement node: if confidenceScore < 0.5, write ClassificationLabel = "Needs Human Review" instead of the AI-generated label. This prevents propagating inaccurate classifications into downstream reports and workflows.

Write-Back Node Configuration

// SqlUpdateNode — write all enrichment results in a single atomic UPDATE
{
  "nodeType": "SqlUpdateNode",
  "nodeId": "write-enrichment",
  "datasourceId": "sales-data-db",
  "command": "UPDATE Lead SET ClassificationLabel = @classificationLabel, SummaryText = @summaryText, SentimentScore = @sentimentScore, AiProcessedAt = GETUTCDATE(), AiModelVersion = @modelVersion, UpdatedAt = GETUTCDATE() WHERE TenantId = @tenantId AND LeadId = @leadId",
  "parameters": {
    "tenantId": "{{workflow.tenantId}}",
    "leadId": "{{input.leadId}}",
    "classificationLabel": "{{variables.enrichmentData.classificationLabel}}",
    "summaryText": "{{variables.summaryResult.summary}}",
    "sentimentScore": "{{variables.sentimentResult.score}}",
    "modelVersion": "gpt-4o-2024-08-06"
  }
}