Skip to main content
Agents are intelligent actors that autonomously accomplish assigned goals. They can plan, take notes on a filesystem, curate context on every turn, and delegate work to parallel sub-agents. Each agent operates in a loop: build context, decide on next steps, call tools, and gather responses. This cycle continues until the goal is accomplished and there are no more tool calls needed. Flowchart showing the agent loop: (1) Build context from instructions, memory, and tools, (2) Send context to language model, (3) Receive tool calls from model, (4) Execute tools and gather responses, (5) Repeat until goal is achieved or no more tool calls are needed. In each iteration of its loop, an agent invokes a model to understand information, it has gathered in its context so far, and pick what next steps will take it towards its goal. The model returns these next steps as a list tools calls for the agent to invoke. The Autonomy Framework and the Autonomy Computer work together to give you components and infrastructure to manage memories across many users and curate context for agents working on long and complex tasks. They also provide you with a foundation to operate tools that are necessary for deep work. Agents can invoke python functions as tools, or call tools provided by MCP servers. They can access a dedicated file system to save plans and take notes. Agents can also create many sub-agents that concentrate on sub-tasks. Parallel agents, each focused on a small part, achieve the overall goal faster. They are also more successful because the context that they provide to their language model contains much less noise.

Create an Agent

You can create a simple agent by providing a name, instructions, and a model:
images/main/main.py
from autonomy import Agent, Model, Node


async def main(node):
  await Agent.start(
    node=node,
    name="henry",
    instructions="You are Henry, an expert legal assistant",
    model=Model("claude-sonnet-4-v1")
  )


Node.start(main)
Once an agent is running, you can send messages to it using the built-in HTTP API.
curl
curl --request POST \
  --header "Content-Type: application/json" \
  --data '{"message": "What are the key elements of a valid contract?"}' \
  "https://${CLUSTER}-${ZONE}.cluster.autonomy.computer/agents/henry"
For longer responses, use the streaming API to receive chunks as they’re generated:
curl
curl --request POST \
  --header "Content-Type: application/json" \
  --data '{"message": "Explain the doctrine of promissory estoppel in detail."}' \
  "https://${CLUSTER}-${ZONE}.cluster.autonomy.computer/agents/henry"
This returns newline-delimited JSON chunks as the agent generates its response.

Learn More


This example demonstrates a sophisticated legal research application that combines multiple Autonomy features:
  • Custom FastAPI endpoint for case submission.
  • Lead researcher agent that breaks cases into research questions.
  • Filesystem tools for organizing research notes and drafts (conversation-level).
  • Parallel subagents that investigate each question simultaneously.
  • Subagent filesystem tools for organizing individual research work (conversation-level).
  • MCP tools (Brave Search) for finding legal authorities and case law.

How It Works

  1. Attorney submits a case description via API.
  2. Lead researcher agent analyzes the case and identifies specific research questions.
  3. Lead researcher saves research plan to filesystem for organization.
  4. Each question is delegated to a research assistant subagent using delegate_to_subagents_parallel.
  5. Subagents use Brave Search to find statutes, case law, and legal authorities.
  6. Subagents use filesystem to organize their research notes and draft responses.
  7. Subagents return findings via tool call responses to lead researcher.
  8. Lead researcher compiles all findings into a comprehensive legal research memo.
from autonomy import Agent, FilesystemTools, HttpServer, McpClient, McpTool, Model, Node, NodeDep
from fastapi import FastAPI
from asyncio import create_task

app = FastAPI()


@app.post("/research")
async def research_legal_case(request: dict, node: NodeDep):
    """
    Research a legal case by breaking it into research questions and investigating each question.
    """
    case_description = request.get("case_description", "")

    if not case_description:
        return {"error": "No case description provided"}

    # Start the lead researcher agent with parallel research subagents
    lead_researcher = await Agent.start(
        node=node,
        name=f"lead_researcher_{id(case_description)}",
        instructions="""
You are a lead legal researcher coordinating a research team.

Your job is to:
1. Analyze the case and break it down into specific, focused research questions
2. Save your research plan to a file for reference
3. Use delegate_to_subagents_parallel to assign each question to research assistant subagents
4. As findings come in, save them to organized files
5. Compile all research findings into a comprehensive legal research memo and save it

You have filesystem access to:
- Save research plans and notes
- Organize findings by topic or question
- Draft the research memo incrementally
- Create a final polished memo

Focus on actionable research questions such as:
- Relevant statutes and their interpretations
- Applicable case law and precedents
- Jurisdictional issues
- Elements that must be proven
- Defenses that may apply
- Recent developments in this area of law

When you have identified the research questions, use the delegate_to_subagents_parallel tool
to have all questions researched simultaneously by passing the role "research_assistant"
and a list of research questions as tasks.

Use the filesystem to stay organized throughout the research process.""",
        model=Model("claude-sonnet-4-v1"),
        tools=[FilesystemTools(visibility="conversation")],
        subagents={
            "research_assistant": {
                "instructions": """
You are a legal research assistant specializing in thorough legal research.

When given a research question:
1. Use the brave_web_search tool to find relevant legal authorities, statutes, and case law
2. Use filesystem tools to save your research notes and organize your findings
3. Analyze the sources to extract key legal principles and holdings
4. Synthesize your findings into a clear, well-organized response
5. Cite specific authorities with case names, statutory citations, or source URLs

You have filesystem access for organizing your research work. Use this to:
- Save important case summaries and statutory findings as you find them
- Keep notes on sources you've reviewed
- Draft and refine your response before returning it
- Maintain organized research files

Focus on finding:
- Controlling statutes and regulations
- Binding precedent from relevant jurisdictions
- Persuasive authority from other jurisdictions
- Recent cases that interpret or apply relevant law

Prefer authoritative legal sources:
- Court opinions from official reporters or government sites (.gov)
- Legislative websites for statutory text
- Law school websites (.edu) for scholarly analysis
- Legal research databases (Justia, FindLaw, etc.)

Format your response as:
Research Question: [Restate the question]
Key Findings: [Summarize the most important discoveries]
Relevant Authorities: [List statutes, cases, and other sources with citations]
Analysis: [Explain how these authorities apply to the question]
Recommendations: [Suggest next steps or further research needed]""",
                "model": Model("claude-sonnet-4-v1"),
                "auto_start": False,
                "tools": [
                    McpTool("brave_search", "brave_web_search"),
                    FilesystemTools(visibility="conversation")
                ],
                "max_execution_time": 120
            }
        }
    )

    try:
        # Send the case to the lead researcher
        response = await lead_researcher.send(
            f"""
Please conduct comprehensive legal research on this case:

{case_description}

Break this down into focused research questions, assign each question to a research assistant
in parallel, and compile the findings into a detailed legal research memo that includes:
- Executive summary of the case
- Research questions identified
- Findings for each question with citations
- Overall legal analysis and recommendations""",
            timeout=3600
        )

        # Extract the final response
        research_memo = response[-1].content.text if response else "No response"

        return {"research_memo": research_memo}

    except Exception as e:
        return {"error": str(e)}
    finally:
        # Clean up the lead researcher agent
        create_task(Agent.stop(node, lead_researcher.name))


Node.start(
    http_server=HttpServer(app=app),
    mcp_clients=[
        McpClient(name="brave_search", address="http://localhost:8001/sse")
    ]
)
Submit a case for research:
curl
curl --request POST \
  --header "Content-Type: application/json" \
  --data '{
    "case_description": "Our client, a software company, terminated an employee
    for violating a non-compete agreement. The employee started working for a
    competitor within 30 days. The non-compete was signed in California in 2023
    and has a 2-year restriction period with nationwide scope. We need to assess
    the enforceability of this agreement and potential claims."
  }' \
  "https://${CLUSTER}-${ZONE}.cluster.autonomy.computer/research"
The API returns a comprehensive legal research memo with research questions, findings, citations, and recommendations.