From Agent Roles to an Actual Runtime
AutoHedge's central engineering question in this chapter is not whether it has several agent names; it is where a task goes and who owns each transition. The repository describes a Director, specialist analysts, a risk role, and an execution role, but the package entrypoint exposes a much smaller call path. Tracing both views lets the reader distinguish a configured dependency from a verified state change and understand what a real task actually encounters.
The roles are contracts, not autonomous departments
AutoHedge assigns the Trading Director the broadest responsibility. Its system prompt asks it to orchestrate the trading process, conduct market analysis, develop a thesis that combines technical and fundamental considerations, collaborate with specialists, and make decisions about execution. This is a coordinator's mandate, but it is also unusually wide. The same prompt asks for the conclusion, the factors behind it, the risk assessment, and the trade parameters. Unless later stages can challenge or reject those outputs, “Director” can become a name for the entire decision rather than an owner of one well-defined transition.
The Quantitative Analysis Agent is meant to narrow that responsibility. Its prompt names moving averages, relative strength index, Bollinger Bands, mean reversion, momentum, volatility, Value-at-Risk, Expected Shortfall, Greeks, and a probability of trade success. The more specific quantitative template asks for a ticker, several scores, volatility, and support, resistance, and pivot levels. These are recognizable analytical concepts, but the source does not show a calculation engine that produces them from a data frame. The prompt expresses the kind of analysis the model should provide; it does not establish how the numbers are computed, what period they cover, or whether their denominators and units are consistent.
The Risk Manager has a different responsibility again. Its prompt asks for a recommended position size, maximum drawdown risk, market-risk exposure, correlation risk, and an overall risk score. That is an appropriate place to ask how much capital a thesis should put at risk. It is not automatically an approval boundary. A risk agent can describe a dangerous trade, recommend a small position, or produce a confident score, but another component must decide whether a proposed size is permitted given current holdings and prior orders. The repository's role name tells us what kind of judgment is intended; it does not tell us who has final authority to refuse.
The Execution Agent sits closest to an external side effect. Its prompt asks for an order type, quantity, entry price, stop loss, take profit, and time in force. These fields are more concrete than a narrative thesis, but concreteness is not validation. A quantity can be syntactically present and economically impossible. An entry price can be stale. A stop loss can be on the wrong side of a trade. A time constraint can be incompatible with the venue. The important interface question is therefore not simply whether the Execution Agent returns all six fields. It is whether a typed and policy-aware component checks those fields before any signing or submission step.
The Sentiment Agent adds another perspective. Its prompt asks for news sentiment, social sentiment, institutional commentary, themes, critical events, changes over time, trading implications, and contrarian signals. That work can enrich a thesis, but it also introduces a different evidence problem from quantitative analysis. A sentiment score depends on which documents or posts were collected, over what period, and with what selection bias. A specialist boundary is useful only if the receiving agent can see those qualifications instead of receiving a decontextualized number.
These roles form a set of intended contracts. The contract should answer four practical questions: what input does the agent receive, what output does it return, who can reject that output, and what state must persist after the handoff? AutoHedge's prompts answer the first question only partially and describe desired outputs in natural language. They do not locally establish the other three. That is not a defect in the idea of delegation; it is the point at which delegation must become system design.
The repository also contains two different representations of the handoff structure. The README offers a clean line from Director to Quant to Risk Manager to Execution Agent and then to trade output. In workers.py, the Director is constructed with a collection of four specialists as handoffs, including Sentiment. The collection proves that the Director has been given those relationships. It does not prove that the framework will call them in the README's order, that the Quant result will be passed to the Risk Manager exactly as intended, or that a Sentiment result is always part of the same decision.
This distinction matters because a handoff is not the same as a message schema. In a robust interface, the next agent should know whether it is receiving raw market observations, a thesis, a proposal, a rejection, or a final authorization. It should know which timestamp applies and whether the input is complete. It should be able to signal “insufficient data” without being forced to manufacture a score. The local source does not define those states. The external Swarms framework may supply behavior, but the repository does not specify enough of it for a reader to treat the relationship as a complete operational protocol.
A concrete AutoHedge handoff makes the missing detail easier to see. The Director might send the Quant Agent a symbol, a time window, the observations used, and a thesis to challenge. The Quant Agent's response would need to distinguish a measured value from an estimate and carry the observation time forward. The Risk Manager would then need to know whether a proposed size is expressed in dollars, tokens, or another unit, and whether it is a new exposure or an adjustment to an existing one. Only after those meanings are fixed could the Execution Agent interpret quantity and prices. The source names the fields, but it does not define this chain of meanings.
The failure case is even more revealing than the successful case. If the data are incomplete, a quantitative specialist should be able to return “not enough information” rather than a fabricated confidence score. If the Risk Manager cannot see current holdings, it should be able to refuse to size the position. If an Execution Agent receives a recommendation for an instrument that the selected venue cannot represent, the correct transition is a rejection or a request for clarification. None of these outcomes is an ordinary text reply that can safely be treated as progress. They are states that downstream code must understand. AutoHedge's local code does not define them, so the reader cannot infer how a handoff failure propagates.
The one-loop configuration adds a related constraint. Each specialist agent is constructed with max_loops=1, which indicates a single model loop for that agent rather than a locally specified retry or deliberation policy. That can be a reasonable choice for latency and cost, but it places more weight on the input being complete and on the receiving boundary checking the result. A one-pass output is not inherently unreliable; it simply makes explicit validation, rejection, and retry ownership more important. The repository does not state which component owns those decisions.
What a task actually encounters
The package's visible runtime begins in AutoHedge, not in a loop over securities. When an instance is created, it stores configuration values, creates the configured output directory, and initializes a time-enabled Conversation. The conversation is the local record of messages during a run. It is not described as a portfolio ledger or an authorization store.
When run receives a free-form task, it performs a short sequence. It adds the task as a user message. It calls director_agent.run(task=task). It adds the returned value as a Director message. It then returns the conversation in one of three presentation forms: a list of messages, a dictionary representation, or a string history. If an unknown output type is supplied, it falls back to the message list. The method does not itself take a ticker list, request a market snapshot, call a risk function, build an order object, or submit a transaction.
The sequence is easier to inspect when the declared handoffs and the visible wrapper are drawn together:
The dotted messages in this diagram are deliberately qualified. They represent a configured relationship, not an observed run. The package calls the Director, and the Director is given handoffs; the local source does not show the external framework's internal scheduler. A reader can therefore state with confidence that delegation is part of the design, while remaining uncertain about which specialist runs, in what order, with what context, and what happens after a specialist returns.
That boundary also clarifies what “continuous analysis” would require. Continuous operation is not produced by a prompt that says to analyze the market. It needs a scheduler or event loop, a clock, a repeat policy, state carried from one cycle to the next, and rules for stale or missing data. The visible run method performs one call for one task. The worker definitions set max_loops=1 for the specialist agents. Those facts do not prove that Swarms cannot perform internal handoffs, but they do mean the AutoHedge package does not visibly implement a continuing per-asset cycle of its own.
Ticker discovery provides a similarly useful test. The prompt file contains a Director prompt that asks for only a JSON array of relevant US stock symbols. That is an instruction the model could follow if the application used it. In the visible runtime, the raw task is passed directly to the Director; no local code invokes that discovery template, iterates over its result, or attaches a market-data snapshot to a new analysis prompt. The distinction is subtle but important. A natural-language request can tell an agent what to do, while a programmatic discovery stage must store the result, validate it, handle an empty array, and decide what happens when a symbol is ambiguous.
The prompt definitions reveal another interface boundary. Alongside the broad system prompts, prompts.py declares format-string templates for a Director thesis, quantitative analysis, risk assessment, execution order, and a final Director decision. The worker module imports the broad role prompts, then appends short instructions to the agent system prompts. The more specific templates are not visibly used in that construction. This does not make them useless—they may be planned or retained examples—but it does mean a reader should not assume that the detailed template is the exact message sent at runtime.
The output type makes the same point from another angle. The Quant, Risk, and Execution agents are configured to return strings. A string can contain a well-formed JSON document, but the local code does not show a parser that requires that format, rejects missing fields, or checks numeric ranges. The README's promise of structured JSON recommendations is therefore best read as a desired interface. In the visible package, the strong guarantee is only that the caller receives a conversation representation after the Director call. A message history is useful for inspection, but it is not the same as a typed decision object with explicit status, instrument, units, constraints, and authorization.
The wrapper's error behavior also belongs in this interface analysis. If the Director call raises an exception, AutoHedge.run logs the error and re-raises it. That is a clear failure signal for a caller that knows how to handle exceptions, but it is not a domain-level outcome such as “data stale,” “risk rejected,” or “order not authorized.” The command-line interface catches the exception and prints an error to the user. That is appropriate for an interactive shell, yet it leaves the repository without a visible contract for whether a failed specialist handoff should be retried, abandoned, or recorded as a non-trading decision.
The REPL further shows how the package treats tasks at its user-facing edge. Each nonempty line that is not a help or exit command is treated as a free-form task; the CLI creates an AutoHedge instance, runs it, and displays a bounded slice of the result. This is a convenient way to try the system, not evidence of a long-lived portfolio process. A new conversation is created by each new system instance in the visible flow, and the displayed history is not described as persistent trading state. For an exploratory research request, that may be enough. For repeated autonomous operation, the application would need explicit ownership of state across runs.
This leaves a carefully bounded conclusion. AutoHedge is not just a static diagram: it instantiates real agents, configures a Director with specialist handoffs, and wraps a model call in a reusable Python class and command-line interface. Those are meaningful building blocks. But the repository does not expose a complete, locally testable state machine from task to market action. The missing details are not cosmetic. They determine whether a downstream component can tell a valid recommendation from an incomplete one, whether a failure stops the run or is silently passed along, and whether a later action can be traced back to the data and judgment that produced it.
The next question is therefore not whether AutoHedge has enough roles. It is whether the roles receive the right information. A Quant Agent cannot make a current calculation without a defined data input. A Risk Manager cannot assess exposure without holdings and prior orders. An Execution Agent cannot safely identify an asset from a stock-oriented phrase if the venue requires a Solana mint. Once the call path is visible, data lineage and instrument identity become the next boundaries to examine.