deepagents-code-review

安装量: 73
排名: #10567

安装

npx skills add https://github.com/existential-birds/beagle --skill deepagents-code-review

Deep Agents Code Review

When reviewing Deep Agents code, check for these categories of issues.

Critical Issues 1. Missing Checkpointer with interrupt_on

BAD - interrupt_on without checkpointer

agent = create_deep_agent( tools=[send_email], interrupt_on={"send_email": True}, # No checkpointer! Interrupts will fail )

GOOD - checkpointer required for interrupts

from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent( tools=[send_email], interrupt_on={"send_email": True}, checkpointer=InMemorySaver(), )

  1. Missing Store with StoreBackend

BAD - StoreBackend without store

from deepagents.backends import StoreBackend

agent = create_deep_agent( backend=lambda rt: StoreBackend(rt), # No store! Will raise ValueError at runtime )

GOOD - provide store

from langgraph.store.memory import InMemoryStore

store = InMemoryStore() agent = create_deep_agent( backend=lambda rt: StoreBackend(rt), store=store, )

  1. Missing thread_id with Checkpointer

BAD - no thread_id when using checkpointer

agent = create_deep_agent(checkpointer=InMemorySaver()) agent.invoke({"messages": [...]}) # Error!

GOOD - always provide thread_id

config = {"configurable": {"thread_id": "user-123"}} agent.invoke({"messages": [...]}, config)

  1. Relative Paths in Filesystem Tools

BAD - relative paths not supported

read_file(path="src/main.py") read_file(path="./config.json")

GOOD - absolute paths required

read_file(path="/workspace/src/main.py") read_file(path="/config.json")

  1. Windows Paths in Virtual Filesystem

BAD - Windows paths rejected

read_file(path="C:\Users\file.txt") write_file(path="D:/projects/code.py", content="...")

GOOD - Unix-style virtual paths

read_file(path="/workspace/file.txt") write_file(path="/projects/code.py", content="...")

Backend Issues 6. StateBackend Expecting Persistence

BAD - expecting files to persist across threads

agent = create_deep_agent() # Uses StateBackend by default

Thread 1

agent.invoke({"messages": [...]}, {"configurable": {"thread_id": "a"}})

Agent writes to /data/report.txt

Thread 2 - file won't exist!

agent.invoke({"messages": [...]}, {"configurable": {"thread_id": "b"}})

Agent tries to read /data/report.txt - NOT FOUND

GOOD - use StoreBackend or CompositeBackend for cross-thread persistence

agent = create_deep_agent( backend=CompositeBackend( default=StateBackend(), routes={"/data/": StoreBackend(store=store)}, ), store=store, )

  1. FilesystemBackend Without root_dir Restriction

BAD - unrestricted filesystem access

agent = create_deep_agent( backend=FilesystemBackend(root_dir="/"), # Full system access! )

GOOD - scope to project directory

agent = create_deep_agent( backend=FilesystemBackend(root_dir="/home/user/project"), )

  1. CompositeBackend Route Order Confusion

BAD - shorter prefix shadows longer prefix

agent = create_deep_agent( backend=CompositeBackend( default=StateBackend(), routes={ "/mem/": backend_a, # This catches /mem/long-term/ too! "/mem/long-term/": backend_b, # Never reached }, ), )

GOOD - CompositeBackend sorts by length automatically

But be explicit about your intent:

agent = create_deep_agent( backend=CompositeBackend( default=StateBackend(), routes={ "/memories/": persistent_backend, "/workspace/": ephemeral_backend, }, ), )

  1. Expecting execute Tool Without SandboxBackend

BAD - execute tool won't work with StateBackend

agent = create_deep_agent() # Default StateBackend

Agent calls execute("ls -la") → Error: not supported

GOOD - use FilesystemBackend for shell execution

agent = create_deep_agent( backend=FilesystemBackend(root_dir="/project"), )

Agent calls execute("ls -la") → Works

Subagent Issues 10. Subagent Missing Required Fields

BAD - missing required fields

agent = create_deep_agent( subagents=[{ "name": "helper", # Missing: description, system_prompt, tools }] )

GOOD - all required fields present

agent = create_deep_agent( subagents=[{ "name": "helper", "description": "General helper for misc tasks", "system_prompt": "You are a helpful assistant.", "tools": [], # Can be empty but must be present }] )

  1. Subagent Name Collision

BAD - duplicate subagent names

agent = create_deep_agent( subagents=[ {"name": "research", "description": "A", ...}, {"name": "research", "description": "B", ...}, # Collision! ] )

GOOD - unique names

agent = create_deep_agent( subagents=[ {"name": "web-research", "description": "Web-based research", ...}, {"name": "doc-research", "description": "Document research", ...}, ] )

  1. Overusing Subagents for Simple Tasks

BAD - subagent overhead for trivial task

In system prompt or agent behavior:

"Use the task tool to check the current time" "Delegate file reading to a subagent"

GOOD - use subagents for complex, isolated work

"Use the task tool for multi-step research that requires many searches" "Delegate the full analysis workflow to a subagent"

  1. CompiledSubAgent Without Proper State

BAD - subgraph with incompatible state schema

from langgraph.graph import StateGraph

class CustomState(TypedDict): custom_field: str # No messages field!

sub_builder = StateGraph(CustomState)

... build graph

subgraph = sub_builder.compile()

agent = create_deep_agent( subagents=[CompiledSubAgent( name="custom", description="Custom workflow", runnable=subgraph, # State mismatch! )] )

GOOD - ensure compatible state or use message-based interface

class CompatibleState(TypedDict): messages: Annotated[list, add_messages] custom_field: str

Middleware Issues 14. Middleware Order Misunderstanding

BAD - expecting custom middleware to run first

class PreProcessMiddleware(AgentMiddleware): def transform_request(self, request): # Expecting this runs before built-in middleware return request

agent = create_deep_agent(middleware=[PreProcessMiddleware()])

Actually runs AFTER TodoList, Filesystem, SubAgent, etc.

GOOD - understand middleware runs after built-in stack

Built-in order:

1. TodoListMiddleware

2. FilesystemMiddleware

3. SubAgentMiddleware

4. SummarizationMiddleware

5. AnthropicPromptCachingMiddleware

6. PatchToolCallsMiddleware

7. YOUR MIDDLEWARE HERE

8. HumanInTheLoopMiddleware (if interrupt_on set)

  1. Middleware Mutating Request/Response

BAD - mutating instead of returning new object

class BadMiddleware(AgentMiddleware): def transform_request(self, request): request.messages.append(extra_message) # Mutation! return request

GOOD - return modified copy

class GoodMiddleware(AgentMiddleware): def transform_request(self, request): return ModelRequest( messages=[request.messages, extra_message], *other_fields )

  1. Middleware Tools Without Descriptions

BAD - tool without docstring

@tool def my_tool(arg: str) -> str: return process(arg)

class MyMiddleware(AgentMiddleware): tools = [my_tool] # LLM won't know how to use it!

GOOD - descriptive docstring

@tool def my_tool(arg: str) -> str: """Process the input string and return formatted result.

Args:
    arg: The string to process

Returns:
    Formatted result string
"""
return process(arg)

System Prompt Issues 17. Duplicating Built-in Tool Instructions

BAD - re-explaining what middleware already covers

agent = create_deep_agent( system_prompt="""You have access to these tools: - write_todos: Create task lists - read_file: Read files from the filesystem - task: Delegate to subagents

When using files, always use absolute paths..."""

)

This duplicates what FilesystemMiddleware and TodoListMiddleware inject!

GOOD - focus on domain-specific guidance

agent = create_deep_agent( system_prompt="""You are a code review assistant.

Workflow:
1. Read the files to review
2. Create a todo list of issues found
3. Delegate deep analysis to subagents if needed
4. Compile findings into a report"""

)

  1. Contradicting Built-in Instructions

BAD - contradicting default behavior

agent = create_deep_agent( system_prompt="""Never use the task tool. Always process everything in the main thread. Don't use todos, just remember everything.""" )

Fighting against the framework!

GOOD - work with the framework

agent = create_deep_agent( system_prompt="""For simple tasks, handle directly. For complex multi-step research, use subagents. Track progress with todos for tasks with 3+ steps.""" )

  1. Missing Stopping Criteria

BAD - no guidance on when to stop

agent = create_deep_agent( system_prompt="Research everything about the topic thoroughly." )

Agent may run indefinitely!

GOOD - define completion criteria

agent = create_deep_agent( system_prompt="""Research the topic with these constraints: - Maximum 5 web searches - Stop when you have 3 reliable sources - Limit subagent delegations to 2 parallel tasks - Summarize findings within 500 words""" )

Performance Issues 20. Not Parallelizing Independent Subagents

BAD - sequential subagent calls (in agent behavior)

Agent calls: task(research topic A) → wait → task(research topic B) → wait

GOOD - parallel subagent calls

Agent calls in single turn:

task(research topic A)

task(research topic B)

task(research topic C)

All run concurrently!

Guide via system prompt:

agent = create_deep_agent( system_prompt="""When researching multiple topics, launch all research subagents in parallel in a single response.""" )

  1. Large Files in State

BAD - writing large files to StateBackend

Agent writes 10MB log file to /output/full_log.txt

This bloats every checkpoint!

GOOD - use FilesystemBackend for large files or paginate

agent = create_deep_agent( backend=CompositeBackend( default=StateBackend(), # Small files routes={ "/large_files/": FilesystemBackend(root_dir="/tmp/agent"), }, ), )

  1. InMemorySaver in Production

BAD - ephemeral checkpointer in production

agent = create_deep_agent( checkpointer=InMemorySaver(), # Lost on restart! )

GOOD - persistent checkpointer

from langgraph.checkpoint.postgres import PostgresSaver

agent = create_deep_agent( checkpointer=PostgresSaver.from_conn_string(DATABASE_URL), )

  1. Missing Recursion Awareness

BAD - no guard against long-running loops

agent = create_deep_agent( system_prompt="Keep improving the solution until it's perfect." )

May hit recursion limit (default 1000)

GOOD - explicit iteration limits

agent = create_deep_agent( system_prompt="""Improve the solution iteratively: - Maximum 3 revision cycles - Stop if quality score > 90% - Stop if no improvement after 2 iterations""" )

Code Review Checklist Configuration Checkpointer provided if using interrupt_on Store provided if using StoreBackend Thread ID provided in config when using checkpointer Backend appropriate for use case (ephemeral vs persistent) Backends FilesystemBackend scoped to safe root_dir StoreBackend has corresponding store parameter CompositeBackend routes don't shadow each other unintentionally Not expecting persistence from StateBackend across threads Subagents All required fields present (name, description, system_prompt, tools) Unique subagent names CompiledSubAgent has compatible state schema Subagents used for complex tasks, not trivial operations Middleware Custom middleware added after built-in stack (expected behavior) Tools have descriptive docstrings Not mutating request/response objects System Prompt Not duplicating built-in tool instructions Not contradicting framework defaults Stopping criteria defined for open-ended tasks Parallelization guidance for independent tasks Performance Large files routed to appropriate backend Production uses persistent checkpointer Recursion/iteration limits considered Independent subagents parallelized

返回排行榜