Skip to content

Repository files navigation

Assistant vs Claw

tests MIT Pages Open in Colab

Assistant vs Claw — whose keys are in the lock?

On-behalf-of Assistants and fixed-identity Claws and why the distinction matters the moment you share an agent.

Runnable illustrations of the two authorization models in LangSmith Fleet. Same word agent. Two completely different trust boundaries.

Created by Cobus Greyling. Part of the Fleet Engineering stack.

→ cobusgreyling.github.io/assistant-vs-claw


The bottleneck moved

Six months ago, building an agent meant hiring an engineer. Today you describe a job in plain English and get a working agent back.

The hard part is no longer "can the LLM call a tool?" It is who is the agent when it calls that tool?

  • When Alice asks your onboarding agent to pull her Rippling profile, it should use Alice's credentials.
  • When Bob asks the same agent, it should use Bob's. Neither should see the other's private Notion pages.
  • When your email agent replies to a stranger who wants a meeting, it should not become that stranger. It acts as you — or a dedicated service identity with a fixed calendar and inbox.

LangSmith Fleet names them Assistants and Claws. The difference is not intelligence or autonomy. It is whose keys are in the lock.

Assistant Claw
Acts as The person using it Itself
Credentials Per-user, at runtime Fixed, at setup
Data scope Whatever that user can see Whatever the agent account can see
Best for Personal, per-user workflows Shared bots, scheduled jobs, public channels

LangChain shorthand:

  • Assistants → on-behalf-of
  • Claws → own fixed credentials

If you have used OpenClaw, you have already met the Claw model: create an agent, give it accounts, let others interact with it — but everyone shares the same underlying identity.


Quick start

git clone https://github.com/cobusgreyling/assistant-vs-claw.git
cd assistant-vs-claw

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Run the full side-by-side comparison
avc-compare

# Or run individual scenarios
avc-onboarding
avc-email
avc-product
avc-slack
avc-vendor

# Verify trust boundaries
make all

No API keys required — everything runs against mock Notion, Slack, and OAuth data.

No local setup? Open the Colab notebook.


What this looks like in code

Fleet hides most of this behind OAuth and channel mapping. The pattern is the same whether you wire LangGraph by hand or click "Set identity" in the UI.

Assistant: credentials follow the human

# credentials follow whoever invoked the agent
def get_user_credentials(user_id: str) -> Credentials:
    return token_store.get(user_id)  # Alice gets Alice's tokens

def search_notion(query: str, user_id: str) -> list[str]:
    creds = get_user_credentials(user_id)
    return notion_search(creds, query)  # only pages THAT user can access

def run_agent(user_id: str, message: str):
    return agent.invoke({"message": message, "user_id": user_id})

Alice and Bob hit the same agent. Different tokens. Different data. The agent is a proxy — it wears your badge.

See: src/identity_models/assistant.py

Claw: credentials baked in at birth

# one identity, always
AGENT_CREDENTIALS = load_credentials("product-bot@company.com")

def search_notion(query: str) -> list[str]:
    return notion_search(AGENT_CREDENTIALS, query)  # same scope for everyone

def run_agent(message: str, sender: str | None = None):
    # sender is context for the reply, NOT for auth
    return agent.invoke({"message": message, "sender": sender})

A competitor researcher, a vendor-intake bot, a @weekly-numbers Slack agent — same credentials whether the CEO or an intern triggers it. The agent has its own desk, not yours.

See: src/identity_models/claw.py

Structured audit events

Every run emits a Fleet-style audit record:

{
    "principal": "alice@co",
    "model": "assistant",
    "action": "notion.search",
    "query": "salary",
    "pages": ("Alice Chen — Compensation",),
    "triggered_by": "alice@co",
}

See: src/identity_models/audit.py · docs/FLEET_MAPPING.md

Side by side: one Slack message, two outcomes

Someone posts in #general: "What's our Q3 roadmap?"

Model What happens
Assistant Map U_ALICEalice@co, load Alice's OAuth, search Notion → only pages Alice can see
Claw Search Notion with product-bot@company.com credentials → same pages for every asker

Same prompt. Same tool. Different trust boundary.

Run it: avc-slack or examples/04_side_by_side_slack.py


Four real agents, four design choices

Agent Model Why
Onboarding Agent Assistant Each hire sees their Rippling record and Notion docs. Alice's thread must never surface Bob's salary.
Email Agent Claw Responds to inbound mail from anyone. Always checks your calendar and drafts from your identity. Sender is context, not delegation.
Product Agent Claw Monitors competitors in a shared Notion workspace as @product-bot. One curated account — not everyone's personal permissions mashed together.
Vendor Intake Bot Claw Shared intake queue with editor-only review before sensitive writes ship.

Examples: examples/ · Console: avc-onboarding, avc-email, avc-product, avc-vendor


How to choose

See the full decision guide: docs/CHOOSING.md

flowchart TD
    A[New agent] --> B{Each user must see only their own data?}
    B -->|Yes| C[Assistant — OAuth per user]
    B -->|No| D{Team resource, schedule, or public channel?}
    D -->|Yes| E[Claw — scoped service account]
    D -->|No| F[Re-evaluate: mixed model or inbox HITL]
Loading

Pick an Assistant when each user must see only their own data, audit trails should name the human, and personalization is the point.

Pick a Claw when the agent is a team resource, runs on a schedule or public channel, or needs a deliberately scoped service account.

Common mistake: building a Claw with your personal OAuth. Anyone who messages the bot inherits everything you can see. Give the Claw its own account with only the permissions the job needs.


Beyond credentials: memory and inbox

Concern Assistant Claw
Memory Per-user threads — Alice's context does not leak to Bob Shared team resource
Inbox Private per-user for sensitive personal tasks Editor-only: leads review before sensitive actions ship
Channels Needs Slack/Teams user ID → LangSmith user mapping Can drop into more surfaces — only needs the message

See: src/identity_models/memory.py · src/identity_models/inbox.py


Repository layout

assistant-vs-claw/
├── src/identity_models/     # Core patterns (Assistant, Claw, audit, inbox, memory)
├── examples/                # Runnable scenarios (thin wrappers over CLI)
├── demos/                   # Full comparison runner
├── notebooks/               # Colab notebook
├── tests/                   # Trust boundary + snapshot assertions
└── docs/                    # CHOOSING, FLEET_MAPPING, GitHub Pages site

Essay / Substack

Writing a post? Use the outline in docs/ESSAY_HOOK.md — working title: "Whose Keys Are in the Lock?"


The shift in one sentence

We used to ask: Can we build an agent that does this task?

Now we ask: Whose identity should execute that task — the human in the loop, or the agent we provisioned for the job?

That is the whole Claw vs. Assistant split. Not autonomy. Not model choice. Authorization.

  • Assistants are agents that work for you, as you.
  • Claws are agents that work as themselves, on behalf of the team.

Get that wrong and you either over-expose data or build something too weak to be useful. Get it right and the same prompt-to-agent workflow scales from a personal inbox to a governed fleet.


Related

Contributing

See CONTRIBUTING.md. Security: SECURITY.md.

License

MIT — see LICENSE.

About

Runnable illustrations of Assistant (on-behalf-of) vs Claw (fixed-identity) agent authorization

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages