Back to Memorize

Flashcards

263 grounded cards across 16 decks — each defined from the real source, with a memory hook and three plausible-but-wrong distractors.

Agent Frameworks

13 cards
asyncio with business cards

Which framework does the analogy "asyncio with business cards" describe, and what are the two halves of it?

Show answer

The OpenAI Agents SDK. The asyncio half is the fan-out — `asyncio.Semaphore(4)` plus `asyncio.gather(..., return_exceptions=True)`, pure stdlib. The business-card half is delegation: `agent.as_tool()` hands one agent to another as a callable, with no graph, queue, or handoff protocol in between.

Memory hook A conference where everyone runs in parallel and delegation is just swapping cards — no org chart was ever drawn.

Common confusions (wrong answers)

LangGraph — its nodes are plain async functions and `Send` is just a fancy `gather`.

LlamaIndex Workflows — steps are async methods and events are the business cards passed between them.

CrewAI — agents are declared as roles and hand tasks to each other by name.

a workflow engine with a save-game file

Which framework is "a workflow engine with a save-game file", and what is the save-game file made of?

Show answer

LangGraph. The save-game file is the checkpointer — `compile(checkpointer=MemorySaver())` writes state after every superstep, and swapping in `AsyncSqliteSaver` puts it on disk so a paused run survives a process restart. It is the only one of the three with durability.

Memory hook Close the laptop mid-boss-fight and the run is still there tomorrow. That is the whole pitch.

Common confusions (wrong answers)

LlamaIndex Workflows — `ctx.store` is persisted per run, so a workflow can be reloaded by id.

The OpenAI Agents SDK — the trace store lets you re-attach to a previous `run_id`.

AutoGen — its conversation log doubles as the checkpoint you replay from.

a typed pub/sub mailroom

Which framework is "a typed pub/sub mailroom", and what plays the role of the sorting table?

Show answer

LlamaIndex Workflows. Typed `Event` subclasses are the envelopes, and the step return annotations ARE the sorting table — a step returning `ResearchQueryEvent` is routed to whichever step accepts that type, so the graph is inferred from Python types rather than declared with `add_edge`.

Memory hook You don't wire the mailroom. You label the envelopes, and the labels do the wiring.

Common confusions (wrong answers)

LangGraph — its `TypedDict` state schema types every message that moves between nodes.

Pydantic AI — every message is a validated model, so routing follows the type.

The OpenAI Agents SDK — handoffs are typed by the agent signature they target.

the stranded superstep

LangGraph footgun #1: what happens when one parallel branch raises an uncaught exception, and what does that force you to write?

Show answer

The exception strands the entire superstep — the graph never advances, so the two healthy branches are wasted too. It forces you to convert failures into state: the branch catches its own exception and returns `{"failures": [{"query": q, "error": str(exc)}]}` so the superstep still completes and the synthesizer runs on whatever came back.

Memory hook A rowing crew: the boat only moves when every oar finishes the stroke. One caught crab stops the boat, not just that seat.

Common confusions (wrong answers)

The failing branch is retried automatically from the last checkpoint, up to the graph's retry policy.

The branch is dropped and the graph proceeds with the remaining results, logging the exception.

The exception propagates to the caller but the other branches finish and their writes are still committed.

the serializer boundary

LangGraph footgun #2: why can't a Timeline object or an `emit` callback live in graph state, and where does it go instead?

Show answer

Because everything in state passes through the checkpointer's serializer, and live runtime objects don't survive it. They ride in `config["configurable"]` instead — runtime-only config that is threaded to every node but never checkpointed.

Memory hook State is the luggage that gets scanned. Live objects fly in the cabin — `config["configurable"]`.

Common confusions (wrong answers)

Because state is deep-copied per branch, so each researcher would get its own Timeline and the spans would diverge.

Because reducers require every state field to be a list, and a callback has no `operator.add`.

Because state is validated against the `TypedDict` at runtime and rejects non-JSON types.

the collect_events deadlock

A LlamaIndex Workflow hangs silently until its timeout. What is the cause, and what is the fix?

Show answer

A step raised, so it never emitted its event. `ctx.collect_events(ev, [ResearchResultEvent] * n)` returns `None` until all n arrive — that `None` IS the barrier — so the count never completes and there is no error to read. The fix: every step returns its event on every path, with the failure carried inside it (`ResearchResultEvent(query=..., error=str(exc))`).

Memory hook Counting heads before the bus leaves. One passenger who never boards keeps the engine idling until closing time.

Common confusions (wrong answers)

`num_workers` was lower than the number of events sent, so the surplus was dropped; raise the cap to match.

The final step returned a plain dict instead of a `StopEvent`, so the run never terminated; wrap the result.

Two steps declared the same return type, so the router couldn't choose; give each step a distinct event class.

Send API

How does LangGraph launch a runtime-decided number of parallel branches?

Show answer

A conditional edge returns a list of `Send` objects — `[Send("researcher", {"query": q}) for q in state["research_queries"]]`. Each `Send` starts one concurrent copy of that node with its own private payload, so the branch count comes from state at runtime, not from the graph you built.

Memory hook A mail merge: one template, one addressed envelope per recipient, all posted at once.

Common confusions (wrong answers)

You call `graph.add_node` once per query before compiling, so the fan width is fixed at build time.

A node returns a list and LangGraph maps the next node over it automatically.

You wrap the node in `asyncio.gather` inside a single node function.

reducer

In LangGraph, what turns three branches' separate results into one merged list without any join code?

Show answer

A reducer declared on the state field: `findings: Annotated[list[dict], operator.add]`. Each branch returns its own one-element list and LangGraph concatenates them. Fan-in is a type annotation, not code you write.

Memory hook The `+` sign lives on the field, not in your code.

Common confusions (wrong answers)

A join node that reads each branch's output from `config["configurable"]` after the superstep.

The checkpointer, which replays every branch's write in completion order into the final state.

`collect_events`, which buffers the branch results until the expected count arrives.

num_workers

What is `@step(num_workers=3)`, and what is its hand-rolled equivalent in the asyncio version?

Show answer

It is LlamaIndex's declarative concurrency cap: at most three instances of that step run at once, however many events are queued for it. The hand-rolled equivalent in the OpenAI Agents SDK build is `asyncio.Semaphore(4)` wrapped around each researcher call.

Memory hook Three tills open at the supermarket. The queue is as long as it is; three people are being served.

Common confusions (wrong answers)

It is the number of events the step will collect before it fires — the fan-in width, not the concurrency cap.

It is the size of the thread pool the step's sync code is offloaded to.

It is the retry count: three attempts per event before the step gives up.

the provider tax

What does it cost to point the OpenAI Agents SDK at a non-OpenAI provider, and why is the shape of that cost worth flagging?

Show answer

Three global mutations at import time: `set_default_openai_client(AsyncOpenAI(base_url=..., api_key=...))`, `set_default_openai_api("chat_completions")`, and `set_tracing_disabled(True)`. Cheap in lines, but process-wide rather than per-agent — the configuration is global state, which is exactly what you'd call out in review.

Memory hook Three lines, but they're shouted at the whole process — global state wearing a convenience API.

Common confusions (wrong answers)

A `RunConfig(model=...)` passed to every `Runner.run` call, since there is no global default to override.

A custom `ModelProvider` subclass registered per agent, plus a shim that translates tool-call schemas.

Nothing — the SDK reads `OPENAI_BASE_URL` from the environment and adapts automatically.

LangChain vs LangGraph

"Should we use LangChain or LangGraph?" — what's wrong with the question?

Show answer

It's a version question, not a choice. For building agents, LangChain's own maintainers route you to LangGraph. The LangChain layer that actually survives in this codebase is integrations — `langchain_deepseek` for the model client — not orchestration.

Memory hook Asking "Python 2 or Python 3?" — one of those is just where everyone already went.

Common confusions (wrong answers)

Nothing — they're genuine alternatives: LangChain for linear chains, LangGraph once you need branching.

It's backwards — LangGraph is the low-level runtime that LangChain's AgentExecutor compiles down to, so you pick LangChain.

They're different vendors' products, so the real question is which ecosystem you want to be locked into.

the decision rule

State the three-branch rule for choosing between these frameworks.

Show answer

Durability, pause/resume, or human-in-the-loop → LangGraph. Retrieval-heavy work, or typed orchestration you want to whiteboard → LlamaIndex Workflows. Stateless fan-out → the OpenAI Agents SDK, or plain asyncio.

Memory hook One word decides it: hear "durable" and stop reading, the answer is LangGraph.

Common confusions (wrong answers)

Prototype with the OpenAI SDK, ship on LangGraph, and reach for LlamaIndex only when you already run its index.

Pick by team familiarity — the three are close enough in capability that switching cost dominates.

Pick by measured speedup: LlamaIndex at 2.6× wins unless you specifically need OpenAI-native tracing.

wall vs serial

What single measurement proves a fan-out is real, and why does it outrank the framework choice?

Show answer

Wall-clock milliseconds against summed serial milliseconds — the ratio is the speedup (2.3× / 2.0× / 2.6× here), and a gantt of the spans shows the bars overlapping. It outranks the framework choice because every framework claims concurrency; only overlapping bars are the receipt that you got it.

Memory hook Overlapping bars are the receipt. Without them, "it's parallel" is a claim, not a result.

Common confusions (wrong answers)

The peak number of in-flight tasks, since a semaphore or `num_workers` cap guarantees the rest.

Total token spend, which falls as parallel branches share less context.

Time-to-first-event, which drops as soon as the fan-out dispatches.

Agentic Frontier

13 cards
agentic systems

What does an agentic system do that a standard language model cannot?

Show answer

Agentic systems autonomously plan, use memory, and invoke external tools to pursue goals.

Common confusions (wrong answers)

Agentic systems decompose tasks into multiple thought steps and explore multiple reasoning possibilities at each step.

Agentic systems estimate an answerability posterior and apply a structural validity gate before generating a response.

Agentic systems compress the context by removing irrelevant tokens based on a relevance score.

four-stage pipeline

How does the four-stage pipeline achieve full automation of fire source characteristic inversion?

Show answer

The four-stage pipeline achieves automation by reorganizing the conventional research pipeline into four dedicated specialized agents: physical modeling, data governance, model training, and evaluation analysis.

Memory hook Four-stage pipeline swallows a tunnel fire and regurgitates its source inversion through four specialized agent stages.

Common confusions (wrong answers)

Chain of thought achieves automation by decomposing complex tasks into step-by-step reasoning to enhance model performance.

Tool use achieves automation by enabling agents to call external APIs for missing information such as current data or code execution.

Long-term memory achieves automation by providing the capability to retain and recall infinite information over extended periods using an external vector store.

tool use

When the LLM in this subsystem calls a headless tool registered on the client, what does the tool use mechanism cause to happen?

Show answer

It triggers a run interrupt, allowing the client environment to execute the tool's action before the graph resumes.

Memory hook Tool Use hurls a headless hammer that hangs frozen until the client grabs and swings, then the hammer disappears.

Common confusions (wrong answers)

It retains and recalls information over extended periods by leveraging an external vector store and fast retrieval.

It decomposes complex tasks into smaller, manageable steps using chain-of-thought prompting.

It selects relevant sentences from the input context for compression to reduce computational cost.

metacognitive calibration

In a multi-agent system like MetaCogAgent, what does metacognitive calibration enable an agent to do before executing a given task?

Show answer

It enables an agent to evaluate its own competence for the task by combining its uncertainty estimates with historical performance data, then route low-confidence tasks to more capable agents.

Common confusions (wrong answers)

It enables an agent to retain relevant information from the ongoing conversation for immediate use.

It enables an agent to call external APIs to retrieve information that is missing from its pre-trained weights.

It enables an agent to break a complex task into smaller, manageable steps through chain-of-thought reasoning.

cognitive architecture

What does a cognitive architecture define in an LLM-based agent system?

Show answer

It defines the flow of code, prompts, and LLM calls that transforms user input into actions or responses.

Memory hook Cognitive architecture shoves user input down a slide of prompts into an LLM blender that spins out responses.

Common confusions (wrong answers)

It stores and retrieves information over long periods using an external vector store.

It enables the agent to call external APIs for missing information not in model weights.

It decomposes complex tasks into smaller steps using chain-of-thought prompting.

enough tokens to think

What does the practice of providing 'enough tokens to think' encourage an LLM to do during inference?

Show answer

It encourages the model to generate a longer chain-of-thought sequence to improve reasoning accuracy.

Memory hook Enough tokens pour fuel into a thinking engine, revving its chain-of-thought motor.

Common confusions (wrong answers)

It compresses the input context by removing low-relevance tokens to reduce computational cost.

It breaks down a complex task into smaller, sequential steps for easier execution.

It identifies tokens that draw disproportionately high attention to aggregate preceding information.

internal verification

Where in the LangGraph pipeline does internal verification execute?

Show answer

Internal verification is the first stage of the LangGraph pipeline that intercepts factual inaccuracies using intrinsic verification with early-exit logic, before adaptive search routing and extrinsic regeneration.

Memory hook The internal guard intercepts lies at the first checkpoint, kicking them out before extrinsic regeneration.

Common confusions (wrong answers)

It retains and recalls information over extended periods using an external vector store.

It calls external APIs to retrieve current information or execute code.

It decomposes complex tasks into smaller steps using chain-of-thought prompting.

atomic level checking

What is the primary function of atomic level checking in a multi-layer hallucination-detection framework?

Show answer

Atomic level checking decomposes an LLM response into atomic factual claims, retrieves evidence for each, verifies them with a small language model, and passes uncertain cases to a neuro-symbolic reasoning layer for refinement.

Memory hook A referee tosses confusing claims into a glowing neuro-symbolic wrestling ring for final crushing.

Common confusions (wrong answers)

It estimates an answerability posterior and decomposes uncertainty into epistemic and aleatoric components before applying a structural validity gate.

It retrieves and integrates long-term memories from an external vector store to provide the agent with recall over extended periods.

It decomposes a complex task into smaller steps using chain-of-thought prompting and explores multiple reasoning paths via tree-structured search.

Intrinsic verification

In a four-phase pipeline that optimizes compute using conditional early termination, what is the role of the Intrinsic verification phase?

Show answer

It is the first phase that applies early-exit logic to determine whether computation can be halted early, thereby optimizing resource use.

Memory hook A guard named Veri scans the first checkpoint and shouts "early exit!" to save fuel.

Common confusions (wrong answers)

It decomposes complex tasks into smaller, manageable steps to facilitate planning.

It instructs the model to think step by step, decomposing hard tasks into simpler steps.

It explores multiple reasoning possibilities at each step by generating a tree structure and using BFS or DFS search.

Epistemic Field Theory

What conclusion does Epistemic Field Theory draw about a response based on multiple model outputs?

Show answer

It predicts the probability that the response is a hallucination using the formula P(H) = (1 - σ) · η, where σ is a consensus field and η is a model-specific noise coefficient.

Memory hook In Epistemic Field Theory, a judge σ raises a green flag for consensus, while a masked villain η drops a red flag for hallucination.

Common confusions (wrong answers)

It estimates answerability posterior by decomposing uncertainty into epistemic and aleatoric components and applying a structural validity gate.

It compresses context length to reduce computational cost while retaining helpful information for the given question.

It augments sparsified attention mechanisms with dynamically integrated in-context information from an efficient retrieval system.

judging by committee

What is the composition of the evaluation panel in the judging by committee approach to LLM assessment?

Show answer

It employs an 'LLM jury' composed of multiple different models to balance model-specific biases.

Memory hook A committee of robot judges slams gavels together, yet only one verdict cracks differently.

Common confusions (wrong answers)

It relies on a single model generating multiple thought steps and exploring various reasoning paths.

It retrieves relevant information from an external vector store to augment the model's context.

It calls external APIs to obtain missing data such as current information or code execution results.

reference free protocol

What is the core principle that distinguishes the reference free protocol from traditional evaluation methods?

Show answer

A reference free protocol evaluates LLM outputs without requiring gold labels or reference annotations, relying instead on validation against human preferences.

Memory hook A robot judge wielding the reference-free protocol brings down a gavel that shatters all reference notes.

Common confusions (wrong answers)

A method that estimates answerability posterior and applies a structural validity gate before deciding whether to answer.

A method that compresses the prompt to reduce computational cost while retaining relevant information for a given question.

A method that uses an efficient retrieval system to augment sparsified attention for long-context scenarios.

selective forgetting

At which stage of an LLM agent's memory lifecycle does selective forgetting act?

Show answer

Selective forgetting enhances LLM agent memory management by pruning irrelevant data for efficiency, updating outdated context for quality, and actively forgetting sensitive information for security.

Memory hook Selective forgetting burns a stack of sensitive password lists.

Common confusions (wrong answers)

It involves leveraging in-context learning to temporarily hold information for immediate task execution.

It allows the agent to store and retrieve an unlimited amount of information over long periods via an external database.

It empowers the agent to fetch real-time or private data by invoking external tools and APIs.

Agentic Rag

16 cards
RAGState

What is RAGState in the RAG pipeline?

Show answer

RAGState is a dictionary-like object that stores the pipeline's current data (e.g., question, documents, rewrites) and is passed between nodes to carry and update state during execution.

Memory hook RAGState is a backpack that moves from node to node, each worker adding or removing "question" and "documents."

Common confusions (wrong answers)

A JSON schema used to validate the output of the generate_answer node.

The configuration object that sets the mode (agentic, retrieve, recommend) before the graph starts.

A function that rewrites the user's question to improve semantic retrieval.

agentic

What does the 'agentic' mode do in the agentic_rag graph?

Show answer

In agentic mode, the graph uses a prompt-driven JSON-router to decide whether to retrieve or respond, generating a search query when retrieval is chosen.

Memory hook Agentic mode's JSON-router forks: one road leads to a search query, the other straight to talk.

Common confusions (wrong answers)

Agentic mode is a fast single-node path that does not use an LLM to decide.

In agentic mode, the graph always responds directly without retrieval.

Agentic mode uses bind_tools and with_structured_output to route decisions.

retrieve

What does the 'retrieve' node do in the RAG state graph?

Show answer

It performs hybrid dense‑and‑sparse semantic search over the Qdrant Cloud agentic_rag_companies collection via qdrant_rag.search and returns a dict of documents.

Memory hook Retrieve searches Qdrant's hybrid dense‑and‑sparse shelves, then returns a stack of documents to the graph's next fork.

Common confusions (wrong answers)

It rewrites the user question to improve semantic retrieval.

It grades the relevance of retrieved documents and decides whether to rewrite or answer.

It generates a final answer using the provided company documents.

generate_query_or_respond

What does the generate_query_or_respond node do in the agentic RAG graph?

Show answer

A LangGraph node that uses a DeepSeek LLM to decide whether to return a retrieval action with a search query or a direct answer, forming the first step in the agentic RAG flow.

Memory hook generate_query_or_respond is the DeepSeek fork that either sends a search query down the retrieval path or answers directly.

Common confusions (wrong answers)

A node that retrieves documents from Qdrant Cloud using semantic search.

A node that rewrites the user's question to improve semantic retrieval using a DeepSeek flash model.

A node that grades whether retrieved documents are relevant to the user's question and decides whether to rewrite or generate an answer.

retrieve_only

What does the 'retrieve_only' node do in the RAG state graph?

Show answer

It executes a single embed+search round trip over the Qdrant agentic_rag_companies collection using the raw user question, bypassing any query rewriting or LLM involvement, and is routed from START when the state's mode is 'retrieve'.

Memory hook Like a bullet train from START, retrieve_only fires the raw question once into Qdrant and returns results without any rewrites.

Common confusions (wrong answers)

It rewrites the user query using an LLM before performing a semantic search over the company database.

It is the entry point for the 'recommend' mode, performing a knowledge-graph retrieval before fusing with vector hits.

It grades the relevance of retrieved documents and decides whether to rewrite the question or generate an answer.

retrieve_kg

What is the role of the `retrieve_kg` node in the RAG state graph?

Show answer

It is the entry point of the KG-RAG recommend path when `state["mode"]` is `"recommend"`, after which the graph proceeds to the `retrieve` node to fuse vector hits.

Memory hook A key labeled "kg" clicks into the "recommend" lock, opening the gate to fuse vector hits.

Common confusions (wrong answers)

It is a fast no-LLM node that directly returns search results for the streaming `/rag` chat.

It rewrites the user's question to improve semantic retrieval over the company database.

It grades whether retrieved documents are relevant and decides whether to rewrite or generate an answer.

grade_documents

What does the grade_documents function do in the RAG graph?

Show answer

It grades whether retrieved documents are relevant to the user's question and routes to generate_answer or rewrite_question based on relevance and rewrite count.

Memory hook A teacher stamps "relevant=true" or "false" on documents, sending students to answer or rewrite.

Common confusions (wrong answers)

Retrieves documents from the Qdrant collection for the user's question.

Rewrites the user's question to improve semantic retrieval over the company database.

Generates the final answer using only the provided company documents.

rewrite_question

What is the role of the rewrite_question node in a RAG workflow?

Show answer

The rewrite_question node uses an LLM to reformulate the user's question to improve semantic retrieval over a company database, incrementing a rewrites counter, and is triggered when retrieved documents are irrelevant and the rewrite limit is not reached.

Memory hook Like a librarian rewrites vague questions into precise search terms when the first books miss the mark.

Common confusions (wrong answers)

It directly answers the user's question using the content of retrieved documents.

It decides whether the system should retrieve documents or respond directly to the user.

It retrieves relevant documents from a vector database based on the user's question.

generate_answer

What is the generate_answer node in the RAG graph?

Show answer

It is a terminal node that, unless in recommend mode, uses an LLM with the _ANSWER_SYSTEM prompt to produce a final answer from retrieved documents and the user's question, reached after retrieval or the grade–rewrite loop.

Memory hook generate_answer is the terminal librarian who writes a response only using the handed documents and the user's query, after the grade–rewrite loop finishes.

Common confusions (wrong answers)

It is a node that rewrites the user's question to improve semantic retrieval over a company database.

It is a node that decides whether to retrieve documents or respond directly based on the question.

It is a node that grades the relevance of retrieved documents and decides whether to rewrite the question or generate an answer.

qdrant_rag.search

What does qdrant_rag.search do in the RAG retrieval pipeline?

Show answer

It performs hybrid dense-plus-sparse search over the Qdrant Cloud 'agentic_rag_companies' collection using in-process fastembed, returning a list of documents (or an empty list on failure) for downstream grading and memory recall.

Memory hook Picture a two-headed search engine—one dense, one sparse—diving into the Qdrant Cloud collection and handing back a stack of documents for grading.

Common confusions (wrong answers)

It queries a local PostgreSQL database using a pgvector index for similarity search.

It calls an external API endpoint that runs a separate embedding service and returns raw similarity scores.

It performs only dense vector search without any sparse component, returning the top-k matching document IDs.

TOP_K

What does the constant TOP_K define in the RAG system?

Show answer

TOP_K is a constant set to 6 that specifies the number of top documents to retrieve in unfiltered hybrid search for agentic mode and also limits the documents fed into the answer-generation node.

Memory hook TOP_K grabs the top six golden documents from the hybrid search pile.

Common confusions (wrong answers)

MAX_REWRITES limits the number of times a question can be rewritten before generating an answer.

TOP_K_RETRIEVE sets the number of documents retrieved from the Qdrant vector store in a single search.

EMBEDDING_DIM determines the dimensionality of the text embeddings used for semantic similarity.

MAX_REWRITES

What does the constant MAX_REWRITES do in the RAG graph?

Show answer

MAX_REWRITES is the maximum number of rewriting iterations allowed; when the rewrite count reaches or exceeds this threshold, the system stops rewriting and proceeds to generate an answer.

Memory hook MAX_REWRITES is the rewrites fuel gauge: hit E, and the engine switches to answer.

Common confusions (wrong answers)

MAX_REWRITES is the maximum number of documents that can be retrieved from the database.

MAX_REWRITES is the maximum number of times the user can submit a question before being blocked.

MAX_REWRITES is the maximum length of the rewritten question in characters.

ainvoke_json

What does the asynchronous function ainvoke_json do?

Show answer

ainvoke_json sends a list of messages to a language model and returns the parsed JSON response.

Memory hook Throw a chat log at the language model; ainvoke_json tosses back a neat JSON parcel.

Common confusions (wrong answers)

ainvoke_json is a synchronous function that stores messages in a JSON database.

ainvoke_json is an asynchronous function that converts JSON strings to Python dictionaries.

ainvoke_json is a function that retrieves documents from Qdrant and returns them as JSON.

tool_call_span

What does the tool_call_span context manager do in the retrieval process?

Show answer

It wraps a retrieval dispatch so that it appears as a child tool run in LangSmith traces, carrying the search query as an argument and the document count as the result.

Memory hook tool_call_span wraps a retrieval so LangSmith sees it as a tool run, with search query as input, document count as output.

Common confusions (wrong answers)

It directly calls the Qdrant search API and returns the retrieved documents.

It is a decorator that logs the execution time of the retrieval function.

It rewrites the user's question before performing semantic search.

agent_run_span

What is the purpose of the agent_run_span context manager in the generate_query_or_respond node?

Show answer

It wraps the LLM call and routing decision to create a labelled chain run in LangSmith with metadata and tags, and is a strict no-op when LANGSMITH_TRACING is unset.

Memory hook Like a ghost labeler, agent_run_span stamps "agent:rag" on the LLM call, but only when LangSmith’s lights are on.

Common confusions (wrong answers)

It is a tool call span that wraps the retrieve dispatch for visibility in LangSmith.

It is used exclusively in the retrieve_only node to trace memory recall from mem0.

It forces the LLM to output structured JSON and disables tracing when debug mode is off.

mem0

What is mem0 in the context of the RAG graph?

Show answer

mem0 is a per-user memory system that stores and recalls prior /rag questions, used by the retrieve_only node to return a sanitized memory_block and persist the current question when a user_id is supplied.

Memory hook Mem0 is your private sticky note that stores every past /rag question and fetches a clean version for you.

Common confusions (wrong answers)

mem0 is a vector database for storing company document embeddings.

mem0 is a relevance grading system that determines if retrieved documents are relevant to the question.

mem0 is a system that rewrites user questions to improve semantic retrieval over a company database.

Campaign

16 cards
Durable-thread campaign engine

What is the durable-thread campaign engine?

Show answer

It uses one LangGraph thread per (campaign, contact) with a stable thread ID, compiled with the D1 checkpointer so state survives between touches—it sends a touch, schedules the next, interrupts, and a Cloudflare cron resumes it later.

Memory hook Like a bookmark in a book, each campaign-contact thread remembers its exact page after every touch, even after pausing for days.

Common confusions (wrong answers)

It uses a single thread for all contacts and campaigns, relying on in-memory state that resets after every touch.

It sends all touches immediately without scheduling, using a stateless graph that does not survive between interrupts.

It persists state in a remote queue and resumes via webhooks instead of LangGraph checkpoints.

LangGraph thread

What is a LangGraph thread in the context of the durable-thread campaign engine?

Show answer

A LangGraph thread is a persistent execution context identified by a stable thread_id (e.g., campaign-<campaignId>-<contactId>) that uses a checkpointer to survive between touches and can be resumed via Command(resume=True) from a cron or UI interrupt.

Memory hook A LangGraph thread is like a paused game save file named `campaign-contact` that the cron clock resumes later.

Common confusions (wrong answers)

A LangGraph thread is a lightweight process that runs in parallel to handle multiple campaign touches simultaneously.

A LangGraph thread is a unique identifier for a single graph node invocation within a run.

A LangGraph thread is a data structure that stores the entire campaign configuration for each campaign.

D1 checkpointer

What is the D1 checkpointer?

Show answer

The D1 checkpointer is the persistence layer that stores LangGraph thread state in Cloudflare D1 tables so threads compiled with `resumable=True` survive between touches and can be resumed later via `Command(resume=True)`.

Memory hook The D1 checkpointer saves each thread’s brain like a game checkpoint, so you resume later exactly where you paused.

Common confusions (wrong answers)

The Cloudflare cron job that periodically resumes threads at scheduled intervals.

The graph node that checks for inbound replies before deciding whether to compose the next touch.

The gate that approves or rejects a draft before it is sent to the contact.

CF cron

What is the CF cron in the campaign engine context?

Show answer

CF cron is the Cloudflare Workers cron trigger whose scheduled() handler sends a request to /cron/tick, invoking run_campaign_resume_due to resume campaign threads with past wake_at times.

Memory hook CF cron is an alarm clock that rings /cron/tick to wake overdue campaign threads.

Common confusions (wrong answers)

CF cron is the function that checks if a contact has replied before scheduling the next touch.

CF cron is the mechanism that generates the email draft and stores it pending approval.

CF cron is the database checkpointer that saves thread state between interruptions.

run_campaign_resume_due

What does run_campaign_resume_due do?

Show answer

It queries campaign_threads for status='waiting' rows whose wake_at has passed, then resumes each thread with Command(resume=True) on the compiled campaign graph, handling terminal states and reconciling the campaign when all threads finish.

Memory hook Like a rooster at dawn, run_campaign_resume_due checks the waiting list and wakes each idle campaign thread when its alarm passes.

Common confusions (wrong answers)

It sends a touch message directly to a contact and schedules the next touch.

It checks for incoming replies from a contact and updates the campaign state accordingly.

It creates a new campaign thread for a given contact and generates an initial draft for approval.

interrupt(kind="approval")

What does interrupt(kind="approval") do in the campaign graph?

Show answer

It pauses the campaign thread in the await_approval node until an operator decides on the held draft, then resumes via Command(resume=…) without regenerating the draft.

Memory hook The draft freezes mid-air for the boss's stamp, then resumes exactly as left.

Common confusions (wrong answers)

It pauses the thread in the schedule_next node until the CF cron resumes it for the next touch.

It runs the agent_eval graph to produce a multi-level verdict that can auto-approve the draft.

It generates the email draft in the compose_touch node and then immediately sends it without pausing.

interrupt(kind="cadence")

What does interrupt(kind='cadence') do in the campaign graph?

Show answer

interrupt(kind='cadence') pauses the durable thread (a 'cadence sleep') by raising an __interrupt__ with kind='cadence'; the Cloudflare cron resumes the exact thread once its wake_at time passes, only for threads with status='waiting'.

Memory hook The thread hits a "cadence pause" button and dozes until the cron alarm rings at wake_at.

Common confusions (wrong answers)

interrupt(kind='approval') pauses the thread for human approval, and the cron resumes it automatically when an operator approves the draft.

interrupt(kind='cadence') permanently ends the campaign sequence by setting the thread status to 'completed' and clearing the wake_at time.

interrupt(kind='cadence') immediately sends the next touch without pausing, bypassing the cron scheduler entirely.

compose_touch

What does the compose_touch node do in the campaign graph?

Show answer

compose_touch is a node in the campaign graph that drafts a touch email using the email_outreach graph against a post_text built from the contact's opportunity and resume_context, and then routes to gate_draft for human review or directly to send_touch if auto_approve is enabled.

Memory hook compose_touch builds a draft from opportunity and resume, then sends it to a human gate or straight to send.

Common confusions (wrong answers)

check_reply is a node that checks if the contact has replied to a previous touch and if so, ends the campaign sequence.

await_approval is a node that pauses execution with an interrupt(kind='approval') until a human operator approves or rejects the draft.

schedule_next is a node that sets the next touch's scheduled time based on cadence and then interrupts for the cron to resume later.

await_approval

What is the function of the 'await_approval' node in the campaign graph?

Show answer

It pauses the campaign graph for a human operator's decision on a drafted touch (approve, edit, reject, or skip) and then routes to send_touch, schedule_next, or stops the campaign with draft_rejected accordingly.

Memory hook A red stop sign holds the email draft until a human clicks approve, edit, reject, or skip.

Common confusions (wrong answers)

It generates the draft of the email to be sent.

It sends the approved email to the recipient.

It checks for a reply from the recipient to decide the next step.

send_touch

What does the send_touch node do in the campaign graph?

Show answer

It dispatches the composed email after enforcing a per-vertical daily send cap and re-checking suppression and do_not_contact lists, then routes to schedule_next unless the thread's status is terminal.

Memory hook Send_touch is the gatekeeper that checks the daily cap and blocklist before releasing the email, then hands to schedule_next unless terminal.

Common confusions (wrong answers)

It composes the email draft by invoking the email_outreach graph based on post_text and resume context.

It checks for replies and updates the thread status to 'replied' if a response is detected.

It holds the draft for human approval and waits for an interrupt to approve or reject.

schedule_next

What does the schedule_next node do in the campaign state graph?

Show answer

It advances the campaign sequence by either completing the thread when max touches are reached or writing a 'waiting' state with a wake_at timestamp and interrupting for cron-based resume, then returning updated step and 'running' status to route back to check_reply.

Memory hook When the touch limit hits, schedule_next stamps the thread "completed" like closing a book; otherwise it writes a "waiting" note with a future alarm and hits pause.

Common confusions (wrong answers)

It generates the email draft using the campaign touch policy and stores it in state with a 'draft_pending' status, then routes to either gate_draft or send_touch.

It sends the email via the email outreach system, updates campaign counts, and then routes to schedule_next or END.

It checks whether the contact has replied to any previous touch and, if so, sets status to 'replied' and ends the thread; otherwise it routes to compose_touch.

check_reply

What does the 'check_reply' node do in the campaign graph?

Show answer

It checks for inbound emails from the contact after the last touch; if found, sets status to 'replied' and ends the sequence, otherwise routes to compose_touch.

Memory hook Check_reply scans for a fresh reply; if it finds one, it shuts down the campaign sequence.

Common confusions (wrong answers)

It generates an email draft and holds it for human approval.

It sends the composed email and then schedules the next touch.

It pauses the campaign thread until a future cron resume.

auto_approve

What does the auto_approve flag do in a campaign graph?

Show answer

When true, it routes compose_touch directly to send_touch—skipping gate_draft and await_approval—and replaces the default eligibility check with a strict fail-closed gate that requires outreach_eligible=1, enforces per-vertical daily caps, and re-checks suppression before sending.

Memory hook Auto_approve launches the draft straight to send, bypassing the human approval booth like an express train.

Common confusions (wrong answers)

It causes all touches to be sent without any eligibility checks, as no human reviews them.

It makes the campaign skip only await_approval but still pass through gate_draft for human review.

It is an environment variable that automatically approves all drafts after agent evaluation.

_is_campaign_eligible

What does the function _is_campaign_eligible do in the campaign graph?

Show answer

It is the eligibility gate for the human-approval campaign engine that blocks only definitive negatives (do_not_contact=1, missing email, outreach_eligible=0) and allows inconclusive NULL through because every touch is manually approved.

Memory hook For human‑approval campaigns, a gate that lets uncertain cases slip through because a manager will review every guest before they enter.

Common confusions (wrong answers)

It is the strict eligibility gate used in autonomous mode that requires outreach_eligible=1 and fails closed on NULL.

It checks whether the contact's role confirmation is conclusive and blocks if inconclusive.

It enforces a per-vertical daily send cap to prevent exceeding 20 sends per day.

_is_eligible

What does the _is_eligible function do in the context of the campaign graph?

Show answer

_is_eligible is a strict V135 gate from graphs.pipeline_graph that only allows contacts with outreach_eligible=1, failing closed on NULL or error, because no human reviews the auto-approved touch before it sends.

Memory hook _is_eligible is a strict gate that only opens for outreach_eligible=1, locking shut on NULL because no human checks the send.

Common confusions (wrong answers)

It allows contacts with outreach_eligible=NULL through because the campaign is draft-first and every send is reviewed by a human.

It constructs the synthetic post_text by folding opportunity details and resume context into a single string.

It records the agent_eval verdict for the email_outreach graph and persists it to the database for outcome tracking.

_upsert_thread

What does the _upsert_thread function do in the campaign engine?

Show answer

It writes the thread's scheduling state into the D1 campaign_threads index so the cron can find it and the UI can render a held draft, and when called with critical=True it re-raises on failure to prevent the thread from stalling silently.

Memory hook _upsert_thread_ pins a thread's next wake-up on a D1 bulletin board so the cron clock sees it.

Common confusions (wrong answers)

It advances the sequence and schedules the next touch via interrupt() for cron-resumed cadence sleep.

It computes the wake time for deferred auto-approve sends, adding jitter based on contact ID.

It sends the actual email via dispatch_send and records the provider_message_id.

Classification

12 cards
wrap_untrusted

What does the function wrap_untrusted do in the inbound email classification graph?

Show answer

wrap_untrusted fences untrusted inbound email body text with a label before embedding it in the LLM prompt to prevent injection attacks.

Memory hook Wrap_untrusted fences untrusted text with a label so the LLM can't see hidden [SYSTEM] commands.

Common confusions (wrong answers)

wrap_untrusted checks the email body for injection markers and logs a warning if found.

wrap_untrusted directly invokes the LLM to classify the email intent from the raw body text.

wrap_untrusted extracts scheduling information such as proposed meeting times from the email body.

INTENT_ROUTES

What does the INTENT_ROUTES dictionary do in the inbound email classify graph?

Show answer

INTENT_ROUTES is a deterministic dictionary that maps each opportunity intent ("interested", "objection", "out") to a corresponding downstream route ("reply_graph", "playbook", "suppress"), serving as the only source of truth for routing decisions.

Memory hook Interested intent goes to reply_graph, objection to playbook, out to suppress — INTENT_ROUTES is that fixed map.

Common confusions (wrong answers)

It stores the mapping from email labels to intents for fallback classification when the LLM returns an invalid intent.

It computes the opportunity score for an inbound email based on the predicted intent label.

It provides few-shot examples to the LLM for classifying inbound email replies into one of nine labels.

LABEL_TO_INTENT

What is the purpose of LABEL_TO_INTENT in the inbound email classification system?

Show answer

LABEL_TO_INTENT is a dictionary that maps email reply labels to intents, used as a deterministic fallback when the LLM returns an invalid intent.

Memory hook When the LLM fumbles, LABEL_TO_INTENT catches each label and shows its true intent.

Common confusions (wrong answers)

It maps intents to routing destinations for the email processing pipeline.

It defines the expected vertical extraction for each inbound reply label.

It stores the opportunity score ranges corresponding to each reply label.

classify

What does the classify node do in the inbound email classification graph?

Show answer

It classifies an inbound email into one of nine reply types using an LLM and returns label, confidence, reasoning, vertical, intent, opportunity_score, and route.

Memory hook Classify passes the email to an LLM that sorts it into one of nine types; if no result, it dumps the email into the "not_interested" bin.

Common confusions (wrong answers)

It scores the email's opportunity value and updates the GTM-intent score.

It extracts meeting scheduling details from the email body.

It checks whether the sender should be suppressed based on bounce or unsubscribe history.

extract_scheduling_handoff

What does the extract_scheduling_handoff node do in the inbound-email classification graph?

Show answer

Extract_scheduling_handoff is a LangGraph node that, only when the intent is 'interested', uses DeepSeek to extract meeting information from the fenced email body, returning a scheduling handoff payload; for other intents it returns null fields.

Memory hook Only when the email shows interest does the scheduling handoff node unlock the DeepSeek vault for times.

Common confusions (wrong answers)

Extract_scheduling_handoff is a node that classifies the inbound email into one of nine labels using a DeepSeek prompt.

Extract_scheduling_handoff runs before the classification node to preprocess the email body.

Extract_scheduling_handoff is triggered for all intents to extract meeting times and timezone from the email.

suppression_feedback

What does the suppression_feedback function do in the inbound email classify graph?

Show answer

It automatically adds the sender’s email address to the suppression list when the label is 'bounced' or 'unsubscribe', logging only the email domain and writing an audit row via the suppression module.

Memory hook When an email bounces or unsubscribes, suppression_feedback quietly silences that sender's domain in the log.

Common confusions (wrong answers)

It removes a sender from the suppression list when the label is 'interested' or 'info_request'.

It logs the full email address of the sender and updates the audit table only on success.

It classifies the email label and returns the route decision to the graph.

InboundEmailClassifyState

What is InboundEmailClassifyState in the inbound email classification graph?

Show answer

It is the state schema imported from `schemas.state` that holds inbound email fields such as `intent`, `subject`, and `body`, used as input and output state for the LangGraph that classifies replies and extracts scheduling handoff data.

Memory hook InboundEmailClassifyState is a backpack carrying intent, subject, and body from the classify node to the scheduling handoff node.

Common confusions (wrong answers)

It is the LangGraph node that calls the LLM to classify the email label and derive intent.

It is the JSON payload returned by the extract_scheduling_handoff function when meeting_intent is false.

It is the deterministic routing table that maps intent to downstream graph routes.

ainvoke_json_with_telemetry

What does the async function ainvoke_json_with_telemetry do in the inbound email classification graph?

Show answer

ainvoke_json_with_telemetry is an async function that invokes a DeepSeek LLM with system and user prompts, returning a JSON result and a telemetry dict, used to extract structured handoff data such as meeting_intent, proposed_times, timezone, and evidence.

Memory hook The 'ainvoke_json_with_telemetry' function is like a postal worker who reads an email, then hands back a JSON envelope with meeting times and a tracking slip.

Common confusions (wrong answers)

make_llm creates the LLM client object but does not invoke it for JSON extraction.

wrap_untrusted fences untrusted inbound text before embedding it in a prompt.

detect_injection checks for prompt injection in the input, not for LLM invocation.

meeting_intent

What does the 'meeting_intent' field indicate in the inbound email classification system?

Show answer

A boolean flag that is true when the sender is requesting, proposing, or confirming a meeting, and when false, the subsystem clears proposed_times, timezone, and evidence to null.

Memory hook Meeting_intent is the green light that only glows when the sender is asking for or confirming a meeting.

Common confusions (wrong answers)

It stores the exact time slots proposed in the email.

It determines whether the email should be routed to the reply graph or suppressed.

It represents the confidence level of the label classification.

_AUTO_SUPPRESS_LABELS

What does _AUTO_SUPPRESS_LABELS do in the inbound email classification graph?

Show answer

_AUTO_SUPPRESS_LABELS is a frozenset of the strings 'bounced' and 'unsubscribe', and when the classified label matches one of these, the sender's from_email is added to the suppression list.

Memory hook A bouncer only lets "bounced" and "unsubscribe" into the suppression list, blocking them forever.

Common confusions (wrong answers)

_AUTO_SUPPRESS_LABELS is a frozenset containing all labels that can trigger suppression, including 'spam' and 'complaint'.

_AUTO_SUPPRESS_LABELS determines the routing intent for the email, such as 'suppress' or 'reply_graph'.

_AUTO_SUPPRESS_LABELS maps each suppressed label to its source string, like 'hard_bounce' for 'bounced'.

SYSTEM_PROMPT

In the inbound email classify graph, what is the SYSTEM_PROMPT constant used for?

Show answer

It is a constant string that provides system-role instructions to the DeepSeek Flash LLM, guiding it to classify an inbound reply and return JSON with fields like label, vertical, intent, opportunity_score, confidence, and reasoning.

Memory hook The SYSTEM_PROMPT is the recipe card that tells the LLM chef exactly what JSON meal to cook from each inbound reply.

Common confusions (wrong answers)

It is a template for composing outbound outreach emails to generate leads.

It is a configuration setting that defines the threshold for routing intents like interested or objection.

It is a loop that repeatedly calls the LLM until a valid JSON response is obtained.

FEW_SHOT

What is the role of the FEW_SHOT variable in the inbound_email_classify subsystem?

Show answer

FEW_SHOT is a sequence of example messages that are placed between the system prompt and the user message in the LLM call to provide few-shot learning examples.

Memory hook FEW_SHOT sits like training wheels between the system’s rules and the user’s question, showing the model how to answer.

Common confusions (wrong answers)

FEW_SHOT is a function that classifies the inbound email label and intent based on the sender's reply.

FEW_SHOT is a suppression feedback node that automatically adds bounced or unsubscribed senders to the suppression list.

FEW_SHOT is a dictionary mapping labels to intents for fallback when the LLM returns an invalid intent.

Discovery

15 cards
HostLimiter

What does the HostLimiter class do in the discovery and persist flows?

Show answer

It uses a global semaphore plus per-host semaphores so that async with slot(host) acquires a global cap and optionally the host's cap, preventing a single slow host from monopolizing the global budget or starving other hosts.

Memory hook HostLimiter's global cap is a big coffee pot, with per-host mugs ensuring no single host drinks the whole pot.

Common confusions (wrong answers)

It is a simple time-based rate limiter that allows only a fixed number of requests per second across all hosts.

It manages per-host request queues and automatically retries failed requests to avoid throttling.

It provides a balanced round-robin scheduler that distributes the global budget equally among all hosts without regard for host-specific limits.

expand_seed

What does the graph node expand_seed do?

Show answer

expand_seed asynchronously extracts B2B company-search facets (vertical, geography, size_band, keywords) from a seed query using a DeepSeek LLM, and only executes when the seed-query source is active.

Memory hook Like a farmer, DeepSeek magnifies a seed query into four labeled bins: vertical, geography, size, keywords.

Common confusions (wrong answers)

expand_seed runs on every discovery tick regardless of source, extracting facets from the user's profile.

expand_seed directly scores and inserts the extracted candidates into the database.

expand_seed merges multiple seed queries from different sources into a unified set of facets.

brainstorm

What is the 'brainstorm' channel in the discovery subsystem?

Show answer

Brainstorm is the only synthetic channel, where an LLM (DeepSeek) generates candidate companies for a micro-vertical direction, and its output is hard-stripped at the persist write boundary so only real-data sources are used for scoring and outreach.

Memory hook Brainstorm ideas are like sticky notes written in sand—washed away before the final decision is built from real bricks.

Common confusions (wrong answers)

It is a real-data channel that fetches candidates from Common Crawl and launch feeds.

It is the final step that persists all candidate companies to the D1 database.

It is a legacy channel that has been replaced by ATS and launch feed for all candidate generation.

dedupe

What does the dedupe function do in this subsystem?

Show answer

It filters a list of candidate domains by querying the companies table for existing canonical_domain values via a SELECT DISTINCT IN clause, returning only the subset of candidates whose domain is not already stored and providing a count of skipped_existing duplicates.

Memory hook Dedupe bounces each domain against the company database, letting only fresh ones through and tallying the repeats turned away.

Common confusions (wrong answers)

It inserts new candidate domains into the companies table and updates existing records.

It assigns a confidence score to each candidate domain based on vertical relevance using a micro-vertical weight resolution.

It generates a list of candidate domains by prompting an LLM with vertical, geography, and keywords.

pre_score

What does the `pre_score` function do in the discovery subsystem?

Show answer

It computes a numeric score for each candidate by summing calibrated weights from sub‑niche, vertical, or default `score_weights` and capping the sum at 1.0.

Memory hook pre_score is a keyword jackpot where each matched keyword drops a coin into a bucket that never overflows past one full dollar.

Common confusions (wrong answers)

It filters out candidates whose domains already exist in the companies database.

It generates a list of candidate domains by brainstorming with an LLM based on a seed query.

It aggregates the total candidate counts per vertical from ATS, brainstorm, CC, and launch feed results.

_resolve_sources

What does the function _resolve_sources do in the discovery graph?

Show answer

_resolve_sources takes a DiscoveryState and returns a set of strings representing the effective discovery channels for a run, following defined precedence and always stripping the synthetic brainstorm channel.

Memory hook _resolve_sources is the gatekeeper that always boots the synthetic brainstorm from the party of real discovery channels.

Common confusions (wrong answers)

A function that adds the synthetic brainstorm channel to the sources list.

A function that resolves the vertical and geography from the discovery state.

A function that returns the number of candidate domains found in a tick.

_SEED_SOURCE

What does the constant `_SEED_SOURCE` represent in the discovery graph?

Show answer

It is the identifier string (likely 'seed_query') that activates the seed-query discovery channel and is used in `expand_seed` to skip facet extraction when not active.

Memory hook _SEED_SOURCE is the key that unlocks the seed-query path; without it, expand_seed skips facet extraction.

Common confusions (wrong answers)

It is the default seed query string used when the caller supplies none.

It is the function that expands seed queries into facets like vertical and keywords.

It is the maximum number of candidate domains allowed from the brainstorm channel.

_SYNTHETIC_SOURCES

What is _SYNTHETIC_SOURCES in the discovery graph?

Show answer

_SYNTHETIC_SOURCES is a frozenset containing only 'brainstorm' that identifies LLM-invented discovery channels, which are stripped from the discovery pipeline to ensure decisions use only real data.

Memory hook When brainstorm clouds appear, they're fake inventions that get swept away to keep decisions real.

Common confusions (wrong answers)

A set of default real data sources like 'launchfeed' and 'commoncrawl' used in discovery.

A constant that controls the maximum number of concurrent connections for LLM-based queries.

A flag that enables the seed_query channel for company discovery.

_ATS_PATH_SOURCES

What is the purpose of _ATS_PATH_SOURCES in the discovery graph?

Show answer

_ATS_PATH_SOURCES is a set of source identifiers used in the plan_targets node to check whether the current run involves ATS sources; when the intersection of resolved sources with this set is empty, the function short-circuits and returns an empty dictionary, skipping the rotation cursor logic for seed-query-only runs.

Memory hook Think of _ATS_PATH_SOURCES as a bouncer checking IDs: if no ATS sources are in the set, the plan_targets node takes the shortcut.

Common confusions (wrong answers)

It defines the list of verticals to be used for ATS source discovery.

It stores the candidate domains that have been excluded from previous ticks.

It is a flag indicating whether the seed-query path should be executed instead of the ATS path.

DEFAULT_CONCURRENCY

What is the role of DEFAULT_CONCURRENCY in the discovery graph?

Show answer

DEFAULT_CONCURRENCY is the default global concurrency cap (set to 6) used by HostLimiter to gate the total number of concurrent async operations, overridable per run via the ``concurrency`` input.

Memory hook DEFAULT_CONCURRENCY is a bouncer waving in only six guests at once—you can raise the limit per party.

Common confusions (wrong answers)

It is the per-host concurrency cap for the 'llm' host, set to 4.

It is the default timeout in seconds for the HTTP client used in discovery.

It is the maximum number of companies allowed in the brainstorm channel.

DEFAULT_PER_HOST

What does the term DEFAULT_PER_HOST refer to in the discovery graph?

Show answer

DEFAULT_PER_HOST is a dictionary that sets default per-host concurrency caps for limiting parallel requests, used by HostLimiter to create per-host semaphores, and can be overridden per-run via the per_host input.

Memory hook DEFAULT_PER_HOST caps each host's parallel requests, like a six-person elevator for Common Crawl but only four for LLM.

Common confusions (wrong answers)

DEFAULT_PER_HOST is the global concurrency cap that limits all hosts to the same maximum number of parallel requests.

DEFAULT_PER_HOST is a set of forbidden synthetic data sources that cannot be used for company discovery.

DEFAULT_PER_HOST is a cap on the number of Common-Crawl lookups per run, set to 40.

DEFAULT_SOURCES

What does DEFAULT_SOURCES represent in the discovery graph?

Show answer

It is a tuple containing only 'launchfeed' that serves as the default set of real-signal discovery channels for directions-driven or CLI runs, excluding synthetic sources.

Memory hook Picture the default launch feed as a single trough where only real companies drink, never brainstorming.

Common confusions (wrong answers)

It is a dictionary mapping host names to concurrency limits for different discovery services.

It is a set of synthetic channels like 'brainstorm' that are forbidden in production discovery.

It is a constant specifying the maximum number of candidate companies per run across all sources.

_fetch_yc_launches

What does the function _fetch_yc_launches do?

Show answer

Asynchronous function that fetches recent YC launch stories from the HN Algolia public search API, using a slug for vertical keyword-match tagging, returning company-candidate dicts with launch_source and launch_date provenance fields, with no LLM involvement and fail-soft error handling.

Memory hook _fetch_yc_launches is the robot that searches HN Algolia for YC launch stories and stamps each with a vertical keyword tag.

Common confusions (wrong answers)

Function that fetches ProductHunt launches from RSS feed and returns candidates with launch_source and launch_date.

Function that uses an LLM to brainstorm company candidates for a given vertical and returns scored results.

Function that persists launch candidates to the D1 database and emits launch signals.

_fetch_ph_launches

What does the async function _fetch_ph_launches do?

Show answer

An async function that retrieves the ProductHunt RSS feed, parses items to extract company candidates for a given vertical slug using deterministic keyword matching, and returns dicts with launch_source 'producthunt' and launch_date provenance.

Memory hook Fetch the RSS feed and hook each matching product by its keyword, tagging it with "producthunt" and its launch date.

Common confusions (wrong answers)

_fetch_ph_launches is an async function that retrieves YC launch stories from the HN Algolia API and returns candidates with launch_source 'yc'.

_fetch_ph_launches uses an LLM to match launch descriptions to vertical keywords before returning candidates.

_fetch_ph_launches persists the parsed launch candidates directly into the companies table via an upsert operation.

_LAUNCH_LOOKBACK_DAYS

What does the constant _LAUNCH_LOOKBACK_DAYS represent in the discovery graph?

Show answer

_LAUNCH_LOOKBACK_DAYS is a constant used to define the lookback window for filtering recent launch-feed entries by subtracting that number of days from the current time to compute a cutoff timestamp.

Memory hook A 90-day rearview mirror that throws out any launch older than three months.

Common confusions (wrong answers)

_LAUNCH_LOOKBACK_DAYS sets the decay period for launch intent signals after they are emitted.

_LAUNCH_LOOKBACK_DAYS defines the maximum number of launch candidates that can be persisted in a single tick.

_LAUNCH_LOOKBACK_DAYS determines the threshold for excluding launch candidates based on whether their domain appears on a blocklist.

Embeddings

15 cards
Embedding (mental model)

What is the core mental model for embeddings, and what does every downstream task reduce to?

Show answer

A learned map where distance means meaning: items become points in a continuous space where semantically similar things land near each other, so search, RAG retrieval, clustering, and classification all reduce to geometry operations (nearest-neighbor, dot product, cluster) on that map.

Memory hook Pins on a surveyed city map — 'near' on the map means 'similar' in meaning.

Common confusions (wrong answers)

A compressed hash of the input that lets you reconstruct the original text exactly from the vector.

A lookup table of synonyms: two items match only when they share surface keywords.

A probability distribution over the vocabulary; downstream tasks reduce to sampling from it.

Cosine vs Euclidean

Why aren't cosine similarity and Euclidean distance interchangeable, and which suits normalized semantic vectors?

Show answer

Cosine measures the angle and is invariant to vector magnitude, while Euclidean distance is sensitive to magnitude. For L2-normalized embeddings, cosine similarity equals the dot product and is the standard choice — and you must know which metric your vector DB uses by default.

Memory hook The map's projection and units — miles vs kilometers look like numbers either way, but mean nothing when mixed.

Common confusions (wrong answers)

Euclidean distance is magnitude-invariant, which makes it the safer default for semantic similarity.

They always produce the same ranking, so the choice only affects raw score values, never results.

Cosine similarity only works on integer vectors, so float embeddings require Euclidean distance.

Pooling mismatch

You index a corpus with mean-pooled vectors but embed queries with the CLS token. What happens?

Show answer

Nothing throws: dimensions match and cosine scores still look plausible, but recall silently collapses because query pins and corpus pins were placed by different rules. Pooling (mean, CLS, last-token) must be identical at index time and query time.

Memory hook A campus gets one pin: geographic center (mean) or main entrance (CLS) — but the same rule for every pin.

Common confusions (wrong answers)

The vector database rejects the query vectors because their pooling metadata doesn't match the index.

Scores drop to exactly zero, making the bug obvious in the first smoke test.

Nothing changes — pooling strategies are mathematically equivalent after L2 normalization.

Normalization rule

What is the one rule for metrics and normalization in an embedding search stack?

Show answer

Pick one metric and normalize consistently on both sides — index time and query time — forever. Cosine similarity is just a dot product on L2-normalized (unit-length) vectors; normalize one side only and the scores become meaningless.

Memory hook One projection, one set of units, on both sides of the map.

Common confusions (wrong answers)

Normalize only at index time — query vectors should keep their raw magnitude to preserve intent strength.

Normalization is a storage optimization; it never affects similarity rankings.

Alternate metrics per query type: cosine for short queries, Euclidean for long ones.

ANN tradeoff

What do HNSW's `ef` and IVF's `nprobe` control, and what is the underlying tradeoff?

Show answer

They are the recall-vs-latency dial of approximate nearest-neighbor search: exact search is O(N), so production indexes trade a little recall for huge speed. Turn the dial left for speed, right for recall — and tune it against your real query load, not library defaults.

Memory hook Asking a well-connected local instead of measuring the distance to every address — instant, occasionally misses the true closest.

Common confusions (wrong answers)

They set the embedding dimensionality the index stores, trading storage for nuance.

They control write throughput during index builds and have no effect on query results.

They toggle between cosine and Euclidean distance at query time.

Re-embedding on model upgrade

What does upgrading your embedding model force you to do, and why?

Show answer

Re-embed the entire corpus: vectors from different model versions live on different maps and are never comparable. The safe path is building the v2 index alongside v1, comparing recall on shadow traffic, then cutting over. Changing chunking forces the same full re-embed.

Memory hook A new surveyor redraws the map — every old pin is now on the wrong map.

Common confusions (wrong answers)

Only re-embed new documents — the vector DB interpolates between old and new model spaces.

Run both models per query and average their similarity scores during a transition window.

Nothing, as long as both model versions output vectors of the same dimensionality.

Chunking

How do you embed a document that exceeds the model's context window, and how do you get a document-level vector?

Show answer

Split it into semantically coherent chunks (sentences, paragraphs, or sliding windows with overlap) and embed each separately; retrieval matches the query against chunks. For a document-level vector, average the chunk embeddings or cluster them and take the centroid. Never split mid-sentence.

Memory hook What counts as one address — pin a whole city block and nobody finds suite 4B; pin every doorknob and the map is noise.

Common confusions (wrong answers)

Truncate to the first N tokens — the opening of a document reliably summarizes the rest.

Embed the document title only and rely on metadata filters for the body.

Increase the model's context window parameter; embedding models accept arbitrary lengths at higher cost.

Hybrid search

What weakness of pure vector search does hybrid search fix, and how are the two result sets combined?

Show answer

Pure vector search misses exact keyword matches (acronyms, codes, names like 'Article 4, Clause B'). Hybrid runs vector and keyword (BM25) search in parallel, normalizes each result set's scores, and fuses them with Reciprocal Rank Fusion or a weighted sum.

Memory hook Map + street signs: proximity for meaning, exact names for exact terms.

Common confusions (wrong answers)

It fixes vector search's slow indexing by writing keywords first and backfilling vectors asynchronously.

The keyword engine filters first, and vector search runs only on documents containing every query term.

Scores are combined by taking whichever engine returns the higher raw number per document.

Embedding cache key

What must an embedding cache key include besides the content hash, and why?

Show answer

The model name/version. The same sentence has different coordinates under different models, so a cache keyed on content alone serves pins from the wrong map after any model change. Pattern: `embed:<model>:<sha256(text)>`.

Memory hook Saving coordinates in your contacts is only safe if you note which surveyor's map they came from.

Common confusions (wrong answers)

The request timestamp, so stale vectors expire naturally without a TTL.

The user ID, because embeddings are personalized per requester.

Nothing else — embedding outputs are deterministic across models of the same dimensionality.

Symmetric vs asymmetric search

What distinguishes symmetric from asymmetric semantic search, and which needs a specially trained model?

Show answer

Symmetric compares same-kind, same-length items (find sentences like this sentence, dedup) — one plain similarity model embeds both sides. Asymmetric matches a short query against long passages, so it needs a model trained on (question, passage) pairs — a bi-encoder, e5-style query/passage prefixes — plus optionally a cross-encoder re-ranker.

Memory hook 'Find a café like this café' vs a tourist's 5-word question matching a guidebook's full page.

Common confusions (wrong answers)

Symmetric means the index is rebuilt on every query; asymmetric means it is append-only.

Asymmetric search just means using Euclidean distance instead of cosine similarity.

Symmetric search requires a cross-encoder; asymmetric works fine with any plain similarity model.

Sparse vs dense

When would you choose sparse representations (TF-IDF/BM25) over dense embeddings?

Show answer

When interpretability and exact keyword matching are critical, the domain is niche with limited data, and you want cheap computation with no pre-trained model — classic term-driven search. Dense wins for semantic similarity, synonyms and rephrasing, and transferring pre-trained knowledge.

Memory hook Phone book vs map — the phone book finds exact names; the map finds what's nearby in meaning.

Common confusions (wrong answers)

Sparse is always better for large corpora because dense vectors cannot be indexed at scale.

Dense embeddings require labeled training data from your own domain, so sparse is the only zero-setup option.

Sparse representations capture synonyms better because each dimension is a human-readable word.

Cold start

A recommendation system uses user embeddings. How do you handle a brand-new user with no interaction history?

Show answer

You need an explicit strategy: assign a default embedding, or build a provisional one from side information (demographics, onboarding signals) until real interactions accumulate. Ignoring cold start is a classic design red flag.

Memory hook A brand-new building has no coordinates yet — drop a provisional pin based on its neighborhood.

Common confusions (wrong answers)

New users automatically get the global centroid — vector DBs handle this without application logic.

Delay all recommendations until the user has enough history for a converged embedding.

Reuse the embedding of the most recently registered user as an approximation.

Vector DB as derived data

Why must the vector database not serve as your primary data store?

Show answer

It is a specialized search index over derived data. Canonical data belongs in a source-of-truth SQL/NoSQL store; the vector DB holds embeddings plus metadata and must be rebuildable from the source if lost. If you can't rebuild it, you've made a disposable index your canonical store.

Memory hook The map is not the territory — lose the map, re-survey from the buildings.

Common confusions (wrong answers)

Vector databases cannot store any non-vector fields, so metadata would be lost.

Vector databases lack replication, making them technically incapable of durability.

It's fine to use one as the primary store as long as backups run nightly.

Training objectives

How do skip-gram and contrastive training make 'distance mean meaning' in the embedding space?

Show answer

Skip-gram (Word2Vec) predicts context words from a target, pushing words that appear in similar contexts toward similar vectors. Contrastive/triplet training on (anchor, positive, negative) examples pulls the anchor toward the positive and pushes it from the negative — geometry is shaped directly by the objective.

Memory hook The surveying method decides what 'near' means — a map surveyed for driving is wrong for hiking.

Common confusions (wrong answers)

The embedding matrix is initialized from a dictionary so synonyms start adjacent and stay fixed.

Distances are hand-tuned after training by projecting vectors onto a human-labeled similarity grid.

Backpropagation minimizes reconstruction error of the original one-hot vector, which incidentally clusters synonyms.

Dimensionality

What is the tradeoff between 384-, 1536-, and 3072-dimensional embeddings?

Show answer

Higher dimensions capture more nuance but cost more storage, memory, and query latency; lower dimensions are faster and cheaper but coarser (and often weaker out-of-domain). Pick the resolution the task needs — e.g. all-MiniLM-L6-v2 (384) vs text-embedding-3-small (1536) vs -3-large (3072).

Memory hook Map resolution — the 1:1000 survey captures every alleyway but is heavy; the pocket map is often enough.

Common confusions (wrong answers)

Dimensionality only affects index build time; query latency is dimension-independent.

Higher dimensions always improve retrieval quality, so use the largest that fits on disk.

Vectors of different dimensionality are interchangeable at query time if both are L2-normalized.

Enrichment

15 cards
CompanyEnrichmentState

What does CompanyEnrichmentState represent as it flows through the enrichment graph's nodes?

Show answer

It is the typed state schema imported from schemas.state that holds fields like company_id, classification, and scores and is passed through each node of the linear pipeline.

Memory hook A company's passport gets stamped at five embassy windows: load, fetch, classify, score, persist.

Common confusions (wrong answers)

It is the LLM-based grader that returns a verdict on classification groundedness and can trigger a retry.

It is the heuristic fallback function that performs regex keyword matching to assign category and tier.

It is the async function that extracts funding stage and team-size estimates using LLM prompts for all companies.

fetch

What does the 'fetch' async function do in the company enrichment pipeline?

Show answer

It builds URLs for the company's home and careers pages, fetches them in parallel using asyncio.gather, and returns markdown content along with a timing record.

Memory hook A hyper-caffeinated golden retriever fetches two pages at once, dropping markdown and a stopwatch into your hand.

Common confusions (wrong answers)

It grades the classification output for groundedness and returns a verdict of 'ok' or requests a retry.

It extracts the funding stage and team size estimate from the page text using an LLM prompt.

It extracts PI signals like demand automation and medical record summarization for legal-pi-demand companies.

classify

Which node in the enrichment pipeline produces a classification dictionary by either calling an LLM with cache and memory or falling back to a keyword-based heuristic?

Show answer

Classify (Node 3) generates the classification dictionary using the LLM path or the `_heuristic_classify` fallback when LLM cannot be used.

Memory hook Classify sorts companies like a Harry Potter sorting hat: LLM magic or keyword guesswork.

Common confusions (wrong answers)

The grade node re-classifies a company by grounding the LLM output and always returns a verdict of 'ok' or 'retry'.

The `_heuristic_classify` function is the primary classification method, with the LLM only used as an occasional fallback.

The `detect_ai_signals` function produces the classification by scanning repos and tech stacks for AI-related keywords.

grade

In the company enrichment pipeline, what does the 'grade' node's output determine?

Show answer

The grade node returns a verdict of 'ok' or 'retry' that the router uses to either continue to score or retry classification with flagged issues.

Memory hook A report card stamped with "RETRY" means the student must redo the assignment with the teacher's notes.

Common confusions (wrong answers)

The classify node uses an LLM to produce the initial classification of the company.

The _heuristic_classify function performs a regex keyword match to classify without LLM.

The grade_router function reads the grade verdict and returns the next node to execute.

score

What does the `score` node in the company enrichment graph compute from the state's classification fields?

Show answer

It returns a numerical score by summing weighted contributions from category, tier, remote_policy, and has_open_roles, and optionally adjusts it with a hiring-velocity signal that is only applied when grounded and sufficiently confident.

Memory hook A sports scoreboard adds points for category, tier, remote policy, and open roles, then a hiring‑velocity bonus only if evidence is clear.

Common confusions (wrong answers)

It returns a verdict of 'retry' or 'ok' after critiquing the classification's groundedness against the page text.

It returns the best persona title and fit score after comparing each persona against careers markdown.

It returns a funding stage, signals, team size, confidence, reason, and evidence extracted from the page text.

persist

Which graph node executes an UPDATE on the companies table after score is computed and before GitHub analysis?

Show answer

It writes enrichment results (classification, confidence, score, reasons, timestamps) to the companies table via an UPDATE statement, running after score and before analyse_github.

Memory hook Persist purrs as she writes classification and scores into the companies table, right after scoring and before GitHub analysis.

Common confusions (wrong answers)

It evaluates classification groundedness and returns a verdict, possibly triggering a retry to classify (grade node).

It performs LLM-based classification of the company into category, tier, and other fields (classify node).

It extracts funding stage, signals, and team-size estimate from page text (extract_funding_stage node).

_grade_router

In the company enrichment graph, what does the _grade_router conditional edge return when the grade verdict is 'retry' and fewer than two attempts have been made?

Show answer

It returns 'classify' to retry the LLM classification, otherwise it returns 'score' to continue enrichment.

Memory hook A 'retry' grade flips the router switch back to classify for exactly one redo.

Common confusions (wrong answers)

It returns 'grade' to re-run the grader on the same classification output.

It returns 'score' only after a minimum of three retry attempts have been exhausted.

It returns 'classify' unconditionally on the first pass to ensure a second opinion.

_heuristic_classify

What does _heuristic_classify return that causes the grade node to be skipped for its outputs?

Show answer

It returns a classification with source set to 'heuristic' and low confidence, and the grade function checks classify_source == 'heuristic' to skip grading.

Memory hook Heuristic the detective quickly tags companies by keyword hits, stamps "guess" in red, and dodges grading duty.

Common confusions (wrong answers)

It returns an LLM-based verdict with source 'llm' that the grade node audits for groundedness and may request a retry.

It returns a detailed JSON with category, tier, and remote_policy that the grade node uses to compute a confidence score.

It returns a list of AI signals detected from tech stack and repos that the grade node uses to adjust the classification.

CRAG

What does the CRAG gate do when the `grade` verdict is 'retry'?

Show answer

It routes the pipeline back to `classify` for a single retry, with a maximum of two total attempts, and only gates the fields `category_ok`, `tier_ok`, and `remote_policy_ok`.

Memory hook A climber on a crag grades three key holds – category, tier, remote policy – then loops back to re-classify only once.

Common confusions (wrong answers)

It computes the final enrichment score after grading passes.

It bypasses the LLM grader entirely when the classification source is 'heuristic'.

It extracts PI signals for legal-pi-demand verticals after GitHub analysis.

_FRESHNESS_DAYS

What constant determines the threshold for the freshness skip gate that avoids re-enriching recently classified companies?

Show answer

_FRESHNESS_DAYS is the TTL constant (in days) used by the stale re-enrichment scheduler to select companies whose classification is old enough to require refresh.

Memory hook A chef slaps 'past _FRESHNESS_DAYS' stamp on a stale company file before tossing it into the re-enrich oven.

Common confusions (wrong answers)

_CRAG_MAX_ATTEMPTS is the constant limiting how many times the grade node can retry a classification before moving on.

_EARLY_STAGES is the set of funding stages (pre-seed, seed, series-a) that lower the seniority bar for applied-vertical startups.

_VALID_FUNDING_STAGES is the set of all accepted funding stages used to validate the LLM output in extract_funding_stage.

classification

Which node in the company enrichment graph produces a structured dictionary with keys like 'category', 'tier', and 'confidence', and what two methods can generate it?

Show answer

The classification is produced by the classify node, either via an LLM call or a heuristic fallback that matches keywords.

Memory hook A company's classification is a report card with five slots—category, tier, remote_policy, confidence, reason—filled by an AI teacher or a keyword cheat sheet.

Common confusions (wrong answers)

A function that audits the classification for groundedness and returns a verdict of 'ok' or 'retry', defaulting to 'ok' on failure.

A keyword-matching fallback that returns a low-confidence classification with evidence strings, used when no LLM output is available.

A set of pattern detectors that scan tech stack and repos to identify AI-related signals like topics, repo names, or Python-heavy ratios.

company_facts

What role does the company_facts table serve in the company enrichment pipeline?

Show answer

The company_facts table is written during the persist phase, storing enrichment results like buying_intent and classification data with fields such as company_id, field, value_json, confidence, and extractor_version, allowing co-existence with rows from a separate Rust enricher.

Memory hook The "company_facts" table is a shared tray where Python's "buying_intent" index card and Rust's card sit side by side.

Common confusions (wrong answers)

The companies table is updated during the persist phase with category, tier, score, reasons, and updated_at, storing overall company classification.

The state dictionary in the extract_pi_signals function holds AI-generated signals for demand automation and medical record summarization, stored only during the PI demand vertical run.

The long-term memory store is written by the classify node via pm.write_fact, persisting distilled classification facts with an 'classify:' key prefix.

extractor_version

What does extractor_version record when a fact row is persisted during enrichment?

Show answer

extractor_version records the version identifier of the extraction logic that produced the data, persisted alongside each fact row.

Memory hook A juice-extractor stamping each bottle it fills with its own version number so you know which machine squeezed the data.

Common confusions (wrong answers)

grade_attempts counts how many times the classify node was retried before the grade node approved.

_CRAG_GATED_FIELDS lists the fields whose low-confidence verdicts trigger a single classify retry.

_PI_VERTICAL defines the vertical string that gates PI signal extraction.

hiring_velocity

What does the extract_hiring_velocity node produce and how does it influence the company score?

Show answer

It produces a structured JSON classification of hiring trend (rising, flat, or falling) with magnitude and confidence, and the score node uses the trend to boost or dampen the ICP score.

Memory hook A hiring manager's speedometer needle reads "rising" only when a green "evidence" badge lights up, then a boost rocket fires.

Common confusions (wrong answers)

It produces a JSON object with stage, funding_signals, team_size_estimate, and confidence, and is used to adjust the seniority bar for early-stage companies.

It extracts named customers and case-study logos from marketing copy and returns a list of customer names with verbatim evidence.

It classifies the company's industry vertical by analyzing its product landing page and returns a relevance score and reasoning.

wrap_untrusted

What function does `wrap_untrusted` serve when preparing scraped markdown for LLM calls?

Show answer

wrap_untrusted fences scraped product or careers copy before an LLM call, preventing planted ``[SYSTEM]`` injections from steering the extraction; it is used on the ``home_markdown`` and ``careers_markdown`` strings with a label and character limit.

Memory hook A bouncer wraps a spy's note in barbed wire before handing it to the CEO, blocking any hidden commands.

Common confusions (wrong answers)

grade is a function that performs LLM-based grading of the classification for groundedness, returning a verdict of 'ok' or 'retry' to either continue or loop back to classify.

_count_tokens_hits is a function that counts regex-safe token hits in text, returning a 0..1 score capped at a max expected count.

_normalize_severity is a function that maps severity synonyms (e.g., 'critical') to a standard set ('high', 'medium', 'low') using a synonym dictionary.

Glossary Llamaindex

33 cards
agent

What is an agent in LlamaIndex?

Show answer

An agent is a system that uses an LLM, memory, and tools to handle inputs from outside users, semi-autonomously performing tasks in a reasoning loop that decides which tool to use next.

Memory hook A digital butler checks its memory and tools, then picks the right one to answer your request.

Common confusions (wrong answers)

A workflow is a specific event-driven abstraction that orchestrates a sequence of steps and LLM calls.

A retriever is a component responsible for fetching the most relevant context given a user query.

A tool is a callable function that agents use to perform actions, but it is not itself an agent.

agentic application

What is an 'agentic application' in LlamaIndex?

Show answer

An agentic application is any application where an LLM is used to make decisions, take actions, and/or interact with the world, and it can be built using the `Workflow` class to orchestrate a sequence of steps and LLMs.

Memory hook An agentic application is a decision-making conductor using Workflow to orchestrate LLM steps into actions.

Common confusions (wrong answers)

An application that only retrieves documents and passes them to the LLM without any iterative decision-making or tool use.

An application that uses a predefined, non-adaptive sequence of steps with no LLM involvement.

An application that uses the LLM solely for generating a single response to a user query without any memory or tools.

AgentWorkflow

What does the AgentWorkflow class do?

Show answer

It combines multiple agents into a system where each agent hands off control to coordinate task completion.

Memory hook Agents pass a digital baton, each handing control to the next for coordinated task completion.

Common confusions (wrong answers)

It defines a single agent's reasoning loop with tools and memory.

It is a tool specification for wrapping external APIs into agent-compatible functions.

It manages chat memory by storing and retrieving conversation history for an agent.

FunctionAgent

What does a FunctionAgent in LlamaIndex do?

Show answer

A FunctionAgent uses an LLM provider's function or tool calling capabilities to execute tools.

Memory hook Think of FunctionAgent as a robot that calls the right function tool from its toolbox whenever the LLM tells it to.

Common confusions (wrong answers)

It relies on a sequential list of nodes to determine which tool to call.

It wraps an existing query engine to provide tool access.

It automatically generates code for tool execution without needing an LLM.

workflow

What is a workflow in LlamaIndex?

Show answer

A workflow is an event-driven, step-based abstraction that orchestrates a sequence of steps and LLM calls, used to implement agentic applications.

Memory hook A game of catch where each throw (event) triggers the next player's action (step), and an LLM decides the next throw.

Common confusions (wrong answers)

A workflow is a data structure that stores vector embeddings for quick retrieval of relevant context.

A workflow is a tool that wraps an existing query engine and can call other agents.

A workflow is a retriever that fetches the most relevant context from an index for a user query.

step

What is a step in the context of a Workflow?

Show answer

A step is a method decorated with the @step decorator that performs a unit of work within a Workflow, triggered by Events and emitting Events to activate further steps.

Memory hook A worker labeled @step only starts when an Event bell rings, then finishes and tosses a new Event to the next worker.

Common confusions (wrong answers)

A step is a directed acyclic graph that defines the execution flow of a workflow.

A step is a data structure that stores vector embeddings for retrieval-augmented generation.

A step is a response mode that iterates over text chunks to refine an answer.

event

What is an event in LlamaIndex?

Show answer

In LlamaIndex, an event is a user-defined Pydantic object that inherits from the Event class and is used in workflows to trigger and pass data between steps.

Memory hook An event is a custom post-it note that you toss into the workflow machine to trigger the next step and hand off data.

Common confusions (wrong answers)

A Node that stores a chunk of a document and its metadata.

A Retriever that fetches the most relevant context for a user query.

A Workflow class that orchestrates a sequence of steps and LLMs.

StartEvent / StopEvent

What is the role of StartEvent and StopEvent in a LlamaIndex workflow?

Show answer

StartEvent marks the entry point of a workflow and holds arbitrary attributes passed via the .run() method, while StopEvent designates the final step that, when returned, terminates the workflow and returns the value stored in its result parameter.

Memory hook Imagine a starting gate where the .run() method hands over a bag of attributes to begin the race.

Common confusions (wrong answers)

They are objects that store and share state across steps in a workflow.

They are used to index documents into nodes for retrieval-augmented generation.

They are parameters that control the response mode of a response synthesizer.

Context (workflow)

What is the purpose of a workflow Context object?

Show answer

A workflow Context object is passed between steps and is used to store and share state across steps, so steps do not have to pass every value explicitly through events.

Memory hook Think of Context as a shared backpack each step carries, holding all shared state so steps never need to hand off individual items.

Common confusions (wrong answers)

An Event is passed between steps to trigger the next step and carry data.

A StartEvent marks the entry point of a workflow and holds arbitrary attributes passed via .run().

A StopEvent designates final steps and terminates the workflow, returning its result.

tool

What is a tool in LlamaIndex?

Show answer

In LlamaIndex, a tool is an abstraction that implements a callable interface with metadata (name, description, function schema) and is used by agents to perform actions.

Memory hook A tool is a labeled lever that an agent pulls to execute a named function with a given description.

Common confusions (wrong answers)

A node is a discrete chunk of a source document that stores text and metadata.

A retriever fetches the most relevant context given a user query or chat message.

A document is a general container for any data source that preserves text and metadata.

FunctionTool

What does the FunctionTool class do in LlamaIndex?

Show answer

FunctionTool converts any user-defined Python function into a LlamaIndex Tool, automatically inferring the function schema or allowing customization.

Memory hook FunctionTool takes any Python function and turns it into a LlamaIndex tool, like a factory stamping parts into finished products.

Common confusions (wrong answers)

FunctionTool wraps an existing query engine to provide retrieval capabilities for an agent.

FunctionTool is a pre-built collection of tools for a single service like Gmail or Google Calendar.

FunctionTool converts a list of Documents into Node objects by splitting text on sentence boundaries.

QueryEngineTool

What is a QueryEngineTool?

Show answer

A QueryEngineTool wraps an existing query engine and can also wrap other agents.

Memory hook Picture a wrench that wraps around a whole query engine, letting you use it as a tool.

Common confusions (wrong answers)

A QueryEngineTool converts any user-defined function into a Tool.

A QueryEngineTool defines one or more tools around a single service like Gmail.

A QueryEngineTool wraps other tools to handle returning large amounts of data from a tool.

ToolSpec

What is a ToolSpec in LlamaIndex?

Show answer

A ToolSpec is a community-contributed specification that defines one or more tools around a single service and implements a `to_tool_list` method.

Memory hook A ToolSpec is a community-crafted toolbox for one service, ready to call its list of tools.

Common confusions (wrong answers)

A tool that converts any user-defined function into a Tool and auto-infers the function schema.

A tool that wraps an existing query engine and can also wrap other agents.

A utility tool that wraps other tools to handle returning large amounts of data, such as OnDemandLoaderTool.

memory

In LlamaIndex, what is the role of memory in agents?

Show answer

Memory is a core component of agents that stores chat history and context, managed by default with ChatMemoryBuffer and customizable by declaring it separately and passing it to the agent.

Memory hook Think of memory as the agent's shopping list, storing every past question and answer.

Common confusions (wrong answers)

It stores the vector embeddings of all indexed documents for retrieval.

It manages the execution order of tool calls in the agent loop.

It retrieves the most relevant context from the index for a user query.

query engine

What is a query engine in LlamaIndex?

Show answer

A query engine is a generic interface that takes a natural language query and returns a rich response, typically built on one or more indexes using retrievers.

Memory hook A librarian engine that hears your question in plain English and pulls the perfect book from its index shelves.

Common confusions (wrong answers)

A query engine is a stateful interface for having multi-turn conversations with your data while maintaining chat history.

A query engine is a data structure that stores document chunks and their vector embeddings for efficient similarity search.

A query engine is a component that fetches the most relevant context from an index given a user query.

chat engine

What is a chat engine?

Show answer

A chat engine is a high-level, stateful interface for having a multi-turn conversation with your data, maintaining conversation history to consider previous context, and serving as the counterpart to a query engine.

Memory hook Picture a chatty assistant that remembers your past questions, so each reply builds on the last.

Common confusions (wrong answers)

A chat engine is a component that retrieves the most relevant context from an index in response to a user query.

A chat engine is a data structure that stores documents as nodes and computes vector embeddings for quick retrieval.

A chat engine is a system that uses an LLM, memory, and tools to handle inputs and execute tool calls in a loop.

retriever

What is the role of a retriever in LlamaIndex?

Show answer

It is responsible for fetching the most relevant context given a user query or chat message and defines how to efficiently retrieve that context from an index.

Memory hook A librarian dashing into the index shelves to grab the perfect paragraphs for your question.

Common confusions (wrong answers)

It generates a final answer from retrieved context using an LLM.

It determines which retriever to use based on the query or chat message.

It is a data structure that stores vector embeddings for quick retrieval.

router

What does a router do in LlamaIndex?

Show answer

A router determines which retriever will be used to retrieve relevant context, using the RouterRetriever class to select one or multiple candidate retrievers based on their metadata and the query.

Memory hook A router reads each query's label and points it to the right retriever shelf.

Common confusions (wrong answers)

A router converts user queries into vector embeddings for similarity search.

A router re-ranks retrieved nodes by relevance to improve response quality.

A router generates the final response by synthesizing retrieved context with an LLM.

node postprocessor

What does a node postprocessor do in LlamaIndex?

Show answer

A node postprocessor takes in a set of retrieved nodes and applies transformations, filtering, or re‑ranking logic to them, such as a reranker that reorders nodes by relevance.

Memory hook A node postprocessor is like a librarian who sorts a stack of books by relevance after the initial search.

Common confusions (wrong answers)

A retriever that fetches the most relevant nodes from an index given a query.

A response synthesizer that generates a response from an LLM using a query and retrieved text chunks.

A router that determines which retriever will be used to retrieve relevant context based on the query.

response synthesizer

What does a Response Synthesizer do in LlamaIndex?

Show answer

It generates a response from an LLM using a user query and a given set of retrieved text chunks, used after nodes are retrieved and node-postprocessors have been applied.

Memory hook After retrieving and polishing relevant notes, the response synthesizer blends your question into a single LLM answer.

Common confusions (wrong answers)

It fetches the most relevant context from an index given a user query.

It maintains conversation history and generates responses across multiple back-and-forth exchanges.

It applies transformations to retrieved nodes before they are used for response generation.

response mode

What is a response mode in LlamaIndex?

Show answer

A response mode is a setting passed as the `response_mode` keyword argument to a response synthesizer that determines how the synthesizer generates a Response object from a user query and a set of retrieved text chunks.

Memory hook Like a chef picking a recipe mode, response mode decides how to blend query and chunks into a final answer.

Common confusions (wrong answers)

A response mode is a setting that controls which nodes are retrieved by the retriever based on similarity to the query.

A response mode is a type of index, such as VectorStoreIndex, that organizes documents for efficient retrieval.

A response mode is a data connector that ingests data from different sources into Documents and Nodes.

index

What is an Index in LlamaIndex?

Show answer

An Index is a data structure constructed from Documents that stores information in Node objects, enabling quick retrieval of relevant context for user queries through its Retriever interface, and serves as the foundation for building Query Engines and Chat Engines.

Memory hook An index is a filing cabinet where each Document is split into labeled Nodes, letting you quickly pull relevant context for any query.

Common confusions (wrong answers)

A tool that ingests data from various sources and converts them into Documents and Nodes.

A mechanism that selects which retriever to use for a given query.

A node postprocessor that re-ranks retrieved nodes by relevance.

VectorStoreIndex

What is the VectorStoreIndex in LlamaIndex?

Show answer

It splits documents into nodes, computes vector embeddings for each node, and stores them to retrieve the nodes most similar to a query embedding at query time.

Memory hook Think of VectorStoreIndex as a filing clerk who chops your documents into note cards, paints each with a unique color code, then finds the cards that match your query's color.

Common confusions (wrong answers)

It creates a sequential list of nodes designed for summarization over whole documents.

It retrieves relevant context for a query by directly using an LLM without embeddings.

It parses documents into nodes and stores them without any similarity-based retrieval.

SummaryIndex

What does the SummaryIndex do?

Show answer

The SummaryIndex stores nodes as a sequential list and returns all nodes for a query, making it useful for summarization over a whole document.

Memory hook Think of the SummaryIndex as a scroll that unrolls every sentence in order for a question, so you can summarize the entire story.

Common confusions (wrong answers)

It stores nodes as vector embeddings and retrieves only the most similar nodes based on query embedding.

It retrieves nodes using a retriever mode that selects between multiple candidate retrievers based on query metadata.

It uses a tree structure to recursively combine answers from text chunks until a single final answer is produced.

document

In LlamaIndex, what is a Document?

Show answer

A Document is a general container for any data source that preserves text content along with metadata and relationship attributes.

Memory hook A folder that holds a PDF's words, sticky notes of metadata, and chains to other folders.

Common confusions (wrong answers)

A Document is a discrete chunk of a source document used as the atomic unit of data.

A Document is a data structure that stores vector embeddings for quick retrieval of relevant context.

A Document is a component that fetches the most relevant context given a user query.

node

What is a Node in LlamaIndex?

Show answer

A Node is a discrete chunk of content—such as a text segment or image—derived from a source Document, with its own metadata and relationships to other Nodes.

Memory hook Imagine a Lego brick snapped from a document, labeled with its own tags and connected to other bricks.

Common confusions (wrong answers)

A Node is the entire data source container that holds text and metadata from a PDF or API.

A Node is a data structure that stores vector embeddings and allows fast retrieval of relevant context.

A Node is a component that generates a response by iterating over text chunks using an LLM.

node parser

What does a node parser do in LlamaIndex?

Show answer

It takes a list of Documents and chunks them into Node objects by splitting text on sentence boundaries while respecting a configured chunk size and overlap.

Memory hook A node parser is a smart knife that cuts documents into sentence chunks, with each chunk overlapping like roof shingles.

Common confusions (wrong answers)

It stores vector embeddings of document chunks for similarity search.

It retrieves the most relevant context from an index given a user query.

It generates a response from an LLM using a user query and retrieved text chunks.

embedding

What does the term 'embedding' refer to in LlamaIndex?

Show answer

Embeddings are numerical representations of data used to find relevant context by comparing vector similarity between queries and stored nodes.

Memory hook Embeddings map text to number coordinates so the system finds nodes with the nearest coordinates.

Common confusions (wrong answers)

Embeddings are text chunks that store metadata about documents.

Embeddings are indexes that store documents for quick retrieval.

Embeddings are retriever classes that fetch context from an index.

vector store

What is a vector store?

Show answer

A specialized database that stores vector embeddings and finds data numerically similar to a query embedding.

Memory hook A vector store is a memory palace where each idea has a number, and you find similar ideas by number.

Common confusions (wrong answers)

A data structure that splits documents into nodes for indexing.

A numerical representation of data used to measure similarity.

A reader that ingests data from different sources into Documents and Nodes.

data connector (Reader)

What does a data connector (Reader) do in LlamaIndex?

Show answer

It ingests data from different data sources and data formats into Documents and Nodes, used in the loading stage of retrieval-augmented generation.

Memory hook A librarian Reader swallows PDFs, APIs, and databases, then spits out Document and Node pages.

Common confusions (wrong answers)

It computes vector embeddings for each node and stores them in a vector store.

It retrieves the most relevant context from an index given a user query.

It splits documents into chunks and creates Node objects from Documents using a NodeParser.

ingestion pipeline

What does an ingestion pipeline do?

Show answer

It applies transformations to input data, producing nodes that are either returned or inserted into a vector database, and caches each node‑transformation combination to save time on subsequent runs.

Memory hook Like a factory conveyor belt, the ingestion pipeline transforms raw data into neat node packages, ready for storage or querying.

Common confusions (wrong answers)

It retrieves the most relevant context from an index based on a user query.

It stores vector embeddings of data in a specialized database for similarity search.

It generates a response from an LLM using a user query and a set of retrieved text chunks.

transformation

What does the term 'transformation' mean in LlamaIndex?

Show answer

A transformation is an operation that converts source Documents into Node objects, commonly performed using NodeParser classes.

Memory hook A chef chops a whole document into bite-sized node chunks with a sentence-splitter blade.

Common confusions (wrong answers)

It is the process of retrieving the most relevant nodes from an index given a user query.

It is the method of generating a response from an LLM using a user query and retrieved text chunks.

It is the data structure created by splitting documents and storing vector embeddings for similarity search.

RAG

What is RAG in LlamaIndex?

Show answer

RAG is a core technique in LlamaIndex that provides your private data to an LLM at query time to answer questions, rather than training the LLM on that data.

Memory hook Imagine handing a chef your private recipe card at dinner time, so they cook your dish without memorizing it.

Common confusions (wrong answers)

RAG is a method that trains the LLM on your private data to improve its knowledge.

RAG is an index type that stores vector embeddings for efficient retrieval.

RAG is a tool that generates embeddings for your documents.

Human In The Loop

12 cards
the four HITL shapes

Name the four human-in-the-loop interaction shapes, and the one that sits INSIDE a step rather than between steps.

Show answer

Approval gate (bless the plan between steps), tool-call review (intercept a specific call with its exact arguments), state edit (fix the agent's intermediate state and resume), and multi-turn input (the agent asks, the human answers). Tool-call review sits inside a step — the model already emitted the call — which is why newer SDKs made it their only HITL surface.

Memory hook Gate between steps, review inside a step, edit the state, answer the question.

Common confusions (wrong answers)

Approve, reject, retry, and escalate — the four verdicts an approval UI must render.

Pause, persist, resume, and identify — the four shapes a reviewer can act in.

Pre-hoc review, post-hoc audit, sampling, and shadow mode — the four oversight regimes.

pause / persist / resume / identify

What are the four mechanics every HITL implementation must solve, per the rubric?

Show answer

Pause the run without burning a worker; persist it somewhere a DIFFERENT process can find it (state plus a waiting-for marker); resume by injecting the human's payload at the pause point, not the beginning; and identify which of the paused runs an arriving approval belongs to, via a durable handle the approval UI carries.

Memory hook Can it stop? Does the stop survive? Where does the answer re-enter? What names the waiting run?

Common confusions (wrong answers)

Draft, notify, decide, execute — the lifecycle of one approval gate.

Serialize, store, deserialize, replay — the four steps of checkpoint-based recovery.

Intercept, display, collect, apply — the four responsibilities of the review UI.

the pause is a save point

LangGraph HITL in three calls: park, persist, resume — name them, plus the handle that identifies the run.

Show answer

Park with `interrupt()` inside a node; persist via the checkpointer passed to `compile()` (SqliteSaver/Postgres saver — state was already saved every superstep); resume with `invoke(Command(resume=payload), config)`, where the payload becomes `interrupt()`'s return value. The handle is the `thread_id` in config — the string your approval links carry.

Memory hook Every superstep is a save point, so 'wait for a human' is just declining to continue an already-saved run.

Common confusions (wrong answers)

Emit `InputRequiredEvent`, snapshot with `ctx.to_dict()`, answer with `send_event(HumanResponseEvent(...))` — keyed by the context blob.

Mark the tool `needs_approval`, store `state.to_string()`, re-run with the rebuilt `RunState` — keyed by your storage key.

Set `human_input=True`, persist with `@persist`, re-kick the flow with the decision in state — keyed by the flow id.

the replay footgun

A LangGraph node calls an LLM, then interrupt(). The human approves. What happens to that LLM call, and what is the discipline?

Show answer

It runs again: resume re-executes the interrupted node from its top — this time interrupt() returns the payload instead of parking — so every line above the interrupt runs twice. Discipline: side effects go AFTER the interrupt line, or into their own node so the checkpoint boundary protects them.

Memory hook The save point reloads from the start of the room — not the pixel you stood on.

Common confusions (wrong answers)

Nothing — the checkpointer cached the LLM response and replays it from the snapshot.

The node resumes from the exact interrupt() line, so earlier statements never re-run.

The graph raises unless the node is declared idempotent in its config.

the pause is an event

What is LlamaIndex Workflows' HITL event pair, and how does each direction travel?

Show answer

Out: the step emits `InputRequiredEvent` and suspends on `ctx.wait_for_event(HumanResponseEvent)`; the driver catches it iterating `handler.stream_events()`. Back: the driver calls `handler.ctx.send_event(HumanResponseEvent(...))`, and the awaiting step continues with the typed payload. Other steps keep running while one waits.

Memory hook A letter posted out, a letter awaited back — and the mailroom keeps sorting everyone else's post.

Common confusions (wrong answers)

`interrupt()` out and `Command(resume=...)` back, on the same thread_id.

`DeferredToolRequests` out and `DeferredToolResults` back, carried with the message history.

`agent.custom_tool_use` out and `user.custom_tool_result` back, over the session event stream.

snapshot or it didn't happen

How does a pending LlamaIndex approval survive a pod restart — and what is the failure mode if you skip it?

Show answer

Serialize the context BEFORE parking: `ctx.to_dict(serializer=JsonSerializer())` stored externally, then rebuild with `Context.from_dict(workflow, data)` and re-run; the `waiter_id` deduplicates the re-emitted request so the human isn't asked twice. Skip it and the suspended coroutine dies silently with the process — LangGraph makes you defend against double execution, LlamaIndex against forgetting to save.

Memory hook No suspended coroutine survives a restart. The snapshot is the survival.

Common confusions (wrong answers)

It survives automatically — the checkpointer wrote the context after every step.

The HumanResponseEvent carries the run_id, so the event bus routes it to whichever pod restarted the flow.

It can't — LlamaIndex workflows never resume across processes; that is why /llama-agents exists.

the pause is a console prompt

What does CrewAI's `Task(human_input=True)` actually do, and what is CrewAI's real production-gate answer?

Show answer

It blocks the process on stdin after the task completes — the human types feedback in the terminal and the agent revises. Honest developer loop, but nothing is persisted and there's no external handle. Production gates use Flows: end the flow at the decision point with `@persist` state, notify from your app, re-kick with the decision recorded, and a `@router` routes on it — a pattern you design, not a primitive you inherit.

Memory hook Great while you're at the keyboard; gone when the terminal is.

Common confusions (wrong answers)

It emits an InputRequiredEvent on the crew's event stream that your web app answers.

It parks the task in CrewAI's hosted review queue until an approver acts.

It serializes the crew to a RunState string you store and later re-run with the decision.

the pause is serialized state

Walk the OpenAI Agents SDK approval flow from `needs_approval` to resumed run.

Show answer

A tool marked `needs_approval=True` makes the run return early with `result.interruptions`. `result.to_state().to_string()` serializes the whole run — history, pending calls, flags — to a string you store under your own key. Later: `RunState.from_string(agent, s)`, record `state.approve(...)` / `state.reject(...)` per interruption, then `Runner.run(agent, state)` — approved calls execute, rejections go back to the model as messages.

Memory hook The pause is a value — and values are easy to store, inspect, and ship across processes.

Common confusions (wrong answers)

`interrupt()` inside the tool, checkpointer persistence, `Command(resume="approve")` on the thread.

The run ends with a DeferredToolRequests output; resume by re-running with deferred_tool_results and the message history.

A can_use_tool callback fires before the call; return allow/deny and the live session continues.

the durability carve-out

The Agents SDK 'has no durability story' — so why is its HITL state serializable, and what is the remaining limit?

Show answer

Tool approval forced the carve-out: a paused run must live somewhere while the human thinks, so RunState became a storable value. But it's a snapshot at the pause boundary only — no checkpointer writes every step, so a crash BETWEEN pauses still loses the run, and only the tool boundary can pause at all.

Memory hook HITL got the durability exception; the rest of the run didn't.

Common confusions (wrong answers)

Because tracing was enabled — the trace store doubles as the checkpoint you re-attach to.

It isn't — approvals only work while the original process stays alive.

Because OpenAI stores the paused run server-side, keyed by run_id, for 30 days.

the human is another agent

What is AutoGen's `human_input_mode` dial on UserProxyAgent, and what does the human-as-participant framing deliberately not solve?

Show answer

ALWAYS asks the human before every reply; TERMINATE runs autonomously and asks only when the conversation would otherwise end; NEVER is full autonomy. The framing collapses every HITL shape into 'the human says something' — but the default input function blocks a live process on the console, nothing is persisted, and durable away-from-keyboard gates remain your infrastructure (AG2 keeps the classic API; Microsoft's line moved into the Agent Framework).

Memory hook The human has a seat at the table — but only while the table is still standing.

Common confusions (wrong answers)

It routes tool calls to the human for approval: ALWAYS every call, TERMINATE only destructive ones, NEVER none.

It sets how the proxy executes code: ALWAYS locally, TERMINATE in docker, NEVER disabled.

It controls checkpoint frequency: ALWAYS every message, TERMINATE at conversation end, NEVER off.

the run that ends on purpose

How does Pydantic AI implement tool approval without keeping anything alive, and what covers the state-edit shape?

Show answer

Tools marked `requires_approval=True` don't fire — the run ENDS with a `DeferredToolRequests` output listing the pending calls. Message history plus requests are plain data; store them anywhere. Resume by re-running with `message_history` and `deferred_tool_results`, mapping each tool_call_id to `ToolApproved` or `ToolDenied(msg)`. `ToolApproved(override_args=...)` is the state-edit shape at the tool level; the denial message steers the model instead of crashing the run.

Memory hook No coroutine to babysit: the pause IS the return value.

Common confusions (wrong answers)

A suspended coroutine awaits HumanResponseEvent; serialize the context if the wait may outlive the process.

The run parks on interrupt() and the checkpointer keeps it; resume with Command(resume=ToolApproved()).

A can_use_tool callback decides inline; modified input rides back on the allow result.

the court of last resort

Where does the Claude Agent SDK's `can_use_tool` callback sit in permission evaluation, and where must always-run checks go instead?

Show answer

Last: hooks run first, then deny rules, ask rules, the permission mode, and allow rules — only calls nothing earlier settled reach the callback, which returns allow (optionally with modified input) or deny with a message. A matching allow rule or acceptEdits/bypassPermissions silently bypasses it, so checks that must run on EVERY call belong in a PreToolUse hook, which even bypassPermissions can't skip.

Memory hook It only hears cases no earlier rule already settled — and an allow rule settles the case before it's heard.

Common confusions (wrong answers)

First — it screens every call before rules run, so it can never be bypassed.

It replaces the permission system: when a callback is registered, modes and rules are ignored.

It only fires for MCP and custom tools; built-ins are governed by modes alone.

Live Coding

18 cards
the compass

What single question is the interviewer trying to answer during a live-coding round?

Show answer

"Would I want to pair-program with this person?" Every behavior should make the answer yes — if a prep rule makes you annoying to pair with, ignore the rule.

Memory hook A compass needle that always points at 'good pairing partner', never at 'finished feature'.

Common confusions (wrong answers)

"Can this candidate produce the most working code in sixty minutes?"

"Does this candidate already know our exact production stack?"

"Can this candidate finish without asking any clarifying questions?"

minute-zero line

What do you say in your first breath of the interview, and what four things does it do?

Show answer

"Walk me through what you'd want this prototype to do, then I'll sketch a thin slice, ask a couple questions, and we'll build from there." It sets collaboration tone, scopes the task, buys 30 seconds to breathe, and puts you in the driver's seat.

Memory hook One sentence, four birds: tone, scope, breath, driver's seat.

Common confusions (wrong answers)

"Let me start by setting up my environment and installing dependencies while you talk."

"I'll read the whole task silently first, then summarize it back to you to confirm."

"What stack do you use in production, so I can match it exactly?"

Prep 0

What are the three moves of the first five minutes, before any code?

Show answer

State a thin slice in their domain ("smallest version that works end-to-end"), ask exactly two scope questions, and give one stack-bridge line tying your stack choice to their constraint.

Memory hook Slice, two questions, bridge — a 1-2-1 boxing combo before the bell.

Common confusions (wrong answers)

Sketch the full architecture, list every edge case, and agree on a test plan.

Ask as many clarifying questions as possible so nothing is ambiguous later.

Write a README with the plan, then get the interviewer to sign off on it.

mantra #1

What is the one unsheddable narration mantra, said after every unit of work?

Show answer

"Done with X. Next: Y, because Z." Fork narration plus intent — Layer 1 of the overload hierarchy, the one thing you never drop.

Memory hook X done, Y next, Z why — the drumbeat under the whole hour.

Common confusions (wrong answers)

"Let me walk you through every line I just wrote."

"As you can see, I'm now going to refactor this for readability."

"I'll explain my reasoning at the end once everything works."

overload hierarchy

Your brain is full and you can only do one thing. What still makes a strong interview?

Show answer

Layer 1: say "Done with X. Next: Y, because Z" after every unit of work. That alone is 80% of a strong interview; alternatives and self-tests are layers 2-3 if capacity returns.

Memory hook When the RAM is full, one process survives: the X-Y-Z drumbeat.

Common confusions (wrong answers)

Stop narrating entirely and focus on shipping code — results speak loudest.

Slow down and apply all five principles deliberately, even if you build less.

Ask the interviewer for a short break to collect your thoughts.

screen boundary

Principle 2: what do you narrate, and what do you leave to the screen?

Show answer

The screen keeps the visible — code, prompt text, error traces. You say the invisible: rejected alternatives, assumptions, and intent. "Screen shows what. I'm saying why."

Memory hook The screen is the film; you're the director's commentary track.

Common confusions (wrong answers)

Read your prompts aloud as you type them so the interviewer can follow your AI usage.

Explain each generated block line by line so nothing on screen goes unexplained.

Keep a running commentary of everything you do so there is never silence.

no alternative

You genuinely only know one way to do something. What do you say?

Show answer

"I only know one way — open to better ones." Honest and collaborative; inventing rejected alternatives you never considered is worse than silence.

Memory hook One tool in the belt? Say so — honesty is the power move.

Common confusions (wrong answers)

Quickly invent a plausible alternative and explain why you rejected it.

Say nothing — narrating uncertainty undermines your seniority signal.

Ask the AI assistant to list alternatives and present them as your own.

review proof

What phrase proves you critically read generated code without a line-by-line audit?

Show answer

"One thing I checked: [specific]." Pointing at one concrete verified thing is review; "looks good" with no specifics is approval, not review.

Memory hook The customs officer opens ONE suitcase — and says which one and why.

Common confusions (wrong answers)

"I've reviewed all of it carefully and it all looks correct to me."

"Nothing jumps out at me, so let's keep moving."

"The AI is usually right about this kind of code, so I trust it."

review sizes

How does review strategy change for ≤50-line diffs, >50-line generations, and streaming output?

Show answer

≤50 lines: per-file verdict. >50 lines: scan only the riskiest file and say which and why ("checking auth — if that's wrong, nothing else matters"). Streaming: narrate as it arrives — the narration IS the review.

Memory hook Small: verdict per file. Big: riskiest file only. Streaming: talk over it.

Common confusions (wrong answers)

Always review every line regardless of size — anything less is rubber-stamping.

Skip review for small diffs and only audit generations over 100 lines.

Pause streaming output until you have read everything generated so far.

debug triage

Name the four debug triage tiers and their trigger words.

Show answer

"Typo." — fix instantly, zero ceremony. "I've seen this." — known issue, ~30-second check. "Let me think." — internal logic/config error, hypothesis → test. "External." — rate limit / outage / quota, check the service BEFORE the code.

Memory hook An ER triage nurse: classify the patient before treating anyone.

Common confusions (wrong answers)

Reproduce, isolate, fix, verify — the four classic debugging phases.

Set a five-minute timer per bug and escalate to the interviewer when it expires.

Syntax errors, runtime errors, logic errors, and integration errors.

external tier

Why does the External triage tier exist as its own category?

Show answer

A rate limit, API outage, or quota error can eat the entire round if treated as a logic bug. Ask "Is the service up? Is my key valid? Am I rate-limited?" before debugging your own code.

Memory hook Don't operate on the patient when the hospital's power is out.

Common confusions (wrong answers)

External bugs are the interviewer's responsibility, so flagging them scores points.

External services fail so rarely that ruling them out first is nearly free.

It gives you a socially acceptable reason to pause and regroup mid-interview.

three hypotheses

On an internal bug, when do you ask for guidance — and with what words?

Show answer

After 3 failed hypotheses: "Three things ruled out. My best guess is [X]. Should I continue or move on?" Count hypotheses, not minutes; after 7, shift fully collaborative.

Memory hook Three strikes → surface. Seven strikes → hand over the map.

Common confusions (wrong answers)

After five minutes of silence, apologize and ask for a hint.

Never — asking for help on a bug signals you can't debug independently.

Immediately, so the interviewer sees you collaborating from the first error.

rule of two

The AI's first generation is wrong. What is the protocol?

Show answer

You get ONE fix-prompt. If the second generation is still wrong: "Two attempts — I'll write this one manually." Interviewers specifically watch for whether you can code without the AI.

Memory hook Two swings of the AI bat, then you grab the keyboard yourself.

Common confusions (wrong answers)

Keep refining the prompt until the AI produces the right code — prompting skill is the point.

Switch to a different AI model and try the same prompt again.

Abandon the AI for the rest of the interview to be safe.

generation waits

What do you do while the AI is generating code?

Show answer

Talk — generation waits are free narration time. "While it generates, my plan is [X]. The interesting decision coming up is [Y]." Never sit silent watching tokens stream.

Memory hook The AI types, you talk — two workers, zero idle seconds.

Common confusions (wrong answers)

Watch the output closely and silently so you can review it the moment it finishes.

Start writing the next prompt in a scratch buffer to stay ahead.

Use the pause to check the clock and re-budget your remaining time.

narration budget

What is the hard narration budget, and what's the throttle rule?

Show answer

≤10 minutes of narration total in a 60-minute round (v4 measured 18-22 minutes — too much). Track on a phone timer; if you're past 5 minutes by T-30, throttle to mantra-only: "Done with X. Next: Y."

Memory hook Ten minutes of talk in sixty — past half by T-30, drumbeat only.

Common confusions (wrong answers)

Narrate continuously — more visible reasoning always scores higher.

≤20 minutes total, with a checkpoint every quarter hour.

There is no budget; narrate whenever it feels natural and stop when it doesn't.

the landing

After the T-15 feature freeze, what are the three steps of the landing?

Show answer

1) Happy-path demo ("here's the core flow working"), 2) one deliberate, pre-chosen failure ("here's what happens when [most likely failure]"), 3) hand it back: "What would you poke at first?"

Memory hook Land the plane: smooth touchdown, one practiced stall, tower gets the radio.

Common confusions (wrong answers)

Refactor for cleanliness, add comments, then walk through the final code top to bottom.

Demo every feature, list known bugs, and estimate the work remaining.

Ship one more small feature, then ask the interviewer for overall feedback.

task too big

The task obviously doesn't fit in 60 minutes. What is the senior move?

Show answer

Say it out loud: "This is a lot for 60 minutes — where should I focus?" Junior developers try to build it all; seniors scope in the open.

Memory hook Seniors shrink the map out loud; juniors sprint at the whole continent.

Common confusions (wrong answers)

Build the hardest part first to demonstrate maximum technical depth.

Silently cut scope yourself and explain the cuts at the end if asked.

Speed up by skipping narration and review to fit everything in.

draw to think

When do you draw a diagram, and when do you abandon the drawing tool?

Show answer

Draw when you can't hold the system in your head — it's a thinking tool, not a deliverable. If the tool fights you for more than 60 seconds, stop and describe it verbally; annotate a messy diagram rather than redrawing for cleanliness.

Memory hook Napkin, not blueprint — a messy sketch that clarifies beats a pretty one that decorates.

Common confusions (wrong answers)

Open every session with an architecture diagram so the interviewer sees system thinking.

Draw only at the end, as documentation of what you built.

Redraw the diagram whenever it gets messy so it stays presentation-ready.

Llamaindex Anti Patterns

10 cards
The Quickstart Is Not a Product

Your prod query path is still `index.as_query_engine().query(q)` — five lines, no cutoff, no reranker — and it has never once said "I don't know." Which one is it?

Show answer

The Quickstart Is Not a Product — you're doing this when your prod query path is still `index.as_query_engine().query(q)` — five lines, no cutoff, no reranker — and it has never once said "I don't know."

Common confusions (wrong answers)

Paying Twice for the Same Corpus

Tuning Chunk Size Against Generation Quality

Thresholding After the Reranker

Paying Twice for the Same Corpus

The nightly job re-reads and re-embeds all 40k documents whether or not any of them changed, and your embedding bill is a flat line that only ever goes up. Which one is it?

Show answer

Paying Twice for the Same Corpus — you're doing this when the nightly job re-reads and re-embeds all 40k documents whether or not any of them changed, and your embedding bill is a flat line that only ever goes up.

Common confusions (wrong answers)

Tuning Chunk Size Against Generation Quality

Thresholding After the Reranker

Tenancy in the Prompt

Tuning Chunk Size Against Generation Quality

You bumped `chunk_size` until the answers *read* better, and you have no hit-rate number from before or after. Which one is it?

Show answer

Tuning Chunk Size Against Generation Quality — you're doing this when you bumped `chunk_size` until the answers *read* better, and you have no hit-rate number from before or after.

Common confusions (wrong answers)

Thresholding After the Reranker

Tenancy in the Prompt

Trusting an Empty Retrieve

Thresholding After the Reranker

You put a similarity cutoff at the end of `node_postprocessors` to "keep only the good ones," and now half your queries return nothing at all. Which one is it?

Show answer

Thresholding After the Reranker — you're doing this when you put a similarity cutoff at the end of `node_postprocessors` to "keep only the good ones," and now half your queries return nothing at all.

Common confusions (wrong answers)

Tenancy in the Prompt

Trusting an Empty Retrieve

Reaching for a Bigger Model

Tenancy in the Prompt

Your system prompt says "only answer using documents belonging to tenant acme" — and that sentence is the entire access-control layer. Which one is it?

Show answer

Tenancy in the Prompt — you're doing this when your system prompt says "only answer using documents belonging to tenant acme" — and that sentence is the entire access-control layer.

Common confusions (wrong answers)

Trusting an Empty Retrieve

Reaching for a Bigger Model

Letting the Globals Drift

Trusting an Empty Retrieve

Nothing in your code ever checks `len(nodes)`, because a failed retrieval raises, right? Which one is it?

Show answer

Trusting an Empty Retrieve — you're doing this when nothing in your code ever checks `len(nodes)`, because a failed retrieval raises, right?

Common confusions (wrong answers)

Reaching for a Bigger Model

Letting the Globals Drift

An Agent Where a Query Engine Would Do

Reaching for a Bigger Model

Quality is bad, so the plan is to upgrade the LLM — and nobody in the room can say what the retriever's hit rate is. Which one is it?

Show answer

Reaching for a Bigger Model — you're doing this when quality is bad, so the plan is to upgrade the LLM — and nobody in the room can say what the retriever's hit rate is.

Common confusions (wrong answers)

Letting the Globals Drift

An Agent Where a Query Engine Would Do

Grading Your RAG With a Golden Set the Model Wrote

Letting the Globals Drift

Ingest and query are two different processes, each configures `Settings` in its own module, and no startup check compares them. Which one is it?

Show answer

Letting the Globals Drift — you're doing this when ingest and query are two different processes, each configures `Settings` in its own module, and no startup check compares them.

Common confusions (wrong answers)

An Agent Where a Query Engine Would Do

Grading Your RAG With a Golden Set the Model Wrote

The Quickstart Is Not a Product

An Agent Where a Query Engine Would Do

Every question goes through a tool-calling loop, so the same query retrieves different chunks on different days — and your eval set has quietly stopped meaning anything. Which one is it?

Show answer

An Agent Where a Query Engine Would Do — you're doing this when every question goes through a tool-calling loop, so the same query retrieves different chunks on different days — and your eval set has quietly stopped meaning anything.

Common confusions (wrong answers)

Grading Your RAG With a Golden Set the Model Wrote

The Quickstart Is Not a Product

Paying Twice for the Same Corpus

Grading Your RAG With a Golden Set the Model Wrote

Your eval fixture is the raw output of a question generator, no human ever read it, and every threshold passes. Which one is it?

Show answer

Grading Your RAG With a Golden Set the Model Wrote — you're doing this when your eval fixture is the raw output of a question generator, no human ever read it, and every threshold passes.

Common confusions (wrong answers)

The Quickstart Is Not a Product

Paying Twice for the Same Corpus

Tuning Chunk Size Against Generation Quality

Llamaindex Architecture

10 cards
Documents and Nodes: the only data model

Retrieval is pulling the right *document* but the wrong *span* — or your metadata is polluting the embedding it was supposed to help. Which layer is it?

Show answer

Documents and Nodes: the only data model — cut this seam when retrieval is pulling the right *document* but the wrong *span* — or your metadata is polluting the embedding it was supposed to help.

Common confusions (wrong answers)

The StorageContext: where an index actually lives

Indexes: a build strategy, not a data structure

Retrievers: the narrowest useful interface

The StorageContext: where an index actually lives

You need persistence, multi-tenancy, or a real vector DB — and `persist()` to a local folder has stopped being an answer. Which layer is it?

Show answer

The StorageContext: where an index actually lives — cut this seam when you need persistence, multi-tenancy, or a real vector DB — and `persist()` to a local folder has stopped being an answer.

Common confusions (wrong answers)

Indexes: a build strategy, not a data structure

Retrievers: the narrowest useful interface

Node postprocessors: the interception seam

Indexes: a build strategy, not a data structure

The question type doesn't match the index type — summarize-the-corpus against a top-k vector index, or find-one-fact against a summary index. Which layer is it?

Show answer

Indexes: a build strategy, not a data structure — cut this seam when the question type doesn't match the index type — summarize-the-corpus against a top-k vector index, or find-one-fact against a summary index.

Common confusions (wrong answers)

Retrievers: the narrowest useful interface

Node postprocessors: the interception seam

Response synthesizers: how N chunks become one answer

Retrievers: the narrowest useful interface

You need retrieval logic the built-ins don't have — fusion, custom scoring, a hand-rolled hybrid — and you'd rather not fork a query engine to get it. Which layer is it?

Show answer

Retrievers: the narrowest useful interface — cut this seam when you need retrieval logic the built-ins don't have — fusion, custom scoring, a hand-rolled hybrid — and you'd rather not fork a query engine to get it.

Common confusions (wrong answers)

Node postprocessors: the interception seam

Response synthesizers: how N chunks become one answer

Query engines, chat engines, agents

Node postprocessors: the interception seam

Retrieval is *fine* but the top-k is noisy: you want to rerank, threshold, dedupe, or expand a chunk into its neighbours before the LLM sees it. Which layer is it?

Show answer

Node postprocessors: the interception seam — cut this seam when retrieval is *fine* but the top-k is noisy: you want to rerank, threshold, dedupe, or expand a chunk into its neighbours before the LLM sees it.

Common confusions (wrong answers)

Response synthesizers: how N chunks become one answer

Query engines, chat engines, agents

Settings: the global injection container

Response synthesizers: how N chunks become one answer

The answer ignores evidence that you can see in `source_nodes`, or your LLM bill scales linearly with `similarity_top_k`. Which layer is it?

Show answer

Response synthesizers: how N chunks become one answer — cut this seam when the answer ignores evidence that you can see in `source_nodes`, or your LLM bill scales linearly with `similarity_top_k`.

Common confusions (wrong answers)

Query engines, chat engines, agents

Settings: the global injection container

Workflows: the runtime underneath the agents

Query engines, chat engines, agents

You're picking the top-level abstraction and need to know what each one buys — and what it costs in latency and non-determinism. Which layer is it?

Show answer

Query engines, chat engines, agents — cut this seam when you're picking the top-level abstraction and need to know what each one buys — and what it costs in latency and non-determinism.

Common confusions (wrong answers)

Settings: the global injection container

Workflows: the runtime underneath the agents

Instrumentation: the dispatcher and the span tree

Settings: the global injection container

Something is calling OpenAI that you never told to call OpenAI — or a component's config is being silently overridden. Which layer is it?

Show answer

Settings: the global injection container — cut this seam when something is calling OpenAI that you never told to call OpenAI — or a component's config is being silently overridden.

Common confusions (wrong answers)

Workflows: the runtime underneath the agents

Instrumentation: the dispatcher and the span tree

Documents and Nodes: the only data model

Workflows: the runtime underneath the agents

The control flow is genuinely yours — branches, loops, human approval, parallel fan-out — and a query engine is the wrong shape for it. Which layer is it?

Show answer

Workflows: the runtime underneath the agents — cut this seam when the control flow is genuinely yours — branches, loops, human approval, parallel fan-out — and a query engine is the wrong shape for it.

Common confusions (wrong answers)

Instrumentation: the dispatcher and the span tree

Documents and Nodes: the only data model

The StorageContext: where an index actually lives

Instrumentation: the dispatcher and the span tree

You cannot answer "why did it retrieve *that*" from production, and printing `source_nodes` has stopped scaling. Which layer is it?

Show answer

Instrumentation: the dispatcher and the span tree — cut this seam when you cannot answer "why did it retrieve *that*" from production, and printing `source_nodes` has stopped scaling.

Common confusions (wrong answers)

Documents and Nodes: the only data model

The StorageContext: where an index actually lives

Indexes: a build strategy, not a data structure

Llamaindex Patterns

10 cards
The Baseline: VectorStoreIndex + Query Engine

You want a corpus queryable in an afternoon — and a baseline number every later retrieval change has to beat. Which pattern do you reach for?

Show answer

The Baseline: VectorStoreIndex + Query Engine — reach for it when you want a corpus queryable in an afternoon — and a baseline number every later retrieval change has to beat.

Common confusions (wrong answers)

Ingestion Pipeline: Caching, Dedup, Incremental Sync

Chunking & Node Parsing

Metadata Filtering & Auto-Retrieval

Ingestion Pipeline: Caching, Dedup, Incremental Sync

The same corpus gets ingested more than once and re-runs need to cost near-zero: content-hash caching, docstore-backed upserts, incremental sync. Which pattern do you reach for?

Show answer

Ingestion Pipeline: Caching, Dedup, Incremental Sync — reach for it when the same corpus gets ingested more than once and re-runs need to cost near-zero: content-hash caching, docstore-backed upserts, incremental sync.

Common confusions (wrong answers)

Chunking & Node Parsing

Metadata Filtering & Auto-Retrieval

Hybrid Search + Reranking

Chunking & Node Parsing

Retrieval quality is bad and the embeddings aren't the problem — the unit of text you indexed is. Which pattern do you reach for?

Show answer

Chunking & Node Parsing — reach for it when retrieval quality is bad and the embeddings aren't the problem — the unit of text you indexed is.

Common confusions (wrong answers)

Metadata Filtering & Auto-Retrieval

Hybrid Search + Reranking

Query Transformations: HyDE, Multi-Step, Sub-Question

Metadata Filtering & Auto-Retrieval

Your corpus is partitioned by something the embedding can't see — tenant, year, service, doc type — and similarity keeps dragging in the wrong slice. Which pattern do you reach for?

Show answer

Metadata Filtering & Auto-Retrieval — reach for it when your corpus is partitioned by something the embedding can't see — tenant, year, service, doc type — and similarity keeps dragging in the wrong slice.

Common confusions (wrong answers)

Hybrid Search + Reranking

Query Transformations: HyDE, Multi-Step, Sub-Question

Routing: Picking the Right Index

Hybrid Search + Reranking

Embeddings alone miss exact terms — IDs, error codes, product names — and you can afford one extra scoring pass to buy precision back. Which pattern do you reach for?

Show answer

Hybrid Search + Reranking — reach for it when embeddings alone miss exact terms — IDs, error codes, product names — and you can afford one extra scoring pass to buy precision back.

Common confusions (wrong answers)

Query Transformations: HyDE, Multi-Step, Sub-Question

Routing: Picking the Right Index

Agentic RAG: The Query Engine as a Tool

Query Transformations: HyDE, Multi-Step, Sub-Question

Retrieval fails because the question is worded wrong or asks three things at once — not because the index is bad. Which pattern do you reach for?

Show answer

Query Transformations: HyDE, Multi-Step, Sub-Question — reach for it when retrieval fails because the question is worded wrong or asks three things at once — not because the index is bad.

Common confusions (wrong answers)

Routing: Picking the Right Index

Agentic RAG: The Query Engine as a Tool

Structured Extraction Over Retrieved Context

Routing: Picking the Right Index

One corpus has to answer structurally different question types — summarize-the-whole-thing vs find-me-this-fact — and a single retriever is wrong for at least one. Which pattern do you reach for?

Show answer

Routing: Picking the Right Index — reach for it when one corpus has to answer structurally different question types — summarize-the-whole-thing vs find-me-this-fact — and a single retriever is wrong for at least one.

Common confusions (wrong answers)

Agentic RAG: The Query Engine as a Tool

Structured Extraction Over Retrieved Context

Evaluation & Observability: The Gate

Agentic RAG: The Query Engine as a Tool

One retrieval pass isn't enough — the question spans several corpora, or needs a follow-up query the user never wrote. Which pattern do you reach for?

Show answer

Agentic RAG: The Query Engine as a Tool — reach for it when one retrieval pass isn't enough — the question spans several corpora, or needs a follow-up query the user never wrote.

Common confusions (wrong answers)

Structured Extraction Over Retrieved Context

Evaluation & Observability: The Gate

The Baseline: VectorStoreIndex + Query Engine

Structured Extraction Over Retrieved Context

The consumer of your retrieval step is code, not a human — you need typed records out of retrieved prose, with validation as the reliability contract. Which pattern do you reach for?

Show answer

Structured Extraction Over Retrieved Context — reach for it when the consumer of your retrieval step is code, not a human — you need typed records out of retrieved prose, with validation as the reliability contract.

Common confusions (wrong answers)

Evaluation & Observability: The Gate

The Baseline: VectorStoreIndex + Query Engine

Ingestion Pipeline: Caching, Dedup, Incremental Sync

Evaluation & Observability: The Gate

You need to change a retriever, prompt, or model and know — before you ship — whether you made the system better or just different. Which pattern do you reach for?

Show answer

Evaluation & Observability: The Gate — reach for it when you need to change a retriever, prompt, or model and know — before you ship — whether you made the system better or just different.

Common confusions (wrong answers)

The Baseline: VectorStoreIndex + Query Engine

Ingestion Pipeline: Caching, Dedup, Incremental Sync

Chunking & Node Parsing

Outreach

16 cards
suppression_gate

What does the suppression_gate node do in the email outreach graph?

Show answer

suppression_gate is a node that runs after lookup_contact and before check_stop_conditions; it checks the suppression_list table by SHA-256 email hash and domain, and on a hit writes an audit row and sets skip_reason to short-circuit the graph to END, blocking the send.

Memory hook The suppression_gate hashes each email and slams shut if the digital fingerprint matches the do-not-contact list.

Common confusions (wrong answers)

check_stop_conditions checks the suppression list by SHA-256 hash to block unsolicited emails.

decide_cadence enforces the do-not-contact list by setting a cadence gap of 2 days.

select_sequence emits a structured plan and also checks the suppression list for efficiency.

check_stop_conditions

What does the check_stop_conditions node do in the email outreach graph?

Show answer

It inspects the contact's current thread state using status values like bounced, complained, followup_status stopped, and reply classification, and terminates the run with a specific machine-readable reason when a stop condition applies, serving as a separate guard from the permanent suppression gate.

Memory hook A bouncer checks for "bounced" and "complained" flags on a clipboard, then stops the run cold.

Common confusions (wrong answers)

It checks the recipient email against a central do-not-contact suppression list by SHA-256 hash and domain, setting a skip_reason if there is a hit.

It determines an adaptive cadence gap for scheduling the next outreach based on engagement signal and days since last send, returning a days_gap and next_touch_at.

It extracts a personalized hook from the recipient's post text to use in the initial email body, falling back to a default if none is found.

decide_cadence

What does the decide_cadence node do in the email outreach graph?

Show answer

Decide_cadence is a graph node that uses a DeepSeek LLM to determine the optimal days_gap (clamped between 2 and 14 days) based on engagement signals like opened, no_response, or first_touch, and runs after check_stop_conditions but before select_template.

Memory hook Like a traffic light adjusting to driver speed, decide_cadence shortens wait days for opens and lengthens them for no response.

Common confusions (wrong answers)

It checks whether a contact is on a suppression list and blocks the send if so.

It selects the email template and draft content based on the contact's vertical.

It removes personally identifiable information from the LLM prompts for security compliance.

select_sequence

What does the `select_sequence` function do in the email outreach graph?

Show answer

It is a pure lookup that returns a structured plan (sequence_id and touches list) for a given vertical and optional sub-niche, or None for unknown verticals as a graceful fallback.

Memory hook If the vertical is unknown, select_sequence gives back a blank page instead of crashing.

Common confusions (wrong answers)

It runs after the suppression gate and before the stop conditions check to block suppressed contacts.

It uses an LLM call to generate the sequence plan based on the contact's history.

It selects the email template based on the vertical and sub-niche to use for drafting.

draft_step

What does the draft_step node do in the email outreach graph?

Show answer

It generates per-step email copy by applying a vertical-specific step directive from VERTICAL_SEQUENCE_DEFS, falling back to the generic draft node logic when company_vertical is absent or sequence_step is None or 0, and it runs after extract_hook and before build_outreach_evidence.

Memory hook draft_step follows the extracted hook to write each sequence touch from the vertical's step script.

Common confusions (wrong answers)

It selects the appropriate vertical sequence definition and touch angles for the outreach.

It extracts a hook from the recipient's context to personalize the email.

It converts the final email body into HTML for rendering.

VERTICAL_SEQUENCE_DEFS

What does VERTICAL_SEQUENCE_DEFS do?

Show answer

It maps vertical slugs to default sequence definitions, serving as the fallback when no sub-niche-specific entry exists, and is referenced by get_sequence_def and get_step_directive to retrieve the vertical-level sequence plan or step directive.

Memory hook Think of VERTICAL_SEQUENCE_DEFS as the backup drawer of outreach blueprints for each industry, used when no custom plan exists.

Common confusions (wrong answers)

It maps sub-niche slugs to tailored sequence definitions, overriding the vertical-level defaults when a sub-niche is specified.

It is a function that returns the per-step copy directive for a given vertical and step, falling back to the generic draft node if no vertical match exists.

It is the list of touch-angle descriptors for a sequence plan, generated by build_sequence_touches from the sequence definition.

SUB_NICHE_SEQUENCE_DEFS

What does the data structure SUB_NICHE_SEQUENCE_DEFS do?

Show answer

SUB_NICHE_SEQUENCE_DEFS is a nested dictionary that maps vertical names to sub-niche names to sequence definitions, providing tailored outreach copy for specific sub-niches, falling back to vertical-level definitions when sub-niche is missing or None.

Memory hook Imagine a two-level filing cabinet: each vertical drawer holds sub-niche folders; if a sub-folder is missing, use the drawer’s master file.

Common confusions (wrong answers)

A dictionary that stores the default sequence definitions for each vertical, used when no sub-niche is specified.

A list of email templates for each step of the outreach sequence, keyed by vertical and sub-niche.

A function that selects the appropriate sequence definition based on vertical and sub-niche, returning None if not found.

sequence_id

What does 'sequence_id' represent in the email outreach graph?

Show answer

Sequence_id is the unique identifier for a vertical-level or sub-niche sequence definition returned by select_sequence; it is logged alongside the touch count for observability and stored in selected_sequence so the approval layer can inspect the plan before any draft is generated.

Memory hook Sequence_id tags the outreach blueprint like a flight number, logged before any email takes off.

Common confusions (wrong answers)

The sequence_id is the number of touches in a sequence plan returned by select_sequence.

The sequence_id is the name of the company vertical (e.g., 'legal-pi-demand') that the sequence is tailored for.

The sequence_id is a placeholder inserted by the LLM when the sender's name is missing from the resume context.

touch_angles

What does the 'touch_angles' key contain in a sequence definition in the email outreach graph?

Show answer

A list of angle descriptions for each step in a sequence, converted by build_sequence_touches into a structured [{step, angle}] list for the sequence plan.

Memory hook Each touch_angle is a pre-planned approach for one email step, like a photographer's angle per shot.

Common confusions (wrong answers)

A list of day intervals between emails in the sequence, controlling cadence.

A list of full email templates (subject and body) for each step.

A unique identifier that maps the sequence to a specific vertical or sub-niche.

build_sequence_touches

What does the function build_sequence_touches do?

Show answer

It converts a sequence definition's touch_angles list into the structured [{step, angle}] list required by the spec.

Memory hook Build_sequence_touches melts raw angles into a tidy step-and-angle chain for the sequence plan.

Common confusions (wrong answers)

It performs a pure lookup to return a sequence plan for a known vertical, returning None for unknown verticals.

It is a LangGraph node that writes the full sequence plan into state, making it deterministic with no LLM call.

It is applied to inbound post_text or recipient context to guard against prompt-injection before the LLM sees it.

cadence_days

What does the `cadence_days` attribute represent in the sequence definitions (e.g., `VERTICAL_SEQUENCE_DEFS`)?

Show answer

It is a list of integers, with the same length as the `steps` array, that specifies the minimum number of days between each sequential step (with the first element always 0).

Memory hook Cadence days are the numbered gaps between sequence steps, like days on a calendar between follow-ups.

Common confusions (wrong answers)

It specifies the maximum number of days allowed between any two follow-up emails in the sequence.

It indicates the total duration in days that the entire outreach sequence should span.

It defines the number of retry attempts before the sequence moves to the fallback step.

fallback_step

What does the fallback_step field do in a vertical or sub-niche sequence definition?

Show answer

fallback_step specifies the step index to use when the requested step exceeds the length of the steps list, clamping out-of-range steps to a designated fallback step.

Memory hook When your sequence runs past its last step, fallback_step catches it like a safety net returning to the finale.

Common confusions (wrong answers)

fallback_step sets the minimum number of days between consecutive emails in the sequence.

fallback_step defines the short angle label for each touch point in the sequence.

fallback_step determines the initial step index for the first email in the sequence.

wrap_untrusted

What does the function wrap_untrusted do in the email outreach system?

Show answer

wrap_untrusted fences attacker-influenceable text with a label to neutralize it and prevent it from steering the draft.

Memory hook Like a quarantine sticker, wrap_untrusted seals suspicious text to keep it from infecting the draft.

Common confusions (wrong answers)

It formats the email body with proper line breaks and paragraph spacing.

It audits each personalized claim in the email body for grounding in evidence.

It resolves the sender's name from resume_context or environment variables.

LLM_KILL_SWITCH

What does the LLM_KILL_SWITCH environment variable do?

Show answer

LLM_KILL_SWITCH is an environment variable that, when set to a truthy value, short-circuits the faithfulness_check node by returning a faithfulness_score of 1.0 and the unmodified body without an LLM call, and also causes the make_llm() function to raise an LlmDisabledError for every LLM path in the system.

Memory hook Flick the kill switch to skip the LLM judge and keep every claim untouched.

Common confusions (wrong answers)

LLM_KILL_SWITCH is a safety mechanism that suppresses any personalized claims in the email body to prevent hallucinations.

LLM_KILL_SWITCH is an environment variable that disables the entire email graph, preventing any email from being drafted or sent.

LLM_KILL_SWITCH is a configuration flag that forces all emails to be sent immediately without any approval step.

skip_reason

What does the 'skip_reason' field in EmailOutreachState do?

Show answer

skip_reason is a state field that, when set to a non‑None value, causes the conditional edge function _route_after_stop_check to return 'skip' and short‑circuit the graph to END, preventing further LLM work.

Memory hook skip_reason flips the 'stop' switch, diverting the pipeline straight to END before any AI work.

Common confusions (wrong answers)

skip_reason is a node that writes an audit row to the suppression_audit table when a suppressed email is detected.

skip_reason is set by the select_template node when no product-driven template is available for outreach.

skip_reason is a list of status values (e.g., bounced, unsubscribed, stopped) that the system checks before sending any email.

plan-approval gate

What is the function of the plan-approval gate in the email outreach pipeline?

Show answer

It is an interrupt-based gate in pipeline_graph.outreach_queue that requires human approval before the outreach graph runs, and the graph is executed only after approval and never sends emails.

Memory hook A human guard pulls a lever at the plan-approval gate, halting the outreach graph until they say go.

Common confusions (wrong answers)

It checks whether the recipient is on a do-not-contact suppression list before drafting any email.

It determines the optimal number of days to wait before the next outreach based on engagement signals.

It selects the sequence steps and touch angles for the current vertical's outreach plan.

Sql

39 cards
CREATE TABLE

What is the function of the CREATE TABLE command in PostgreSQL?

Show answer

CREATE TABLE creates an initially empty table in the current database, automatically creates a composite type for its row type, and allows constraints to be defined as column constraints or table constraints, with every column constraint expressible as a table constraint.

Memory hook Picture an empty box labeled "table" that instantly grows a ghostly row-shaped stamp inside.

Common confusions (wrong answers)

CREATE TABLE creates a table that is immediately populated with data from a subquery and does not create any composite type.

CREATE TABLE automatically creates a primary key constraint on the first column of the table.

CREATE TABLE requires all columns to have a default value specified and does not support table constraints.

INTEGER

What does the INTEGER numeric type (and related smallint, bigint) in PostgreSQL do?

Show answer

It stores whole numbers (no fractional parts) using two, four, or eight bytes respectively, and an error occurs if a value outside its allowed range is stored.

Memory hook An integer is a whole-number brick - try to cram a giant one into a tiny 2-byte box and it shatters with an error.

Common confusions (wrong answers)

It stores numbers with fractional parts, like 3.14, using variable precision.

It is the only integer type available in PostgreSQL.

It can store values of any size without producing an error.

PRIMARY KEY

What does the PRIMARY KEY constraint do in PostgreSQL?

Show answer

It specifies that a column or columns can contain only unique, nonnull values, and adding it automatically creates a unique btree index.

Memory hook A barcode that never blanks or repeats—that's a primary key.

Common confusions (wrong answers)

It guarantees that every row has a unique value and allows null values.

It ensures that values in a column or group of columns must exist in another table's primary key.

It creates a GiST index automatically and is used for temporal keys with range types.

VARCHAR

What is VARCHAR according to the PostgreSQL documentation?

Show answer

VARCHAR is an alias for character varying; when used with a length specifier n, n must be between 1 and 10,485,760, and without a specifier it accepts strings of any length.

Memory hook VARCHAR(n) is a bouncer at a club who lets in at most 10,485,760 characters and rejects the rest.

Common confusions (wrong answers)

VARCHAR is an alias for the text type, which stores strings of any length.

VARCHAR without a length specifier is equivalent to character(1), storing exactly one character.

VARCHAR(n) will always store exactly n characters by padding with spaces.

NOT NULL

What does the NOT NULL constraint mean for a column in PostgreSQL?

Show answer

The column is not allowed to contain null values.

Memory hook A bouncer named NOT NULL blocks any row without a value from entering the column.

Common confusions (wrong answers)

The column is allowed to contain null values.

The column must contain unique values.

The column must have a default value.

REFERENCES

What does the REFERENCES clause do in a PostgreSQL foreign key constraint?

Show answer

It specifies the referenced table and columns that values in the referencing columns must match, with an optional match type.

Memory hook When you add a foreign key, REFERENCES is the address that tells the database which house (table and column) your key must match.

Common confusions (wrong answers)

It grants the REFERENCES privilege on a table.

It defines a unique constraint on the referenced columns.

It ensures that all values in the referencing column must be non-null.

SELECT

What is the SELECT output list in SQL?

Show answer

It specifies expressions that form the output rows, can include expressions, column references, or * to select all columns, and output column names can be used in ORDER BY and GROUP BY but not in WHERE or HAVING.

Memory hook SELECT can grab columns by name, asterisk, or expression, but its nicknames only work in ORDER BY and GROUP BY, not WHERE or HAVING.

Common confusions (wrong answers)

It is used to filter rows from a table based on conditions.

It is used to combine rows from two or more tables based on a related column.

It specifies the tables from which data is retrieved.

AS

What is the rule for using the AS keyword in PostgreSQL SELECT statements?

Show answer

PostgreSQL requires the AS keyword when the output column alias matches any keyword, reserved or not, and recommends using AS or double-quoting to avoid conflicts with future keywords.

Memory hook Think of AS as a mandatory guard when your column alias is a keyword, like locking a door marked "SELECT."

Common confusions (wrong answers)

AS is always optional in PostgreSQL SELECT lists.

AS is never required in PostgreSQL; you can use a comma instead.

AS is used only to rename tables in FROM clauses.

CASE

In PostgreSQL, what does the CASE expression do?

Show answer

It evaluates conditions in order and returns the result for the first true condition; if none are true, it returns the ELSE result or null.

Memory hook A detective opens a CASE and reads each suspect’s name (WHEN) in order, arresting the first match.

Common confusions (wrong answers)

It compares an initial expression to each WHEN value and returns the result for the first match.

It returns the result of the last true condition in the list.

It raises an error if no WHEN condition is true and no ELSE is provided.

WHEN

What does the WHEN clause do in the general form of a CASE expression?

Show answer

A WHEN condition is a boolean expression; if it evaluates to true, the corresponding THEN result becomes the CASE value and the remainder of the CASE expression is not processed, and the CASE expression does not evaluate subexpressions that are not needed to determine the result.

Memory hook WHEN is a guard at a door: if its boolean check passes, the matching result enters and the rest of the corridor stays dark.

Common confusions (wrong answers)

In a CASE expression, every WHEN condition is evaluated, and the result is the combination of all THEN results that are true.

WHEN acts like COALESCE, returning the first non-null value from the list of conditions.

WHEN is used only in the simple CASE form to compare an expression to a constant value, and all WHEN conditions must be true for the result to be returned.

AVG

What does the `avg` aggregate function compute in PostgreSQL?

Show answer

The `avg` aggregate function computes the average (arithmetic mean) of all the non-null input values.

Memory hook Imagine stacking a pile of numbers, then AVG smooths them into a single flat mean.

Common confusions (wrong answers)

Computes the sum of all non-null input values.

Counts the number of non-null input values.

Returns the median of all input values.

THEN

What does the THEN keyword do in a PostgreSQL CASE expression?

Show answer

In a CASE expression, THEN specifies the result value to return when the preceding WHEN condition is true.

Memory hook Think of a lazy librarian: WHEN the book is requested, THEN they grab it from the shelf, but only if someone actually asks.

Common confusions (wrong answers)

It evaluates the condition that determines which branch to return.

It provides a default result if none of the WHEN conditions are true.

It ensures all WHEN clauses are evaluated before selecting a result.

ELSE

What is the purpose of the ELSE clause in a SQL CASE expression?

Show answer

In a CASE expression, if no WHEN condition is true, the ELSE clause’s result is returned; if ELSE is omitted and no condition matches, the result is null.

Memory hook When every WHEN door is locked, ELSE is the spare key that opens the result.

Common confusions (wrong answers)

ELSE always returns its result even when a WHEN condition matches.

ELSE is mandatory in a CASE expression; omitting it causes a syntax error.

ELSE is evaluated before any WHEN conditions to determine a default value.

END

What does the END keyword do in a PostgreSQL CASE expression?

Show answer

END marks the end of a CASE conditional expression.

Memory hook Imagine a CASE box of conditions; the END keyword snaps its lid shut.

Common confusions (wrong answers)

END defines the default result when no condition is true.

END is used to close a COALESCE function call.

END terminates a subquery in a row constructor.

FROM

What does the FROM clause do in a SELECT query?

Show answer

The FROM clause specifies the source table(s) for a SELECT query, deriving a virtual table by cross-joining multiple references or including descendant tables unless ONLY is used.

Memory hook FROM blends multiple tables into one virtual table, mixing them together like a cross-join.

Common confusions (wrong answers)

The FROM clause filters rows based on a condition after the table is derived.

The FROM clause orders the result set based on one or more columns.

The FROM clause groups rows that have the same values in specified columns.

JOIN

What is a JOIN in PostgreSQL?

Show answer

In PostgreSQL, a JOIN is used in the FROM clause to combine two tables based on a join condition, with INNER being the default join type.

Memory hook Picture two tables merging like puzzle pieces; JOIN snaps them in the FROM clause, defaulting to inner fit.

Common confusions (wrong answers)

JOIN is used in the WHERE clause to filter rows from a table.

JOIN always uses LEFT OUTER as the default join type.

JOIN combines tables using the UNION operator.

INNER JOIN

What does an INNER JOIN do in PostgreSQL?

Show answer

According to PostgreSQL, an INNER JOIN produces a row for each pair of rows from two tables that satisfies the join condition, and it is the default join type (INNER is the default).

Memory hook Imagine two puzzle pieces; only matching pairs snap together in an inner join.

Common confusions (wrong answers)

It produces a Cartesian product of all rows from both tables regardless of any condition.

It returns all rows from the left table and matching rows from the right table, with NULLs for non-matching rows.

It returns only rows that do not satisfy the join condition, excluding any matches.

LEFT JOIN

What does a LEFT OUTER JOIN return?

Show answer

It returns all rows from the left-hand table, and for each left row with no matching right row, a joined row is added with null values in the right-hand columns.

Memory hook Left table keeps all rows; missing right matches are filled with nulls like empty chairs.

Common confusions (wrong answers)

It returns only the rows that have matching values in both tables.

It returns all rows from the right-hand table, plus unmatched left rows with nulls.

It returns all rows from both tables, with nulls for missing matches on either side.

WHERE

What does the WHERE clause do in a SQL query?

Show answer

The WHERE clause eliminates rows that do not satisfy its condition.

Memory hook WHERE acts like a bouncer, tossing out rows that fail the condition before GROUP BY starts grouping.

Common confusions (wrong answers)

The WHERE clause groups rows based on a condition.

The WHERE clause sorts the result set based on a condition.

The WHERE clause joins two tables based on a condition.

HAVING

What does the HAVING clause do in a SQL query?

Show answer

HAVING eliminates group rows that do not satisfy the condition, filtering group rows created by GROUP BY after aggregation.

Memory hook HAVING is the bouncer checking IDs after groups are seated, tossing out any whole table that fails.

Common confusions (wrong answers)

HAVING filters individual rows before the GROUP BY clause is applied.

HAVING groups rows that have the same values in specified columns.

HAVING computes a single value for each group, such as sum or count.

COUNT

What does the COUNT function do in PostgreSQL?

Show answer

The provided context does not contain any information about the COUNT function.

Memory hook count(*) sweeps every row into the tally like a net catching all fish.

Common confusions (wrong answers)

It counts the number of distinct values in a column.

It returns the first non-null value in a column.

It calculates the average of a numeric column.

DISTINCT

What does the DISTINCT clause do in PostgreSQL?

Show answer

The DISTINCT clause eliminates duplicate rows from the result set, and it is the default behavior for UNION, INTERSECT, and EXCEPT (unless ALL is specified).

Memory hook Picture a bouncer at a party removing every duplicate guest so each person appears only once.

Common confusions (wrong answers)

It keeps all duplicate rows in the result.

It selects only the first row of each group of rows with equal values in specified columns.

It sorts the result rows in ascending or descending order.

OVER

What does the OVER clause do in a window function call?

Show answer

The OVER clause determines exactly how the rows of the query are split up for processing by the window function, with PARTITION BY dividing the rows into partitions that share the same values of the PARTITION BY expression(s).

Memory hook OVER is the lens that separates rows into matching groups for the window function to process.

Common confusions (wrong answers)

The OVER clause groups selected rows into a single output row, similar to an aggregate function without a window.

The OVER clause specifies a filter condition that removes rows from the window function's input.

The OVER clause orders the entire query result set as if it were a top-level ORDER BY clause.

PARTITION BY

What does the PARTITION BY clause do within a window function's OVER clause?

Show answer

PARTITION BY divides rows into groups (partitions) based on specified expressions, and without it all rows form a single partition.

Memory hook Imagine sorting a deck of cards into piles by suit — PARTITION BY groups rows with matching values.

Common confusions (wrong answers)

It determines the order of rows within each partition for processing.

It specifies the set of rows (the window frame) relative to the current row, such as all rows from the start to the current row.

It groups rows into single output rows and computes aggregates for each group, similar to GROUP BY.

BETWEEN

What does the BETWEEN predicate do in PostgreSQL?

Show answer

It performs a range test that includes the endpoint values, equivalent to a >= x AND a <= y.

Memory hook Picture a fence between points x and y; you can stand on both endpoints because BETWEEN includes them.

Common confusions (wrong answers)

It performs a range test that excludes the endpoint values, equivalent to a > x AND a < y.

It is used to match patterns using regular expressions.

It checks whether a value is NULL.

NULL

What does the NULL value represent in PostgreSQL, and how is equality comparison handled?

Show answer

NULL represents an unknown value, and standard comparisons like = with NULL yield null, not true or false, so IS NULL and IS NOT NULL operators are used to test for nullness.

Memory hook Picture a blank question mark: asking "Is ? equal to ?" also returns a question mark, not a yes or no.

Common confusions (wrong answers)

NULL represents a zero or empty string, and comparisons with NULL always return false.

NULL is equivalent to false in boolean expressions, so = NULL returns false.

NULL is equal to another NULL, so you can use = NULL to test for null values.

EXPLAIN

What does the EXPLAIN command do in PostgreSQL?

Show answer

It shows the query plan for a given query, and when used with the ANALYZE option it executes the query and displays the true row counts and run time per node along with the planner's estimates.

Memory hook To see the query's roadmap, EXPLAIN draws the plan tree before the journey.

Common confusions (wrong answers)

It returns the actual result rows of the query along with the plan node cost estimates.

It modifies the query plan to improve performance, such as by disabling sequential scans.

It provides only the planner's cost estimates without any actual execution data.

NUMERIC

What does the PostgreSQL NUMERIC type do?

Show answer

The NUMERIC type stores exact decimal numbers with user-specified precision and scale, performing exact addition, subtraction, and multiplication but slower than integer or floating-point types.

Memory hook Precise accountant NUMERIC counts every cent exactly but takes longer than fast, loose float counters.

Common confusions (wrong answers)

Stores approximate numeric values with fast calculations and is ideal for scientific computations.

Stores only whole numbers (no fractional part) and is the most space-efficient choice.

Automatically generates unique integer values for primary keys without manual insertion.

ON

What does the ON clause do in a SQL query?

Show answer

The ON clause takes a Boolean value expression, and a pair of rows from the two tables match if that expression evaluates to true.

Memory hook Like a master key, ON opens the join door only when the Boolean expression unlocks a pair of matching rows.

Common confusions (wrong answers)

The ANALYZE option runs the query and displays actual execution statistics.

The BUFFERS option shows the count of buffers hit, read, dirtied, and written.

A subplan is a subquery that is evaluated once per execution and its results are reused.

GROUP BY

What is the purpose of the GROUP BY clause in PostgreSQL?

Show answer

It groups rows with equal values in specified columns into a single summary row per group, allowing aggregate functions to compute values over each group.

Memory hook Group your socks by color; each color pile becomes one row, and you count socks per pile.

Common confusions (wrong answers)

It filters rows based on a condition after grouping has occurred.

It sorts the result set in ascending or descending order.

It removes duplicate rows from the result set.

ORDER BY

What does the ORDER BY clause do in a PostgreSQL query?

Show answer

It sorts the result rows according to the specified expression(s), with ascending order as the default and null values sorting as if larger than any non‑null value (NULLS LAST for ASC, NULLS FIRST for DESC) unless overridden.

Memory hook ORDER BY sorts results smallest first by default, floating nulls like huge balloons to the very end (ASC).

Common confusions (wrong answers)

It filters rows based on a condition before sorting.

It groups rows that have the same values in specified columns into summary rows.

It limits the number of rows returned after sorting.

CAST

What does a CAST expression do in PostgreSQL?

Show answer

A CAST expression succeeds only if a suitable type conversion operation has been defined, and explicit casting can usually be omitted when there is no ambiguity about the required type, though automatic casting is applied only for casts marked 'OK to apply implicitly.'

Memory hook A CAST is like a pre-approved plug adapter—it only works if the right adapter type is defined.

Common confusions (wrong answers)

A CAST expression always converts any value to the target type without error.

Explicit CAST is always required when converting between data types.

Automatic casting is applied for all type conversions.

DECIMAL

What does the DECIMAL type in PostgreSQL do?

Show answer

DECIMAL is the numeric type in PostgreSQL for exact, arbitrary-precision decimal numbers with declared precision and scale, and automatic rounding if the input scale exceeds the declared scale.

Memory hook Imagine a DECIMAL column as a scale that automatically rounds extra pennies to match its declared decimal places.

Common confusions (wrong answers)

DECIMAL is an array constructor that builds an array from a subquery returning a single column.

DECIMAL is a row constructor that creates a composite value from the ROW keyword.

DECIMAL is an aggregate expression that computes a single value from a set of rows.

WITH

What is the purpose of the WITH keyword in PostgreSQL?

Show answer

WITH introduces a Common Table Expression (CTE) that defines a temporary named result set available only within the enclosing query, and it can optionally use the RECURSIVE modifier to enable recursive queries.

Memory hook Think of WITH as a Post-it note table that vanishes after you finish reading the big query.

Common confusions (wrong answers)

WITH creates a permanent view that is stored in the database schema and persists across sessions.

WITH is used to combine multiple SELECT results into a single result set using UNION operations.

WITH defines a subquery that must return exactly one row and one column, acting as a scalar subquery.

INTERVAL

How does PostgreSQL internally store an INTERVAL value and apply it when added to a timestamp?

Show answer

PostgreSQL stores intervals as three separate integral fields (months, days, and microseconds) and adds them sequentially: months first, then days, then microseconds.

Memory hook Months advance the date first, days nudge it next, microseconds add exactly last—interval’s three-step order.

Common confusions (wrong answers)

PostgreSQL stores intervals as a single floating-point number of seconds and adds them all at once.

PostgreSQL stores intervals as years, months, days, hours, minutes, and seconds separately, and adds them in random order.

PostgreSQL stores intervals as a text string and parses it each time it is used.

NOW

What does the PostgreSQL function now() return?

Show answer

It returns the start time of the current transaction, equivalent to CURRENT_TIMESTAMP and transaction_timestamp().

Memory hook Picture a transaction as a bubble; NOW stamps the entire bubble with the same clock tick.

Common confusions (wrong answers)

It returns the actual current time that can change within a single SQL statement.

It returns the start time of the current statement, which may differ from the transaction start time.

It returns the time when the table was created if used in a DEFAULT clause.

<=

What does the <= (less-than-or-equal) operator do in PostgreSQL?

Show answer

The less-than-or-equal operator (<=) is a binary comparison operator that returns boolean type, yields null when either input is null, and is used in the BETWEEN predicate as part of the condition a >= x AND a <= y, working for any data type that supports comparison.

Memory hook A slice of cake cut at the line: you get that piece or a smaller one, never more.

Common confusions (wrong answers)

It is a binary operator that returns null only when both inputs are null.

It is a pattern matching operator used with LIKE and SIMILAR TO.

It is a conditional expression similar to CASE that evaluates to true or false.

=

What does the equality operator (=) do in PostgreSQL?

Show answer

In PostgreSQL, the equality operator (=) returns null when either input is null, and performs standard equality comparison for non-null inputs.

Memory hook When either input is null, PostgreSQL's equals sign returns null, like a foggy window that hides the answer.

Common confusions (wrong answers)

It returns false when either input is null.

It returns true when both inputs are null.

It raises an error when comparing null values.

<

What does the less-than operator (<) do in PostgreSQL?

Show answer

It is a binary operator that returns a boolean true/false and yields null when either input is null.

Memory hook A hungry alligator opens its mouth left for less, but if one side is null, it shrugs and returns null instead of true or false.

Common confusions (wrong answers)

It extracts a substring matching a pattern from a string.

It returns a selected result based on a boolean condition.

It constructs an array value from a subquery.