Inside Workflows: keeping agent research reproducible
Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.
September 15, 2026
Engineering, Agents, Workflows/12 minutes read
Someone has to be able to check financial research. Not “does the answer sound right”, but “show me the sentence in the transcript that supports this number”. Then, next quarter, the same analysis has to run again and produce something comparable. A credit review that changes method every time it runs is not a review.Reproducibility and transparency are therefore hard requirements. They also sit awkwardly next to the thing agents are best at. The most valuable move a research agent makes is usually the one nobody scripted. It reads a transcript, notices that the guidance language has softened, and goes looking for the 8-K on its own. That judgement is where the quality comes from, and it is the first thing you give up if you decide a run has to be predictable.That is the tension Workflows was built to remove. The user declares what to investigate and with what, the model decides how, and the system still guarantees that the run is reproducible and that every claim in it is checkable. An earlier post covers what Workflows does and how to call it. This one is about how that guarantee is built, and the three pieces of engineering that hold it up.
What reproducibility actually requires
Start with what the person checking the work needs. Nobody reviewing a credit note cares whether the analyst ran four searches or seven. They need to know five things:
it searched the same sources as last quarter
it was about the same company, not a close match
it asked the same questions
the answer came back in the same format
every claim in it points to a source you can open
That is the whole list. The path the run took is not on it. The path is easy to check, so people use it as a stand-in for reproducibility, and it is also the most expensive thing to guarantee.Fixing the path is still a fair way to get the rest of the list, and most workflow tools do it that way. You can inspect the run before it executes, it costs roughly what you expect, and it fails somewhere you can point at. Those are advantages and we took them seriously before deciding against them.The cost is the second hop. Take a question we get constantly. Has anything in this company’s disclosure changed in a way that matters? You read the latest transcript, and what you find there decides what comes next. Management softened the guidance language, so now the 8-K and the prior two calls matter. Or they did not, but an analyst pushed three times on inventory, so now the balance sheet detail and last week’s competitor commentary do. Neither of those was predictable from the question. Both are obvious once you have read the first document, and an agent that reads before it decides will follow them without being told.
Both shapes answer the question. The difference is what they can reach. A fixed path visits the sources someone drew an edge to. An agent visits whatever this company's disclosure turns out to require.
In research the hop worth taking is usually the one nobody anticipated. Whoever read the first document is in the best position to pick the second one.The second argument compounds over time. Every branch condition you hard-code is a judgement you made on the model’s behalf, fixed at the moment you made it. Every decision you leave to the model gets better on its own as the models do.
Leave a decision to the model and it gets better at that decision for free.
We have run this system through several model generations. The decisions we left to the model improved without us touching them. The ones we hard-coded are the ones we have since rewritten.So the agent works out the detail of the path. That puts the whole load on the rest of the list, because the path is no longer the thing holding a run together.
What a Workflow declares
Every item on that list can be fixed up front without fixing the path, and that is what a Workflow template does.
You set the company, the sources and the questions. The agent works out the rest, and the report comes back in the same shape.
You set out what the run needs before it starts, such as a list of companies and a date range. Next quarter you fill in the same fields with new values, instead of rewriting the instructions and hoping you phrased them the same way as last time. You give it a research plan, which lists the questions this kind of analysis has to ask. You set which sources it may search, and this is the part finance users reach for first, because the run then cannot go outside the sources you accept as evidence. You also say what a finished answer has to contain, such as a summary, a table of figures and a list of risks.What you do not declare is how many searches to run, whether to delegate, or when the work is done.The template owns the context and the procedure. The agent owns the execution. A run is fixed in the ways that make it comparable and free in the ways that make it useful.Our docs list everything a template can set, with worked examples, and there is a library of example templates covering what people build most.
The orchestrator is where the plan runs
For anything spanning several companies or several angles, one agent orchestrates and the rest do the work. The orchestrator has no research tools. It cannot search, read a filing, or run code. It has a planning tool and a delegation tool and nothing else. We got this wrong the first time. An orchestrator that can do the work will do the work, fill its context window with raw tool output, and lose track of the plan it was supposed to be running. Each delegation opens a subagent with a clean context window and one part of the plan.
Resolving the company comes first
Two runs are only comparable if “NVIDIA” means the same thing in both.In finance it frequently does not. A ticker is not a company. A company is not its listed parent, or its subsidiaries, or the entity that actually issued the debt you are analysing. Names collide, tickers get reused, companies rename and merge and spin off, and the same firm appears under four different strings across a transcript, a filing, a news wire and a broker note. An agent that resolves those strings loosely will produce an answer that looks right and is about the wrong company, and there is no way to tell from the output.
One name can mean several real companies. We resolve it once, and every tool after that takes the id rather than the name.
RavenPack has been solving this since long before any of it was agentic, and the rest of the system is built on it. We resolve the company once, against the knowledge graph, and every tool then takes that resolved id rather than the string the user typed. Search, transcripts, filings, tearsheets and the calendar all take the same id.A whole class of failure then disappears. When the agent asks for the filings of an id rather than the filings of “Volkswagen”, it cannot hand back Volkswagen Financial Services when you meant Volkswagen AG, and you can prove that the sources it returns are about the company the user asked for. You can also audit the run afterwards, because the company a claim refers to is a resolved id and not something inferred from the surrounding text.The rest of the tools follow the same idea. Our earnings calendar returns the dates, the EPS figures and the links to the transcript and filings for each one, and it already knows the company’s fiscal calendar. The agent never has to search for a document it could have been handed, or guess whether “the latest quarter” means the fiscal one. If you know something about how research in your field works, put it in the tool result.If you are building agents over financial data, build this part first. It is the cheapest piece of infrastructure described here and it has prevented more wrong answers than anything else we have shipped.
Grounding: every claim points at a source
Every sentence in a finished answer is tied to the document it came from. Because the path is not fixed, a run uses whatever sources it turned out to need, found as it went, sometimes across several agents. We cannot wire up attribution in advance. It has to be built while the run happens, which means what gets recorded is what the run actually did.
Nothing becomes a citation unless a tool in that run produced it. We build the registry while the run happens, so what the answer can cite is exactly what it retrieved.
We register every tool result as it comes back, along with the individual references inside it, such as the specific chunk of a transcript or the specific passage of a filing. As the model writes, it marks the text it is supporting and names the sources it used. We resolve those marks against what was registered during that run and turn them into citations while the answer is still streaming. A mark that does not resolve to something the run retrieved never becomes a citation.So the agent cannot cite a source it did not read. The only things it can cite are results of tools that ran. What the answer claims about its own sources is checked against what the run did, rather than taken on trust.The grounding data also stays with the conversation. A follow-up question three turns later can resolve a citation from the first turn without re-running the tool that produced it, and a user clicking a reference in an answer from last week still lands on the passage it came from.
A side effect: citations are also how the agents talk
We did not plan this next part. Once the grounding data exists while the run is going, it becomes the obvious thing to pass between agents.Most multi-agent systems pass summaries. A subagent finishes, writes a paragraph about what it found, and hands the paragraph up. That works, but it loses the sources at the point where you need them. The orchestrator now believes something it cannot attribute. Ask it to cite that claim later and it will either invent a source or re-fetch everything the subagent already read.So we pass sources instead of prose, in both directions. A subagent inherits the orchestrator’s sources with the content attached, so it can build on what has been found rather than search for it again. When the subagent returns, we attach its citations to the message the orchestrator receives. The orchestrator can then quote a passage it never read itself, in any later turn, and nobody has to trust a summary.
Python instead of more tools
The third piece follows from the same decision to leave judgement with the model.Model coding ability has improved faster than any other capability we depend on. Two years ago, giving a research agent a Python interpreter meant supervising it. Now the code is routinely better than what we would have written for the same task, and it is written in the moment, for the specific question, against the specific data.That changes what a tool is for. When an agent cannot do something, the instinct is to add a tool. But every tool is something you design, name, describe and maintain, and it takes a slot in a list that gets worse as it grows. You can also only add tools for the analyses you thought of.So our most useful tool contains no analysis at all. The agent writes Python against a library that exposes the platform, including prices, financials, company data, search, entity lookup, holdings and charting. It can pull a price series, join it to a screen result, compute the metric nobody built a tool for, and chart the output. None of that had to be anticipated, and the tool list did not grow.Handing an agent an interpreter only works if the interpreter can reach your data and nothing else. The two easier answers both fail. A shell on real infrastructure gives the model a way to send data out. An approval prompt on every action gives you a product nobody uses.
Everything the sandbox can reach passes through one layer. New libraries go above that layer, so the platform can grow without the security code changing.
This is what works for us. The code runs in a sandbox with no credentials the model can read and no general route out. It reaches our platform only through libraries we upload into the session. Every call those libraries make goes through one shared layer, which attaches a service key the model never sees, applies the requesting user’s own entitlements, and records what the code consumes. Adding a new capability means writing a self-contained package and one line in a registry. The new package gets all of that without its author touching any of it, so a data scientist who knows a dataset can put it in front of every agent without going near the security code.
Where this leaves us
Reproducibility turned out to rest on four things that are true about a run: what it was asked, who it was about, what it was allowed to look at, and what it can prove. Pin those four and you can leave the rest to the model. The rest is also the part that gets better on its own every time the models do.
About Workflows
Workflows turn a research procedure into something you can run across your whole coverage universe, with every claim tied to the document that produced it. Start with creating a template, or take one from the example templates and edit it.
Juan Luis Domínguez
AI Engineer
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Bigdata.com API developer docs","colors":{"primary":"#4CA7F9","light":"#4CA7F9","dark":"#4CA7F9"},"logo":{"light":"https://mintcdn.com/ravenpackinternational/O1z6qnY-XMCwjEFX/logo/bigdata_logo_v3c_dark.svg?fit=max\u0026auto=format\u0026n=O1z6qnY-XMCwjEFX\u0026q=85\u0026s=946489fc058b9cc72700f20c4a07234d","dark":"https://mintcdn.com/ravenpackinternational/O1z6qnY-XMCwjEFX/logo/bigdata_logo_v3c_light.svg?fit=max\u0026auto=format\u0026n=O1z6qnY-XMCwjEFX\u0026q=85\u0026s=e100148ed224aa533563ab5a82c155c6"},"favicon":"https://mintcdn.com/ravenpackinternational/oXZ2k4-F2a4nJaoe/favicon-32x32.png?fit=max\u0026auto=format\u0026n=oXZ2k4-F2a4nJaoe\u0026q=85\u0026s=287ed1df194928ab25af5ed2186e58d0","appearance":{"default":"dark"},"background":{"color":{"dark":"#121212"}},"navbar":{"links":[{"href":"https://app.bigdata.com/signup?utm_source=docs","label":"Sign Up"}],"primary":{"type":"button","label":"Developer Platform","href":"https://platform.bigdata.com/"}},"footer":{"socials":{"x":"https://x.com/bigdatadotcom","linkedin":"https://www.linkedin.com/company/bigdata","instagram":"https://www.instagram.com/bigdatadotcom"}},"seo":{"metatags":{"canonical":"https://docs.bigdata.com"}},"integrations":{"gtm":{"tagId":"GTM-PFT937B"},"mixpanel":{"projectToken":"4725ad1c5253be8eb3543aeef1a60146"}},"contextual":{"options":["download-spec"],"display":"header"},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"ravenpackinternational","hasAudioNarration":false,"actualSubdomain":"ravenpackinternational","customDomains":["docs.bigdata.com"],"gitSource":{"type":"github","owner":"ravenpack","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af74a1db6ccd6eca79dc28e","clientVersion":"0.0.4142","searchFilterCounts":[{"language":"default","tag":"API","count":135},{"language":"default","tag":"MCP","count":53},{"language":"default","tag":"Getting Started","count":41},{"language":"default","tag":"Research Service","count":34},{"language":"default","tag":"Tools","count":33},{"language":"default","tag":"Structured Data","count":33},{"language":"default","tag":"How to guides","count":31},{"language":"default","tag":"Knowledge Graph","count":30},{"language":"default","tag":"Bigdata services","count":30},{"language":"default","tag":"Cookbooks","count":29}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"@import url('./widgets/widgets.css');html{scroll-behavior:smooth}.center-container{display:flex;justify-content:center;align-items:center}.medium_size{height:200px}.hero-bg{background-image:url(\"https://mintlify.s3.us-west-1.amazonaws.com/ravenpackinternational/images/hero-bg-enhanced.jpg\"),\n url(\"https://mintlify.s3.us-west-1.amazonaws.com/ravenpackinternational/images/hero-bg.jpg\");background-size:cover;background-position:center;background-repeat:no-repeat}.hero-bg-content{color:#111!important}.hero-logo{filter:none!important}.text-playground-input{color:#171a1b!important}.dark .text-playground-input{color:#ffffff!important}.text-playground-input option{color:#171a1b!important;background-color:#ffffff!important}.dark .text-playground-input option{color:#ffffff!important;background-color:#171a1b!important}#navbar img.nav-logo{height:24px}@media (max-width: 600px){#navbar img.nav-logo{height:20px}}.author-avatar-image{width:100%;height:100%;display:block;object-fit:cover;margin:0}.dark img[src$=\"/images/logos/grok.svg\"],.dark img[src$=\"/images/logos/chatgpt.svg\"],.dark img[src$=\"/images/logos/cursor.svg\"]{filter:invert(1)}.agent-cards [data-component-part=\"card-content-container\"]{align-items:flex-start}.compact-table td,.compact-table th{min-width:0!important;padding-right:0.75rem}"},{"filePath":"widgets/widgets.css","content":""}],"page":{"pagePath":"blog/workflows/inside-workflows","slug":"/blog/workflows/inside-workflows","pageMetadata":{"title":"Inside Workflows: keeping agent research reproducible","sidebarTitle":"Inside Workflows","description":"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.","href":"/blog/workflows/inside-workflows"},"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: \"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.\"\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`,blockquote:`blockquote`,hr:`hr`,li:`li`,p:`p`,ul:`ul`,..._provideComponents(),...props.components},{Frame,Heading,OptimizedImage}=_components;if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);return _jsxs(_Fragment,{children:[_jsx(`p`,{class:`mint-text-gray-400 mint-text-base mint-mb-8`,children:`September 15, 2026`}),`\n`,_jsxs(`div`,{class:`mint-flex mint-items-center mint-gap-3 mint-mb-6`,children:[_jsx(`span`,{class:`mint-text-sm mint-font-medium text-primary`,children:`Engineering, Agents, Workflows`}),_jsx(`span`,{class:`mint-text-gray-500`,children:`/`}),_jsx(`span`,{class:`mint-text-sm mint-text-gray-400`,children:`12 minutes read`})]}),`\n`,_jsx(_components.p,{children:`Someone has to be able to check financial research. Not “does the answer sound right”, but “show me the sentence in the transcript that supports this number”. Then, next quarter, the same analysis has to run again and produce something comparable. A credit review that changes method every time it runs is not a review.`}),`\n`,_jsx(_components.p,{children:`Reproducibility and transparency are therefore hard requirements. They also sit awkwardly next to the thing agents are best at. The most valuable move a research agent makes is usually the one nobody scripted. It reads a transcript, notices that the guidance language has softened, and goes looking for the 8-K on its own. That judgement is where the quality comes from, and it is the first thing you give up if you decide a run has to be predictable.`}),`\n`,_jsxs(_components.p,{children:[`That is the tension Workflows was built to remove. The user declares what to investigate and with what, the model decides how, and the system still guarantees that the run is reproducible and that every claim in it is checkable. `,_jsx(_components.a,{href:`/blog/workflows/automate-your-research-process`,children:`An earlier post`}),` covers what Workflows does and how to call it. This one is about how that guarantee is built, and the three pieces of engineering that hold it up.`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-reproducibility-actually-requires`,children:`What reproducibility actually requires`}),`\n`,_jsx(_components.p,{children:`Start with what the person checking the work needs. Nobody reviewing a credit note cares whether the analyst ran four searches or seven. They need to know five things:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`it searched the same sources as last quarter`}),`\n`,_jsx(_components.li,{children:`it was about the same company, not a close match`}),`\n`,_jsx(_components.li,{children:`it asked the same questions`}),`\n`,_jsx(_components.li,{children:`the answer came back in the same format`}),`\n`,_jsx(_components.li,{children:`every claim in it points to a source you can open`}),`\n`]}),`\n`,_jsx(_components.p,{children:`That is the whole list. The path the run took is not on it. The path is easy to check, so people use it as a stand-in for reproducibility, and it is also the most expensive thing to guarantee.`}),`\n`,_jsx(_components.p,{children:`Fixing the path is still a fair way to get the rest of the list, and most workflow tools do it that way. You can inspect the run before it executes, it costs roughly what you expect, and it fails somewhere you can point at. Those are advantages and we took them seriously before deciding against them.`}),`\n`,_jsx(_components.p,{children:`The cost is the second hop. Take a question we get constantly. Has anything in this company’s disclosure changed in a way that matters? You read the latest transcript, and what you find there decides what comes next. Management softened the guidance language, so now the 8-K and the prior two calls matter. Or they did not, but an analyst pushed three times on inventory, so now the balance sheet detail and last week’s competitor commentary do. Neither of those was predictable from the question. Both are obvious once you have read the first document, and an agent that reads before it decides will follow them without being told.`}),`\n`,_jsx(Frame,{caption:`Both shapes answer the question. The difference is what they can reach. A fixed path visits the sources someone drew an edge to. An agent visits whatever this company's disclosure turns out to require.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/fixed-path-vs-agentic.png?fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=371843a6d600fcc75fd5f6fc8f9aaa56`,alt:`Side by side comparison. A fixed graph runs a predetermined chain of steps and never reaches a source no edge points at. An agentic workflow lets the agent reach whichever sources the question turns out to need, including the one the graph missed.`,\"data-og-width\":`1984`,width:`1984`,\"data-og-height\":`904`,height:`904`,\"data-path\":`images/blog/inside-workflows/fixed-path-vs-agentic.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/fixed-path-vs-agentic.png?w=280\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=3b5e1d3ff21370eaf5010c7d62fc2cc0 280w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/fixed-path-vs-agentic.png?w=560\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=63459a71eff188879f96db662e6828e6 560w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/fixed-path-vs-agentic.png?w=840\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=133a478f54dd1e94010c51db8a5a972a 840w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/fixed-path-vs-agentic.png?w=1100\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=bff9857b26ac6f3f3f78643815792669 1100w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/fixed-path-vs-agentic.png?w=1650\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=a796a43a8892142e87d7c1c4cc84f49a 1650w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/fixed-path-vs-agentic.png?w=2500\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=b0b9423546f174ca71ce6217317f7e51 2500w`})}),`\n`,_jsx(_components.p,{children:`In research the hop worth taking is usually the one nobody anticipated. Whoever read the first document is in the best position to pick the second one.`}),`\n`,_jsx(_components.p,{children:`The second argument compounds over time. Every branch condition you hard-code is a judgement you made on the model’s behalf, fixed at the moment you made it. Every decision you leave to the model gets better on its own as the models do.`}),`\n`,_jsxs(_components.blockquote,{children:[`\n`,_jsx(_components.p,{children:`Leave a decision to the model and it gets better at that decision for free.`}),`\n`]}),`\n`,_jsx(_components.p,{children:`We have run this system through several model generations. The decisions we left to the model improved without us touching them. The ones we hard-coded are the ones we have since rewritten.`}),`\n`,_jsx(_components.p,{children:`So the agent works out the detail of the path. That puts the whole load on the rest of the list, because the path is no longer the thing holding a run together.`}),`\n`,_jsx(Heading,{level:`2`,id:`what-a-workflow-declares`,children:`What a Workflow declares`}),`\n`,_jsx(_components.p,{children:`Every item on that list can be fixed up front without fixing the path, and that is what a Workflow template does.`}),`\n`,_jsx(Frame,{caption:`You set the company, the sources and the questions. The agent works out the rest, and the report comes back in the same shape.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/what-a-template-declares.png?fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=74fc93d02bd962409b5bec3a43c5c930`,alt:`One earnings review in three columns. On the left, the template you set: the company, the allowed sources and the three questions. In the middle, what the agent did, with the reason for each step. On the right, the report, whose sections are the same on every run.`,\"data-og-width\":`1984`,width:`1984`,\"data-og-height\":`704`,height:`704`,\"data-path\":`images/blog/inside-workflows/what-a-template-declares.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/what-a-template-declares.png?w=280\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=9db23167ca0575cc767ba28ee8931a5b 280w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/what-a-template-declares.png?w=560\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=14673aa38ff71ab30962bb354a9de58c 560w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/what-a-template-declares.png?w=840\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=2b59cfa27db82f299e73ad81e12c9261 840w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/what-a-template-declares.png?w=1100\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=cb4b529283dd975b6d238b24c320c6bb 1100w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/what-a-template-declares.png?w=1650\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=78e9f343f8ebadd44692cd7d9fef2115 1650w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/what-a-template-declares.png?w=2500\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=464edd3c38d213034e535a19e77b6862 2500w`})}),`\n`,_jsx(_components.p,{children:`You set out what the run needs before it starts, such as a list of companies and a date range. Next quarter you fill in the same fields with new values, instead of rewriting the instructions and hoping you phrased them the same way as last time. You give it a research plan, which lists the questions this kind of analysis has to ask. You set which sources it may search, and this is the part finance users reach for first, because the run then cannot go outside the sources you accept as evidence. You also say what a finished answer has to contain, such as a summary, a table of figures and a list of risks.`}),`\n`,_jsx(_components.p,{children:`What you do not declare is how many searches to run, whether to delegate, or when the work is done.`}),`\n`,_jsx(_components.p,{children:`The template owns the context and the procedure. The agent owns the execution. A run is fixed in the ways that make it comparable and free in the ways that make it useful.`}),`\n`,_jsxs(_components.p,{children:[`Our `,_jsx(_components.a,{href:`/how-to-guides/agents/workflows/creating_templates`,children:`docs`}),` list everything a template can set, with worked examples, and there is a library of `,_jsx(_components.a,{href:`/how-to-guides/agents/workflows/example_templates`,children:`example templates`}),` covering what people build most.`]}),`\n`,_jsx(Heading,{level:`3`,id:`the-orchestrator-is-where-the-plan-runs`,children:`The orchestrator is where the plan runs`}),`\n`,_jsx(_components.p,{children:`For anything spanning several companies or several angles, one agent orchestrates and the rest do the work. The orchestrator has no research tools. It cannot search, read a filing, or run code. It has a planning tool and a delegation tool and nothing else. We got this wrong the first time. An orchestrator that can do the work will do the work, fill its context window with raw tool output, and lose track of the plan it was supposed to be running. Each delegation opens a subagent with a clean context window and one part of the plan.`}),`\n`,_jsx(Heading,{level:`2`,id:`resolving-the-company-comes-first`,children:`Resolving the company comes first`}),`\n`,_jsx(_components.p,{children:`Two runs are only comparable if “NVIDIA” means the same thing in both.`}),`\n`,_jsx(_components.p,{children:`In finance it frequently does not. A ticker is not a company. A company is not its listed parent, or its subsidiaries, or the entity that actually issued the debt you are analysing. Names collide, tickers get reused, companies rename and merge and spin off, and the same firm appears under four different strings across a transcript, a filing, a news wire and a broker note. An agent that resolves those strings loosely will produce an answer that looks right and is about the wrong company, and there is no way to tell from the output.`}),`\n`,_jsx(Frame,{caption:`One name can mean several real companies. We resolve it once, and every tool after that takes the id rather than the name.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/entity-resolution.png?fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=8f0ac8755e1dcf7cc2005b499202dea2`,alt:`The name Volkswagen resolves through the knowledge graph to three real companies. The run means the listed parent, and that entity id is what every tool in the system receives.`,\"data-og-width\":`1984`,width:`1984`,\"data-og-height\":`904`,height:`904`,\"data-path\":`images/blog/inside-workflows/entity-resolution.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/entity-resolution.png?w=280\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=080de9b2e35ec9cdb04241e36addffff 280w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/entity-resolution.png?w=560\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=fdcecc4808a8f9ec13a9bc8e6fc0708e 560w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/entity-resolution.png?w=840\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=f399a7dbcff61498e03b576b25fd9bf4 840w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/entity-resolution.png?w=1100\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=6ae69bb38c8b8fda6ee208c07f3c6481 1100w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/entity-resolution.png?w=1650\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=90db6e0db4cf9824bca7fce3ddc0afef 1650w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/entity-resolution.png?w=2500\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=b6ff9c21a8253215de5d2e2561381a3c 2500w`})}),`\n`,_jsx(_components.p,{children:`RavenPack has been solving this since long before any of it was agentic, and the rest of the system is built on it. We resolve the company once, against the knowledge graph, and every tool then takes that resolved id rather than the string the user typed. Search, transcripts, filings, tearsheets and the calendar all take the same id.`}),`\n`,_jsx(_components.p,{children:`A whole class of failure then disappears. When the agent asks for the filings of an id rather than the filings of “Volkswagen”, it cannot hand back Volkswagen Financial Services when you meant Volkswagen AG, and you can prove that the sources it returns are about the company the user asked for. You can also audit the run afterwards, because the company a claim refers to is a resolved id and not something inferred from the surrounding text.`}),`\n`,_jsx(_components.p,{children:`The rest of the tools follow the same idea. Our earnings calendar returns the dates, the EPS figures and the links to the transcript and filings for each one, and it already knows the company’s fiscal calendar. The agent never has to search for a document it could have been handed, or guess whether “the latest quarter” means the fiscal one. If you know something about how research in your field works, put it in the tool result.`}),`\n`,_jsx(_components.p,{children:`If you are building agents over financial data, build this part first. It is the cheapest piece of infrastructure described here and it has prevented more wrong answers than anything else we have shipped.`}),`\n`,_jsx(Heading,{level:`2`,id:`grounding-every-claim-points-at-a-source`,children:`Grounding: every claim points at a source`}),`\n`,_jsx(_components.p,{children:`Every sentence in a finished answer is tied to the document it came from. Because the path is not fixed, a run uses whatever sources it turned out to need, found as it went, sometimes across several agents. We cannot wire up attribution in advance. It has to be built while the run happens, which means what gets recorded is what the run actually did.`}),`\n`,_jsx(Frame,{caption:`Nothing becomes a citation unless a tool in that run produced it. We build the registry while the run happens, so what the answer can cite is exactly what it retrieved.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/grounding-registry.png?fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=554c3b86aa2e06e5b200744d1ba57f62`,alt:`Tools execute and their individual references are registered as the run proceeds. When the model writes, each marked claim is checked against that registry, and the marks that match become clickable citations.`,\"data-og-width\":`1944`,width:`1944`,\"data-og-height\":`764`,height:`764`,\"data-path\":`images/blog/inside-workflows/grounding-registry.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/grounding-registry.png?w=280\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=dcb72b764726e7e10cd9f9dab6beeaac 280w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/grounding-registry.png?w=560\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=772b9993cb75bf586a8b22586c14bd13 560w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/grounding-registry.png?w=840\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=7851cf0d3de502e79cf4385cb7d0d308 840w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/grounding-registry.png?w=1100\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=1fa43f14dcdfea707618cf3f6b97c390 1100w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/grounding-registry.png?w=1650\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=11a7b7ee379c498ed2034b65d0915fcb 1650w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/grounding-registry.png?w=2500\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=ab30884c0bb4190158f0a8ab35f74e80 2500w`})}),`\n`,_jsx(_components.p,{children:`We register every tool result as it comes back, along with the individual references inside it, such as the specific chunk of a transcript or the specific passage of a filing. As the model writes, it marks the text it is supporting and names the sources it used. We resolve those marks against what was registered during that run and turn them into citations while the answer is still streaming. A mark that does not resolve to something the run retrieved never becomes a citation.`}),`\n`,_jsx(_components.p,{children:`So the agent cannot cite a source it did not read. The only things it can cite are results of tools that ran. What the answer claims about its own sources is checked against what the run did, rather than taken on trust.`}),`\n`,_jsx(_components.p,{children:`The grounding data also stays with the conversation. A follow-up question three turns later can resolve a citation from the first turn without re-running the tool that produced it, and a user clicking a reference in an answer from last week still lands on the passage it came from.`}),`\n`,_jsx(Heading,{level:`3`,id:`a-side-effect-citations-are-also-how-the-agents-talk`,children:`A side effect: citations are also how the agents talk`}),`\n`,_jsx(_components.p,{children:`We did not plan this next part. Once the grounding data exists while the run is going, it becomes the obvious thing to pass between agents.`}),`\n`,_jsx(_components.p,{children:`Most multi-agent systems pass summaries. A subagent finishes, writes a paragraph about what it found, and hands the paragraph up. That works, but it loses the sources at the point where you need them. The orchestrator now believes something it cannot attribute. Ask it to cite that claim later and it will either invent a source or re-fetch everything the subagent already read.`}),`\n`,_jsx(_components.p,{children:`So we pass sources instead of prose, in both directions. A subagent inherits the orchestrator’s sources with the content attached, so it can build on what has been found rather than search for it again. When the subagent returns, we attach its citations to the message the orchestrator receives. The orchestrator can then quote a passage it never read itself, in any later turn, and nobody has to trust a summary.`}),`\n`,_jsx(Heading,{level:`2`,id:`python-instead-of-more-tools`,children:`Python instead of more tools`}),`\n`,_jsx(_components.p,{children:`The third piece follows from the same decision to leave judgement with the model.`}),`\n`,_jsx(_components.p,{children:`Model coding ability has improved faster than any other capability we depend on. Two years ago, giving a research agent a Python interpreter meant supervising it. Now the code is routinely better than what we would have written for the same task, and it is written in the moment, for the specific question, against the specific data.`}),`\n`,_jsx(_components.p,{children:`That changes what a tool is for. When an agent cannot do something, the instinct is to add a tool. But every tool is something you design, name, describe and maintain, and it takes a slot in a list that gets worse as it grows. You can also only add tools for the analyses you thought of.`}),`\n`,_jsx(_components.p,{children:`So our most useful tool contains no analysis at all. The agent writes Python against a library that exposes the platform, including prices, financials, company data, search, entity lookup, holdings and charting. It can pull a price series, join it to a screen result, compute the metric nobody built a tool for, and chart the output. None of that had to be anticipated, and the tool list did not grow.`}),`\n`,_jsx(_components.p,{children:`Handing an agent an interpreter only works if the interpreter can reach your data and nothing else. The two easier answers both fail. A shell on real infrastructure gives the model a way to send data out. An approval prompt on every action gives you a product nobody uses.`}),`\n`,_jsx(Frame,{caption:`Everything the sandbox can reach passes through one layer. New libraries go above that layer, so the platform can grow without the security code changing.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/code-execution-sandbox.png?fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=aca2394c8facde2940ff32e35e554720`,alt:`Agent-written Python runs inside a sandbox with no general network and no readable credentials. It reaches the platform only through uploaded libraries, and every call passes through one shared access layer that holds the service key, the entitlements and the metering.`,\"data-og-width\":`1544`,width:`1544`,\"data-og-height\":`1064`,height:`1064`,\"data-path\":`images/blog/inside-workflows/code-execution-sandbox.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/code-execution-sandbox.png?w=280\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=c634ac1adb6eb845483066ca9b4a8bcf 280w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/code-execution-sandbox.png?w=560\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=462cdf43da0d1143bc8295b2d0503a97 560w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/code-execution-sandbox.png?w=840\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=3ecbdb459f34b16f85d162347d729477 840w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/code-execution-sandbox.png?w=1100\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=76efd4dc2021f5e5356df3365f63424c 1100w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/code-execution-sandbox.png?w=1650\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=16be8765961a06ce0b0df40eb407f3fb 1650w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/inside-workflows/code-execution-sandbox.png?w=2500\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=ab5cebbdeb7242eb0bf45ceaa1386a88 2500w`})}),`\n`,_jsx(_components.p,{children:`This is what works for us. The code runs in a sandbox with no credentials the model can read and no general route out. It reaches our platform only through libraries we upload into the session. Every call those libraries make goes through one shared layer, which attaches a service key the model never sees, applies the requesting user’s own entitlements, and records what the code consumes. Adding a new capability means writing a self-contained package and one line in a registry. The new package gets all of that without its author touching any of it, so a data scientist who knows a dataset can put it in front of every agent without going near the security code.`}),`\n`,_jsx(Heading,{level:`2`,id:`where-this-leaves-us`,children:`Where this leaves us`}),`\n`,_jsx(_components.p,{children:`Reproducibility turned out to rest on four things that are true about a run: what it was asked, who it was about, what it was allowed to look at, and what it can prove. Pin those four and you can leave the rest to the model. The rest is also the part that gets better on its own every time the models do.`}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`about-workflows`,children:`About Workflows`}),`\n`,_jsxs(_components.p,{children:[`Workflows turn a research procedure into something you can run across your whole coverage universe, with every claim tied to the document that produced it. Start with `,_jsx(_components.a,{href:`/how-to-guides/agents/workflows/creating_templates`,children:`creating a template`}),`, or take one from the `,_jsx(_components.a,{href:`/how-to-guides/agents/workflows/example_templates`,children:`example templates`}),` and edit it.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(`div`,{class:`mint-mt-8`,children:_jsx(`div`,{class:`mint-flex mint-flex-row mint-flex-wrap mint-gap-8 mint-items-start`,children:_jsxs(`div`,{class:`mint-flex mint-items-center mint-gap-3 mint-shrink-0`,children:[_jsx(`div`,{class:`mint-w-10 mint-h-10 mint-rounded-full mint-overflow-hidden mint-shrink-0`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/authors/juanlu_dominguez.png?fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=87e08a82e3f665e9f00f8f43b86a5c37`,alt:`Juan Luis Domínguez`,class:`author-avatar-image`,\"data-og-width\":`512`,width:`512`,\"data-og-height\":`512`,height:`512`,\"data-path\":`images/blog/authors/juanlu_dominguez.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/authors/juanlu_dominguez.png?w=280\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=05cd1586cd6d04fe3adad0aff80cf3dd 280w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/authors/juanlu_dominguez.png?w=560\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=6c4eeb306c9f4f8cf21ede84d77ba7ad 560w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/authors/juanlu_dominguez.png?w=840\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=be3402a6a5753b31fc11f8b64e14f86f 840w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/authors/juanlu_dominguez.png?w=1100\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=799f44b06c37de16445d9bca0c2db981 1100w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/authors/juanlu_dominguez.png?w=1650\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=657a005903a660075ce916b6637a970f 1650w, https://mintcdn.com/ravenpackinternational/HNhp0ovTYVm8OpWq/images/blog/authors/juanlu_dominguez.png?w=2500\u0026fit=max\u0026auto=format\u0026n=HNhp0ovTYVm8OpWq\u0026q=85\u0026s=0f27a85f157b1e00ccf1968250be504d 2500w`})}),_jsxs(`div`,{children:[_jsx(`p`,{class:`mint-text-sm mint-font-semibold mint-m-0`,children:`Juan Luis Domínguez`}),_jsx(`p`,{class:`mint-text-xs mint-text-gray-400 mint-m-0`,children:`AI Engineer`})]})]})})})]})}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":"Inside Workflows: keeping agent research reproducible","sidebarTitle":"Inside Workflows","description":"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.","href":"/blog/workflows/inside-workflows"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What reproducibility actually requires","slug":"what-reproducibility-actually-requires","depth":2,"children":[]},{"title":"What a Workflow declares","slug":"what-a-workflow-declares","depth":2,"children":[{"title":"The orchestrator is where the plan runs","slug":"the-orchestrator-is-where-the-plan-runs","depth":3,"children":[]}]},{"title":"Resolving the company comes first","slug":"resolving-the-company-comes-first","depth":2,"children":[]},{"title":"Grounding: every claim points at a source","slug":"grounding-every-claim-points-at-a-source","depth":2,"children":[{"title":"A side effect: citations are also how the agents talk","slug":"a-side-effect-citations-are-also-how-the-agents-talk","depth":3,"children":[]}]},{"title":"Python instead of more tools","slug":"python-instead-of-more-tools","depth":2,"children":[]},{"title":"Where this leaves us","slug":"where-this-leaves-us","depth":2,"children":[]},{"title":"About Workflows","slug":"about-workflows","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/ravenpackinternational/e8fac7367cdeecdc/script.js"],"dynamicCss":".mint-m-0 {\n margin: 0px\n}\n.mint-mb-6 {\n margin-bottom: 1.5rem\n}\n.mint-mb-8 {\n margin-bottom: 2rem\n}\n.mint-mt-8 {\n margin-top: 2rem\n}\n.mint-flex {\n display: flex\n}\n.mint-h-10 {\n height: 2.5rem\n}\n.mint-w-10 {\n width: 2.5rem\n}\n.mint-shrink-0 {\n flex-shrink: 0\n}\n.mint-flex-row {\n flex-direction: row\n}\n.mint-flex-wrap {\n flex-wrap: wrap\n}\n.mint-items-start {\n align-items: flex-start\n}\n.mint-items-center {\n align-items: center\n}\n.mint-gap-3 {\n gap: 0.75rem\n}\n.mint-gap-8 {\n gap: 2rem\n}\n.mint-overflow-hidden {\n overflow: hidden\n}\n.mint-rounded-full {\n border-radius: 9999px\n}\n.mint-text-base {\n font-size: 1rem;\n line-height: 1.5rem\n}\n.mint-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem\n}\n.mint-text-xs {\n font-size: 0.75rem;\n line-height: 1rem\n}\n.mint-font-medium {\n font-weight: 500\n}\n.mint-font-semibold {\n font-weight: 600\n}\n.mint-text-gray-400 {\n --tw-text-opacity: 1;\n color: rgb(156 163 175 / var(--tw-text-opacity, 1))\n}\n.mint-text-gray-500 {\n --tw-text-opacity: 1;\n color: rgb(107 114 128 / var(--tw-text-opacity, 1))\n}","subdomain":"ravenpackinternational","siteName":"Bigdata.com API developer docs","title":"Inside Workflows: keeping agent research reproducible - Bigdata.com API developer docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-09T13:06:40.765Z","originalFileLocation":"blog/workflows/inside-workflows.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=\"dark\"}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=\"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Bigdata.com API developer docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Inside Workflows: keeping agent research reproducible - Bigdata.com API developer docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Bigdata.com API developer docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.bigdata.com/blog/workflows/inside-workflows\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://ravenpackinternational.mintlify.site/_mintlify/api/og/v2?division=September+-+2026\u0026amp;title=Inside+Workflows%3A+keeping+agent+research+reproducible\u0026amp;description=Agents+are+good+at+deciding+what+to+look+at+next.+Financial+research+has+to+be+repeatable+and+checkable.+Those+sound+like+opposing+requirements%2C+and+most+of+our\u0026amp;theme=0fc28b44b457f1524ebe9144\u0026amp;signature=50236b24d2ea6c41bb7ff2a9e017009b9c7a3c80f8e912a4482b69d887bf8b80\">\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=\"Inside Workflows: keeping agent research reproducible - Bigdata.com API developer docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://ravenpackinternational.mintlify.site/_mintlify/api/og/v2?division=September+-+2026\u0026amp;title=Inside+Workflows%3A+keeping+agent+research+reproducible\u0026amp;description=Agents+are+good+at+deciding+what+to+look+at+next.+Financial+research+has+to+be+repeatable+and+checkable.+Those+sound+like+opposing+requirements%2C+and+most+of+our\u0026amp;theme=0fc28b44b457f1524ebe9144\u0026amp;signature=50236b24d2ea6c41bb7ff2a9e017009b9c7a3c80f8e912a4482b69d887bf8b80\">\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=\"/mintlify-assets/_mintlify/favicons/ravenpackinternational/0ZQJThiL-hYHaY_C/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Bigdata.com API developer docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#4CA7F9\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.bigdata.com/blog/workflows/inside-workflows\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/blog/workflows/inside-workflows.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.bigdata.com/#organization\",\"name\":\"Bigdata.com API developer docs\",\"url\":\"https://docs.bigdata.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/ravenpackinternational/O1z6qnY-XMCwjEFX/logo/bigdata_logo_v3c_dark.svg?fit=max\u0026auto=format\u0026n=O1z6qnY-XMCwjEFX\u0026q=85\u0026s=946489fc058b9cc72700f20c4a07234d\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.bigdata.com#website\",\"name\":\"Bigdata.com API developer docs\",\"url\":\"https://docs.bigdata.com\",\"publisher\":{\"@id\":\"https://docs.bigdata.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.bigdata.com/blog/workflows/inside-workflows#webpage\",\"url\":\"https://docs.bigdata.com/blog/workflows/inside-workflows\",\"name\":\"Inside Workflows: keeping agent research reproducible\",\"description\":\"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.\",\"dateModified\":\"2026-09-09T13:06:40.765Z\",\"isPartOf\":{\"@id\":\"https://docs.bigdata.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.bigdata.com/blog/workflows/inside-workflows#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.bigdata.com/blog/workflows/inside-workflows#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Bigdata.com API developer docs\",\"item\":\"https://docs.bigdata.com\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Inside Workflows: keeping agent research reproducible\",\"item\":\"https://docs.bigdata.com/blog/workflows/inside-workflows\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.bigdata.com/blog/workflows/inside-workflows#article\",\"headline\":\"Inside Workflows: keeping agent research reproducible\",\"name\":\"Inside Workflows: keeping agent research reproducible\",\"description\":\"Agents are good at deciding what to look at next. Financial research has to be repeatable and checkable. Those sound like opposing requirements, and most of our architecture comes from finding out that they are not.\",\"url\":\"https://docs.bigdata.com/blog/workflows/inside-workflows\",\"mainEntityOfPage\":{\"@id\":\"https://docs.bigdata.com/blog/workflows/inside-workflows#webpage\"},\"dateModified\":\"2026-09-09T13:06:40.765Z\",\"publisher\":{\"@id\":\"https://docs.bigdata.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.bigdata.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Bigdata.com API developer docs\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Bigdata.com API developer docs\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/blog/workflows/inside-workflows.md","siteName":"Bigdata.com API developer docs","nav":{"global":null,"tabs":[{"tab":"Getting Started","pages":[{"title":"Getting Started","href":"/getting-started/home"}]},{"tab":"How to guides","pages":[{"title":"How to guides","href":"/how-to-guides/introduction"}]},{"tab":"Cookbooks","pages":[{"title":"Cookbooks","href":"/use-cases/introduction"}]},{"tab":"MCP","pages":[{"title":"MCP","href":"/mcp-reference/introduction"}]},{"tab":"Skills","pages":[{"title":"Skills","href":"/skills-reference/introduction"}]},{"tab":"API","pages":[{"title":"API","href":"/api-rest/introduction"}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/release-notes/api_changelog"}]},{"tab":"Content Partners","pages":[{"title":"Content Partners","href":"/partner-content-upload/introduction"}]},{"tab":"FAQ","pages":[{"title":"FAQ","href":"/faq/privacy_questions"}]},{"tab":"Support","pages":[{"title":"Support","href":"/support"}]},{"tab":"Blog","pages":[{"title":"Bigdata developers blog","href":"/blog/introduction"},{"group":"November - 2026","pages":[{"title":"Inside Monitors: how a monitor decides what's new","sidebarTitle":"Inside Monitors","href":"/blog/monitors/inside-monitors"},{"title":"FinSearch-Eval: Evaluating Financial Search on Live, Billion-Document Corpora","sidebarTitle":"A Benchmark for Financial Search","href":"/blog/search/finsearch-eval"}]},{"group":"October - 2026","pages":[{"title":"From Screen to Signal: Building a Global Robotics Watchlist with the Bigdata MCP","sidebarTitle":"Global robotics watchlist","href":"/blog/mcp/global-robotics-watchlist"},{"title":"From investment theme to proprietary signal with NVIDIA Nemotron","sidebarTitle":"From Theme to Signal","description":"Turn a plain-language investment idea into a backtestable dataset using [Bigdata.com](https://bigdata.com) for portfolio-scale retrieval and NVIDIA Nemotron open models for private, high-throughput classification.","href":"/blog/research/theme-to-proprietary-signal"}]},{"group":"September - 2026","pages":[{"title":"Inside Workflows: keeping agent research reproducible","sidebarTitle":"Inside Workflows","href":"/blog/workflows/inside-workflows"}]},{"group":"August - 2026","pages":[{"title":"Baking Behavior into Weights: Fine-Tuning a Language Model for Financial Search","sidebarTitle":"Fine-Tuning for Financial Search","description":"How we turned the query-planning layer behind Bigdata.com Search Smart Mode into a fast, controlled specialist, without teaching the model facts it should retrieve.","href":"/blog/search/baking-behavior-into-weights"}]},{"group":"July - 2026","pages":[{"title":"Sentiment in Bigdata.com: The Trend and the Story","sidebarTitle":"Sentiment in Bigdata.com","href":"/blog/market-data/entity-sentiment-signals"}]},{"group":"June - 2026","pages":[{"title":"How We Rebuilt Bigdata Briefs","sidebarTitle":"How We Rebuilt Bigdata Briefs","href":"/blog/workflows/bigdata-briefs-automated-pipeline"}]},{"group":"May - 2026","pages":[{"title":"From API key to production AI research assistant - in a single afternoon","sidebarTitle":"Introducing Bigdata Widgets","href":"/blog/widgets/widgets_release"},{"title":"Quantum Computing Is Hitting Its Commercial Inflection Point","sidebarTitle":"Quantum thematic report","href":"/blog/mcp/quantum_thematic_report"},{"title":"Unifying Web Search within the Bigdata.com Search API","sidebarTitle":"Introducing Web Search","href":"/blog/search/introducing-web-search"}]},{"group":"April - 2026","pages":[{"title":"Smart Batching: plan-then-execute search for universe-scale screening","sidebarTitle":"Smart Batching for universe-scale screening","href":"/blog/search/smart-batching-universe-scale-screening"},{"title":"Turn a fresh laptop into a financial-intelligence agent you chat with on Telegram","sidebarTitle":"NemoClaw + Bigdata on Telegram","href":"/blog/nemoclaw/nemoclaw-bigdata-telegram"},{"title":"Turn Buyback Signals into Alpha with Claude, Bigdata MCP, and Skills","sidebarTitle":"Share Buyback Research","href":"/blog/search/share-buyback-financial-research"},{"title":"How to Use Your Indexed Email Archive as a Search Grounding Layer","sidebarTitle":"Fuel your Research Workflow with Email Content","href":"/blog/proprietary-content/private-newsletters-grounded-reports"},{"title":"The Workflows API: turning an analyst's research process into an API call","sidebarTitle":"The Workflows API: Automate your research process","href":"/blog/workflows/automate-your-research-process"}]},{"group":"March - 2026","pages":[{"title":"Introducing Diversified Search for AI Agents","sidebarTitle":"Diversified Search for AI Agents","href":"/blog/search/diversified-search"},{"title":"How to Automate Portfolio Research with Claude Cowork and Bigdata","sidebarTitle":"Portfolio briefs with Claude Cowork","href":"/blog/mcp/claude_cowork_with_bigdata"},{"title":"Professional-Grade Financial Reports with Claude, Bigdata MCP, and Skills","sidebarTitle":"Reports with Claude and Bigdata","href":"/blog/mcp/claude_with_bigdata"}]}]}]},"basePath":"","title":"Inside Workflows: keeping agent research reproducible - Bigdata.com API developer docs","buildId":"dpl_G2Qd45vZZ7MkBiGF9yYx8ZsbbKXX","deploymentId":"dpl_G2Qd45vZZ7MkBiGF9yYx8ZsbbKXX","dynamics":["07c022d89b","a74be98ba7"],"chunks":["Frame-DL7q6v_h.js","DynamicMarkdown-CaSwclgK.js","zoom-image-lightbox-BLUesUNd.js","lightbox-handle-r17bVUz3.js"]}