Project

deepagents

0.0
The project is in a healthy, maintained state
Ruby implementation of deepagents - a library for creating deep agents with planning capabilities, sub-agent spawning, and a mock file system
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 13.0
~> 3.0
~> 1.21

Runtime

 Project Readme

🧠🤖 DeepAgents for Ruby

Using an LLM to call tools in a loop is the simplest form of an agent. This architecture, however, can yield agents that are "shallow" and fail to plan and act over longer, more complex tasks. Applications like "Deep Research", "Manus", and "Claude Code" have gotten around this limitation by implementing a combination of four things: a planning tool, sub agents, access to a file system, and a detailed prompt.

deepagents is a Ruby gem that implements these in a general purpose way so that you can easily create a Deep Agent for your application.

Acknowledgements: This project was inspired by the Python deepagents library and is a Ruby implementation of its functionality.

Installation

Add this line to your application's Gemfile:

gem 'deepagents'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install deepagents

Usage

Basic Usage

require 'deepagents'
require 'anthropic'

# Initialize the Anthropic client
anthropic_client = Anthropic::Client.new(api_key: ENV['ANTHROPIC_API_KEY'])

# Define a search tool
def internet_search(query, max_results: 5, topic: 'general', include_raw_content: false)
  # In a real implementation, this would call a search API
  # For example, you could use a Ruby wrapper for Tavily or another search API
  "Search results for: #{query}"
end

# Create a tool object
search_tool = DeepAgents::Tool.new(
  "internet_search",
  "Run a web search"
) do |query, max_results: 5, topic: 'general', include_raw_content: false|
  internet_search(query, max_results: max_results, topic: topic, include_raw_content: include_raw_content)
end

# Prompt prefix to steer the agent to be an expert researcher
research_instructions = <<~INSTRUCTIONS
  You are an expert researcher. Your job is to conduct thorough research, and then write a polished report.

  You have access to a few tools.

  ## `internet_search`

  Use this to run an internet search for a given query. You can specify the number of results, the topic, and whether raw content should be included.
INSTRUCTIONS

# Create the agent using built-in model adapters
agent = DeepAgents.create_deep_agent(
  [search_tool],
  research_instructions,
  model: DeepAgents.claude_model() # or DeepAgents.openai_model()
)

# Invoke the agent
result = agent.invoke({
  messages: [{role: "user", content: "what is Ruby on Rails?"}]
})

# Access the agent's response
puts result.messages.last[:content]

Using with langchainrb and langgraph_rb

require 'deepagents'
require 'langchainrb'
require 'langgraph_rb'

# Create a search tool using langchainrb's tool system
search_tool = Langchain::Tool.new(
  name: "internet_search",
  description: "Run a web search",
  function: ->(query:, max_results: 5) {
    # In a real implementation, this would call a search API
    "Search results for: #{query}"
  }
)

# Convert to DeepAgents tool
deep_search_tool = DeepAgents::Tool.from_langchain(search_tool)

# Create a deep agent with langchainrb integration
agent = DeepAgents.create_deep_agent(
  [deep_search_tool],
  "You are an expert researcher. Your job is to conduct thorough research.",
  model: "claude-3-sonnet-20240229" # Will automatically create appropriate model adapter
)

# Run the agent
result = agent.run("What is Ruby on Rails?")
puts result

Creating a custom deep agent

There are three parameters you can pass to create_deep_agent to create your own custom deep agent.

tools (Required)

The first argument to create_deep_agent is tools. This should be an array of tool objects created using DeepAgents::Tool.new. The agent (and any subagents) will have access to these tools.

instructions (Required)

The second argument to create_deep_agent is instructions. This will serve as part of the prompt of the deep agent. Note that there is a built-in system prompt as well, so this is not the entire prompt the agent will see.

model (Optional)

By default, deepagents uses a simple placeholder model. You should provide your own model implementation that interfaces with an LLM API like Anthropic's Claude or OpenAI.

Your model class should implement a generate method that takes a prompt and messages array and returns a response string.

subagents (Optional)

A keyword parameter to create_deep_agent is subagents. This can be used to specify any custom subagents this deep agent will have access to.

subagents should be an array of DeepAgents::SubAgent objects, where each has:

  • name: The name of the subagent, and how the main agent will call the subagent
  • description: The description of the subagent that is shown to the main agent
  • prompt: The prompt used for the subagent
  • tools: The list of tools that the subagent has access to (optional)

To use it looks like:

research_sub_agent = DeepAgents::SubAgent.new(
  name: "research-agent",
  description: "Used to research more in depth questions",
  prompt: sub_research_prompt
)

agent = DeepAgents.create_deep_agent(
  tools,
  prompt,
  subagents: [research_sub_agent]
)

Integration with langchainrb and langgraph_rb

DeepAgents now integrates with the popular Ruby gems langchainrb and langgraph_rb to provide enhanced functionality and compatibility with the broader LLM ecosystem.

langchainrb Integration

The langchainrb integration provides:

  • Model Compatibility: All DeepAgents model adapters can be converted to langchainrb models using the to_langchain_model method
  • Tool Interoperability: Convert between DeepAgents tools and langchainrb tools
  • Vector Database Access: Leverage langchainrb's vector database integrations for RAG applications
  • Prompt Management: Use langchainrb's prompt templates with DeepAgents

langgraph_rb Integration

The langgraph_rb integration enables:

  • Stateful Agents: Build agents that maintain state across interactions
  • Directed Graphs: Create complex agent workflows with directed graph structures
  • Multi-Actor Systems: Coordinate multiple agents working together
  • Checkpointing: Save and restore agent state

Deep Agent Details

The below components are built into deepagents and help make it work for deep tasks off-the-shelf.

Planning Tool

deepagents comes with a built-in planning tool. This planning tool is very simple and is based on ClaudeCode's TodoWrite tool. This tool doesn't actually do anything - it is just a way for the agent to come up with a plan, and then have that in the context to help keep it on track.

File System Tools

deepagents comes with four built-in file system tools: ls, edit_file, read_file, write_file. These do not actually use a file system - rather, they mock out a file system using the agent's state object.

Right now the "file system" will only be one level deep (no sub directories).

These files can be passed in (and also retrieved) by using the files key in the agent's state.

agent = DeepAgents.create_deep_agent(...)

result = agent.invoke({
  messages: [...],
  # Pass in files to the agent using this key
  # files: {"foo.txt" => "foo", ...}
})

# Access any files afterwards like this
result.files

Sub Agents

deepagents comes with the built-in ability to call sub agents. It has access to a general-purpose subagent at all times - this is a subagent with the same instructions as the main agent and all the tools that it has access to. You can also specify custom sub agents with their own instructions and tools.

Sub agents are useful for "context quarantine" (to help not pollute the overall context of the main agent) as well as custom instructions.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.