UNPKG

@botpress/adk-cli

Version:

Command-line interface for the Botpress Agent Development Kit (ADK)

429 lines (314 loc) 16.9 kB
# Conversation Analysis How to summarize and explain full conversations using the `adk conversations` command. A conversation spans multiple turns (traces), so this is a higher-level view than single-trace analysis. For single-trace summaries, see `trace-summarization.md`. This document covers multi-turn conversation-level analysis. --- ## CLI Commands ### List recent conversations ```bash adk conversations --format json adk conversations list limit=5 --format json ``` **Output** (JSON): Array of objects, each with: | Field | Type | Description | | ---------------- | ------- | ----------------------------------------------------------------------- | | `conversationId` | string | Unique conversation identifier | | `firstSeen` | string | ISO timestamp of the first recorded turn | | `lastSeen` | string | ISO timestamp of the most recent turn | | `traceCount` | number | Total number of turns in the conversation | | `integration` | string | Which integration the conversation came from (e.g., `slack`, `webchat`) | | `channel` | string | Which channel within the integration (e.g., `dm`, `thread`) | | `hasErrors` | boolean | Whether any turn in the conversation had errors | ### Show a conversation's timeline ```bash # Standard view adk conversations show <conversation-id> --format json # With LLM reasoning included adk conversations show <conversation-id> --include-llm --format json ``` **Output** (JSON): Object with: | Field | Type | Description | | ---------------- | ------ | ---------------------------- | | `conversationId` | string | The conversation ID | | `turnCount` | number | Total number of turns | | `turns` | array | Ordered list of turn objects | Each turn object contains: | Field | Type | Description | | ------------ | ------ | ------------------------------------------------------------ | | `traceId` | string | Trace ID for this turn (use for drill-down) | | `startedAt` | string | ISO timestamp when the turn started | | `duration` | string | How long the turn took (e.g., `"2.3s"`) | | `status` | string | `"ok"` or `"error"` | | `trigger` | string | What started this turn (e.g., user message, event, workflow) | | `toolCalls` | array | Tools invoked during this turn | | `errors` | array | Error strings, if any | | `llmContent` | array | LLM reasoning data (only with `--include-llm`) | Each `toolCalls` entry has: `name`, `status`, `duration`, `error?` Each `llmContent` entry has: `name`, `data` --- ## Two Modes of Analysis ### 1. Summarize a Conversation **Purpose:** Give a concise overview of what happened -- a paragraph or two covering the full conversation arc. **When to use:** The developer asks "What happened in this conversation?", "Summarize conversation X", or wants a quick picture before diving deeper. **Data source:** ```bash adk conversations show <conversation-id> --format json ``` No need for `--include-llm` -- the standard view has enough for a summary. **What to cover:** 1. **Who and where** -- integration, channel, how many turns, time span 2. **The flow** -- what the user asked for, what the agent did, how the conversation progressed 3. **Tools used** -- which tools were called and how often 4. **Outcome** -- did the conversation succeed? Were there errors? How did it end? 5. **Red flags** -- only if present: errors, long durations, many turns for a simple task **How to write it:** Write a natural-language paragraph, not a list or template. Synthesize the turn data into a narrative. #### Example Given this conversation data: ```json { "conversationId": "conv_abc123", "turnCount": 4, "turns": [ { "traceId": "tr_001", "startedAt": "2026-04-21T14:00:00.000Z", "duration": "1.8s", "status": "ok", "trigger": "User message via slack/dm", "toolCalls": [], "errors": [] }, { "traceId": "tr_002", "startedAt": "2026-04-21T14:00:05.000Z", "duration": "3.2s", "status": "ok", "trigger": "User message via slack/dm", "toolCalls": [{ "name": "lookupOrder", "status": "ok", "duration": "0.9s" }], "errors": [] }, { "traceId": "tr_003", "startedAt": "2026-04-21T14:00:15.000Z", "duration": "4.1s", "status": "error", "trigger": "User message via slack/dm", "toolCalls": [ { "name": "cancelOrder", "status": "error", "duration": "1.2s", "error": "Cannot cancel shipped order" } ], "errors": ["Cannot cancel shipped order"] }, { "traceId": "tr_004", "startedAt": "2026-04-21T14:00:25.000Z", "duration": "2.0s", "status": "ok", "trigger": "User message via slack/dm", "toolCalls": [], "errors": [] } ] } ``` **Good summary:** > A 4-turn Slack DM conversation over about 30 seconds. The user started with a greeting, then asked about an order -- the agent looked it up with `lookupOrder`. The user then asked to cancel the order, but `cancelOrder` failed because the order was already shipped. The agent recovered in the final turn without needing more tools, likely explaining the situation to the user. One error occurred (`cancelOrder` failure) but it was handled gracefully. **Bad summary:** > Turn 1: traceId tr_001, status ok, no tools. Turn 2: traceId tr_002, called lookupOrder, status ok. Turn 3: traceId tr_003, called cancelOrder, status error, error "Cannot cancel shipped order". Turn 4: traceId tr_004, status ok, no tools. --- ### 2. Explain a Conversation **Purpose:** Provide a detailed, step-by-step breakdown where the developer understands every decision the agent made. **When to use:** The developer asks "Walk me through this conversation", "Explain what happened", "Why did the bot respond that way?", or is investigating a specific behavior. **Data source:** ```bash adk conversations show <conversation-id> --include-llm --format json ``` **Always use `--include-llm`** for explanations. Without it, you lose the LLM's reasoning, which is essential for explaining _why_ the agent did what it did. **What to cover for each turn:** 1. **The trigger** -- what started this turn (user message, event, workflow continuation) 2. **LLM reasoning** -- what the agent decided to do and why (from `llmContent`) 3. **Tool calls** -- what was called, with what inputs, what happened 4. **Errors** -- what went wrong and how the agent responded 5. **The response** -- what the agent said back (infer from context if not explicit) 6. **Transitions** -- how one turn's outcome led to the next **How to write it:** Walk through turns chronologically. For each turn, narrate what happened as a coherent paragraph. Use tool names in backticks, quote key values, and explain the agent's reasoning when `llmContent` provides it. #### Example Given the same conversation with `--include-llm`: ```json { "conversationId": "conv_abc123", "turnCount": 4, "turns": [ { "traceId": "tr_001", "startedAt": "2026-04-21T14:00:00.000Z", "duration": "1.8s", "status": "ok", "trigger": "User message via slack/dm", "toolCalls": [], "errors": [], "llmContent": [ { "name": "cognitive.iteration", "data": "The user said 'Hi, I need help with an order'. This is a greeting with intent to discuss an order. I'll respond and ask for the order number." } ] }, { "traceId": "tr_002", "startedAt": "2026-04-21T14:00:05.000Z", "duration": "3.2s", "status": "ok", "trigger": "User message via slack/dm", "toolCalls": [{ "name": "lookupOrder", "status": "ok", "duration": "0.9s" }], "errors": [], "llmContent": [ { "name": "cognitive.iteration", "data": "The user provided order number #4521. I should look this up to get the details before responding." } ] }, { "traceId": "tr_003", "startedAt": "2026-04-21T14:00:15.000Z", "duration": "4.1s", "status": "error", "trigger": "User message via slack/dm", "toolCalls": [ { "name": "cancelOrder", "status": "error", "duration": "1.2s", "error": "Cannot cancel shipped order" } ], "errors": ["Cannot cancel shipped order"], "llmContent": [ { "name": "cognitive.iteration", "data": "The user wants to cancel order #4521. I'll use cancelOrder." }, { "name": "cognitive.iteration", "data": "cancelOrder failed -- the order is already shipped. I need to tell the user and suggest a return instead." } ] }, { "traceId": "tr_004", "startedAt": "2026-04-21T14:00:25.000Z", "duration": "2.0s", "status": "ok", "trigger": "User message via slack/dm", "toolCalls": [], "errors": [], "llmContent": [ { "name": "cognitive.iteration", "data": "The user asked how to start a return. I know the process from the instructions -- they need to go to the returns portal. No tool call needed." } ] } ] } ``` **Good explanation:** > **Turn 1** (tr_001, 1.8s): The user opened the conversation in Slack DM with "Hi, I need help with an order." The agent recognized this as a greeting with order-related intent and responded by asking for the order number. No tools were needed. > > **Turn 2** (tr_002, 3.2s): The user provided order #4521. The agent called `lookupOrder` to retrieve the order details (completed in 0.9s). The lookup succeeded and the agent relayed the order information to the user. > > **Turn 3** (tr_003, 4.1s): The user asked to cancel the order. The agent called `cancelOrder`, which failed with "Cannot cancel shipped order" -- the order had already shipped. The agent's reasoning shows it recognized the failure and decided to suggest a return as an alternative. The turn is marked as `error` because of the tool failure, but the agent handled it gracefully. > > **Turn 4** (tr_004, 2.0s): The user asked how to start a return. The agent answered from its instructions without needing any tool calls, directing the user to the returns portal. The conversation ended successfully. > > **Overall:** The conversation followed a natural support flow -- greeting, order lookup, failed cancellation handled with a fallback suggestion, and resolution. The `cancelOrder` error is expected behavior for a shipped order, not a bug. --- ## Picking Which Conversation to Analyze When the developer doesn't specify a conversation ID, help them find the right one. ### Step 1: List conversations ```bash adk conversations --format json ``` ### Step 2: Narrow down Use the list output to identify the conversation. Key signals: | Signal | How to Use | | ------------------------- | ------------------------------------------------------------------------------- | | `lastSeen` | Most recent conversation is usually the one they're asking about | | `hasErrors` | If they're debugging a failure, look for `hasErrors: true` | | `integration` / `channel` | If they mention "the Slack conversation" or "the webchat issue", match on these | | `traceCount` | High turn counts may indicate stuck loops or long interactions | ### Step 3: Show the conversation ```bash adk conversations show <conversation-id> --format json ``` If the developer needs more detail, add `--include-llm`. --- ## Correlating with Trace Data Each turn in the conversation has a `traceId`. This is the bridge between conversation-level and trace-level analysis. **When to drill into a trace:** - A turn has `status: "error"` and you need the full span tree to understand why - A tool call failed and you need the stack trace or detailed error - The LLM reasoning (from `llmContent`) is surprising and you want to see the full `think` spans - You need to see the exact inputs/outputs of a tool call **How to drill down:** ```bash # Get the full trace for a specific turn adk traces trace=<trace-id> --include-llm --format json ``` Then use the trace-reading techniques from `trace-summarization.md` to analyze the individual trace. **Flow:** ``` adk conversations list find the conversation adk conversations show <id> see the timeline adk traces trace=<trace-id> drill into a specific turn ``` --- ## Common Patterns to Highlight When analyzing conversations, watch for these patterns and call them out. ### Long conversations A conversation with many turns (10+) for what should be a simple task. **What to say:** Flag the turn count, identify where the conversation got stuck or went off track, and suggest whether the issue is in the agent's instructions, tool design, or workflow logic. ### Error recovery The agent encounters an error but recovers in a subsequent turn. **What to say:** Note that the agent handled the error gracefully, explain the recovery path, and confirm whether the behavior is correct or accidental. ### Tool call chains Multiple tools called in sequence within a single turn, or across turns, to accomplish a multi-step task. **What to say:** Describe the chain, note whether each step depended on the previous one's output, and flag any unnecessary calls. ### Stuck loops The agent calls the same tool repeatedly across multiple turns or within a single turn. **What to say:** Identify the repeating pattern, explain why the agent is stuck (from `llmContent` if available), and suggest fixes (improve tool output, add `onBeforeTool` guard, set `maxIterations`). See `llm-debugging.md` for more on looping. ### Silent failures A turn completes with `status: "ok"` but the agent didn't actually accomplish the task (e.g., returned a generic response without calling a tool). **What to say:** Flag the gap between expected and actual behavior, and suggest investigating the LLM reasoning with `--include-llm`. ### Integration-specific patterns Different integrations have different conversation patterns -- Slack threads vs webchat sessions vs API calls. **What to say:** Note the integration and channel, and flag anything unusual for that context (e.g., a webchat conversation with 50 turns might indicate the user is stuck in a loop, while a Slack thread with 50 turns might be a busy channel). --- ## Patterns **Summarize first, explain on request** ``` Developer: "What happened in conv_abc123?" Start with a summary (no --include-llm needed) Only drill into explanation if they ask for more detail ``` **Use the conversation timeline as a map** ``` Good: "The conversation had 4 turns. Turn 3 is where the error occurred. Let me drill into that trace." Bad: Immediately fetching all traces for all turns and dumping everything. ``` **Name the integration and channel** ``` Good: "A 4-turn Slack DM conversation..." Bad: "A conversation with 4 turns..." ``` **Connect turns to each other** ``` Good: "The user asked about the order in turn 2, then tried to cancel it in turn 3 -- the cancellation failed because the lookup in turn 2 showed the order was already shipped." Bad: "Turn 2: lookupOrder called. Turn 3: cancelOrder failed." ``` **Suggest drill-down when appropriate** ``` Good: "Turn 3 failed with a cancelOrder error. To see the full stack trace, run: adk traces trace=tr_003 --include-llm --format json" Bad: Automatically fetching and dumping the full trace without being asked. ``` **Don't dump raw JSON in the analysis** The developer already has the JSON. Your job is to synthesize it into understanding. **Don't speculate about what the user said** The conversation timeline shows what the agent did, not the exact user messages. Use `trigger` and `llmContent` to infer context, but be clear when you're inferring vs. when you have direct evidence. **Don't re-explain tool behavior the developer already knows** If the developer built the tools, they know what `lookupOrder` does. Focus on _what happened_ and _why_, not what the tool is for. **Don't ignore the overall arc** Even in a detailed explanation, start and end with the big picture. A list of turns without a conclusion is incomplete.