# Record
**Author:** @cameron.stream (`did:plc:gfrmhdmjvxn2sjedzboeudef`)

## `knowledge-choosing-an-agent-topology`
**Collection:** `site.standard.document`
**AT URI:** `at://did:plc:gfrmhdmjvxn2sjedzboeudef/site.standard.document/knowledge-choosing-an-agent-topology`

**Title:** Choosing an Agent Topology
**Published:** Wed, 12 Aug 2026 19:50:08 GMT
**Updated:** Wed, 12 Aug 2026 19:35:00 GMT
**Description:** How to choose among one agent, several conversations, per-user agents, role-specific agents, and shared memory repositories.
**Publication:** `at://did:plc:gfrmhdmjvxn2sjedzboeudef/site.standard.publication/3mr4py6clps2f`
**Path:** /choosing-an-agent-topology
**Tags:** knowledge, practice, ai, agents, letta, agent-sdk, conversations, memory, multi-agent

**Content:**
````json
{
  "text": "An agent topology assigns identity, memory, conversations, tools, and shared files across an application. The central rule is simple: use one agent wherever identity and long-term memory should be shared. Use separate agents wherever those things should remain independent.\n\nIn [Letta's state model](https://docs.letta.com/concepts/stateful-agents/index.md), every conversation on an agent shares that agent's memory. A new conversation separates message threads. It is not a privacy or tenancy boundary.\n\n## Choose the boundary before the count\n\nThe useful question is not “How many agents should this application have?” Ask which experiences should change the same future behavior.\n\n| Topology | Shared identity and memory | Separate message history | Best fit |\n| --- | --- | --- | --- |\n| One agent, one main conversation | Yes | No | Personal partner, continuous work thread |\n| One agent, several conversations | Yes | Yes | Parallel topics for one person or role |\n| One agent per user | No | Yes | Personalized products with user-specific memory |\n| Several role agents | No | Yes | Independent responsibilities, tools, or policies |\n| Several agents with shared memory | Shared files only | Yes | A team working from common plans or knowledge |\n\nThe table separates two ideas that are easy to blur. Conversations organize interaction with one identity. Shared memory repositories let independent identities work on common files.\n\n## One agent with one main conversation\n\nUse one main conversation when the work benefits from a continuous thread and topic boundaries do not help the user. A personal research partner or project collaborator often begins here.\n\nThis topology has the fewest routing decisions. It also concentrates context, so the application's retrieval and compaction behavior must keep long histories usable.\n\n## One agent with several conversations\n\nUse several conversations when one agent should remember across distinct threads. Product planning, email, and research can each have their own conversation while sharing the same preferences and long-term memory.\n\nThe [conversation guide](https://docs.letta.com/concepts/conversations/index.md) treats the split as a user preference rather than a correctness rule. Long threads can compact and continue. Start a new conversation to separate work, not because the old thread reached an arbitrary age.\n\nDo not use conversations to separate users who should not share memory. A fact learned in one conversation can shape another conversation on the same agent.\n\n## One agent per user\n\nUse a separate agent for each user when personalization should accumulate independently. Store the user-to-agent mapping in application state, and route every request through the authenticated user rather than an agent ID supplied by the client.\n\n```typescript\nconst agentId = await userAgents.requireAgentFor(authenticatedUser.id);\nconst conversationId = await threads.requireConversation({\n  agentId,\n  applicationThreadId,\n});\n\nawait using session = client.resumeSession(conversationId, sessionOptions);\n```\n\nThis topology gives each user an independent MemFS and conversation set. The application still must enforce access control around the mapping, tools, repositories, and execution environments. Separate agents do not repair a caller that can request someone else's agent ID.\n\n## Several agents for distinct roles\n\nCreate separate agents when responsibilities need different identities, memories, tools, or authority. A researcher and a publisher may work for the same user while remaining separate agents. The researcher can accumulate source judgment without inheriting publication credentials; the publisher can enforce a narrow release procedure without absorbing every research thread.\n\nRole agents should exchange explicit artifacts rather than assume shared interior state. A report, task packet, source bundle, or proposed change is easier to inspect than an informal handoff that depends on one agent impersonating another.\n\nAvoid creating a new agent for every temporary task. If no identity or memory should accumulate, use deterministic code, a one-shot prompt, or a new conversation on an existing agent. Agent proliferation creates routing, cleanup, and evaluation work without necessarily creating useful specialization.\n\n## Several agents with shared memory\n\n[Shared memory](https://docs.letta.com/concepts/shared-memory/index.md) gives cloud-hosted agents access to the same organization-owned Git repository. Each agent keeps its own MemFS. The shared repository holds common files such as plans, product knowledge, research, or team conventions.\n\nChoose the attachment lifetime deliberately:\n\n- session `resources` attach a repository for the life of one SDK session;\n- `client.agents.repositories.attach()` keeps the repository attached until explicit detachment.\n\nShared memory is collaborative storage, not merged identity. Agents must commit and push changes, and other agents must synchronize before they observe those commits. Use content-hash preconditions or Git review when concurrent edits should fail rather than overwrite each other.\n\nDo not place material in a shared repository unless every attached agent should be able to retrieve it. [Public and Private Knowledge](https://cameron.stream/knowledge/public-and-private-knowledge) explains why filtering after retrieval is too late for sensitive context.\n\n## A default progression\n\nBegin with one agent and one conversation. Add conversations when thread separation improves navigation. Split into separate agents when memory, identity, tools, or authority need different owners. Add shared memory only when independent agents need a common working surface.\n\nThis progression keeps topology changes tied to an observed boundary. “Multi-agent” is not a quality level. Sometimes it is simply several agents discovering, at great expense, that they all needed the same file.\n\n[Your First Persistent Agent](https://cameron.stream/knowledge/first-persistent-agent) provides the smallest runnable application. [Agent Authority and Effects](https://cameron.stream/knowledge/agent-authority-and-effects) covers the permission and effect boundaries that each topology still needs.\n\n## Sources\n\n- [Stateful agents](<https://docs.letta.com/concepts/stateful-agents/index.md>)\n- [Conversations](<https://docs.letta.com/concepts/conversations/index.md>)\n- [Shared memory](<https://docs.letta.com/concepts/shared-memory/index.md>)\n- [Manage shared memory with the Agent SDK](<https://docs.letta.com/agent-sdk/repositories/index.md>)\n- [Creating agents](<https://docs.letta.com/agent-sdk/agents/index.md>)",
  "$type": "site.standard.content.markdown",
  "version": "1.0"
}
````

---
*Fetched from https://enoki.us-east.host.bsky.network via `com.atproto.repo.getRecord`*