Adding new tool usage and parsing logic

This commit is contained in:
João Moura
2024-02-19 22:43:10 -03:00
parent 6da94c1bba
commit 3cfc8dd4e0
9 changed files with 256 additions and 101 deletions

View File

@@ -1,4 +1,5 @@
from .i18n import I18N
from .instructor import Instructor
from .logger import Logger
from .printer import Printer
from .prompts import Prompts

View File

@@ -0,0 +1,51 @@
from typing import Any, Optional, Type
import instructor
from pydantic import BaseModel, Field, PrivateAttr, model_validator
class Instructor(BaseModel):
"""Class that wraps an agent llm with instructor."""
_client: Any = PrivateAttr()
content: str = Field(description="Content to be sent to the instructor.")
agent: Optional[Any] = Field(
description="The agent that needs to use instructor.", default=None
)
llm: Optional[Any] = Field(
description="The agent that needs to use instructor.", default=None
)
instructions: Optional[str] = Field(
description="Instructions to be sent to the instructor.",
default=None,
)
model: Type[BaseModel] = Field(
description="Pydantic model to be used to create an output."
)
@model_validator(mode="after")
def set_instructor(self):
"""Set instructor."""
if self.agent and not self.llm:
self.llm = self.agent.function_calling_llm or self.agent.llm
self._client = instructor.patch(
self.llm.client._client,
mode=instructor.Mode.TOOLS,
)
return self
def to_json(self):
model = self.to_pydantic()
return model.model_dump_json(indent=2)
def to_pydantic(self):
messages = [{"role": "user", "content": self.content}]
if self.instructions:
messages.append({"role": "system", "content": self.instructions})
model = self._client.chat.completions.create(
model=self.llm.model_name, response_model=self.model, messages=messages
)
return model

View File

@@ -1,6 +1,6 @@
from typing import ClassVar
from typing import Any, ClassVar
from langchain.prompts import PromptTemplate, BasePromptTemplate
from langchain.prompts import BasePromptTemplate, PromptTemplate
from pydantic import BaseModel, Field
from crewai.utilities import I18N
@@ -10,12 +10,18 @@ class Prompts(BaseModel):
"""Manages and generates prompts for a generic agent with support for different languages."""
i18n: I18N = Field(default=I18N())
tools: list[Any] = Field(default=[])
SCRATCHPAD_SLICE: ClassVar[str] = "\n{agent_scratchpad}"
def task_execution_with_memory(self) -> BasePromptTemplate:
"""Generate a prompt for task execution with memory components."""
return self._build_prompt(["role_playing", "tools", "memory", "task"])
slices = ["role_playing"]
if len(self.tools) > 0:
slices.append("tools")
else:
slices.append("no_tools")
slices.extend(["memory", "task"])
return self._build_prompt(slices)
def task_execution_without_tools(self) -> BasePromptTemplate:
"""Generate a prompt for task execution without tools components."""
@@ -23,10 +29,17 @@ class Prompts(BaseModel):
def task_execution(self) -> BasePromptTemplate:
"""Generate a standard prompt for task execution."""
return self._build_prompt(["role_playing", "tools", "task"])
slices = ["role_playing"]
if len(self.tools) > 0:
slices.append("tools")
else:
slices.append("no_tools")
slices.append("task")
return self._build_prompt(slices)
def _build_prompt(self, components: list[str]) -> BasePromptTemplate:
"""Constructs a prompt string from specified components."""
prompt_parts = [self.i18n.slice(component) for component in components]
prompt_parts.append(self.SCRATCHPAD_SLICE)
return PromptTemplate.from_template("".join(prompt_parts))
prompt = PromptTemplate.from_template("".join(prompt_parts))
return prompt