Skip to content

Commit

Permalink
Add CRITIC agent integration (#13108)
Browse files Browse the repository at this point in the history
* init

* more scaffolding

* wireframes

* wip nb

* add introspective agent

* add introspective agent

* got memory working better now

* polish

* refactor

* refactor

* revert core changes

* rm parent_task_id

* refactor for better org

* clean up critic class

* support async for critic

* carry step state forward to next steps

* add dispatcher

* make max_iterations public

* add stopping callable

* implement jerry self reflection

* bug fix and async support for self reflection

* proper verbose propagation

* add mini showdown

* fix tests and llamahub info

* clean up IntrospectiveAgentWorker

* clean up SelfReflection

* update README

* update README

* finish README

* readme wip

* readme wip

* readme wip

* update nb and add copy to docs

* rm dev nb

* remove lock file

* use structured_predict

* update nb

* line up chat history for introspective agent better

* update nb

* update nbs
  • Loading branch information
nerdai committed May 3, 2024
1 parent 29590d2 commit b233b56
Show file tree
Hide file tree
Showing 19 changed files with 3,710 additions and 1 deletion.
1,062 changes: 1,062 additions & 0 deletions docs/docs/examples/agent/introspective_agent_toxicity_reduction.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/docs/module_guides/deploying/agents/modules.md
Expand Up @@ -39,7 +39,7 @@ For more detailed guides on how to use specific tools, check out our [tools modu
- [LLMCompiler Agent](https://llamahub.ai/l/llama-packs/llama-index-packs-agents-llm-compiler?from=) ([Cookbook](https://github.com/run-llama/llama_index/blob/main/llama-index-packs/llama-index-packs-agents-llm-compiler/examples/llm_compiler.ipynb))
- [Chain-of-Abstraction Agent](https://llamahub.ai/l/llama-packs/llama-index-packs-agents-coa?from=) ([Cookbook](https://github.com/run-llama/llama_index/blob/main/docs/docs/examples/agent/coa_agent.ipynb))
- [Language Agent Tree Search Agent](https://llamahub.ai/l/llama-packs/llama-index-packs-agents-lats?from=) ([Cookbook](https://github.com/run-llama/llama_index/blob/main/docs/docs/examples/agent/lats_agent.ipynb))

- [Instrospective Agent](https://llamahub.ai/l/agent/llama-index-agent-introspective?from=agent) ([Cookbook](https://github.com/run-llama/llama_index/blob/main/docs/docs/examples/agent/introspective_agent_toxicity_reduction.ipynb))

## Custom Agents

Expand Down
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Expand Up @@ -86,6 +86,7 @@ nav:
- ./examples/agent/lats_agent.ipynb
- ./examples/agent/llm_compiler.ipynb
- ./examples/agent/structured_planner.ipynb
- ./examples/agent/introspective_agent_toxicity_reduction.ipynb
- Callbacks:
- ./examples/callbacks/HoneyHiveLlamaIndexTracer.ipynb
- ./examples/callbacks/PromptLayerHandler.ipynb
Expand Down
@@ -0,0 +1,158 @@
llama_index/_static
.DS_Store
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
bin/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
etc/
include/
lib/
lib64/
parts/
sdist/
share/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
.ruff_cache

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints
notebooks/

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
pyvenv.cfg

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# Jetbrains
.idea
modules/
*.swp

# VsCode
.vscode

# pipenv
Pipfile
Pipfile.lock

# pyright
pyrightconfig.json

# data
data/

.DS_Store
@@ -0,0 +1,3 @@
poetry_requirements(
name="poetry",
)
@@ -0,0 +1,17 @@
GIT_ROOT ?= $(shell git rev-parse --show-toplevel)

help: ## Show all Makefile targets.
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[33m%-30s\033[0m %s\n", $$1, $$2}'

format: ## Run code autoformatters (black).
pre-commit install
git ls-files | xargs pre-commit run black --files

lint: ## Run linters: pre-commit (black, ruff, codespell) and mypy
pre-commit install && git ls-files | xargs pre-commit run --show-diff-on-failure --files

test: ## Run tests via pytest.
pytest tests

watch-docs: ## Build and watch documentation.
sphinx-autobuild docs/ docs/_build/html --open-browser --watch $(GIT_ROOT)/llama_index/
@@ -0,0 +1,143 @@
# LlamaIndex Agent Integration: Introspective Agent

## Introduction

This agent integration package includes three main agent classes:

1. `IntrospectiveAgentWorker`
2. `ToolInteractiveReflectionAgentWorker`
3. `SelfReflectionAgentWorker`

These classes are used together in order to build an "Introspective" Agent which
performs tasks while applying the reflection agentic pattern. In other words, an
introspective agent produces an initial response to a task and then performs
reflection and subsequently correction to produce an improved response to the task.

### The `IntrospectiveAgentWorker`

<p align="center">
<img height="500" src="https://d3ddy8balm3goa.cloudfront.net/llamaindex/introspective_agents.excalidraw.svg" alt="cover">
</p>

This is the agent that is responsible for performing the task while utilizing the
reflection agentic pattern. It does so by merely delegating the work to two other
agents in a purely deterministic fashion.

Specifically, when given a task, this agent delegates the task to first a
`MainAgentWorker` that generates the initial response to the query. This initial
response is then passed to the `ReflectiveAgentWorker` to perform the reflection and
subsequent correction of the initial response. Optionally, the `MainAgentWorker`
can be skipped if none is provided. In this case, the users input query
will be assumed to contain the original response that needs to go thru
reflection and correction.

### The Reflection Agent Workers

These subclasses of the `BaseAgentWorker` are responsible for performing the
reflection and correction iterations of responses (starting with the initial
response from the `MainAgentWorker`). This package contains two reflection
agent workers: `ToolInteractiveReflectionAgentWorker` and `SelfReflectionAgentWorker`.

#### The `ToolInteractiveReflectionAgentWorker`

This agent worker implements the CRITIC reflection framework introduced
by Gou, Zhibin, et al. (2024) ICLR. (source: https://arxiv.org/pdf/2305.11738)

CRITIC stands for `Correcting with tool-interactive critiquing`. It works
by performing a reflection on a response to a task/query using external tools
(e.g., fact checking using a Google search tool) and subsequently using
the critique to generate a corrected response. It cycles thru tool-interactive
reflection and correction until a specific stopping criteria has been met
or a max number of iterations has been reached.

#### The `SelfReflectionAgentWorker`

This agent performs a reflection without any tools on a given response
and subsequently performs correction. Cycles of reflection and correction are
executed until a satisfactory correction has been generated or a max number of cycles
has been reached. To perform reflection, this agent utilizes a user-specified
LLM along with a PydanticProgram to generate a structured output that contains
an LLM generated reflection of the current response. After reflection, the
same user-specified LLM is used again but this time with another PydanticProgram
to generate a structured output that contains an LLM generated corrected
version of the current response against the priorly generated reflection.

### Usage

To build an introspective agent, we make use of the typical agent usage pattern,
where we construct an `IntrospectiveAgentWorker` and wrap it with an `AgentRunner`.
(Note this can be done convienently with the `.as_agent()` method of any `AgentWorker`
class.)

#### `IntrospectiveAgent` using `SelfReflectionAgentWorker`

```python
from llama_index.agent.introspective import IntrospectiveAgentWorker
from llama_index.agent.introspective import SelfReflectionAgentWorker
from llama_index.llms.openai import OpenAI
from llama_index.agent.openai import OpenAIAgentWorker

verbose = True
self_reflection_agent_worker = SelfReflectionAgentWorker.from_defaults(
llm=OpenAI("gpt-4-turbo-preview"),
verbose=verbose,
)
main_agent_worker = OpenAIAgentWorker.from_tools(
tools=[], llm=OpenAI("gpt-4-turbo-preview"), verbose=verbose
)

introspective_worker_agent = IntrospectiveAgentWorker.from_defaults(
reflective_agent_worker=self_reflection_agent_worker,
main_agent_worker=main_agent_worker,
verbose=True,
)

introspective_agent = introspective_worker_agent.as_agent(verbose=verbose)
introspective_agent.chat("...")
```

#### `IntrospectiveAgent` using `ToolInteractiveReflectionAgentWorker`

Unlike with self reflection, here we need to define another agent worker,
namely the `CritiqueAgentWorker` that performs the reflection (or critique)
using a specified set of tools.

```python
from llama_index.llms.openai import OpenAI
from llama_index.agent.openai import OpenAIAgentWorker
from llama_index.agent.introspective import (
ToolInteractiveReflectionAgentWorker,
)
from llama_index.core.agent import FunctionCallingAgentWorker

verbose = True
critique_tools = []
critique_agent_worker = FunctionCallingAgentWorker.from_tools(
tools=[critique_tools], llm=OpenAI("gpt-3.5-turbo"), verbose=verbose
)

correction_llm = OpenAI("gpt-4-turbo-preview")
tool_interactive_reflection_agent_worker = (
ToolInteractiveReflectionAgentWorker.from_defaults(
critique_agent_worker=critique_agent_worker,
critique_template=(
"..."
), # template containing instructions for performing critique
correction_llm=correction_llm,
verbose=verbose,
)
)


introspective_worker_agent = IntrospectiveAgentWorker.from_defaults(
reflective_agent_worker=tool_interactive_reflection_agent_worker,
main_agent_worker=None, # if None, then its assumed user input is initial response
verbose=verbose,
)
introspective_agent = introspective_worker_agent.as_agent(verbose=verbose)
introspective_agent.chat("...")
```

### Examples

- [Toxicity Reduction Example](https://github.com/runllama/llama_index/blob/main/llama-index-integrations/agent/llama-index-agent-introspective/examples/toxicity_reduction.ipynb) (WARNING: this notebook contains content that may be considered offensive or sensitive to some.)

0 comments on commit b233b56

Please sign in to comment.