Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • Getting Started with AI for VLSI Engineers5
  • Just Enough AI: Models and Context15
  • Prompting13
  • Trust and Verification14
  • Using AI for Engineering Work17
  • Engineering Walkthroughs7
  • Practical Foundations for AI Workflows4
  • Engineering Data5
  • Retrieval-Augmented Generation6
  • Agents and Tool Use18
  • Agent Design8
  • MCP and Skills6
  • Multi-Agent Design6
  • Practical Capstone6
  • Tokens, Cost and Latency12
  • Agentic Workflows for Chip Teams18
    • Regression Triage Agent
      • The Nightly Triage Loop
      • Clustering Failures by Signature
      • Ranking Suspects with Evidence
      • Read-Only by Default
      • Evaluating Against Labelled History
    • Lint-and-Fix Loops
    • Guardrails and Human in the Loop
    • Evaluating and Operating Agents
  • Interview and Judgment10
  • AI Skills: Full Course Index
  • Working with AI Glossary
  • Working with AI Cheatsheet
Loading lesson

‹Regression Triage Agent
  1. Topics
  2. AI Skills for VLSI Engineers
  3. Agentic Workflows for Chip Teams
  4. Regression Triage Agent
  5. Clustering Failures by Signature

Reference: Agentic Workflows for Chip Teams · Beginner to Intermediate

Clustering Failures by Signature

Normalizing log lines into signatures and grouping repeat failures into clusters.

On this page

    Normalization

    Raw log lines never match directly. Timestamps, seeds, and addresses differ on every run, so the agent replaces each with a placeholder before comparing.

    Token load matters here. A common approximate rule is 3 to 4 characters per token for English prose with common tokenizers, fewer for hex and numbers; the exact ratio varies by tokenizer, so measure it before sizing a truncation budget.

    Pattern

    Replaced with

    Why

    Hex addresses

    #

    Same bug fails at different addresses.

    Decimal numbers

    #

    Timestamps and cycle counts always differ.

    The rest

    Kept as is

    The message text carries the signature.

    Grouping

    Lines with equal normalized text share a signature. Runs sharing a signature form one group, and the group size counts the repeats.

    Long inputs are less reliable than short ones. Studies report models use the start and end of long inputs better than the middle, a tendency rather than a law, so keep the error line and the tail when trimming logs.

    Runnable model

    The program below is a scripted stand-in for the clustering step, not a model. Six log lines form three groups with sizes 3, 2 and 1, and the checks verify exactly that.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    import re
    import sys
    
    LOGS = [
        "UVM_ERROR @ 12345 ns: axi_rd_data bad, addr 0x3f20",
        "UVM_ERROR @ 67890 ns: axi_rd_data bad, addr 0x112c",
        "TIMEOUT @ 99999 ns: waiting for irq, addr 0xabcd",
        "UVM_ERROR @ 11111 ns: axi_rd_data bad, addr 0x00ff",
        "TIMEOUT @ 22222 ns: waiting for irq, addr 0x4455",
        "ASSERT @ 33333 ns: fifo full stuck",
    ]
    
    def signature(line):
        s = re.sub(r"0x[0-9a-fA-F]+", "#", line)
        s = re.sub(r"[0-9]+", "#", s)
        return s
    
    def cluster(logs):
        groups = {}
        for i, line in enumerate(logs):
            groups.setdefault(signature(line), []).append(i)
        return groups
    
    groups = cluster(LOGS)
    sizes = sorted((len(v) for v in groups.values()), reverse=True)
    
    if len(groups) != 3:
        print("FAIL: expected 3 groups")
        sys.exit(1)
    if sizes != [3, 2, 1]:
        print("FAIL: expected sizes 3, 2 and 1")
        sys.exit(1)
    if sorted(groups[signature(LOGS[0])]) != [0, 1, 3]:
        print("FAIL: first group wrong")
        sys.exit(1)
    if sorted(groups[signature(LOGS[2])]) != [2, 4]:
        print("FAIL: second group wrong")
        sys.exit(1)
    print("PASS: 6 runs form 3 groups with sizes 3, 2 and 1")

    Common mistakes

    Common pitfall

    Normalizing too aggressively merges distinct bugs. Stripping the message text along with the numbers turns every timeout into one group, and the suspect list becomes meaningless.

    Interview

    Likely probes: what normalization keeps and what it drops, and why group size matters.

    • Numbers and addresses are dropped; message text is kept as the signature.

    • Group size ranks engineer attention: a group of fifty outranks five singletons.

    • Over-merging hides bugs while under-merging spams cards; both show up in labelled evaluation.

    Check yourself Two lines differ only in timestamp and address. Same signature?

    Yes. Both patterns are replaced with placeholders, so the normalized texts match.

    Check yourself In the program, why do runs 0, 1 and 3 land together?

    All three normalize to one UVM_ERROR line with placeholders. Run 2 differs in message text, so it starts its own group.

    Related topics

    • Ranking suspects with evidence

    • Debugging with AI

    Previous

    144 / 173

    Next: Ranking Suspects with Evidence

    Up next

    Up nextRanking Suspects with Evidence

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Read-Only by Default
    • Evaluating Against Labelled History