Understand events, detector evidence, and the policy that decides what happens next.
LoopGuard separates what happened from what the application should do about it.
A repeated call is evidence. Stopping the run is a policy decision.For the broader agent cycle, start with AI agents and loops.
For the difference between a runtime decision and an evaluation, see
tests, traces, and evals.
The tracer stores ordered events. A tool call and its returned result are separate
events, so three tool calls can produce six recorded events.An event describes one observation: which node acted, what it did, its normalized
signature, and any attached details. For example, a search call might produce a
tool:search(query=pricing) signature, followed by result:no results.Live callbacks record tool starts, tool results, and tool errors. They do not record
every token, thought, or arbitrary graph node.
Detectors inspect the new event and the trace so far. A signal describes a
finding, such as a repeated tool call, unchanged output, or a permanent failure.
It includes a score and the evidence behind the finding.Consider these two runs:
search -> no resultssearch -> no resultssearch -> no results
Both repeat an action. The first returns new information; the second doesn’t.
LoopGuard compares recorded output signatures and uses simple text heuristics.
It does not prove whether the agent has achieved a business goal.
A decision combines signals into an action, a risk score, and reasons.
The default policy can produce:
Action
Current behavior
continue
Keep running.
warn
Record evidence worth inspecting.
replan
Record a recommendation to change approach.
pause
Record a recommendation to pause for review.
stop
Request interruption through the active integration.
REPLAN and PAUSE do not rewrite the plan or suspend execution. Your application
must act on those recommendations. Observe-only mode also records STOP without
raising an interrupt.
With the default policy, exact repetition alone produces a warning. Repetition or
an action cycle combined with no-progress evidence can reach STOP. Repeated
permanent failures, repeated closed handoff cycles, and exceeded budgets can also
reach STOP.The monitor retains recent signals. When new evidence fires, the policy considers
up to the last 12 signals. An event with no new signal gets a continue decision;
an earlier STOP still makes the run’s interruption flag true.
The callback handler raises LoopGuardInterrupt on STOP when interruption is
enabled. The surrounding framework must let that exception propagate.The stream wrapper checks the monitor after a streamed update and stops consuming
the stream at STOP. This does not undo completed tool calls or cancel external
work that a tool has already started.Saved-trace analysis replays the entire export. It reports where STOP would have
occurred without rerunning or interrupting the original agent.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"LoopGuard","description":"Detect stuck AI agents without treating every retry as a loop.","colors":{"primary":"#0369A1","light":"#38BDF8","dark":"#0284C7"},"navbar":{"links":[{"href":"https://github.com/mahimathacker/loopguard","label":"GitHub"},{"href":"https://pypi.org/project/loopguard-runtime/","label":"PyPI"}],"primary":{"type":"button","label":"Watch the demo","href":"https://youtu.be/i5XRrvFoPA0"}},"footer":{"socials":{"github":"https://github.com/mahimathacker/loopguard"}},"seo":{"metatags":{"robots":"index, follow","canonical":"https://loopguard.mintlify.site"}},"contextual":{"options":["chatgpt","claude","aistudio","perplexity","grok","copy","view"],"display":"header"},"markdown":{"instructions":["LoopGuard is a Python runtime guardrail SDK. Install loopguard-runtime and import loopguard. Use /getting-started and /guides/integration for application code.","Use the Concepts section for agent loops, tests versus traces versus evals, and trajectory/convergence. The convergence helper compares counts without checking success; LoopGuard events are not OpenTelemetry spans. Distinguish these general concepts from implemented SDK features.","The exact, semantic, calc, and trap UI examples illustrate Python SDK detection behavior. Read /demo/scenarios for runnable SDK examples and /guides/integration to attach callbacks or inspect streamed updates.","These docs follow the checkout. PyPI 0.2.1 lacks Gemini support, controlled demo scenarios, and additional decision display fields; check /development/status before describing release capabilities.","Repetition alone does not force STOP. REPLAN and PAUSE are recorded recommendations. Observe-only mode records decisions without raising. Follow /guides/integration for interrupt propagation.","Use the Python API, CLI, and configuration references for supported names and flags. Screenshots illustrate observed runs, not guaranteed stop counts or benchmark results."]},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"loopguard","hasAudioNarration":false,"actualSubdomain":"loopguard","customDomains":[],"gitSource":{"type":"github","owner":"mahimathacker","repo":"loopguard","deployBranch":"master","contentDirectory":"docs","isPrivate":false,"mountPath":"","label":"","_id":"6ae482d5516c780aa3740aba"},"chroma":{"latestBuiltDeploymentHistoryId":"6ae498d735628143bec433c7","collectionId":"0ce76fff-8a24-4de9-94d8-94e3386098a1","liveDeploymentHistoryId":"6ae498d735628143bec433c7","schemaVersion":"v3"},"entitlements":{},"buildId":"6ae4baf8d51aac6e910af2e5","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"default","tag":"Use LoopGuard","count":5},{"language":"default","tag":"Test and troubleshoot","count":4},{"language":"default","tag":"Concepts","count":3},{"language":"default","tag":"Start here","count":3},{"language":"default","tag":"Reference","count":3},{"language":"default","tag":"Explore the demo","count":2}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"how-it-works","slug":"/how-it-works","pageMetadata":{"title":"How LoopGuard works","description":"Understand events, detector evidence, and the policy that decides what happens next.","href":"/how-it-works"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Understand events, detector evidence, and the policy that decides what happens next.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{CodeBlock,Heading,Mermaid,Note,Table}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Mermaid)_missingMdxReference(`Mermaid`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Table)_missingMdxReference(`Table`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`LoopGuard separates what happened from what the application should do about it.\nA repeated call is evidence. Stopping the run is a policy decision.`}),`\n`,_jsxs(_components.p,{children:[`For the broader agent cycle, start with `,_jsx(_components.a,{href:`/concepts/agents-and-loops`,children:`AI agents and loops`}),`.\nFor the difference between a runtime decision and an evaluation, see\n`,_jsx(_components.a,{href:`/concepts/tests-traces-and-evals`,children:`tests, traces, and evals`}),`.`]}),`\n`,_jsx(Mermaid,{chart:`flowchart TD\n A[Agent event] --> B[Tracer]\n B --> C[Detectors]\n C --> D[Signals]\n D --> E[Policy]\n E --> F[Continue / Warn / Replan / Pause / Stop]`}),`\n`,_jsx(Heading,{level:`2`,id:`record-what-happened`,children:`Record what happened`}),`\n`,_jsx(_components.p,{children:`The tracer stores ordered events. A tool call and its returned result are separate\nevents, so three tool calls can produce six recorded events.`}),`\n`,_jsxs(_components.p,{children:[`An `,_jsx(_components.strong,{children:`event`}),` describes one observation: which node acted, what it did, its normalized\nsignature, and any attached details. For example, a search call might produce a\n`,_jsx(_components.code,{children:`tool:search(query=pricing)`}),` signature, followed by `,_jsx(_components.code,{children:`result:no results`}),`.`]}),`\n`,_jsx(_components.p,{children:`Live callbacks record tool starts, tool results, and tool errors. They do not record\nevery token, thought, or arbitrary graph node.`}),`\n`,_jsx(Heading,{level:`2`,id:`collect-evidence`,children:`Collect evidence`}),`\n`,_jsxs(_components.p,{children:[`Detectors inspect the new event and the trace so far. A `,_jsx(_components.strong,{children:`signal`}),` describes a\nfinding, such as a repeated tool call, unchanged output, or a permanent failure.\nIt includes a score and the evidence behind the finding.`]}),`\n`,_jsx(_components.p,{children:`Consider these two runs:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`poll job -> pending`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`poll job -> processing`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`poll job -> completed`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`search -> no results`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`search -> no results`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`search -> no results`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.p,{children:`Both repeat an action. The first returns new information; the second doesn’t.\nLoopGuard compares recorded output signatures and uses simple text heuristics.\nIt does not prove whether the agent has achieved a business goal.`}),`\n`,_jsx(Heading,{level:`2`,id:`make-a-decision`,children:`Make a decision`}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.strong,{children:`decision`}),` combines signals into an action, a risk score, and reasons.\nThe default policy can produce:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Action`}),_jsx(_components.th,{children:`Current behavior`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`continue`})}),_jsx(_components.td,{children:`Keep running.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`warn`})}),_jsx(_components.td,{children:`Record evidence worth inspecting.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`replan`})}),_jsx(_components.td,{children:`Record a recommendation to change approach.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`pause`})}),_jsx(_components.td,{children:`Record a recommendation to pause for review.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`stop`})}),_jsx(_components.td,{children:`Request interruption through the active integration.`})]})]})]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`REPLAN`}),` and `,_jsx(_components.code,{children:`PAUSE`}),` do not rewrite the plan or suspend execution. Your application\nmust act on those recommendations. Observe-only mode also records `,_jsx(_components.code,{children:`STOP`}),` without\nraising an interrupt.`]})}),`\n`,_jsxs(_components.p,{children:[`With the default policy, exact repetition alone produces a warning. Repetition or\nan action cycle combined with no-progress evidence can reach `,_jsx(_components.code,{children:`STOP`}),`. Repeated\npermanent failures, repeated closed handoff cycles, and exceeded budgets can also\nreach `,_jsx(_components.code,{children:`STOP`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`The monitor retains recent signals. When new evidence fires, the policy considers\nup to the last 12 signals. An event with no new signal gets a `,_jsx(_components.code,{children:`continue`}),` decision;\nan earlier `,_jsx(_components.code,{children:`STOP`}),` still makes the run’s interruption flag true.`]}),`\n`,_jsx(Heading,{level:`2`,id:`enforce-the-decision`,children:`Enforce the decision`}),`\n`,_jsxs(_components.p,{children:[`The callback handler raises `,_jsx(_components.code,{children:`LoopGuardInterrupt`}),` on `,_jsx(_components.code,{children:`STOP`}),` when interruption is\nenabled. The surrounding framework must let that exception propagate.`]}),`\n`,_jsxs(_components.p,{children:[`The stream wrapper checks the monitor after a streamed update and stops consuming\nthe stream at `,_jsx(_components.code,{children:`STOP`}),`. This does not undo completed tool calls or cancel external\nwork that a tool has already started.`]}),`\n`,_jsxs(_components.p,{children:[`Saved-trace analysis replays the entire export. It reports where `,_jsx(_components.code,{children:`STOP`}),` would have\noccurred without rerunning or interrupting the original agent.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"How LoopGuard works","description":"Understand events, detector evidence, and the policy that decides what happens next.","href":"/how-it-works"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Record what happened","slug":"record-what-happened","depth":2,"children":[]},{"title":"Collect evidence","slug":"collect-evidence","depth":2,"children":[]},{"title":"Make a decision","slug":"make-a-decision","depth":2,"children":[]},{"title":"Enforce the decision","slug":"enforce-the-decision","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"loopguard","siteName":"LoopGuard","title":"How LoopGuard works - LoopGuard","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-30T11:44:49.004Z","originalFileLocation":"how-it-works.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Understand events, detector evidence, and the policy that decides what happens next.\">\u003cmeta data-mint-head name=\"application-name\" content=\"LoopGuard\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"index, follow\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/apple-touch-icon.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/favicon-32x32.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/favicon-16x16.png?v=3\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/favicon.ico?v=3\">\u003cmeta data-mint-head property=\"og:title\" content=\"How LoopGuard works - LoopGuard\">\u003cmeta data-mint-head property=\"og:description\" content=\"Understand events, detector evidence, and the policy that decides what happens next.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"LoopGuard\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://loopguard.mintlify.site/how-it-works\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://loopguard.mintlify.app/_mintlify/api/og/v2?division=Start+here\u0026amp;title=How+LoopGuard+works\u0026amp;description=Understand+events%2C+detector+evidence%2C+and+the+policy+that+decides+what+happens+next.\u0026amp;theme=2c27cc35ccb7ce9812604402\u0026amp;signature=8921691f15beb65811ae5b914551f817bcdf0e304fb680e8c3d712dba2151fcc\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"How LoopGuard works - LoopGuard\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Understand events, detector evidence, and the policy that decides what happens next.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://loopguard.mintlify.app/_mintlify/api/og/v2?division=Start+here\u0026amp;title=How+LoopGuard+works\u0026amp;description=Understand+events%2C+detector+evidence%2C+and+the+policy+that+decides+what+happens+next.\u0026amp;theme=2c27cc35ccb7ce9812604402\u0026amp;signature=8921691f15beb65811ae5b914551f817bcdf0e304fb680e8c3d712dba2151fcc\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"LoopGuard\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0369A1\">\u003clink data-mint-head rel=\"canonical\" href=\"https://loopguard.mintlify.site/how-it-works\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/how-it-works.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://loopguard.mintlify.site/#organization\",\"name\":\"LoopGuard\",\"url\":\"https://loopguard.mintlify.site\"},{\"@type\":\"WebSite\",\"@id\":\"https://loopguard.mintlify.site#website\",\"name\":\"LoopGuard\",\"url\":\"https://loopguard.mintlify.site\",\"publisher\":{\"@id\":\"https://loopguard.mintlify.site/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://loopguard.mintlify.site/how-it-works#webpage\",\"url\":\"https://loopguard.mintlify.site/how-it-works\",\"name\":\"How LoopGuard works\",\"description\":\"Understand events, detector evidence, and the policy that decides what happens next.\",\"dateModified\":\"2026-10-30T11:44:49.004Z\",\"isPartOf\":{\"@id\":\"https://loopguard.mintlify.site#website\"},\"breadcrumb\":{\"@id\":\"https://loopguard.mintlify.site/how-it-works#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://loopguard.mintlify.site/how-it-works#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Start here\",\"item\":\"https://loopguard.mintlify.site/index\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How LoopGuard works\",\"item\":\"https://loopguard.mintlify.site/how-it-works\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://loopguard.mintlify.site/how-it-works#article\",\"headline\":\"How LoopGuard works\",\"name\":\"How LoopGuard works\",\"description\":\"Understand events, detector evidence, and the policy that decides what happens next.\",\"url\":\"https://loopguard.mintlify.site/how-it-works\",\"mainEntityOfPage\":{\"@id\":\"https://loopguard.mintlify.site/how-it-works#webpage\"},\"dateModified\":\"2026-10-30T11:44:49.004Z\",\"publisher\":{\"@id\":\"https://loopguard.mintlify.site/#organization\"},\"isPartOf\":{\"@id\":\"https://loopguard.mintlify.site#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"LoopGuard\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"LoopGuard","nav":{"global":null,"groups":[{"group":"Start here","pages":[{"title":"LoopGuard","sidebarTitle":"Introduction","href":"/index"},{"title":"Getting started","description":"See LoopGuard catch repeated empty results, then attach it to your own agent.","href":"/getting-started"},{"title":"How LoopGuard works","href":"/how-it-works"}]},{"group":"Concepts","pages":[{"title":"AI agents and loops","description":"Understand the agent decision cycle and distinguish useful repetition from a run that is stuck.","href":"/concepts/agents-and-loops"},{"title":"Tests, traces, and evals","href":"/concepts/tests-traces-and-evals"},{"title":"Agent trajectories and convergence","href":"/concepts/trajectory-and-convergence"}]},{"group":"Use LoopGuard","pages":[{"title":"Detecting stuck agents","href":"/detection"},{"title":"LangGraph and LangChain","href":"/guides/integration"},{"title":"Configure LoopGuard","href":"/guides/configuration"},{"title":"Analyze saved traces","href":"/guides/saved-traces"},{"title":"Add a trace regression check","href":"/guides/regression-checks"}]},{"group":"Explore the demo","pages":[{"title":"Demo scenarios","href":"/demo/scenarios"},{"title":"Run the demo UI","href":"/demo/running-locally"}]},{"group":"Test and troubleshoot","pages":[{"title":"Evaluation and tests","href":"/development/evaluation"},{"title":"Troubleshooting","href":"/troubleshooting"},{"title":"Project status","href":"/development/status"},{"title":"Contributing and docs maintenance","href":"/development/contributing"}]},{"group":"Reference","pages":[{"title":"Python API","href":"/reference/python"},{"title":"CLI reference","href":"/reference/cli"},{"title":"Configuration reference","href":"/reference/configuration"}]}]},"title":"How LoopGuard works - LoopGuard","buildId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","deploymentId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","dynamics":[],"chunks":[]}