[{"data":1,"prerenderedAt":1422},["ShallowReactive",2],{"blog-\u002Fblog\u002Fai-should-help-researchers-think-longer":3,"blog-posts":309},{"id":4,"title":5,"author":6,"authorAvatar":7,"authorBio":8,"authorRole":9,"body":10,"cover":293,"coverDark":294,"date":295,"description":296,"draft":297,"extension":298,"meta":299,"navigation":300,"path":301,"seo":302,"stem":303,"tags":304,"video":307,"__hash__":308},"blog\u002Fblog\u002F3.ai-should-help-researchers-think-longer.md","AI should help researchers think deeper, not think less","Meir Zana","\u002Fblog\u002Fimg\u002Fmeirz.webp","We are researchers and engineers building tools that help people reason over large bodies of literature without losing the thread back to the source.","Founder",{"type":11,"value":12,"toc":280},"minimark",[13,17,20,23,34,42,47,50,53,56,59,62,65,74,77,80,84,87,90,111,114,130,133,137,140,143,146,149,152,155,159,162,165,168,171,174,183,187,190,193,219,222,226,229,234,237,240,243,246,250,253,256,259,264,268,271,274,277],[14,15,16],"p",{},"The wrong question is whether AI can replace researchers. The useful question is whether it can help a researcher stay with a hard problem long enough to understand it.",[14,18,19],{},"That distinction sounds philosophical until you start designing the tool. Then it becomes a product requirement, which is the least romantic form a philosophy can take.",[14,21,22],{},"If the goal is replacement, the interface tends toward a button that produces an answer. If the goal is augmentation, the interface has to preserve the parts of research that make knowledge defensible: sources, uncertainty, disagreement, history, revision, and the human decision about what matters.",[14,24,25,26,33],{},"This fork is being argued well beyond research software. Harvard Business Review recently made the case that ",[27,28,32],"a",{"href":29,"rel":30},"https:\u002F\u002Fhbr.org\u002F2026\u002F04\u002Fwhy-companies-that-choose-ai-augmentation-over-automation-may-win-in-the-long-run",[31],"nofollow","companies choosing augmentation over automation may win in the long run",". I think research is where the argument is easiest to settle.",[14,35,36,37,41],{},"We built Agent Bayes around the second idea, not as a line in a manifesto after the fact but at the requirements and design level. The product is not trying to make research feel like ordering a report from a model. ",[38,39,40],"strong",{},"It is trying to help a person build a structure they can inspect, challenge, and keep improving",".",[43,44,46],"h2",{"id":45},"the-scarce-resource-is-not-text-it-is-sustained-attention","The scarce resource is not text, it is sustained attention",[14,48,49],{},"LLMs made text cheap. That is useful, but it also distorts the conversation around research tools.",[14,51,52],{},"Most serious research problems are not blocked because no one can produce another paragraph. They are blocked because the researcher has to hold too many partially connected things in mind (usually across forty Zotero tabs!) at once: which papers agree, which ones only appear to agree, which claims are strongly supported, which ones depend on definitions, where the evidence ends, and which open question is actually worth another week.",[14,54,55],{},"When you as a researcher have a deep understanding of a subject, you can see where everything fits. You can see the contradictions, the gaps, the historical context, and the methodological shortcomings. Only then you can come up with a novel interpretation, challenge a consensus, or propose a new experiment. That is the work that makes research worth doing.",[14,57,58],{},"It is not glamorous. It often happens between sessions with a tool, while walking, rereading a passage, sketching a structure, throwing away a neat idea because a source does not support it, or realizing that two literatures use the same word to mean different things.",[14,60,61],{},"AI can speed up the entry into that state. It can surface relevant passages, provide background when you enter a field, translate across terminology, identify likely gaps, and suggest angles you might have missed.",[14,63,64],{},"But it cannot do the human part for you. It cannot sit with a problem for days, months, or years. It cannot feel when a theory is too neat, recognize the social and historical texture behind an argument, or decide which distinction matters morally, methodologically, or interpretively. In fields like history, archaeology, anthropology, sociology, psychology, and political thought, that human layer is not decoration. It is part of the subject.",[14,66,67,68,73],{},"Mohamed Mannaa, recently ",[27,69,72],{"href":70,"rel":71},"https:\u002F\u002Fscholarlykitchen.sspnet.org\u002F2026\u002F04\u002F29\u002Fguest-post-when-thinking-is-outsourced-a-warning-from-a-scientist-trained-before-ai\u002F",[31],"described"," the strange loop that forms when reviewers use AI to draft their reports and authors use AI to draft the responses. The work still looks human-led, but the thinking has been quietly outsourced on both sides. His warning is the same as ours from the other direction: the danger is not that AI produces text, it is that the person stops doing the part that made the text worth producing.",[14,75,76],{},"On the other hand, the body of research literature is growing faster than any one person can read. Researchers find themselves in a situation where they must use AI to keep up, but they expose themselves to the risk of blindly trusting a model that does not understand the stakes.",[14,78,79],{},"The best research tools should therefore make the human researchers more capable, accelerating their ability to keep the evidence visible, the disagreements legible, and the gaps clear. They should make it easier to think deeper, not think less.",[43,81,83],{"id":82},"quality-beats-quantity","Quality beats quantity",[14,85,86],{},"A bad research assistant gives you more. More summaries, more bullets, more plausible claims, more citations to verify yourself later. Spitting out more text than the U.S. Treasury prints dollars.",[14,88,89],{},"A good one generates claims that are scoped by the evidence, and scored by confidence. It provides accurate provenance for every citation it uses, that you can inspect in context.",[14,91,92,93,98,99,104,105,110],{},"Recent work on citation hallucination and verification is moving in this direction. Papers such as ",[27,94,97],{"href":95,"rel":96},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2604.26835",[31],"HalluCiteChecker",", ",[27,100,103],{"href":101,"rel":102},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2511.16198",[31],"SemanticCite",", and audits of LLM citation behavior such as ",[27,106,109],{"href":107,"rel":108},"https:\u002F\u002Farxiv.org\u002Fabs\u002F2603.03299",[31],"How LLMs Cite and Why It Matters"," all circle the same practical problem: generated academic text can sound finished before it is epistemically earned.",[14,112,113],{},"That is why \"quality over quantity\" cannot be a vague preference. In a research workspace, it has to become a set of constraints:",[115,116,117,121,124,127],"ul",{},[118,119,120],"li",{},"A claim should point to the passage that supports it.",[118,122,123],{},"A citation should be inspectable, not decorative.",[118,125,126],{},"A source disagreement should remain visible.",[118,128,129],{},"A corpus limitation should be reported, not papered over.",[14,131,132],{},"These constraints slow the system down in small ways. They are worth it. Fast wrong answers are not a productivity improvement for work you will later have to defend in a seminar, peer review, policy memo, dissertation committee, or your own conscience. Reviewer 2 has never once been persuaded by the argument that the model sounded confident.",[43,134,136],{"id":135},"research-is-not-only-retrieval","Research is not only retrieval",[14,138,139],{},"The most tempting product fantasy is that research becomes a better search problem. Put the right papers in, ask the right question, retrieve the right chunks, and let the model synthesize.",[14,141,142],{},"Retrieval matters enormously. If the relevant evidence never reaches the model, the rest of the system is theater.",[14,144,145],{},"But retrieval is not enough, because research is not merely locating information. It is building an interpretation under constraint.",[14,147,148],{},"One paper states a conclusion. Another reports that conclusion as a view held by others, then spends the next ten pages attacking it. A third uses the same term in a narrower population. A fourth has a null result that matters precisely because the literature expected otherwise. A fifth is old, methodologically limited, and still historically important because everyone else is responding to it.",[14,150,151],{},"These distinctions are easy to destroy in a fluent synthesis. A model can turn a contested field into a paragraph that sounds balanced and is wrong about the shape of the debate.",[14,153,154],{},"That is why the intermediate representation matters. If everything becomes prose too early, the researcher loses the ability to see what happened to the evidence. If the system first represents claims, citations, conflicts, and gaps as separate objects, the researcher can intervene before prose smooths the edges away.",[43,156,158],{"id":157},"the-tool-should-preserve-the-researcher-not-hide-them","The tool should preserve the researcher, not hide them",[14,160,161],{},"There is a subtle failure mode in AI research products: they make the user feel productive while moving the actual reasoning somewhere opaque.",[14,163,164],{},"You ask and it answers. You ask again and it answers again. The transcript grows, but your model of the field does not necessarily become more inspectable. You may feel momentum, but the work is still trapped in a conversation that is hard to reorganize, audit, or build from. The insight you need is in there somewhere, roughly a few screens up, just past the model's third \"You are right\" apology.",[14,166,167],{},"The experience we want is different.",[14,169,170],{},"You start with a question and a library of sources. The tool helps map what the sources say into a visible structure. You expand a branch because it looks thin. You collapse another because it is a tangent. You open the exact page behind a claim and decide the wording is too strong. You split one node into two because the citation supports the method but not the conclusion. You keep two contradictory explanations next to each other because the disagreement is not a problem to fix yet. It is the thing you are trying to understand.",[14,172,173],{},"The point is not that the agent is always right. The point is that its work is legible enough for you to dwell on it, challenge it, and improve it. The point is that the researcher remains the owner of the knowledge being built.",[14,175,176,177,182],{},"This is also why editing matters. A research system that only generates is asking the user to accept or reject whole artifacts. Perla Khattar ",[27,178,181],{"href":179,"rel":180},"https:\u002F\u002Fethics.nd.edu\u002Fnews-and-events\u002Fnews\u002Fblog-post-automation-vs-augmentation-the-ethics-of-human-oversight-at-work\u002F",[31],"calls this failure symbolic approval",": when a person is asked to sign off on work they had no hand in shaping, oversight becomes a ritual and accountability quietly drains away. A research system that lets the user revise claims, move nodes, attach citations manually, verify wording against passages, and restore previous versions treats the researcher as the owner of the knowledge being built.",[43,184,186],{"id":185},"we-encoded-this-philosophy-as-requirements","We encoded this philosophy as requirements",[14,188,189],{},"Agent Bayes is built around a mindmap because a durable structure gives the researcher something to think with. The map is not a visualization slapped on top of chat. It is the primary artifact.",[14,191,192],{},"At the requirements level, that decision shaped the system:",[115,194,195,198,201,204,207,210,213,216],{},[118,196,197],{},"Every substantive claim in the mindmap needs citation provenance back to the user's library.",[118,199,200],{},"Citations are tied to passages and pages, so the researcher can inspect the evidence in context.",[118,202,203],{},"Inspecting is easy: the user can click a claim and see the relevant passage, or opens the original source document to read the surrounding text using a built-in PDF viewer.",[118,205,206],{},"Contradicting viewpoints are represented as sibling nodes rather than averaged into one consensus paragraph.",[118,208,209],{},"The system distinguishes retrievable gaps from knowledge-base limitations.",[118,211,212],{},"Agent workflows are bounded to a maximum of three refinement loops, so the tool cannot disappear into uncontrolled self-improvement while consuming time and credits.",[118,214,215],{},"The mindmap has version history, undo and redo, and provenance for agent and human edits, because research is iterative and should be easily auditable and inspectable with a built-in diff viewer.",[118,217,218],{},"The user can search the corpus directly and attach citations manually, because not every act of research should require an autonomous agent run.",[14,220,221],{},"Those are product choices, but they are also philosophical choices. They say the researcher remains responsible for interpretation, and the system should make that responsibility easier to carry.",[43,223,225],{"id":224},"using-the-tool-should-feel-like-building-not-receiving","Using the tool should feel like building, not receiving",[14,227,228],{},"From the user's side, the important moment is not \"the AI gave me an answer.\" It is \"I can now see the structure of what I know.\"",[14,230,231],{},[38,232,233],{},"A mindmap that is easily editable, allows you to reorganize nodes, create abstraction layers, and shape the information in a way that forms understanding.",[14,235,236],{},"Imagine you are entering a new field. You have a Zotero library, a rough question, and the uncomfortable sense that everyone else already knows the debate you are trying to reconstruct. You ask Agent Bayes to map the major positions in your sources.",[14,238,239],{},"The first result is not the final literature review. It is a scaffold. You see branches for methods, concepts, competing explanations, and open questions.",[14,241,242],{},"Now the work begins.",[14,244,245],{},"You tell the agent to deepen one branch, but not the whole map. You use semantic search manually for a phrase from a paper you remember. You attach a passage as evidence. You label a set of citations because they might become a section later. You reorganize the map into the shape of an argument. The tool has accelerated you, but it has not replaced your thinking.",[43,247,249],{"id":248},"the-honest-limitation-ai-does-not-understand-why-you-care","The honest limitation: AI does not understand why you care",[14,251,252],{},"There are domains where the most important thing is not only what the sources say, but why the question matters to people.",[14,254,255],{},"Historical actors had incentives, fears, social positions, blind spots, and vocabularies that do not map cleanly onto contemporary categories. Psychological and sociological claims are often entangled with measurement choices, cultural assumptions, and ethical stakes. Archaeological interpretation can turn on material context that is easy to flatten into a clean explanation. Political writing may be strategic, ironic, defensive, or constrained by the institutions around it.",[14,257,258],{},"An AI system can help retrieve, compare, translate, summarize, and challenge. It can surface patterns faster than a person working alone. But it does not have a lived relationship to the question. It does not know why a distinction feels morally loaded, why a silence in an archive matters, or why a claim that looks minor changes the interpretation of a whole field.",[14,260,261],{},[38,262,263],{},"It is a reason to design tools that keep the human close to the evidence.",[43,265,267],{"id":266},"the-future-of-research-tools-is-not-autopilot","The future of research tools is not autopilot",[14,269,270],{},"The next generation of research tooling should not be measured by how much text it can produce while the user looks on his phone.",[14,272,273],{},"It should be measured by whether it helps a serious person think with more context, more precision, and more courage. Can it help you notice that your library does not support a claim you wanted to make? Can it keep a disagreement visible instead of resolving it cosmetically? Can it make your own revisions part of the artifact rather than a private layer outside the system? Can it help you return to a problem after a week and continue from a structure that still makes sense?",[14,275,276],{},"That is the bet behind Agent Bayes.",[14,278,279],{},"AI should make it easier to enter a field, find evidence, see gaps, and generate possibilities. It should also make it harder to hide from the sources, harder to confuse fluency with understanding, and harder to forget that knowledge is something humans build over time.",{"title":281,"searchDepth":282,"depth":282,"links":283},"",4,[284,286,287,288,289,290,291,292],{"id":45,"depth":285,"text":46},2,{"id":82,"depth":285,"text":83},{"id":135,"depth":285,"text":136},{"id":157,"depth":285,"text":158},{"id":185,"depth":285,"text":186},{"id":224,"depth":285,"text":225},{"id":248,"depth":285,"text":249},{"id":266,"depth":285,"text":267},"\u002Fblog\u002Fimg\u002Fthinking-deeper-cover-light.webp","\u002Fblog\u002Fimg\u002Fthinking-deeper-cover-dark.webp","2026-07-02","The useful role for AI in research is not replacing judgment. It is helping a human stay immersed in a problem, keep evidence and disagreement visible, and build knowledge that compounds over time.",false,"md",{},true,"\u002Fblog\u002Fai-should-help-researchers-think-longer",{"title":5,"description":296},"blog\u002F3.ai-should-help-researchers-think-longer",[305,306],"Product Philosophy","Research",null,"a8DO_et_5684xApyfG2uznXk7O6T5z3B2-KESo_9-Cw",[310,490,1223],{"id":4,"title":5,"author":6,"authorAvatar":7,"authorBio":8,"authorRole":9,"body":311,"cover":293,"coverDark":294,"date":295,"description":296,"draft":297,"extension":298,"meta":487,"navigation":300,"path":301,"seo":488,"stem":303,"tags":489,"video":307,"__hash__":308},{"type":11,"value":312,"toc":477},[313,315,317,319,324,328,330,332,334,336,338,340,342,347,349,351,353,355,357,368,370,380,382,384,386,388,390,392,394,396,398,400,402,404,406,408,413,415,417,419,437,439,441,443,447,449,451,453,455,457,459,461,463,467,469,471,473,475],[14,314,16],{},[14,316,19],{},[14,318,22],{},[14,320,25,321,33],{},[27,322,32],{"href":29,"rel":323},[31],[14,325,36,326,41],{},[38,327,40],{},[43,329,46],{"id":45},[14,331,49],{},[14,333,52],{},[14,335,55],{},[14,337,58],{},[14,339,61],{},[14,341,64],{},[14,343,67,344,73],{},[27,345,72],{"href":70,"rel":346},[31],[14,348,76],{},[14,350,79],{},[43,352,83],{"id":82},[14,354,86],{},[14,356,89],{},[14,358,92,359,98,362,104,365,110],{},[27,360,97],{"href":95,"rel":361},[31],[27,363,103],{"href":101,"rel":364},[31],[27,366,109],{"href":107,"rel":367},[31],[14,369,113],{},[115,371,372,374,376,378],{},[118,373,120],{},[118,375,123],{},[118,377,126],{},[118,379,129],{},[14,381,132],{},[43,383,136],{"id":135},[14,385,139],{},[14,387,142],{},[14,389,145],{},[14,391,148],{},[14,393,151],{},[14,395,154],{},[43,397,158],{"id":157},[14,399,161],{},[14,401,164],{},[14,403,167],{},[14,405,170],{},[14,407,173],{},[14,409,176,410,182],{},[27,411,181],{"href":179,"rel":412},[31],[43,414,186],{"id":185},[14,416,189],{},[14,418,192],{},[115,420,421,423,425,427,429,431,433,435],{},[118,422,197],{},[118,424,200],{},[118,426,203],{},[118,428,206],{},[118,430,209],{},[118,432,212],{},[118,434,215],{},[118,436,218],{},[14,438,221],{},[43,440,225],{"id":224},[14,442,228],{},[14,444,445],{},[38,446,233],{},[14,448,236],{},[14,450,239],{},[14,452,242],{},[14,454,245],{},[43,456,249],{"id":248},[14,458,252],{},[14,460,255],{},[14,462,258],{},[14,464,465],{},[38,466,263],{},[43,468,267],{"id":266},[14,470,270],{},[14,472,273],{},[14,474,276],{},[14,476,279],{},{"title":281,"searchDepth":282,"depth":282,"links":478},[479,480,481,482,483,484,485,486],{"id":45,"depth":285,"text":46},{"id":82,"depth":285,"text":83},{"id":135,"depth":285,"text":136},{"id":157,"depth":285,"text":158},{"id":185,"depth":285,"text":186},{"id":224,"depth":285,"text":225},{"id":248,"depth":285,"text":249},{"id":266,"depth":285,"text":267},{},{"title":5,"description":296},[305,306],{"id":491,"title":492,"author":6,"authorAvatar":7,"authorBio":8,"authorRole":9,"body":493,"cover":1212,"coverDark":1213,"date":295,"description":1214,"draft":297,"extension":298,"meta":1215,"navigation":300,"path":1216,"seo":1217,"stem":1218,"tags":1219,"video":1221,"__hash__":1222},"blog\u002Fblog\u002F2.stopping-a-streaming-llm-agent.md","Token accounting and cancellation in durable agent workflows",{"type":11,"value":494,"toc":1203},[495,498,501,504,507,511,519,522,525,528,531,534,537,540,554,557,561,564,571,574,581,588,591,595,602,617,628,638,642,658,661,664,667,760,763,878,885,894,898,905,911,914,921,1032,1035,1038,1042,1045,1048,1054,1178,1186,1189,1193,1196,1199],[14,496,497],{},"Stopping a local coding agent and stopping a remote agent look like the same product gesture. They are not the same engineering problem.",[14,499,500],{},"In a local harness, like Codex or Claude Code, Stop can mean killing the agent loop that is currently driving the model. In a hosted agent setting, the browser stream is only a client connection receiving updates. Killing that stream does not necessarily stop the workflow, the model call, the database writes, or the credit meter behind it.",[14,502,503],{},"Once a remote workflow can both modify application state and consume billable tokens, Stop becomes a backend protocol. The system has to stop future work, preserve committed writes, update the UI to match persisted state, and finalize token usage into credits. Getting it right is a task that spans the frontend, the API server, the durable workflow engine (Temporal), and the agent worker running the workflow and its activities.",[14,505,506],{},"This post reviews how our implementation moved from treating the SSE connection as the main control surface to an orderly cancellation process for the workflow behind it.",[43,508,510],{"id":509},"disconnect-is-not-cancel","Disconnect is not cancel",[14,512,513,514,518],{},"If the agent loop runs inside the API server request context, cancellation is easier to handle. When the browser closes the connection, the server can observe the request abort, propagate an ",[515,516,517],"code",{},"AbortSignal"," into the model call, and run whatever cleanup the handler owns.",[14,520,521],{},"That pattern stops being enough when the work is meant to outlive the request, or when it is carried out in a separate worker.",[14,523,524],{},"Long-running agent workflows usually run in a durable workflow engine, such as Temporal, because the client connection is not a reliable lifetime boundary. The workflow can retry steps after transient failures, resume after a worker restart, and continue after a user refreshes the browser. That is what we needed for long research operations.",[14,526,527],{},"It also means a browser disconnect is not a cancellation signal.",[14,529,530],{},"In Agent Bayes, the research agent runs as a Temporal workflow on a separate worker pool. The browser receives progress over Server-Sent Events, but that stream is only an observer of the workflow. Refreshing the page or navigating away aborts the local SSE request, but the workflow keeps running. The client can later load persisted messages and reconnect to the running conversation stream.",[14,532,533],{},"This also lets users run agents across several mindmaps without keeping several browser streams alive until each one finishes. The workflow is the durable unit of work. The SSE connection is only the live display for whichever operation the user is watching right now.",[14,535,536],{},"That separation matters in ordinary failure cases too. A flaky Wi-Fi connection should not kill three minutes of paid work, because losing Wi-Fi should only cost patience, not credits.",[14,538,539],{},"So we have two actions that look similar in the browser and mean different things on the backend:",[115,541,542,548],{},[118,543,544,547],{},[38,545,546],{},"Disconnect"," aborts the local SSE request and leaves the Temporal workflow alone.",[118,549,550,553],{},[38,551,552],{},"Cancel"," calls the cancel endpoint for the current session, asks Temporal to cancel that workflow, and reflects any state changes that occurred before cancellation completes.",[14,555,556],{},"The rest of the implementation follows from that split: request cancellation through the API, let Temporal deliver it to the workflow execution, let a running activity observe it through heartbeats when needed, then finalize state and accounting from the workflow.",[43,558,560],{"id":559},"cancellation-has-to-settle-state-and-accounting","Cancellation has to settle state and accounting",[14,562,563],{},"Once an agent can change application state, cancellation has to be graceful for two reasons.",[14,565,566,567,570],{},"First, the frontend state has to reflect what actually happened. If the user clicks Stop while the agent is writing nodes into a mindmap, any edits committed before cancellation completes still need to appear in the UI. Otherwise, the visible map diverges from the persisted one. The cancellation path also has to converge on a durable answer status, in our case ",[515,568,569],{},"CANCELLED",", so replay, refresh, and audit history all agree.",[14,572,573],{},"Second, and perhaps more importantly, usage accounting has to finalize. If a workflow stops before accounting closes, provider usage and the product credit ledger can fall out of sync. The provider may still charge for tokens already generated, while the product never records the corresponding credit spend. Over time, that becomes a serious leak.",[14,575,576,577,580],{},"Most products that sell credits have an exchange rate between provider usage tokens and product credits. In our case, we want the user's credit history to show one meaningful row for the workflow, such as ",[515,578,579],{},"mindmap",", not ten rows that expose internal multi-agent steps, tool calls, and retries. Hopefully nobody opens a credit ledger hoping to reverse engineer your orchestration graph.",[14,582,583,584,587],{},"During a workflow, each model response records actual token usage under a shared ",[515,585,586],{},"operation_id",". The credit ledger reserves capacity at the start, then finalizes once at the end by aggregating the operation totals. The user sees one spend entry for the workflow, while the system still keeps per-step usage for internal accounting.",[14,589,590],{},"Cancellation is the case where those two ledgers are most likely to diverge. The workflow has to stop future work, preserve committed state, aggregate whatever usage has landed, charge only the actual credits consumed, and release the unused reserve.",[43,592,594],{"id":593},"temporal-cancellation-is-a-request-not-a-terminal-state","Temporal cancellation is a request, not a terminal state",[14,596,597,598,601],{},"In our API, the cancel endpoint finds the running workflow for the mindmap session and calls ",[515,599,600],{},"handle.cancel()"," on its workflow ID. That call requests cancellation from Temporal, but cancellation is cooperative. The workflow has to observe the request and stop itself. Temporal does not interrupt arbitrary code running inside a workflow or activity.",[14,603,604,605,608,609,612,613,616],{},"The workflow code handles cancellation in two places. If cancellation is observed while the workflow is not inside an activity, the workflow catches ",[515,606,607],{},"asyncio.CancelledError",", marks the run as cancelled, and re-raises. If cancellation is observed while the workflow is waiting on an activity, the workflow catches an ",[515,610,611],{},"ActivityError"," whose cause is Temporal ",[515,614,615],{},"CancelledError",", then marks the run as cancelled.",[14,618,619,620,623,624,627],{},"Both cases rely on the same ",[515,621,622],{},"finally"," block. The workflow always calls ",[515,625,626],{},"finalize_workflow",". That finalization activity records the token summary, writes the cancelled answer state, and finalizes credits in an idempotent way.",[14,629,630,631,633,634,637],{},"The SSE connection is not part of the cancellation mechanism. It keeps reading persisted agent messages and the answer row. When the answer status becomes ",[515,632,569],{},", it emits an ",[515,635,636],{},"answer_completed"," SSE event and closes.",[43,639,641],{"id":640},"temporal-cancellation-depends-on-activity-heartbeats","Temporal cancellation depends on activity heartbeats",[14,643,644,645,648,649,652,653,41],{},"Temporal cannot interrupt arbitrary code running inside a remote activity. The activity has to cooperate. For non-local activities, the Python SDK requires a ",[515,646,647],{},"heartbeat_timeout"," and calls to ",[515,650,651],{},"activity.heartbeat()"," so the worker can receive a ",[27,654,657],{"href":655,"rel":656},"https:\u002F\u002Fdocs.temporal.io\u002Fdevelop\u002Fpython\u002Fworkflows\u002Fcancellation",[31],"cancellation request",[14,659,660],{},"The heartbeat point needs to be inside the work that can run for a long time. In our case, that is the innermost loop over LangGraph stream events, not the workflow loop around whole agent roles.",[14,662,663],{},"A Researcher role may stream tokens for a while, call a retrieval tool, and then resume streaming. If the activity heartbeats only after the role completes, cancellation cannot be observed until that role has already finished.",[14,665,666],{},"We pass a callback into the stream loop and invoke it after each event has been processed:",[668,669,673],"pre",{"className":670,"code":671,"language":672,"meta":281,"style":281},"language-python shiki shiki-themes github-light github-dark","async for stream_mode, data in agent.astream(\n    {\"messages\": messages},\n    **kwargs,\n):\n    # Convert and persist token, tool-call, and tool-result events here.\n\n    if on_event:\n        await on_event({\"stream_mode\": stream_mode})\n","python",[515,674,675,697,709,718,723,730,736,745],{"__ignoreMap":281},[676,677,680,684,687,691,694],"span",{"class":678,"line":679},"line",1,[676,681,683],{"class":682},"szBVR","async",[676,685,686],{"class":682}," for",[676,688,690],{"class":689},"sVt8B"," stream_mode, data ",[676,692,693],{"class":682},"in",[676,695,696],{"class":689}," agent.astream(\n",[676,698,699,702,706],{"class":678,"line":285},[676,700,701],{"class":689},"    {",[676,703,705],{"class":704},"sZZnC","\"messages\"",[676,707,708],{"class":689},": messages},\n",[676,710,712,715],{"class":678,"line":711},3,[676,713,714],{"class":682},"    **",[676,716,717],{"class":689},"kwargs,\n",[676,719,720],{"class":678,"line":282},[676,721,722],{"class":689},"):\n",[676,724,726],{"class":678,"line":725},5,[676,727,729],{"class":728},"sJ8bj","    # Convert and persist token, tool-call, and tool-result events here.\n",[676,731,733],{"class":678,"line":732},6,[676,734,735],{"emptyLinePlaceholder":300},"\n",[676,737,739,742],{"class":678,"line":738},7,[676,740,741],{"class":682},"    if",[676,743,744],{"class":689}," on_event:\n",[676,746,748,751,754,757],{"class":678,"line":747},8,[676,749,750],{"class":682},"        await",[676,752,753],{"class":689}," on_event({",[676,755,756],{"class":704},"\"stream_mode\"",[676,758,759],{"class":689},": stream_mode})\n",[14,761,762],{},"The activity supplies the callback:",[668,764,766],{"className":670,"code":765,"language":672,"meta":281,"style":281},"_last_heartbeat = time.monotonic()\n\nasync def _on_event(event: dict) -> None:\n    nonlocal _last_heartbeat\n    now = time.monotonic()\n    if activity.is_cancelled() or (now - _last_heartbeat) >= 5.0:\n        activity.heartbeat(f\"...\")\n        _last_heartbeat = now\n",[515,767,768,779,783,810,818,827,854,868],{"__ignoreMap":281},[676,769,770,773,776],{"class":678,"line":679},[676,771,772],{"class":689},"_last_heartbeat ",[676,774,775],{"class":682},"=",[676,777,778],{"class":689}," time.monotonic()\n",[676,780,781],{"class":678,"line":285},[676,782,735],{"emptyLinePlaceholder":300},[676,784,785,787,790,794,797,801,804,807],{"class":678,"line":711},[676,786,683],{"class":682},[676,788,789],{"class":682}," def",[676,791,793],{"class":792},"sScJk"," _on_event",[676,795,796],{"class":689},"(event: ",[676,798,800],{"class":799},"sj4cs","dict",[676,802,803],{"class":689},") -> ",[676,805,806],{"class":799},"None",[676,808,809],{"class":689},":\n",[676,811,812,815],{"class":678,"line":282},[676,813,814],{"class":682},"    nonlocal",[676,816,817],{"class":689}," _last_heartbeat\n",[676,819,820,823,825],{"class":678,"line":725},[676,821,822],{"class":689},"    now ",[676,824,775],{"class":682},[676,826,778],{"class":689},[676,828,829,831,834,837,840,843,846,849,852],{"class":678,"line":732},[676,830,741],{"class":682},[676,832,833],{"class":689}," activity.is_cancelled() ",[676,835,836],{"class":682},"or",[676,838,839],{"class":689}," (now ",[676,841,842],{"class":682},"-",[676,844,845],{"class":689}," _last_heartbeat) ",[676,847,848],{"class":682},">=",[676,850,851],{"class":799}," 5.0",[676,853,809],{"class":689},[676,855,856,859,862,865],{"class":678,"line":738},[676,857,858],{"class":689},"        activity.heartbeat(",[676,860,861],{"class":682},"f",[676,863,864],{"class":704},"\"...\"",[676,866,867],{"class":689},")\n",[676,869,870,873,875],{"class":678,"line":747},[676,871,872],{"class":689},"        _last_heartbeat ",[676,874,775],{"class":682},[676,876,877],{"class":689}," now\n",[14,879,880,881,884],{},"The stream loop calls ",[515,882,883],{},"on_event"," after it processes each event. That ordering gives token usage events and tool completion events a chance to be yielded and persisted before the heartbeat delivers the cancellation request that unwinds the activity.",[14,886,887,888,893],{},"This is still cooperative cancellation. If the activity is inside one long awaited tool call, the callback cannot run until control returns. ",[27,889,892],{"href":890,"rel":891},"https:\u002F\u002Fgithub.com\u002Ftemporalio\u002Fsdk-python\u002Fissues\u002F700",[31],"A Temporal Python SDK issue about activity cancellation"," describes the same edge: cancellation is delivered through heartbeats, and Python async cancellation still needs an await point.",[43,895,897],{"id":896},"the-workflow-waits-before-finalizing-accounting","The workflow waits before finalizing accounting",[14,899,900,901,904],{},"Temporal's ",[515,902,903],{},"ActivityCancellationType"," decides what the workflow should wait for after requesting activity cancellation.",[14,906,907,910],{},[515,908,909],{},"TRY_CANCEL"," sends cancellation to the activity and lets the workflow move on promptly. That shortens the workflow's cancellation path, but it does not guarantee that the activity has finished unwinding.",[14,912,913],{},"If the workflow moves to finalization while the activity is still unwinding, finalization can read an incomplete operation total. The last model response may have generated tokens, but the usage event may not have reached the database yet. Now the credit ledger finalizes too early.",[14,915,916,917,920],{},"For an agent role activity, we use ",[515,918,919],{},"WAIT_CANCELLATION_COMPLETED",":",[668,922,924],{"className":670,"code":923,"language":672,"meta":281,"style":281},"result = await workflow.execute_activity(\n    MindmapAgentActivities.execute_role,\n    args=[...],\n    start_to_close_timeout=timedelta(...),\n    heartbeat_timeout=timedelta(...),\n    retry_policy=RetryPolicy(...),\n    cancellation_type=(\n        ActivityCancellationType.WAIT_CANCELLATION_COMPLETED\n    ),\n)\n",[515,925,926,939,944,961,976,989,1003,1013,1021,1027],{"__ignoreMap":281},[676,927,928,931,933,936],{"class":678,"line":679},[676,929,930],{"class":689},"result ",[676,932,775],{"class":682},[676,934,935],{"class":682}," await",[676,937,938],{"class":689}," workflow.execute_activity(\n",[676,940,941],{"class":678,"line":285},[676,942,943],{"class":689},"    MindmapAgentActivities.execute_role,\n",[676,945,946,950,952,955,958],{"class":678,"line":711},[676,947,949],{"class":948},"s4XuR","    args",[676,951,775],{"class":682},[676,953,954],{"class":689},"[",[676,956,957],{"class":799},"...",[676,959,960],{"class":689},"],\n",[676,962,963,966,968,971,973],{"class":678,"line":282},[676,964,965],{"class":948},"    start_to_close_timeout",[676,967,775],{"class":682},[676,969,970],{"class":689},"timedelta(",[676,972,957],{"class":799},[676,974,975],{"class":689},"),\n",[676,977,978,981,983,985,987],{"class":678,"line":725},[676,979,980],{"class":948},"    heartbeat_timeout",[676,982,775],{"class":682},[676,984,970],{"class":689},[676,986,957],{"class":799},[676,988,975],{"class":689},[676,990,991,994,996,999,1001],{"class":678,"line":732},[676,992,993],{"class":948},"    retry_policy",[676,995,775],{"class":682},[676,997,998],{"class":689},"RetryPolicy(",[676,1000,957],{"class":799},[676,1002,975],{"class":689},[676,1004,1005,1008,1010],{"class":678,"line":738},[676,1006,1007],{"class":948},"    cancellation_type",[676,1009,775],{"class":682},[676,1011,1012],{"class":689},"(\n",[676,1014,1015,1018],{"class":678,"line":747},[676,1016,1017],{"class":689},"        ActivityCancellationType.",[676,1019,1020],{"class":799},"WAIT_CANCELLATION_COMPLETED\n",[676,1022,1024],{"class":678,"line":1023},9,[676,1025,1026],{"class":689},"    ),\n",[676,1028,1030],{"class":678,"line":1029},10,[676,1031,867],{"class":689},[14,1033,1034],{},"This ensures finalization does not run until the activity has actually closed.",[14,1036,1037],{},"The implementation separates those concerns: cancellation latency (=heartbeat rate) is handled inside the activity, and accounting order is handled by the workflow.",[43,1039,1041],{"id":1040},"finalization-commits-usage-and-terminal-state","Finalization commits usage and terminal state",[14,1043,1044],{},"At the start of a run we reserve credits. Each model response records actual token usage under the operation ID. At the end, finalization charges the recorded usage and releases the unused reserve.",[14,1046,1047],{},"Finalization is not cleanup after the main work. It is the step that commits the terminal state of the operation. It must run after success, cancellation, resource deletion (think of the case where the agent is working on a task and the user deletes the mindmap, because PhDs can be dramatic sometimes), and failure, and it must be safe to retry.",[14,1049,1050,1051,1053],{},"The workflow carries terminal state into a single ",[515,1052,622],{}," block:",[668,1055,1057],{"className":670,"code":1056,"language":672,"meta":281,"style":281},"finally:\n    await workflow.execute_activity(\n        MindmapAgentActivities.finalize_workflow,\n        args=[MindmapAgentFinalizeInput(\n            ...\n        )],\n        start_to_close_timeout=timedelta(...),\n        retry_policy=RetryPolicy(\n            maximum_attempts=...,\n            backoff_coefficient=...,\n        ),\n        cancellation_type=(\n            ActivityCancellationType.WAIT_CANCELLATION_COMPLETED\n        ),\n    )\n",[515,1058,1059,1065,1072,1077,1087,1092,1097,1110,1120,1132,1143,1149,1159,1167,1172],{"__ignoreMap":281},[676,1060,1061,1063],{"class":678,"line":679},[676,1062,622],{"class":682},[676,1064,809],{"class":689},[676,1066,1067,1070],{"class":678,"line":285},[676,1068,1069],{"class":682},"    await",[676,1071,938],{"class":689},[676,1073,1074],{"class":678,"line":711},[676,1075,1076],{"class":689},"        MindmapAgentActivities.finalize_workflow,\n",[676,1078,1079,1082,1084],{"class":678,"line":282},[676,1080,1081],{"class":948},"        args",[676,1083,775],{"class":682},[676,1085,1086],{"class":689},"[MindmapAgentFinalizeInput(\n",[676,1088,1089],{"class":678,"line":725},[676,1090,1091],{"class":799},"            ...\n",[676,1093,1094],{"class":678,"line":732},[676,1095,1096],{"class":689},"        )],\n",[676,1098,1099,1102,1104,1106,1108],{"class":678,"line":738},[676,1100,1101],{"class":948},"        start_to_close_timeout",[676,1103,775],{"class":682},[676,1105,970],{"class":689},[676,1107,957],{"class":799},[676,1109,975],{"class":689},[676,1111,1112,1115,1117],{"class":678,"line":747},[676,1113,1114],{"class":948},"        retry_policy",[676,1116,775],{"class":682},[676,1118,1119],{"class":689},"RetryPolicy(\n",[676,1121,1122,1125,1127,1129],{"class":678,"line":1023},[676,1123,1124],{"class":948},"            maximum_attempts",[676,1126,775],{"class":682},[676,1128,957],{"class":799},[676,1130,1131],{"class":689},",\n",[676,1133,1134,1137,1139,1141],{"class":678,"line":1029},[676,1135,1136],{"class":948},"            backoff_coefficient",[676,1138,775],{"class":682},[676,1140,957],{"class":799},[676,1142,1131],{"class":689},[676,1144,1146],{"class":678,"line":1145},11,[676,1147,1148],{"class":689},"        ),\n",[676,1150,1152,1155,1157],{"class":678,"line":1151},12,[676,1153,1154],{"class":948},"        cancellation_type",[676,1156,775],{"class":682},[676,1158,1012],{"class":689},[676,1160,1162,1165],{"class":678,"line":1161},13,[676,1163,1164],{"class":689},"            ActivityCancellationType.",[676,1166,1020],{"class":799},[676,1168,1170],{"class":678,"line":1169},14,[676,1171,1148],{"class":689},[676,1173,1175],{"class":678,"line":1174},15,[676,1176,1177],{"class":689},"    )\n",[14,1179,1180,1182,1183,41],{},[515,1181,626],{}," records a token summary, writes the terminal answer and conversation statuses, and calls ",[515,1184,1185],{},"credits_manager.finalize(operation_id)",[14,1187,1188],{},"Credit finalization is idempotent. It takes an advisory lock on the operation ID, checks whether usage has already been recorded, aggregates all usage events for that operation, inserts one or more credit usage rows, and expires the reserve. If credit finalization fails, the activity raises and Temporal retries it.",[43,1190,1192],{"id":1191},"cancellation-is-complete-after-finalization","Cancellation is complete after finalization",[14,1194,1195],{},"The terminal state should be driven by the durable record written after finalization. By then, committed application state has been preserved, the answer has a final status, token usage has been aggregated, and the credit reserve has either been charged or released.",[14,1197,1198],{},"If you made it this far, congratulations. Your reading session can now be finalized, with zero credits charged.",[1200,1201,1202],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":281,"searchDepth":282,"depth":282,"links":1204},[1205,1206,1207,1208,1209,1210,1211],{"id":509,"depth":285,"text":510},{"id":559,"depth":285,"text":560},{"id":593,"depth":285,"text":594},{"id":640,"depth":285,"text":641},{"id":896,"depth":285,"text":897},{"id":1040,"depth":285,"text":1041},{"id":1191,"depth":285,"text":1192},"\u002Fblog\u002Fimg\u002Ftoken-accounting-cancellation-cover-light.webp","\u002Fblog\u002Fimg\u002Ftoken-accounting-cancellation-cover-dark.webp","Closing an LLM stream is not the same as stopping the work behind it. Durable agents need cancellation paths that settle application state and credit accounting before the UI declares victory.",{},"\u002Fblog\u002Fstopping-a-streaming-llm-agent",{"title":492,"description":1214},"blog\u002F2.stopping-a-streaming-llm-agent",[1220],"Engineering","\u002Fblog\u002Fvideo\u002Fcancelling.mp4","4fxFpS5IHqvF6qyeljJltvA_FAv9ZzygoT4DX5yGJEo",{"id":1224,"title":1225,"author":6,"authorAvatar":7,"authorBio":8,"authorRole":9,"body":1226,"cover":1410,"coverDark":1411,"date":1412,"description":1413,"draft":297,"extension":298,"meta":1414,"navigation":300,"path":1415,"seo":1416,"stem":1417,"tags":1418,"video":307,"__hash__":1421},"blog\u002Fblog\u002F1.introducing-agent-bayes.md","Introducing Agent Bayes: research you can actually trust",{"type":11,"value":1227,"toc":1400},[1228,1231,1234,1237,1241,1244,1250,1256,1262,1266,1269,1272,1275,1279,1282,1285,1288,1291,1294,1298,1301,1304,1307,1311,1314,1317,1320,1324,1368,1372,1375,1379,1392],[14,1229,1230],{},"Reading is the easy part. The hard part is holding fifty papers in your head at once: which ones agree, which ones contradict each other, where the evidence is thin, and exactly which sentence in which PDF backs the claim you are about to make. That work does not scale with effort. It scales with the number of sources, and at some point a literature review stops being a reading task and becomes a memory problem.",[14,1232,1233],{},"The tools meant to help have mostly made this worse. A general chatbot will happily summarize a paper it has never read, invent a citation that looks plausible, and forget the whole conversation the moment you close the tab. You get fluent text with no thread back to the evidence. For casual questions that is fine. For research, an unverifiable claim is worse than no claim at all.",[14,1235,1236],{},"We built Agent Bayes to close that gap. It is a multi-agent AI research assistant built around a shared, interactive mindmap, where every substantive claim is backed by a citation from your own library that you can open and check.",[43,1238,1240],{"id":1239},"the-problem-with-chatting-your-way-through-literature","The problem with chatting your way through literature",[14,1242,1243],{},"Most AI research tools are a chat window bolted onto a language model. That design carries three failures that matter enormously when you are doing serious work.",[14,1245,1246,1249],{},[38,1247,1248],{},"They hallucinate sources."," A model optimized to provide answers quickly will produce inaccurate citations that are not easily verifiable. It reads sources, summarizes them, and loses the nuances. You cannot tell the difference from the text alone, so you end up re-verifying everything by hand, which consumes much more time and creates frustration when you find out something is wrong after the fact.",[14,1251,1252,1255],{},[38,1253,1254],{},"They forget."," A chat thread is a transcript, not a workspace. There is no durable structure that accumulates as you work. There's no way to manage numerous follow-ups or trim what's not needed. You end up pasting context you kept in external tools and hope the model will align with where you left off.",[14,1257,1258,1261],{},[38,1259,1260],{},"They flatten disagreement."," When summarizing a contested topic, existing tools tend to average the views into a single confident paragraph. But the disagreement is the most important part of the literature. Smoothing it away hides exactly what a researcher needs to see.",[43,1263,1265],{"id":1264},"research-needs-a-structure-you-can-see","Research needs a structure you can see",[14,1267,1268],{},"Think about how a coding agent works on a real project. It does not operate on one long chat. It works against a codebase: a tree of files and modules, organized so that any part can be found, changed, and reasoned about on its own. That structure is what keeps the work tractable. Take it away, and even a capable agent loses the plot.",[14,1270,1271],{},"Research is no different. A literature review is not a flat list of summaries. It is a hierarchy: themes split into sub-themes, claims supported by evidence, positions answered by counter-positions. That structure is the actual product of synthesis. A wall of prose hides it, and a chat log destroys it.",[14,1273,1274],{},"A mindmap makes the hierarchy visible, and seeing it is what lets you act on it. You take in the shape of the argument at a glance: which branches run deep and which are thin, where two lines of evidence converge, which question still has no answer. You spot the gap because you can see the empty branch. You cut the tangent because you can watch it sprawling. You reorganize because the structure is in front of you instead of buried in paragraphs you did not ask for and in notes you maintain and have to re-read and edit constantly in order to navigate and make progress.",[43,1276,1278],{"id":1277},"where-deep-research-gets-you-halfway","Where \"deep research\" gets you halfway",[14,1280,1281],{},"\"Deep Research\" tools get closer to this than a plain chatbot. They work in two passes: a broad sweep to map out the aspects of a question, then a deeper dive into each one. That first pass is, in effect, a tree, with the aspects as branches. A mind map is simply that tree made explicit and kept around.",[14,1283,1284],{},"The trouble is what happens next. Say the broad pass surfaces eight aspects and writes a long report covering all of them. Maybe three are genuinely interesting. You have paid for the other five in tokens and reading time, and now you want to go deeper on the three that matter. What are your options?",[14,1286,1287],{},"You can ask follow-ups in the same conversation, but as the research grows, the thread becomes impossible to track. Each new answer pushes the earlier structure further out of view, and nothing accumulates into a workspace you can navigate.",[14,1289,1290],{},"Or you can run a fresh deep research pass on each of the three aspects. Now you have three more reports, each with its own structure, none of them connected to the others. You are back to stitching documents together by hand. What you end up with is a pile of notes, citations you never verified pointing at sources you never opened, and claims flattened down to \"this is roughly the spirit of this paper\" rather than what the paper actually says. That is how you get academic slop, and it is a large part of why many researchers are wary of AI in serious work.",[14,1292,1293],{},"Agent Bayes is built so that the tree is the workspace itself, not a byproduct you throw away once the report is written. It stays around so you can expand or trim any branch, reorganize, rephrase, and edit in place as your understanding changes. And it treats provenance as the point, not an afterthought, which is what the next section is about.",[43,1295,1297],{"id":1296},"a-mindmap-not-a-chat-log","A mindmap, not a chat log",[14,1299,1300],{},"Agent Bayes replaces the chat transcript with a persistent mind map. The mind map is the single source of truth for your research, and it grows and reorganizes as you work rather than scrolling away.",[14,1302,1303],{},"You bring a library of papers, uploaded as PDFs or synced from Zotero, and your instructions initiate a multi-agent pipeline that retrieves the relevant passages from your sources, synthesizes citation-backed claims, and writes them into the map as structured nodes. You direct every step, and the work stays yours.",[14,1305,1306],{},"Because the result is a structure rather than a wall of text, you can expand a branch, dive deeper, restructure an argument, reorganize nodes into chapters, or ask for a prose synthesis when you are ready to write. The mind map is something you build on, not a message you scroll past.",[43,1308,1310],{"id":1309},"every-claim-traces-back-to-a-source","Every claim traces back to a source",[14,1312,1313],{},"This is the part we care about most. When the agent writes a claim, it does not just name a paper. It pins the claim to the exact passage it drew from, down to the specific page, and gives you a link straight to that spot in the source so you can read it in context. We have put a great deal of effort into reaching this level of provenance, because a citation you cannot check is not really a citation. The system does not fabricate sources, and it will tell you when the evidence is not there rather than filling the gap with confident prose.",[14,1315,1316],{},"When sources disagree, Agent Bayes preserves the disagreement. Contradicting viewpoints become sibling nodes in the map instead of being averaged into a false consensus. You see the shape of the debate, not a flattened summary of it.",[14,1318,1319],{},"You can also work without the agent at all. Search your library semantically, in English even when the papers are in other languages, and attach citations to nodes you wrote yourself. When you do, the agent can score how well your wording matches the cited passage and suggest a rewrite where the phrasing overstates the evidence.",[43,1321,1323],{"id":1322},"what-you-get-out-of-it","What you get out of it",[115,1325,1326,1332,1338,1344,1350,1356,1362],{},[118,1327,1328,1331],{},[38,1329,1330],{},"Provenance you can check."," Every claim is pinned to the exact passage and page it came from, with a direct link to the source. No invented citations, no unverifiable summaries.",[118,1333,1334,1337],{},[38,1335,1336],{},"A structure you can see."," Your research lives as a visible hierarchy you can navigate, expand, prune, and reorganize, instead of a transcript you scroll.",[118,1339,1340,1343],{},[38,1341,1342],{},"Work that compounds."," The mindmap persists and accumulates across sessions, so your research builds on itself instead of resetting every time you start a new chat.",[118,1345,1346,1349],{},[38,1347,1348],{},"Disagreement preserved."," Competing views are kept as distinct nodes, so the structure of a debate stays visible instead of being smoothed away.",[118,1351,1352,1355],{},[38,1353,1354],{},"You stay in control."," You direct the research, approve the structure, and write your own claims. The agent retrieves and drafts, you decide.",[118,1357,1358,1361],{},[38,1359,1360],{},"A library that answers back."," Semantic search across your whole corpus, across languages, with citations you can attach yourself.",[118,1363,1364,1367],{},[38,1365,1366],{},"Fast enough to stay in flow."," Typical workflows complete in 90 to 180 seconds, streaming updates into the map as they happen.",[43,1369,1371],{"id":1370},"who-this-is-for","Who this is for",[14,1373,1374],{},"Agent Bayes is built for people who work with bodies of literature and need to stand behind what they write: master's and PhD students, postdocs, researchers, analysts, and writers.",[43,1376,1378],{"id":1377},"getting-started","Getting started",[14,1380,1381,1382,1386,1387,1391],{},"The fastest way to understand Agent Bayes is to point it at a few papers and watch a mindmap take shape. Start with the ",[27,1383,1385],{"href":1384},"\u002Fdocs\u002Fgetting-started\u002Fquickstart","Quickstart"," to get your first map going in a few minutes, or read the ",[27,1388,1390],{"href":1389},"\u002Fdocs\u002Fgetting-started\u002Fintroduction","Introduction"," for the full tour.",[14,1393,1394,1395,1399],{},"We are just getting started, and we would love your feedback. If you want access, ",[27,1396,1398],{"href":1397},"\u002F#waitlist","join the waiting list"," and tell us what you are researching.",{"title":281,"searchDepth":282,"depth":282,"links":1401},[1402,1403,1404,1405,1406,1407,1408,1409],{"id":1239,"depth":285,"text":1240},{"id":1264,"depth":285,"text":1265},{"id":1277,"depth":285,"text":1278},{"id":1296,"depth":285,"text":1297},{"id":1309,"depth":285,"text":1310},{"id":1322,"depth":285,"text":1323},{"id":1370,"depth":285,"text":1371},{"id":1377,"depth":285,"text":1378},"\u002Fhero-screenshot-light.webp","\u002Fhero-screenshot-dark.webp","2026-07-01","Why we built a multi-agent research assistant around a shared, citation-backed mindmap, and how it fixes what generic chatbots get wrong about working with literature.",{},"\u002Fblog\u002Fintroducing-agent-bayes",{"title":1225,"description":1413},"blog\u002F1.introducing-agent-bayes",[1419,1420],"Announcements","Product","6oGyUE5smgrcHWdSYCmOhW11rZdMv6VAzbZ_9yapwTs",1783019771825]