Building an AI-Powered IT Knowledge Base Pipeline

Peter Bubenik Β· AWS ML Β· Β· Source
Image for KnowledgeForge: mining gold from the ITSM ticket graveyard

🎯 Learning Outcomes

After studying this material, you should be able to:

  1. Explain the core problem KnowledgeForge solves (trapped ITSM knowledge + decaying knowledge bases)
  2. Describe the two-subsystem architecture (Generation + Curation) and how they form a closed loop
  3. Identify the AWS services used and justify why each was chosen
  4. Understand key engineering patterns: RAG grounding, vector-based duplicate detection, distributed orchestration, quality scoring, and multi-tenant isolation
  5. Apply these architectural patterns to design similar document-processing pipelines

πŸ“š Step-by-Step Teaching Guide


STEP 1: Understand the Problem Before the Solution

Before touching any technology, you must clearly understand what problem exists.

The Two-Sided Problem

SIDE 1: The Ticket Graveyard          SIDE 2: The Messy Knowledge Base
─────────────────────────────         ────────────────────────────────
Thousands of resolved tickets    VS   Knowledge base exists but is:
each month, each containing:          β€’ Full of duplicate articles
  β€’ A symptom                         β€’ Stale/outdated content
  β€’ A root cause                      β€’ Inconsistent quality
  β€’ A working fix                     β€’ Hard to search effectively

Result: Knowledge is TRAPPED          Result: Knowledge is UNUSABLE

Why This Matters

Think of it like a library where new books are locked in the basement (tickets), while the public shelves (knowledge base) are filled with outdated, duplicate copies of the same book.

Key insight: The resolutions already exist. The problem is access and organization, not missing information.


STEP 2: Understand the High-Level Architecture

KnowledgeForge has two subsystems that feed each other in a closed loop.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    CLOSED LOOP                          β”‚
β”‚                                                         β”‚
β”‚  Incident Tickets                                       β”‚
β”‚       β”‚                                                 β”‚
β”‚       β–Ό                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    vectors    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  GENERATION  │◄──────────────│    CURATION      β”‚   β”‚
β”‚  β”‚              β”‚               β”‚                  β”‚   β”‚
β”‚  β”‚ Tickets β†’    │──new articles─►│ Classify         β”‚   β”‚
β”‚  β”‚ Articles     β”‚               β”‚ Deduplicate      β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚ Score Quality    β”‚   β”‚
β”‚                                 β”‚ Improve Content  β”‚   β”‚
β”‚                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                          β”‚              β”‚
β”‚                                          β–Ό              β”‚
β”‚                                  Knowledge Manager      β”‚
β”‚                                  Reviews & Approves     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The Five Stages an Article Travels Through

StageWhat Happens
1. IngestionTicket clusters arrive as JSON in S3
2. GenerationAI writes draft articles from ticket clusters
3. ClassificationArticles are sorted by type
4. CurationDeduplication β†’ Quality Scoring β†’ Improvement
5. ReviewKnowledge manager approves before publishing

STEP 3: Learn the Generation Subsystem

How Generation Works β€” Step by Step

Step 3.1: Input arrives

Resolved Tickets (grouped by theme)
         β”‚
         β–Ό
    JSON file in S3
    (per customer, per theme)
    Contains:
    β€’ Keywords
    β€’ Article scope  
    β€’ Sample ticket descriptions
    β€’ Work notes from engineers

Step 3.2: The queue and compute layer

New S3 file
    β”‚
    β–Ό
Amazon SQS Queue  ←── event notification
    β”‚
    β–Ό
Amazon ECS + AWS Fargate container
(polls queue, processes up to 5 themes at once)

Why ECS + Fargate here?

RequirementWhy Fargate Fits
Work takes several minutes per themeLong-running containers (not short Lambda functions)
Workload arrives in burstsScales task count up/down based on queue depth
Team wants to focus on logic, not serversServerless containers β€” no EC2 management

Step 3.3: RAG Grounding (Critical Concept)

Before writing anything, the system asks: "What already exists on this topic?"

Theme arrives
    β”‚
    β–Ό
Query S3 Vectors index
"Find 5 most similar existing articles"
    β”‚
    β–Ό
Pass those articles as CONTEXT to the AI model
    β”‚
    β–Ό
AI generates new article GROUNDED in existing content

Why this matters: Without grounding, the AI might invent procedures or use inconsistent terminology. With grounding, new articles match the style and accuracy of proven content.

Step 3.4: What gets generated

For each ticket cluster/theme, the model produces two documents:

  1. A Knowledge Base Article (the fix, step-by-step)
  2. A Root Cause Analysis document (why it happened)

The system uses response streaming β€” it assembles the document as tokens arrive rather than waiting for the complete response. This reduces perceived latency on long documents.


STEP 4: Learn the Curation Subsystem

Curation handles all articles β€” both newly generated ones and existing knowledge base articles.

The Four Curation Steps

Article enters curation
        β”‚
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. CLASSIFY      β”‚  What type of article is this?
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  2. DEDUPLICATE   β”‚  Does this already exist?
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  3. SCORE QUALITY β”‚  How good is this article?
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  4. IMPROVE       β”‚  If score is low, rewrite it
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
    Published to ServiceNow
    for knowledge manager review

STEP 5: Deep Dive β€” Duplicate Detection with S3 Vectors

This is one of the most elegant patterns in the system.

Why Keyword Matching Fails

Article A: "Restart the network adapter to fix connectivity"
Article B: "To resolve connection issues, reboot the NIC"
Article C: "Network problems? Cycling the adapter usually works"

Keyword match: These look DIFFERENT
Meaning match: These are the SAME article

How Vector-Based Deduplication Works

Step 5.1: Every article gets converted to a vector

Article text
    β”‚
    β–Ό
Amazon Titan Text Embeddings V2
    β”‚
    β–Ό
1,024-dimension vector
(a list of 1,024 numbers representing the article's MEANING)
    β”‚
    β–Ό
Stored in Amazon S3 Vectors index (per customer)

Step 5.2: New article is compared against existing vectors

New article β†’ embed β†’ query S3 Vectors index
                              β”‚
                              β–Ό
                    Find top-5 nearest vectors
                              β”‚
                              β–Ό
                    Cosine distance < 0.05?
                    (similarity > 95%?)
                         β”‚         β”‚
                        YES        NO
                         β”‚         β”‚
                    DUPLICATE    UNIQUE
                         β”‚
                         β–Ό
                  Keep NEWER article,
                  retire OLDER one

Understanding Cosine Distance Threshold

Distance 0.0 = Identical articles
Distance 0.05 = 95%+ similar = DUPLICATE (flagged)
Distance 0.10 = Related but different = NOT duplicate
Distance 1.0 = Completely unrelated

Tuning insight: Too loose (0.10) β†’ false duplicates flagged. Too tight (0.01) β†’ reworded copies missed. The team sampled flagged pairs and adjusted until behavior was correct.

Why S3 Vectors Instead of a Dedicated Vector Database?

FactorS3 VectorsStandalone Vector DB
InfrastructureNone (uses existing S3)New service to manage
Cost modelPer query + per GBPer running node (always-on cost)
IntegrationAlready in S3 ecosystemRequires new connections
ScaleGrows with your contentMay need resizing

Bonus: The same index serves double duty β€” it's used for RAG grounding in Generation AND for duplicate detection in Curation.


STEP 6: Understand the Orchestration with Step Functions

Why Orchestration Is Needed

Curation processes tens of thousands of articles across many customers. You need:

  • Work distributed across multiple workers
  • Automatic retry on failures
  • State tracking across long-running processes
  • Protection against one bad article breaking everything

The Two-Phase Distributed Map

EventBridge (daily schedule)
        β”‚
        β–Ό
Lambda: Find customers with new/changed articles
        β”‚
        β–Ό
Group into batches β†’ SQS FIFO Queue
        β”‚
        β–Ό
Dispatcher: Pull one batch β†’ Start Step Functions execution
        β”‚
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         STEP FUNCTIONS STATE MACHINE  β”‚
β”‚                                       β”‚
β”‚  PHASE 1: Distributed Map             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ For each article (concurrent):  β”‚  β”‚
β”‚  β”‚  β€’ Classify type                β”‚  β”‚
β”‚  β”‚  β€’ Deduplicate (sequential)     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                       β”‚
β”‚  PHASE 2: Distributed Map             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ For each article (concurrent):  β”‚  β”‚
β”‚  β”‚  β€’ Score quality                β”‚  β”‚
β”‚  β”‚  β€’ Improve if below threshold   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Configuration Decisions Explained

Decision 1: STANDARD vs EXPRESS mode

ModeMax DurationExecution HistoryUse When
EXPRESS5 minutesLimitedShort, high-volume tasks
STANDARD1 yearFull historyLong AI calls + debugging

KnowledgeForge uses STANDARD because Bedrock calls can exceed 5 minutes.

Decision 2: S3 pointer instead of inline state

❌ WRONG approach:
State machine carries full article HTML in its state
β†’ Hits 256 KB limit immediately with large articles

βœ… CORRECT approach:
State machine carries only: { "s3_location": "bucket/article123.json" }
β†’ Workers read directly from S3
β†’ State payload stays tiny regardless of article size

Decision 3: FIFO Queue for ordering

Customer A articles: [A1, A2, A3, A4, A5] β†’ processed in order
Customer B articles: [B1, B2, B3, B4, B5] β†’ processed in order
                                              (parallel to Customer A)

Using customer ID as the message group key ensures:

  • Each customer's batches process in order (prevents dedup race conditions)
  • Different customers still run in parallel (no bottleneck)

STEP 7: Quality Scoring and Content Improvement

The Quality Score

Each article is scored across 10 weighted dimensions (highest to lowest weight):

Dimension                    Weight
─────────────────────────────────────
Technical accuracy           β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (highest)
Completeness                 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
Clarity                      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
Structure/formatting         β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
Step-by-step instructions    β–ˆβ–ˆβ–ˆβ–ˆ
Troubleshooting coverage     β–ˆβ–ˆβ–ˆ
Prerequisites listed         β–ˆβ–ˆ
Examples included            β–ˆβ–ˆ
Links/references             β–ˆ
Metadata quality             β–ˆ (lowest)
─────────────────────────────────────
Weighted total = Quality Score (0-100)

The Improvement Decision

Article scored
      β”‚
      β–Ό
Score β‰₯ threshold?
   β”‚          β”‚
  YES         NO
   β”‚          β”‚
Keep as-is   Send for AI improvement
              β”‚
              β–Ό
         Score AGAIN after improvement
              β”‚
              β–Ό
         New score > Original score?
              β”‚          β”‚
             YES         NO
              β”‚          β”‚
         Keep new    Keep original
         version     (don't make it worse!)

Critical safety check: The before-and-after scoring ensures the pipeline never silently degrades content quality.

The Media Placeholder Pattern

This solves a subtle but important problem: AI models tend to corrupt image URLs and hyperlinks when rewriting prose.

BEFORE improvement:
"See <img src='https://cdn.example.com/diagram.png'> for reference.
Visit <a href='https://docs.example.com/fix'>this guide</a>."

STEP 1 - Replace with tokens:
"See [IMG_1] for reference. Visit [LINK_1]."
(Store: IMG_1 = original img tag, LINK_1 = original link)

STEP 2 - AI improves prose:
"Refer to [IMG_1] for a visual overview. 
Consult [LINK_1] for detailed instructions."

STEP 3 - Restore originals:
"Refer to <img src='https://cdn.example.com/diagram.png'> for a visual overview.
Consult <a href='https://docs.example.com/fix'>this guide</a> for detailed instructions."

The AI never sees raw URLs, so it cannot break them.


STEP 8: Resilience Patterns Under Load

Running tens of thousands of AI model calls concurrently requires careful engineering.

Three Controls for Predictable Generation

Control 1: Rate Limiting
─────────────────────────
Limit concurrent Bedrock calls per batch
β†’ Prevents hitting API quotas
β†’ Keeps costs predictable

Control 2: Guardrail Fallback
──────────────────────────────
If guardrail API throttles:
  β†’ Process article WITHOUT guardrail
  β†’ Log a WARNING
  β†’ Continue (don't fail the whole batch)
Why: Keeps pipeline healthy during load spikes

Control 3: Token Budget Retry
──────────────────────────────
If response is cut off (hit token limit):
  β†’ Detect "stopped at token limit" signal
  β†’ Retry with DOUBLE the token budget
  β†’ Up to model's maximum ceiling
Why: Long articles need more tokens; short articles pay nothing extra

Two Fault-Tolerance Mechanisms

Mechanism 1: Tolerated Failure Percentage
──────────────────────────────────────────
A few bad articles in a batch?
β†’ Continue processing the rest
β†’ Don't abort the entire batch

Mechanism 2: Dead-Letter Queue (DLQ)
──────────────────────────────────────
Repeatedly failing articles?
β†’ Move to DLQ for investigation
β†’ Don't block other articles
β†’ Don't stall the entire run

STEP 9: Multi-Tenant Isolation

The system serves multiple customers on shared infrastructure. Isolation is non-negotiable.

Per-Customer Resources

Customer A                    Customer B
──────────────────────────    ──────────────────────────
S3 Vectors index (A only)     S3 Vectors index (B only)
Custom prompts for A          Custom prompts for B  
Encryption key (A only)       Encryption key (B only)
SQS FIFO message group A      SQS FIFO message group B

Why This Design Is Smart

❌ Shared pool approach:
One index for all customers
β†’ Customer A's articles could appear in Customer B's results
β†’ Data leakage risk
β†’ One customer's bad data affects others

βœ… Per-customer approach:
Duplicate check runs against THIS customer's index only
Content improvement uses THIS customer's prompts only
Data encrypted under THIS customer's key only
β†’ Complete isolation by design

Onboarding new customers: No code changes needed. The system discovers customers from a data catalog at runtime. Adding a customer = provisioning their resources only.


STEP 10: Synthesize β€” The Four Key Lessons

These are the transferable patterns you can apply to your own pipelines:

LessonPatternBenefit
1. Reuse your vector indexSame index for RAG grounding AND duplicate detectionSolves two problems with one infrastructure component
2. Pass pointers, not payloadsS3 location through Step Functions, not article contentEliminates state-size failures at scale
3. Score before AND after improvementQuality check brackets the AI callSafe to run automatically without degrading content
4. Degrade gracefully under throttlingGuardrail throttle = warning, not failurePipeline stays healthy through load spikes

🧠 Knowledge Check

Test your understanding with these questions:

  1. Why does KnowledgeForge use ECS+Fargate for generation but Step Functions for curation?

  2. Explain why cosine distance of 0.05 was chosen for duplicate detection. What happens if you set it to 0.20?

  3. Trace the path of a single article from ticket cluster to published knowledge base article through all five stages.

  4. Why is the media placeholder pattern necessary during content improvement?

  5. What would happen if the system used a shared S3 Vectors index for all customers instead of per-customer indexes?


πŸ“‹ Summary Diagram

ITSM Tickets (resolved, clustered by theme)
              β”‚
              β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚              GENERATION (ECS + Fargate)             β”‚
    β”‚  RAG grounding β†’ Claude Sonnet β†’ KB Article + RCA  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ new articles
                           β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚           CURATION (Step Functions)                 β”‚
    β”‚                                                     β”‚
    β”‚  Classify β†’ Deduplicate    β†’ Score β†’ Improve        β”‚
    β”‚             (S3 Vectors)     (10     (Claude +      β”‚
    β”‚             cosine dist)     dims)   placeholders)  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ vectors stored back
                           β–Ό
              S3 Vectors Index (per customer)
                           β”‚
                           β–Ό (also feeds back to Generation)
              Knowledge Manager Review (ServiceNow)
                           β”‚
                           β–Ό
              βœ… Published Knowledge Base Article

More to study