agentsope/agentsop-tool-scoping
>- Enhancement overlay for multi-agent / tool-using coder agents. Encodes the per-agent tool- scoping discipline that role-based frameworks (CrewAI, LangChain) document only as a every agent is a correctness and blast-radius risk. Activates when an agent system has tools AND there is more than one agent (or one agent holding many tools). Treat a tool as a capability grant; scope by least-privilege. ENHANCE overlay — read alongside [[crewai]], tools per agent, least-privilege agent, agent tool access, tool permissions, limit agent
npx skills add https://github.com/agentsope/SkillAlchemy --skill agentsop-tool-scoping
> Overlay posture: the base frameworks ([[crewai]], LangChain, LangGraph) all
> *define* tools and *bind* them, but treat scoping as a one-line "assign tools
> to the agent that needs them" footnote. This overlay makes the rubric
> first-class. Non-trivial claims cite inline against
> references/R1-source-evidence.md.
The lever the base skills under-surface: **tool definition and tool binding are
two separate decisions.** You define a tool *once* (reusable class/function), but
you *bind* it per-agent deliberately. The [[crewai]] SKILL states this in one
clause — "tool 定义可复用;但每个 agent 只绑定其角色匹配的工具"
[crewai-sop §DC-3] — and then moves on. Production failures (wrong-tool
selection, an agent running a destructive op outside its role) come from skipping
the binding decision and defaulting to "give everyone everything."
Activate when any of these hold:
AutoGen group) AND at least one agent holds ≥1 tool.
selection has started degrading (picks the wrong tool, or "tool-hops").
tools=[search, exec, db]copy-pasted onto every Agent(...), or one bind_tools([...everything]) call
reused for every node. This is the canonical trigger.
DELETE, shell exec,outbound HTTP POST) and you are deciding who may hold it.
to answer "which agent can do what, and why."
Do not activate for: a single agent with 1–3 read-only tools (scoping is
trivial), or a stateless single LLM call with no tools.
A tool is a capability grant, not a convenience. Binding a tool to an agent
is the same act as granting a Unix process a syscall, a service an IAM role, or a
container a Linux capability. The discipline is identical and ancient:
**least-privilege — an agent should hold only the tools its role actually
needs.**
Three load-bearing consequences:
BaseTool /function); decide the *binding* (which agents see it) separately and
minimally. [[crewai]] says "write once, use everywhere" applies to the
*definition* layer only; the *binding* layer is per-role [crewai-sop §DC-3].
it.** The LLM must reason over the full tool list on every turn. More tools =
bigger schema in context = higher token cost AND lower selection accuracy.
This is why a 20-tool agent picks wrong (OP-4, DC-2).
search tool on the wrong agent wastes tokens. A run_sql or send_payment
tool on the wrong agent (or one with no guard) is a production incident. The
LangGraph HITL discipline — "interrupt on irreversible, high-blast-radius
actions only" — is the *runtime* half; tool scoping is the *design-time* half
of the same risk-control [langgraph-sop §Step5].
The mental test before binding any tool to any agent:
> "Does THIS role's goal require THIS capability to be exercised by THIS agent
> autonomously? If a different agent could/should do it, don't bind it here."
A coder agent walks this top-down. Each phase has a gate.
List every tool (name, side-effect class: read | compute | write |
destructive) and every agent (name, one-verb role). If there is exactly one
agent and ≤3 read tools — stop, scoping is trivial.
For each agent, write its role as a single verb (research / analyze / write /
review). Then, for each tool, ask the §2 test. Bind only on a "yes."
consumes upstream output [crewai-sop §DC-3].
Gate: if two agents end up with identical tool sets, ask whether they are really
two roles or one (the [[crewai]] "split-vs-merge" question [crewai-sop §DC-1]).
Any tool classed write or destructive:
interrupt() before the side effect inLangGraph [langgraph-sop §Step5], or an approval/confirm step in CrewAI.
see [[agentsop-llm-tool-idempotency]] and [[agentsop-http-tool-wrapping]]. LangGraph's payment
case (charged twice on resume) is exactly this failure [langgraph-sop §Case4].
If any agent now holds >8 tools, selection accuracy degrades (OP-4). Options:
split the role, group tools behind a router/sub-agent, or move read-only helpers
into the prompt as context instead of tools.
Produce a binding matrix (agents × tools). For each write/destructive cell,
confirm there is exactly one owner and a guard. For each agent, confirm tool
count ≤ limit. This matrix is the security artifact a reviewer reads.
Format: Trigger → Action → Output → Evidence.
tools=[]. Add a tool only when therole's goal *requires that agent* to exercise it. Reuse the tool *definition*
across agents, but bind per-role.
Agent(tools=[...]) / per-node bind_tools([...]) holds theminimal set; a binding matrix.
[crewai-sop §DC-3] "每个 agent 只绑定其角色匹配的工具";[langgraph-sop §Step4] topology binds tools to nodes, not globally.
write or destructive operation.human approval) before the effect, and make the op idempotent.
[langgraph-sop §Step5] interrupt on irreversible only;[langgraph-sop §Case4] double-charge from unguarded side effect; cross-link
[[agentsop-llm-tool-idempotency]], [[agentsop-http-tool-wrapping]].
Decide binding per-agent via OP-1. Never tools=registry.all() on every
agent.
[crewai-sop §DC-3] definition-reuse vs binding-scope split.role, introduce a routing sub-agent, or demote read-only tools to context.
CrewAI's ">5 agents = coordination failure" scaling wall [crewai-sop §6.1 AP-1];
see DC-2.
context=[...](CrewAI) or state (LangGraph).
[crewai-sop §DC-3] "reporter=[] (纯综合)".write/destructivetool bound to >1 agent or lacking a guard; flag any agent over the count limit.
researcher invoking a code executor).
rather than prompt-engineering "please don't use X."
[crewai-sop §DC-3] "agent 跨工具滥用 → 收紧工具白名单是最快的 fix".场景: You have web_search, code_executor, db_query and three agents
(researcher / analyst / reporter). The convenient move is
tools=[search, exec, db] on all three.
两条路:
Problem: the researcher also calls code_executor to "just quickly compute,"
violating role separation; failures become un-localizable (who ran the bad
query?); every agent pays the full 3-tool schema cost every turn.
researcher=[search], analyst=[exec, db],reporter=[]. Clearer responsibilities, localizable errors, smaller per-turn
schema [crewai-sop §DC-3].
判断规则:
BaseTool per tool — reuse is good).to exercise it.
write tool, your rolesare under-specified — go back to role design [crewai-sop §DC-1].
红线: Never let "it's easier to share" be the binding rationale. Ease of
wiring is not a capability requirement.
Evidence: [crewai-sop §DC-3], [langgraph-sop §Step4].
场景: A single "do-everything" agent accumulates 20 tools over time. It now
calls delete_record when the user asked to *read* a record, or burns turns
hopping between near-duplicate tools (search_v1, search_v2, lookup).
陷阱: The instinct is to "improve the prompt" so the model picks better. But
the root cause is the selection space is too large — 20 tool schemas in
context dilute attention and inflate token cost, exactly as ">5 agents" causes
coordination collapse in CrewAI [crewai-sop §6.1 AP-1]. Prompt tweaks paper
over a structural problem.
三条路:
Helps marginally; does not fix the count.
data-agent (db/exec tools), each ≤8 tools. Mirrors the CrewAI "split when one
agent does two jobs" rule [crewai-sop §DC-1].
whose small tool set matches the sub-task [langgraph-sop §Step4].
判断规则:
on a single guarded owner (OP-2), shrinking the dangerous agent's surface.
红线: A destructive tool on a 20-tool agent is the worst case — high
mis-selection probability × high blast radius. Scope it out *first*.
Evidence: [crewai-sop §6.1 AP-1], [langgraph-sop §Step4/§Case4].
场景: Two agents both "occasionally need" to write to the database.
判断规则:
write/destructive tool gets exactly one owning agent(single auditable funnel), per OP-2.
a dedicated single-owner "writer" agent/node** that the others call — not
duplicated. This is the supervisor-funnel argument applied to capabilities
[langgraph-sop §Step4].
([[agentsop-llm-tool-idempotency]], [[agentsop-http-tool-wrapping]]).
红线: Two agents holding the same unguarded destructive tool = two
independent ways to cause the same irreversible incident, and an ambiguous audit
trail.
Evidence: [langgraph-sop §Step5/§Case4], [crewai-sop §DC-3].
| # | Anti-pattern | Symptom | Fix |
|---|---|---|---|
| AP-1 | Blanket tool sharing (tools=[all] on every agent) | role bleed, un-localizable failures, inflated token cost | per-role binding (OP-1, DC-1) |
| AP-2 | No guard on destructive tools | double-charge / accidental delete on retry or mis-selection | single owner + HITL + idempotency (OP-2, [[agentsop-llm-tool-idempotency]]) |
| AP-3 | One mega-agent with 20 tools | wrong-tool selection, tool-hopping, cost | cap ≤8, split or route (OP-4, DC-2) |
| AP-4 | Prompt-patching tool misuse | "please don't use X" in backstory | remove the tool from the binding (OP-7) |
| AP-5 | Sharing the destructive tool itself instead of the definition | two paths to the same incident | extract single-owner writer (DC-3) |
| AP-6 | Binding tools to synthesis agents | writer/reporter "wanders" into search/exec | bind zero tools (OP-5) |
Boundaries — this overlay does NOT cover:
[langgraph-sop §Step5].The scoping decision is universal; only the binding syntax differs.
| Framework | Define a tool | Bind per-agent (the scoping point) | Scoping notes |
|---|---|---|---|
| CrewAI | BaseTool subclass / @tool | Agent(role=..., tools=[search]) — per agent | Definition reusable, binding per-role [crewai-sop §DC-3]. allow_delegation further widens effective capability — keep it False on workers [crewai-sop §DC-5]. |
| LangGraph | a callable / @tool | model.bind_tools([...]) per node, or per create_react_agent | Tools bound to the node that needs them, not globally; topology decides who routes to the tool-bearing node [langgraph-sop §Step2/§Step4]. Guard destructive tools with interrupt() [langgraph-sop §Step5]. |
| LangChain (agents) | @tool / Tool | tools list passed to each AgentExecutor | Same definition-vs-binding split; the base LangChain docs note "give the agent the tools it needs" but leave the per-agent rubric implicit — this overlay fills that gap. |
| OpenAI Assistants | tools=[{type/function...}] | per-Assistant tools array | Each Assistant is a scoping boundary; create role-specific Assistants rather than one with every function. |
| Claude tool_use | tools=[{name, input_schema}] in the API call | the tools list of a given request/agent | Scope by sending only the tools relevant to that agent's turn; large tool lists raise mis-selection and token cost identically. |
One-line cross-walk: CrewAI agent.tools ≈ LangGraph per-node
bind_tools ≈ Assistant tools array ≈ Claude request tools — in every case,
**the right-hand list is the capability grant, and least-privilege says keep it
minimal.**
| web_search | run_sql (write) | send_email (write) | code_exec |
--------------+------------+-----------------+--------------------+-----------+
researcher | ✓ | · | · | · |
analyst | · | · | · | ✓ |
db_writer* | · | ✓ (HITL) | · | · |
notifier* | · | · | ✓ (HITL) | · |
reporter | · | · | · | · | ← zero-tool synthesis
--------------+------------+-----------------+--------------------+-----------+
* single owner of a destructive tool; guarded + idempotent
Audit rule: every (write) column has exactly one ✓, and it is (HITL).
[crewai-sop] = crewai-sop-skill/SKILL.md (per-agent tools §DC-3; split §DC-1; delegation §DC-5; scaling AP-1)[langgraph-sop] = langgraph-sop-skill/SKILL.md (bind_tools to nodes §Step2/4; HITL §Step5; double-charge §Case4)[[crewai]], [[agentsop-http-tool-wrapping]], [[agentsop-llm-tool-idempotency]] — sibling overlaysreferences/R1-source-evidence.mdTake agentsope/agentsop-tool-scoping from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.