Adding tool caching a loop execution prevention. (#25)

* Adding tool caching a loop execution prevention.

This adds some guardrails, to both prevent the same tool to be used
consecutively and also caching tool's results across the entire crew
so it cuts down execution time and eventual LLM calls.

This plays a huge role for smaller opensource models that usually fall
into those behaviors patterns.

It also includes some smaller improvements around the tool prompt and
agent tools, all with the same intention of guiding models into
better conform with agent instructions.
This commit is contained in:
João Moura
2023-12-29 22:35:23 -03:00
committed by GitHub
parent d214100f0a
commit d3ecd1d490
14 changed files with 3046 additions and 54 deletions

View File

@@ -1,10 +1,18 @@
import json
from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel, Field, Json, field_validator, model_validator
from pydantic import (
BaseModel,
Field,
InstanceOf,
Json,
field_validator,
model_validator,
)
from pydantic_core import PydanticCustomError
from .agent import Agent
from .agents import CacheHandler
from .process import Process
from .task import Task
from .tools.agent_tools import AgentTools
@@ -13,6 +21,9 @@ from .tools.agent_tools import AgentTools
class Crew(BaseModel):
"""Class that represents a group of agents, how they should work together and their tasks."""
class Config:
arbitrary_types_allowed = True
tasks: List[Task] = Field(description="List of tasks", default_factory=list)
agents: List[Agent] = Field(
description="List of agents in this crew.", default_factory=list
@@ -26,6 +37,9 @@ class Crew(BaseModel):
config: Optional[Union[Json, Dict[str, Any]]] = Field(
description="Configuration of the crew.", default=None
)
cache_handler: Optional[InstanceOf[CacheHandler]] = Field(
default=CacheHandler(), description="An instance of the CacheHandler class."
)
@classmethod
@field_validator("config", mode="before")
@@ -58,6 +72,10 @@ class Crew(BaseModel):
tasks.append(Task(**task, agent=task_agent))
self.tasks = tasks
if self.agents:
for agent in self.agents:
agent.set_cache_handler(self.cache_handler)
return self
def kickoff(self) -> str:
@@ -66,6 +84,9 @@ class Crew(BaseModel):
Returns:
Output of the crew for each task.
"""
for agent in self.agents:
agent.cache_handler = self.cache_handler
if self.process == Process.sequential:
return self.__sequential_loop()