mirror of
https://github.com/crewAIInc/crewAI.git
synced 2025-12-26 01:08:29 +00:00
Compare commits
41 Commits
test/githu
...
fix/typech
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4f7631e57 | ||
|
|
62679d2fec | ||
|
|
e3d93dbd90 | ||
|
|
4b3f9aedb3 | ||
|
|
ca3de82b09 | ||
|
|
a5a235de62 | ||
|
|
da9cc5f097 | ||
|
|
c005ec3f78 | ||
|
|
6018fe5872 | ||
|
|
bf0e70999e | ||
|
|
175d5b3dd6 | ||
|
|
9e61b8325b | ||
|
|
c4d76cde8f | ||
|
|
9c44fd8c4a | ||
|
|
f9f8c8f336 | ||
|
|
0fb3ccb9e9 | ||
|
|
0e5fd0be2c | ||
|
|
1b45daee49 | ||
|
|
9f384e3fc1 | ||
|
|
377f919d42 | ||
|
|
e6445afac5 | ||
|
|
095015d397 | ||
|
|
614183cbb1 | ||
|
|
0bc92a284d | ||
|
|
d3b6640b4a | ||
|
|
a1a48888c3 | ||
|
|
bb622bf747 | ||
|
|
946c56494e | ||
|
|
2a0e21ca76 | ||
|
|
ea893432e8 | ||
|
|
bf40956491 | ||
|
|
48948e1217 | ||
|
|
27412c89dd | ||
|
|
56f1d24e9d | ||
|
|
ab066a11a8 | ||
|
|
e35e81e554 | ||
|
|
551e48da4f | ||
|
|
21ce0aa17e | ||
|
|
2d6f2830e1 | ||
|
|
24ed8a2549 | ||
|
|
a336381849 |
5
.github/workflows/tests.yml
vendored
5
.github/workflows/tests.yml
vendored
@@ -23,10 +23,9 @@ jobs:
|
||||
|
||||
- name: Install Requirements
|
||||
run: |
|
||||
sudo apt-get update &&
|
||||
pip install poetry &&
|
||||
pip install poetry
|
||||
poetry lock &&
|
||||
poetry install
|
||||
|
||||
- name: Run tests
|
||||
run: poetry run pytest
|
||||
run: poetry run pytest tests
|
||||
|
||||
@@ -2,6 +2,8 @@ repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.4.4
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
args: [--fix]
|
||||
args: ["--fix"]
|
||||
exclude: "templates"
|
||||
- id: ruff-format
|
||||
exclude: "templates"
|
||||
|
||||
24
README.md
24
README.md
@@ -70,6 +70,17 @@ os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API key
|
||||
# os.environ["OPENAI_MODEL_NAME"] ='openhermes' # Adjust based on available model
|
||||
# os.environ["OPENAI_API_KEY"] ='sk-111111111111111111111111111111111111111111111111'
|
||||
|
||||
# You can pass an optional llm attribute specifying what model you wanna use.
|
||||
# It can be a local model through Ollama / LM Studio or a remote
|
||||
# model like OpenAI, Mistral, Antrophic or others (https://docs.crewai.com/how-to/LLM-Connections/)
|
||||
#
|
||||
# import os
|
||||
# os.environ['OPENAI_MODEL_NAME'] = 'gpt-3.5-turbo'
|
||||
#
|
||||
# OR
|
||||
#
|
||||
# from langchain_openai import ChatOpenAI
|
||||
|
||||
search_tool = SerperDevTool()
|
||||
|
||||
# Define your agents with roles and goals
|
||||
@@ -81,18 +92,9 @@ researcher = Agent(
|
||||
You have a knack for dissecting complex data and presenting actionable insights.""",
|
||||
verbose=True,
|
||||
allow_delegation=False,
|
||||
tools=[search_tool]
|
||||
# You can pass an optional llm attribute specifying what model you wanna use.
|
||||
# It can be a local model through Ollama / LM Studio or a remote
|
||||
# model like OpenAI, Mistral, Antrophic or others (https://docs.crewai.com/how-to/LLM-Connections/)
|
||||
#
|
||||
# import os
|
||||
# os.environ['OPENAI_MODEL_NAME'] = 'gpt-3.5-turbo'
|
||||
#
|
||||
# OR
|
||||
#
|
||||
# from langchain_openai import ChatOpenAI
|
||||
# llm=ChatOpenAI(model_name="gpt-3.5", temperature=0.7)
|
||||
# llm=ChatOpenAI(model_name="gpt-3.5", temperature=0.7),
|
||||
tools=[search_tool]
|
||||
)
|
||||
writer = Agent(
|
||||
role='Tech Content Strategist',
|
||||
|
||||
BIN
docs/assets/crewai-langtrace-spans.png
Normal file
BIN
docs/assets/crewai-langtrace-spans.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
docs/assets/crewai-langtrace-stats.png
Normal file
BIN
docs/assets/crewai-langtrace-stats.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 810 KiB |
@@ -24,13 +24,16 @@ description: What are crewAI Agents and how to use them.
|
||||
| **LLM** *(optional)* | Represents the language model that will run the agent. It dynamically fetches the model name from the `OPENAI_MODEL_NAME` environment variable, defaulting to "gpt-4" if not specified. |
|
||||
| **Tools** *(optional)* | Set of capabilities or functions that the agent can use to perform tasks. Expected to be instances of custom classes compatible with the agent's execution environment. Tools are initialized with a default value of an empty list. |
|
||||
| **Function Calling LLM** *(optional)* | Specifies the language model that will handle the tool calling for this agent, overriding the crew function calling LLM if passed. Default is `None`. |
|
||||
| **Max Iter** *(optional)* | The maximum number of iterations the agent can perform before being forced to give its best answer. Default is `25`. |
|
||||
| **Max RPM** *(optional)* | The maximum number of requests per minute the agent can perform to avoid rate limits. It's optional and can be left unspecified, with a default value of `None`. |
|
||||
| **max_execution_time** *(optional)* | Maximum execution time for an agent to execute a task It's optional and can be left unspecified, with a default value of `None`, menaning no max execution time |
|
||||
| **Max Iter** *(optional)* | `max_iter` is the maximum number of iterations the agent can perform before being forced to give its best answer. Default is `25`. |
|
||||
| **Max RPM** *(optional)* | `max_rpm` is Tte maximum number of requests per minute the agent can perform to avoid rate limits. It's optional and can be left unspecified, with a default value of `None`. |
|
||||
| **Max Execution Time** *(optional)* | `max_execution_time` is the Maximum execution time for an agent to execute a task. It's optional and can be left unspecified, with a default value of `None`, meaning no max execution time. |
|
||||
| **Verbose** *(optional)* | Setting this to `True` configures the internal logger to provide detailed execution logs, aiding in debugging and monitoring. Default is `False`. |
|
||||
| **Allow Delegation** *(optional)* | Agents can delegate tasks or questions to one another, ensuring that each task is handled by the most suitable agent. Default is `True`. |
|
||||
| **Step Callback** *(optional)* | A function that is called after each step of the agent. This can be used to log the agent's actions or to perform other operations. It will overwrite the crew `step_callback`. |
|
||||
| **Cache** *(optional)* | Indicates if the agent should use a cache for tool usage. Default is `True`. |
|
||||
| **System Template** *(optional)* | Specifies the system format for the agent. Default is `None`. |
|
||||
| **Prompt Template** *(optional)* | Specifies the prompt format for the agent. Default is `None`. |
|
||||
| **Response Template** *(optional)* | Specifies the response format for the agent. Default is `None`. |
|
||||
|
||||
## Creating an Agent
|
||||
|
||||
@@ -56,12 +59,43 @@ agent = Agent(
|
||||
function_calling_llm=my_llm, # Optional
|
||||
max_iter=15, # Optional
|
||||
max_rpm=None, # Optional
|
||||
max_execution_time=None, # Optional
|
||||
verbose=True, # Optional
|
||||
allow_delegation=True, # Optional
|
||||
step_callback=my_intermediate_step_callback, # Optional
|
||||
cache=True # Optional
|
||||
cache=True, # Optional
|
||||
system_template=my_system_template, # Optional
|
||||
prompt_template=my_prompt_template, # Optional
|
||||
response_template=my_response_template, # Optional
|
||||
config=my_config, # Optional
|
||||
crew=my_crew, # Optional
|
||||
tools_handler=my_tools_handler, # Optional
|
||||
cache_handler=my_cache_handler, # Optional
|
||||
callbacks=[callback1, callback2], # Optional
|
||||
agent_executor=my_agent_executor # Optional
|
||||
)
|
||||
```
|
||||
|
||||
## Setting prompt templates
|
||||
|
||||
Prompt templates are used to format the prompt for the agent. You can use to update the system, regular and response templates for the agent. Here's an example of how to set prompt templates:
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="{topic} specialist",
|
||||
goal="Figure {goal} out",
|
||||
backstory="I am the master of {role}",
|
||||
system_template="""<|start_header_id|>system<|end_header_id|>
|
||||
|
||||
{{ .System }}<|eot_id|>""",
|
||||
prompt_template="""<|start_header_id|>user<|end_header_id|>
|
||||
|
||||
{{ .Prompt }}<|eot_id|>""",
|
||||
response_template="""<|start_header_id|>assistant<|end_header_id|>
|
||||
|
||||
{{ .Response }}<|eot_id|>""",
|
||||
)
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
Agents are the building blocks of the CrewAI framework. By understanding how to define and interact with agents, you can create sophisticated AI systems that leverage the power of collaborative intelligence.
|
||||
Agents are the building blocks of the CrewAI framework. By understanding how to define and interact with agents, you can create sophisticated AI systems that leverage the power of collaborative intelligence.
|
||||
|
||||
@@ -15,16 +15,19 @@ description: Exploring the dynamics of agent collaboration within the CrewAI fra
|
||||
The `Crew` class has been enriched with several attributes to support advanced functionalities:
|
||||
|
||||
- **Language Model Management (`manager_llm`, `function_calling_llm`)**: Manages language models for executing tasks and tools, facilitating sophisticated agent-tool interactions. Note that while `manager_llm` is mandatory for hierarchical processes to ensure proper execution flow, `function_calling_llm` is optional, with a default value provided for streamlined tool interaction.
|
||||
- **Custom Manager Agent (`manager_agent`)**: Allows specifying a custom agent as the manager instead of using the default manager provided by CrewAI.
|
||||
- **Process Flow (`process`)**: Defines the execution logic (e.g., sequential, hierarchical) to streamline task distribution and execution.
|
||||
- **Verbose Logging (`verbose`)**: Offers detailed logging capabilities for monitoring and debugging purposes. It supports both integer and boolean types to indicate the verbosity level. For example, setting `verbose` to 1 might enable basic logging, whereas setting it to True enables more detailed logs.
|
||||
- **Rate Limiting (`max_rpm`)**: Ensures efficient utilization of resources by limiting requests per minute. Guidelines for setting `max_rpm` should consider the complexity of tasks and the expected load on resources.
|
||||
- **Internationalization Support (`language`, `language_file`)**: Facilitates operation in multiple languages, enhancing global usability. Supported languages and the process for utilizing the `language_file` attribute for customization should be clearly documented.
|
||||
- **Internationalization / Customization Support (`language`, `prompt_file`)**: Facilitates full customization of the inner prompts, enhancing global usability. Supported languages and the process for utilizing the `prompt_file` attribute for customization should be clearly documented. [Example of file](https://github.com/joaomdmoura/crewAI/blob/main/src/crewai/translations/en.json)
|
||||
- **Execution and Output Handling (`full_output`)**: Distinguishes between full and final outputs for nuanced control over task results. Examples showcasing the difference in outputs can aid in understanding the practical implications of this attribute.
|
||||
- **Callback and Telemetry (`step_callback`, `task_callback`)**: Integrates callbacks for step-wise and task-level execution monitoring, alongside telemetry for performance analytics. The purpose and usage of `task_callback` alongside `step_callback` for granular monitoring should be clearly explained.
|
||||
- **Crew Sharing (`share_crew`)**: Enables sharing of crew information with CrewAI for continuous improvement and training models. The privacy implications and benefits of this feature, including how it contributes to model improvement, should be outlined.
|
||||
- **Usage Metrics (`usage_metrics`)**: Stores all metrics for the language model (LLM) usage during all tasks' execution, providing insights into operational efficiency and areas for improvement. Detailed information on accessing and interpreting these metrics for performance analysis should be provided.
|
||||
- **Memory Usage (`memory`)**: Indicates whether the crew should use memory to store memories of its execution, enhancing task execution and agent learning.
|
||||
- **Embedder Configuration (`embedder`)**: Specifies the configuration for the embedder to be used by the crew for understanding and generating language. This attribute supports customization of the language model provider.
|
||||
- **Cache Management (`cache`)**: Determines whether the crew should use a cache to store the results of tool executions, optimizing performance.
|
||||
- **Output Logging (`output_log_file`)**: Specifies the file path for logging the output of the crew execution.
|
||||
|
||||
## Delegation: Dividing to Conquer
|
||||
Delegation enhances functionality by allowing agents to intelligently assign tasks or seek help, thereby amplifying the crew's overall capability.
|
||||
@@ -36,4 +39,4 @@ Setting up a crew involves defining the roles and capabilities of each agent. Cr
|
||||
Consider a crew with a researcher agent tasked with data gathering and a writer agent responsible for compiling reports. The integration of advanced language model management and process flow attributes allows for more sophisticated interactions, such as the writer delegating complex research tasks to the researcher or querying specific information, thereby facilitating a seamless workflow.
|
||||
|
||||
## Conclusion
|
||||
The integration of advanced attributes and functionalities into the CrewAI framework significantly enriches the agent collaboration ecosystem. These enhancements not only simplify interactions but also offer unprecedented flexibility and control, paving the way for sophisticated AI-driven solutions capable of tackling complex tasks through intelligent collaboration and delegation.
|
||||
The integration of advanced attributes and functionalities into the CrewAI framework significantly enriches the agent collaboration ecosystem. These enhancements not only simplify interactions but also offer unprecedented flexibility and control, paving the way for sophisticated AI-driven solutions capable of tackling complex tasks through intelligent collaboration and delegation.
|
||||
@@ -22,13 +22,15 @@ A crew in crewAI represents a collaborative group of agents working together to
|
||||
| **Language File** *(optional)* | Path to the language file to be used for the crew. |
|
||||
| **Memory** *(optional)* | Utilized for storing execution memories (short-term, long-term, entity memory). |
|
||||
| **Cache** *(optional)* | Specifies whether to use a cache for storing the results of tools' execution. |
|
||||
| **Embedder** *(optional)* | Configuration for the embedder to be used by the crew. mostly used by memory for now |
|
||||
| **Embedder** *(optional)* | Configuration for the embedder to be used by the crew. Mostly used by memory for now. |
|
||||
| **Full Output** *(optional)*| Whether the crew should return the full output with all tasks outputs or just the final output. |
|
||||
| **Step Callback** *(optional)* | A function that is called after each step of every agent. This can be used to log the agent's actions or to perform other operations; it won't override the agent-specific `step_callback`. |
|
||||
| **Task Callback** *(optional)* | A function that is called after the completion of each task. Useful for monitoring or additional operations post-task execution. |
|
||||
| **Share Crew** *(optional)* | Whether you want to share the complete crew information and execution with the crewAI team to make the library better, and allow us to train models. |
|
||||
| **Output Log File** *(optional)* | Whether you want to have a file with the complete crew output and execution. You can set it using True and it will default to the folder you are currently and it will be called logs.txt or passing a string with the full path and name of the file. |
|
||||
|
||||
| **Output Log File** *(optional)* | Whether you want to have a file with the complete crew output and execution. You can set it using True and it will default to the folder you are currently in and it will be called logs.txt or passing a string with the full path and name of the file. |
|
||||
| **Manager Agent** *(optional)* | `manager` sets a ustom agent that will be used as a manager. |
|
||||
| **Manager Callbacks** *(optional)* | `manager_callbacks` takes a list of callback handlers to be executed by the manager agent when a hierarchical process is used. |
|
||||
| **Prompt File** *(optional)* | Path to the prompt JSON file to be used for the crew. |
|
||||
|
||||
!!! note "Crew Max RPM"
|
||||
The `max_rpm` attribute sets the maximum number of requests per minute the crew can perform to avoid rate limits and will override individual agents' `max_rpm` settings if you set it.
|
||||
@@ -47,23 +49,34 @@ from langchain_community.tools import DuckDuckGoSearchRun
|
||||
researcher = Agent(
|
||||
role='Senior Research Analyst',
|
||||
goal='Discover innovative AI technologies',
|
||||
backstory="""You're a senior research analyst at a large company.
|
||||
You're responsible for analyzing data and providing insights
|
||||
to the business.
|
||||
You're currently working on a project to analyze the
|
||||
trends and innovations in the space of artificial intelligence.""",
|
||||
tools=[DuckDuckGoSearchRun()]
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role='Content Writer',
|
||||
goal='Write engaging articles on AI discoveries',
|
||||
backstory="""You're a senior writer at a large company.
|
||||
You're responsible for creating content to the business.
|
||||
You're currently working on a project to write about trends
|
||||
and innovations in the space of AI for your next meeting.""",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Create tasks for the agents
|
||||
research_task = Task(
|
||||
description='Identify breakthrough AI technologies',
|
||||
agent=researcher
|
||||
agent=researcher,
|
||||
expected_output='A bullet list summary of the top 5 most important AI news'
|
||||
)
|
||||
write_article_task = Task(
|
||||
description='Draft an article on the latest AI technologies',
|
||||
agent=writer
|
||||
agent=writer,
|
||||
expected_output='3 paragraph blog post on the latest AI technologies'
|
||||
)
|
||||
|
||||
# Assemble the crew with a sequential process
|
||||
@@ -98,7 +111,7 @@ print(crew.usage_metrics)
|
||||
## Crew Execution Process
|
||||
|
||||
- **Sequential Process**: Tasks are executed one after another, allowing for a linear flow of work.
|
||||
- **Hierarchical Process**: A manager agent coordinates the crew, delegating tasks and validating outcomes before proceeding. **Note**: A `manager_llm` is required for this process and it's essential for validating the process flow.
|
||||
- **Hierarchical Process**: A manager agent coordinates the crew, delegating tasks and validating outcomes before proceeding. **Note**: A `manager_llm` or `manager_agent` is required for this process and it's essential for validating the process flow.
|
||||
|
||||
### Kicking Off a Crew
|
||||
|
||||
@@ -109,3 +122,37 @@ Once your crew is assembled, initiate the workflow with the `kickoff()` method.
|
||||
result = my_crew.kickoff()
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Kicking Off a Crew
|
||||
|
||||
Once your crew is assembled, initiate the workflow with the appropriate kickoff method. CrewAI provides several methods for better control over the kickoff process: `kickoff()`, `kickoff_for_each()`, `kickoff_async()`, and `kickoff_for_each_async()`.
|
||||
|
||||
`kickoff()`: Starts the execution process according to the defined process flow.
|
||||
`kickoff_for_each()`: Executes tasks for each agent individually.
|
||||
`kickoff_async()`: Initiates the workflow asynchronously.
|
||||
`kickoff_for_each_async()`: Executes tasks for each agent individually in an asynchronous manner.
|
||||
|
||||
```python
|
||||
# Start the crew's task execution
|
||||
result = my_crew.kickoff()
|
||||
print(result)
|
||||
|
||||
# Example of using kickoff_for_each
|
||||
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
|
||||
results = my_crew.kickoff_for_each(inputs=inputs_array)
|
||||
for result in results:
|
||||
print(result)
|
||||
|
||||
# Example of using kickoff_async
|
||||
inputs = {'topic': 'AI in healthcare'}
|
||||
async_result = my_crew.kickoff_async(inputs=inputs)
|
||||
print(async_result)
|
||||
|
||||
# Example of using kickoff_for_each_async
|
||||
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
|
||||
async_results = my_crew.kickoff_for_each_async(inputs=inputs_array)
|
||||
for async_result in async_results:
|
||||
print(async_result)
|
||||
```
|
||||
|
||||
These methods provide flexibility in how you manage and execute tasks within your crew, allowing for both synchronous and asynchronous workflows tailored to your needs
|
||||
@@ -5,16 +5,16 @@ description: Leveraging memory systems in the crewAI framework to enhance agent
|
||||
|
||||
## Introduction to Memory Systems in crewAI
|
||||
!!! note "Enhancing Agent Intelligence"
|
||||
The crewAI framework introduces a sophisticated memory system designed to significantly enhance the capabilities of AI agents. This system comprises short-term memory, long-term memory, entity memory, and newly identified contextual memory, each serving a unique purpose in aiding agents to remember, reason, and learn from past interactions.
|
||||
The crewAI framework introduces a sophisticated memory system designed to significantly enhance the capabilities of AI agents. This system comprises short-term memory, long-term memory, entity memory, and contextual memory, each serving a unique purpose in aiding agents to remember, reason, and learn from past interactions.
|
||||
|
||||
## Memory System Components
|
||||
|
||||
| Component | Description |
|
||||
| :------------------- | :----------------------------------------------------------- |
|
||||
| **Short-Term Memory**| Temporarily stores recent interactions and outcomes, enabling agents to recall and utilize information relevant to their current context. |
|
||||
| **Long-Term Memory** | Preserves valuable insights and learnings from past executions, allowing agents to build and refine their knowledge over time. |
|
||||
| **Short-Term Memory**| Temporarily stores recent interactions and outcomes, enabling agents to recall and utilize information relevant to their current context during the current executions. |
|
||||
| **Long-Term Memory** | Preserves valuable insights and learnings from past executions, allowing agents to build and refine their knowledge over time. So Agents can remeber what they did right and wrong across multiple executions |
|
||||
| **Entity Memory** | Captures and organizes information about entities (people, places, concepts) encountered during tasks, facilitating deeper understanding and relationship mapping. |
|
||||
| **Contextual Memory**| Maintains the context of interactions, aiding in the coherence and relevance of agent responses over a sequence of tasks or a conversation. |
|
||||
| **Contextual Memory**| Maintains the context of interactions by combining `ShortTermMemory`, `LongTermMemory`, and `EntityMemory`, aiding in the coherence and relevance of agent responses over a sequence of tasks or a conversation. |
|
||||
|
||||
## How Memory Systems Empower Agents
|
||||
|
||||
@@ -27,8 +27,7 @@ description: Leveraging memory systems in the crewAI framework to enhance agent
|
||||
## Implementing Memory in Your Crew
|
||||
|
||||
When configuring a crew, you can enable and customize each memory component to suit the crew's objectives and the nature of tasks it will perform.
|
||||
By default, the memory system is disabled, and you can ensure it is active by setting `memory=True` in the crew configuration.
|
||||
The memory will use OpenAI Embeddings by default, but you can change it by setting `embedder` to a different model.
|
||||
By default, the memory system is disabled, and you can ensure it is active by setting `memory=True` in the crew configuration. The memory will use OpenAI Embeddings by default, but you can change it by setting `embedder` to a different model.
|
||||
|
||||
### Example: Configuring Memory for a Crew
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@ description: Detailed guide on workflow management through processes in CrewAI,
|
||||
## Process Implementations
|
||||
|
||||
- **Sequential**: Executes tasks sequentially, ensuring tasks are completed in an orderly progression.
|
||||
- **Hierarchical**: Organizes tasks in a managerial hierarchy, where tasks are delegated and executed based on a structured chain of command. A manager language model (`manager_llm`) must be specified in the crew to enable the hierarchical process, facilitating the creation and management of tasks by the manager.
|
||||
- **Hierarchical**: Organizes tasks in a managerial hierarchy, where tasks are delegated and executed based on a structured chain of command. A manager language model (`manager_llm`) or a custom manager agent (`manager_agent`) must be specified in the crew to enable the hierarchical process, facilitating the creation and management of tasks by the manager.
|
||||
- **Consensual Process (Planned)**: Aiming for collaborative decision-making among agents on task execution, this process type introduces a democratic approach to task management within CrewAI. It is planned for future development and is not currently implemented in the codebase.
|
||||
|
||||
## The Role of Processes in Teamwork
|
||||
Processes enable individual agents to operate as a cohesive unit, streamlining their efforts to achieve common objectives with efficiency and coherence.
|
||||
|
||||
## Assigning Processes to a Crew
|
||||
To assign a process to a crew, specify the process type upon crew creation to set the execution strategy. For a hierarchical process, ensure to define `manager_llm` for the manager agent.
|
||||
To assign a process to a crew, specify the process type upon crew creation to set the execution strategy. For a hierarchical process, ensure to define `manager_llm` or `manager_agent` for the manager agent.
|
||||
|
||||
```python
|
||||
from crewai import Crew
|
||||
@@ -32,15 +32,17 @@ crew = Crew(
|
||||
)
|
||||
|
||||
# Example: Creating a crew with a hierarchical process
|
||||
# Ensure to provide a manager_llm
|
||||
# Ensure to provide a manager_llm or manager_agent
|
||||
crew = Crew(
|
||||
agents=my_agents,
|
||||
tasks=my_tasks,
|
||||
process=Process.hierarchical,
|
||||
manager_llm=ChatOpenAI(model="gpt-4")
|
||||
# or
|
||||
# manager_agent=my_manager_agent
|
||||
)
|
||||
```
|
||||
**Note:** Ensure `my_agents` and `my_tasks` are defined prior to creating a `Crew` object, and for the hierarchical process, `manager_llm` is also required.
|
||||
**Note:** Ensure `my_agents` and `my_tasks` are defined prior to creating a `Crew` object, and for the hierarchical process, either `manager_llm` or `manager_agent` is also required.
|
||||
|
||||
## Sequential Process
|
||||
This method mirrors dynamic team workflows, progressing through tasks in a thoughtful and systematic manner. Task execution follows the predefined order in the task list, with the output of one task serving as context for the next.
|
||||
@@ -48,7 +50,7 @@ This method mirrors dynamic team workflows, progressing through tasks in a thoug
|
||||
To customize task context, utilize the `context` parameter in the `Task` class to specify outputs that should be used as context for subsequent tasks.
|
||||
|
||||
## Hierarchical Process
|
||||
Emulates a corporate hierarchy, CrewAI automatically creates a manager for you, requiring the specification of a manager language model (`manager_llm`) for the manager agent. This agent oversees task execution, including planning, delegation, and validation. Tasks are not pre-assigned; the manager allocates tasks to agents based on their capabilities, reviews outputs, and assesses task completion.
|
||||
Emulates a corporate hierarchy, CrewAI allows specifying a custom manager agent or automatically creates one, requiring the specification of a manager language model (`manager_llm`). This agent oversees task execution, including planning, delegation, and validation. Tasks are not pre-assigned; the manager allocates tasks to agents based on their capabilities, reviews outputs, and assesses task completion.
|
||||
|
||||
## Process Class: Detailed Overview
|
||||
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`). The consensual process is planned for future inclusion, emphasizing our commitment to continuous development and innovation.
|
||||
|
||||
@@ -88,7 +88,7 @@ This demonstrates how tasks with specific tools can override an agent's default
|
||||
|
||||
## Referring to Other Tasks
|
||||
|
||||
In crewAI, the output of one task is automatically relayed into the next one, but you can specifically define what tasks' output, including multiple should be used as context for another task.
|
||||
In crewAI, the output of one task is automatically relayed into the next one, but you can specifically define what tasks' output, including multiple, should be used as context for another task.
|
||||
|
||||
This is useful when you have a task that depends on the output of another task that is not performed immediately after it. This is done through the `context` attribute of the task:
|
||||
|
||||
@@ -225,6 +225,25 @@ While creating and executing tasks, certain validation mechanisms are in place t
|
||||
|
||||
These validations help in maintaining the consistency and reliability of task executions within the crewAI framework.
|
||||
|
||||
## Creating Directories when Saving Files
|
||||
|
||||
You can now specify if a task should create directories when saving its output to a file. This is particularly useful for organizing outputs and ensuring that file paths are correctly structured.
|
||||
|
||||
```python
|
||||
# ...
|
||||
|
||||
save_output_task = Task(
|
||||
description='Save the summarized AI news to a file',
|
||||
expected_output='File saved successfully',
|
||||
agent=research_agent,
|
||||
tools=[file_save_tool],
|
||||
output_file='outputs/ai_news_summary.txt',
|
||||
create_directory=True
|
||||
)
|
||||
|
||||
#...
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Tasks are the driving force behind the actions of agents in crewAI. By properly defining tasks and their outcomes, you set the stage for your AI agents to work effectively, either independently or as a collaborative unit. Equipping tasks with appropriate tools, understanding the execution process, and following robust validation practices are crucial for maximizing CrewAI's potential, ensuring agents are effectively prepared for their assignments and that tasks are executed as intended.
|
||||
Tasks are the driving force behind the actions of agents in crewAI. By properly defining tasks and their outcomes, you set the stage for your AI agents to work effectively, either independently or as a collaborative unit. Equipping tasks with appropriate tools, understanding the execution process, and following robust validation practices are crucial for maximizing CrewAI's potential, ensuring agents are effectively prepared for their assignments and that tasks are executed as intended.
|
||||
|
||||
@@ -94,7 +94,7 @@ crew.kickoff()
|
||||
## Available crewAI Tools
|
||||
|
||||
- **Error Handling**: All tools are built with error handling capabilities, allowing agents to gracefully manage exceptions and continue their tasks.
|
||||
- **Caching Mechanism**: All tools support caching, enabling agents to efficiently reuse previously obtained results, reducing the load on external resources and speeding up the execution time, you can also define finner control over the caching mechanism, using `cache_function` attribute on the tool.
|
||||
- **Caching Mechanism**: All tools support caching, enabling agents to efficiently reuse previously obtained results, reducing the load on external resources and speeding up the execution time. You can also define finer control over the caching mechanism using the `cache_function` attribute on the tool.
|
||||
|
||||
Here is a list of the available tools and their descriptions:
|
||||
|
||||
@@ -107,7 +107,7 @@ Here is a list of the available tools and their descriptions:
|
||||
| **DirectoryReadTool** | Facilitates reading and processing of directory structures and their contents. |
|
||||
| **FileReadTool** | Enables reading and extracting data from files, supporting various file formats. |
|
||||
| **GithubSearchTool** | A RAG tool for searching within GitHub repositories, useful for code and documentation search.|
|
||||
| **SerperDevTool** | A specialized tool for development purposes, with specific functionalities under development. |
|
||||
| **SerperDevTool** | A specialized tool for development purposes, with specific functionalities under development. |
|
||||
| **TXTSearchTool** | A RAG tool focused on searching within text (.txt) files, suitable for unstructured data. |
|
||||
| **JSONSearchTool** | A RAG tool designed for searching within JSON files, catering to structured data handling. |
|
||||
| **MDXSearchTool** | A RAG tool tailored for searching within Markdown (MDX) files, useful for documentation. |
|
||||
@@ -120,13 +120,14 @@ Here is a list of the available tools and their descriptions:
|
||||
| **XMLSearchTool** | A RAG tool designed for searching within XML files, suitable for structured data formats. |
|
||||
| **YoutubeChannelSearchTool**| A RAG tool for searching within YouTube channels, useful for video content analysis. |
|
||||
| **YoutubeVideoSearchTool** | A RAG tool aimed at searching within YouTube videos, ideal for video data extraction. |
|
||||
| **BrowserbaseTool** | A tool for interacting with and extracting data from web browsers. |
|
||||
| **ExaSearchTool** | A tool designed for performing exhaustive searches across various data sources. |
|
||||
|
||||
## Creating your own Tools
|
||||
|
||||
!!! example "Custom Tool Creation"
|
||||
Developers can craft custom tools tailored for their agent’s needs or utilize pre-built options:
|
||||
|
||||
|
||||
To create your own crewAI tools you will need to install our extra tools package:
|
||||
|
||||
```bash
|
||||
@@ -141,7 +142,7 @@ from crewai_tools import BaseTool
|
||||
|
||||
class MyCustomTool(BaseTool):
|
||||
name: str = "Name of my tool"
|
||||
description: str = "Clear description for what this tool is useful for, you agent will need this information to use it."
|
||||
description: str = "Clear description for what this tool is useful for, your agent will need this information to use it."
|
||||
|
||||
def _run(self, argument: str) -> str:
|
||||
# Implementation goes here
|
||||
@@ -154,7 +155,7 @@ class MyCustomTool(BaseTool):
|
||||
from crewai_tools import tool
|
||||
@tool("Name of my tool")
|
||||
def my_tool(question: str) -> str:
|
||||
"""Clear description for what this tool is useful for, you agent will need this information to use it."""
|
||||
"""Clear description for what this tool is useful for, your agent will need this information to use it."""
|
||||
# Function logic here
|
||||
return "Result from your custom tool"
|
||||
```
|
||||
@@ -180,45 +181,14 @@ multiplication_tool.cache_function = cache_func
|
||||
|
||||
writer1 = Agent(
|
||||
role="Writer",
|
||||
goal="You write lesssons of math for kids.",
|
||||
backstory="You're an expert in writting and you love to teach kids but you know nothing of math.",
|
||||
tools=[multiplcation_tool],
|
||||
goal="You write lessons of math for kids.",
|
||||
backstory="You're an expert in writing and you love to teach kids but you know nothing of math.",
|
||||
tools=[multiplication_tool],
|
||||
allow_delegation=False,
|
||||
)
|
||||
#...
|
||||
```
|
||||
|
||||
## Using LangChain Tools
|
||||
!!! info "LangChain Integration"
|
||||
CrewAI seamlessly integrates with LangChain’s comprehensive toolkit for search-based queries and more, here are the available built-in tools that are offered by Langchain [LangChain Toolkit](https://python.langchain.com/docs/integrations/tools/)
|
||||
:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from langchain.agents import Tool
|
||||
from langchain.utilities import GoogleSerperAPIWrapper
|
||||
|
||||
# Setup API keys
|
||||
os.environ["SERPER_API_KEY"] = "Your Key"
|
||||
|
||||
search = GoogleSerperAPIWrapper()
|
||||
|
||||
# Create and assign the search tool to an agent
|
||||
serper_tool = Tool(
|
||||
name="Intermediate Answer",
|
||||
func=search.run,
|
||||
description="Useful for search-based queries",
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
role='Research Analyst',
|
||||
goal='Provide up-to-date market analysis',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[serper_tool]
|
||||
)
|
||||
|
||||
# rest of the code ...
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
Tools are pivotal in extending the capabilities of CrewAI agents, enabling them to undertake a broad spectrum of tasks and collaborate effectively. When building solutions with CrewAI, leverage both custom and existing tools to empower your agents and enhance the AI ecosystem. Consider utilizing error handling, caching mechanisms, and the flexibility of tool arguments to optimize your agents' performance and capabilities.
|
||||
Tools are pivotal in extending the capabilities of CrewAI agents, enabling them to undertake a broad spectrum of tasks and collaborate effectively. When building solutions with CrewAI, leverage both custom and existing tools to empower your agents and enhance the AI ecosystem. Consider utilizing error handling, caching mechanisms, and the flexibility of tool arguments to optimize your agents' performance and capabilities.
|
||||
38
docs/core-concepts/Using-LangChain-Tools.md
Normal file
38
docs/core-concepts/Using-LangChain-Tools.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: Using LangChain Tools
|
||||
description: Learn how to integrate LangChain tools with CrewAI agents to enhance search-based queries and more.
|
||||
---
|
||||
|
||||
## Using LangChain Tools
|
||||
!!! info "LangChain Integration"
|
||||
CrewAI seamlessly integrates with LangChain’s comprehensive toolkit for search-based queries and more, here are the available built-in tools that are offered by Langchain [LangChain Toolkit](https://python.langchain.com/docs/integrations/tools/)
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from langchain.agents import Tool
|
||||
from langchain.utilities import GoogleSerperAPIWrapper
|
||||
|
||||
# Setup API keys
|
||||
os.environ["SERPER_API_KEY"] = "Your Key"
|
||||
|
||||
search = GoogleSerperAPIWrapper()
|
||||
|
||||
# Create and assign the search tool to an agent
|
||||
serper_tool = Tool(
|
||||
name="Intermediate Answer",
|
||||
func=search.run,
|
||||
description="Useful for search-based queries",
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
role='Research Analyst',
|
||||
goal='Provide up-to-date market analysis',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[serper_tool]
|
||||
)
|
||||
|
||||
# rest of the code ...
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
Tools are pivotal in extending the capabilities of CrewAI agents, enabling them to undertake a broad spectrum of tasks and collaborate effectively. When building solutions with CrewAI, leverage both custom and existing tools to empower your agents and enhance the AI ecosystem. Consider utilizing error handling, caching mechanisms, and the flexibility of tool arguments to optimize your agents' performance and capabilities.
|
||||
57
docs/core-concepts/Using-LlamaIndex-Tools.md
Normal file
57
docs/core-concepts/Using-LlamaIndex-Tools.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Using LlamaIndex Tools
|
||||
description: Learn how to integrate LlamaIndex tools with CrewAI agents to enhance search-based queries and more.
|
||||
---
|
||||
|
||||
## Using LlamaIndex Tools
|
||||
|
||||
!!! info "LlamaIndex Integration"
|
||||
CrewAI seamlessly integrates with LlamaIndex’s comprehensive toolkit for RAG (Retrieval-Augmented Generation) and agentic pipelines, enabling advanced search-based queries and more. Here are the available built-in tools offered by LlamaIndex.
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai_tools import LlamaIndexTool
|
||||
|
||||
# Example 1: Initialize from FunctionTool
|
||||
from llama_index.core.tools import FunctionTool
|
||||
|
||||
your_python_function = lambda ...: ...
|
||||
og_tool = FunctionTool.from_defaults(your_python_function, name="<name>", description='<description>')
|
||||
tool = LlamaIndexTool.from_tool(og_tool)
|
||||
|
||||
# Example 2: Initialize from LlamaHub Tools
|
||||
from llama_index.tools.wolfram_alpha import WolframAlphaToolSpec
|
||||
wolfram_spec = WolframAlphaToolSpec(app_id="<app_id>")
|
||||
wolfram_tools = wolfram_spec.to_tool_list()
|
||||
tools = [LlamaIndexTool.from_tool(t) for t in wolfram_tools]
|
||||
|
||||
# Example 3: Initialize Tool from a LlamaIndex Query Engine
|
||||
query_engine = index.as_query_engine()
|
||||
query_tool = LlamaIndexTool.from_query_engine(
|
||||
query_engine,
|
||||
name="Uber 2019 10K Query Tool",
|
||||
description="Use this tool to lookup the 2019 Uber 10K Annual Report"
|
||||
)
|
||||
|
||||
# Create and assign the tools to an agent
|
||||
agent = Agent(
|
||||
role='Research Analyst',
|
||||
goal='Provide up-to-date market analysis',
|
||||
backstory='An expert analyst with a keen eye for market trends.',
|
||||
tools=[tool, *tools, query_tool]
|
||||
)
|
||||
|
||||
# rest of the code ...
|
||||
```
|
||||
|
||||
## Steps to Get Started
|
||||
|
||||
To effectively use the LlamaIndexTool, follow these steps:
|
||||
|
||||
1. **Package Installation**: Confirm that the `crewai[tools]` package is installed in your Python environment.
|
||||
|
||||
```shell
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
2. **Install and Use LlamaIndex**: Follow LlamaIndex documentation [LlamaIndex Documentation](https://docs.llamaindex.ai/) to set up a RAG/agent pipeline.
|
||||
@@ -4,8 +4,7 @@ description: Understanding and logging your agent performance with AgentOps.
|
||||
---
|
||||
|
||||
# Intro
|
||||
Observability is a key aspect of developing and deploying conversational AI agents. It allows developers to understand how their agents are performing, how their agents are interacting with users, and how their agents use external tools and APIs. AgentOps is a product independent of CrewAI that provides a comprehensive observability solution for agents.
|
||||
|
||||
Observability is a key aspect of developing and deploying conversational AI agents. It allows developers to understand how their agents are performing, how their agents are interacting with users, and how their agents use external tools and APIs. AgentOps is a product independent of CrewAI that provides a comprehensive observability solution for agents.
|
||||
|
||||
## AgentOps
|
||||
|
||||
@@ -23,54 +22,53 @@ Additionally, AgentOps provides session drilldowns for viewing Crew agent intera
|
||||

|
||||
|
||||
### Features
|
||||
- **LLM Cost Management and Tracking**: Track spend with foundation model providers
|
||||
- **Replay Analytics**: Watch step-by-step agent execution graphs
|
||||
- **Recursive Thought Detection**: Identify when agents fall into infinite loops
|
||||
- **Custom Reporting**: Create custom analytics on agent performance
|
||||
- **Analytics Dashboard**: Monitor high level statistics about agents in development and production
|
||||
- **Public Model Testing**: Test your agents against benchmarks and leaderboards
|
||||
- **Custom Tests**: Run your agents against domain specific tests
|
||||
- **Time Travel Debugging**: Restart your sessions from checkpoints
|
||||
- **Compliance and Security**: Create audit logs and detect potential threats such as profanity and PII leaks
|
||||
- **Prompt Injection Detection**: Identify potential code injection and secret leaks
|
||||
- **LLM Cost Management and Tracking**: Track spend with foundation model providers.
|
||||
- **Replay Analytics**: Watch step-by-step agent execution graphs.
|
||||
- **Recursive Thought Detection**: Identify when agents fall into infinite loops.
|
||||
- **Custom Reporting**: Create custom analytics on agent performance.
|
||||
- **Analytics Dashboard**: Monitor high-level statistics about agents in development and production.
|
||||
- **Public Model Testing**: Test your agents against benchmarks and leaderboards.
|
||||
- **Custom Tests**: Run your agents against domain-specific tests.
|
||||
- **Time Travel Debugging**: Restart your sessions from checkpoints.
|
||||
- **Compliance and Security**: Create audit logs and detect potential threats such as profanity and PII leaks.
|
||||
- **Prompt Injection Detection**: Identify potential code injection and secret leaks.
|
||||
|
||||
### Using AgentOps
|
||||
|
||||
1. **Create an API Key:**
|
||||
Create a user API key here: [Create API Key](app.agentops.ai/account)
|
||||
Create a user API key here: [Create API Key](app.agentops.ai/account)
|
||||
|
||||
2. **Configure Your Environment:**
|
||||
Add your API key to your environment variables
|
||||
Add your API key to your environment variables
|
||||
|
||||
```
|
||||
AGENTOPS_API_KEY=<YOUR_AGENTOPS_API_KEY>
|
||||
```
|
||||
```bash
|
||||
AGENTOPS_API_KEY=<YOUR_AGENTOPS_API_KEY>
|
||||
```
|
||||
|
||||
3. **Install AgentOps:**
|
||||
Install AgentOps with:
|
||||
```
|
||||
pip install crewai[agentops]
|
||||
```
|
||||
or
|
||||
```
|
||||
pip install agentops
|
||||
```
|
||||
Install AgentOps with:
|
||||
```bash
|
||||
pip install crewai[agentops]
|
||||
```
|
||||
or
|
||||
```bash
|
||||
pip install agentops
|
||||
```
|
||||
|
||||
Before using `Crew` in your script, include these lines:
|
||||
Before using `Crew` in your script, include these lines:
|
||||
|
||||
```python
|
||||
import agentops
|
||||
agentops.init()
|
||||
```
|
||||
```python
|
||||
import agentops
|
||||
agentops.init()
|
||||
```
|
||||
|
||||
This will initiate an AgentOps session as well as automatically track Crew agents. For further info on how to outfit more complex agentic systems, check out the [AgentOps documentation](https://docs.agentops.ai) or join the [Discord](https://discord.gg/j4f3KbeH).
|
||||
This will initiate an AgentOps session as well as automatically track Crew agents. For further info on how to outfit more complex agentic systems, check out the [AgentOps documentation](https://docs.agentops.ai) or join the [Discord](https://discord.gg/j4f3KbeH).
|
||||
|
||||
### Crew + AgentOps Examples
|
||||
- [Job Posting](https://github.com/joaomdmoura/crewAI-examples/tree/main/job-posting)
|
||||
- [Markdown Validator](https://github.com/joaomdmoura/crewAI-examples/tree/main/markdown_validator)
|
||||
- [Instagram Post](https://github.com/joaomdmoura/crewAI-examples/tree/main/instagram_post)
|
||||
|
||||
|
||||
### Further Information
|
||||
|
||||
To get started, create an [AgentOps account](https://agentops.ai/?=crew).
|
||||
|
||||
@@ -42,6 +42,7 @@ def my_simple_tool(question: str) -> str:
|
||||
# Tool logic here
|
||||
return "Tool output"
|
||||
```
|
||||
|
||||
### Defining a Cache Function for the Tool
|
||||
|
||||
To optimize tool performance with caching, define custom caching strategies using the `cache_function` attribute.
|
||||
|
||||
@@ -16,7 +16,7 @@ pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
## Step 1: Assemble Your Agents
|
||||
Define your agents with distinct roles, backstories, and enhanced capabilities like verbose mode and memory usage. These elements add depth and guide their task execution and interaction within the crew.
|
||||
Define your agents with distinct roles, backstories, and enhanced capabilities like verbose mode, memory usage, and the ability to set specific agents as managers. These elements add depth and guide their task execution and interaction within the crew.
|
||||
|
||||
```python
|
||||
import os
|
||||
@@ -24,8 +24,10 @@ os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API key
|
||||
os.environ["OPENAI_API_KEY"] = "Your Key"
|
||||
|
||||
from crewai import Agent
|
||||
from crewai_tools import SerperDevTool
|
||||
from crewai_tools import SerperDevTool, BrowserbaseTool, ExaSearchTool
|
||||
search_tool = SerperDevTool()
|
||||
browser_tool = BrowserbaseTool()
|
||||
exa_search_tool = ExaSearchTool()
|
||||
|
||||
# Creating a senior researcher agent with memory and verbose mode
|
||||
researcher = Agent(
|
||||
@@ -38,8 +40,7 @@ researcher = Agent(
|
||||
"innovation, eager to explore and share knowledge that could change"
|
||||
"the world."
|
||||
),
|
||||
tools=[search_tool],
|
||||
allow_delegation=True
|
||||
tools=[search_tool, browser_tool],
|
||||
)
|
||||
|
||||
# Creating a writer agent with custom tools and delegation capability
|
||||
@@ -53,9 +54,20 @@ writer = Agent(
|
||||
"engaging narratives that captivate and educate, bringing new"
|
||||
"discoveries to light in an accessible manner."
|
||||
),
|
||||
tools=[search_tool],
|
||||
tools=[exa_search_tool],
|
||||
allow_delegation=False
|
||||
)
|
||||
|
||||
# Setting a specific manager agent
|
||||
manager = Agent(
|
||||
role='Manager',
|
||||
goal='Ensure the smooth operation and coordination of the team',
|
||||
verbose=True,
|
||||
backstory=(
|
||||
"As a seasoned project manager, you excel in organizing"
|
||||
"tasks, managing timelines, and ensuring the team stays on track."
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Step 2: Define the Tasks
|
||||
@@ -75,6 +87,8 @@ research_task = Task(
|
||||
expected_output='A comprehensive 3 paragraphs long report on the latest AI trends.',
|
||||
tools=[search_tool],
|
||||
agent=researcher,
|
||||
callback="research_callback", # Example of task callback
|
||||
human_input=True
|
||||
)
|
||||
|
||||
# Writing task with language model configuration
|
||||
@@ -85,15 +99,14 @@ write_task = Task(
|
||||
"This article should be easy to understand, engaging, and positive."
|
||||
),
|
||||
expected_output='A 4 paragraph article on {topic} advancements formatted as markdown.',
|
||||
tools=[search_tool],
|
||||
tools=[exa_search_tool],
|
||||
agent=writer,
|
||||
async_execution=False,
|
||||
output_file='new-blog-post.md' # Example of output customization
|
||||
output_file='new-blog-post.md', # Example of output customization
|
||||
)
|
||||
```
|
||||
|
||||
## Step 3: Form the Crew
|
||||
Combine your agents into a crew, setting the workflow process they'll follow to accomplish the tasks. Now with options to configure language models for enhanced interaction and additional configurations for optimizing performance.
|
||||
Combine your agents into a crew, setting the workflow process they'll follow to accomplish the tasks. Now with options to configure language models for enhanced interaction and additional configurations for optimizing performance, such as creating directories when saving files.
|
||||
|
||||
```python
|
||||
from crewai import Crew, Process
|
||||
@@ -106,7 +119,7 @@ crew = Crew(
|
||||
memory=True,
|
||||
cache=True,
|
||||
max_rpm=100,
|
||||
share_crew=True
|
||||
manager_agent=manager
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
94
docs/how-to/Customize-Prompts.md
Normal file
94
docs/how-to/Customize-Prompts.md
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: Initial Support to Bring Your Own Prompts in CrewAI
|
||||
description: Enhancing customization and internationalization by allowing users to bring their own prompts in CrewAI.
|
||||
|
||||
---
|
||||
|
||||
# Initial Support to Bring Your Own Prompts in CrewAI
|
||||
|
||||
CrewAI now supports the ability to bring your own prompts, enabling extensive customization and internationalization. This feature allows users to tailor the inner workings of their agents to better suit specific needs, including support for multiple languages.
|
||||
|
||||
## Internationalization and Customization Support
|
||||
|
||||
### Custom Prompts with `prompt_file`
|
||||
|
||||
The `prompt_file` attribute facilitates full customization of the agent prompts, enhancing the global usability of CrewAI. Users can specify their prompt templates, ensuring that the agents communicate in a manner that aligns with specific project requirements or language preferences.
|
||||
|
||||
#### Example of a Custom Prompt File
|
||||
|
||||
The custom prompts can be defined in a JSON file, similar to the example provided [here](https://github.com/joaomdmoura/crewAI/blob/main/src/crewai/translations/en.json).
|
||||
|
||||
### Supported Languages
|
||||
|
||||
CrewAI's custom prompt support includes internationalization, allowing prompts to be written in different languages. This is particularly useful for global teams or projects that require multilingual support.
|
||||
|
||||
## How to Use the `prompt_file` Attribute
|
||||
|
||||
To utilize the `prompt_file` attribute, include it in your crew definition. Below is an example demonstrating how to set up agents and tasks with custom prompts.
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import os
|
||||
from crewai import Agent, Task, Crew
|
||||
|
||||
# Define your agents
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Make the best research and analysis on content about AI and AI agents",
|
||||
backstory="You're an expert researcher, specialized in technology, software engineering, AI and startups. You work as a freelancer and is now working on doing research and analysis for a new customer.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role="Senior Writer",
|
||||
goal="Write the best content about AI and AI agents.",
|
||||
backstory="You're a senior writer, specialized in technology, software engineering, AI and startups. You work as a freelancer and are now working on writing content for a new customer.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
# Define your tasks
|
||||
tasks = [
|
||||
Task(
|
||||
description="Say Hi",
|
||||
expected_output="The word: Hi",
|
||||
agent=researcher,
|
||||
)
|
||||
]
|
||||
|
||||
# Instantiate your crew with custom prompts
|
||||
crew = Crew(
|
||||
agents=[researcher],
|
||||
tasks=tasks,
|
||||
prompt_file="prompt.json", # Path to your custom prompt file
|
||||
)
|
||||
|
||||
# Get your crew to work!
|
||||
crew.kickoff()
|
||||
```
|
||||
|
||||
## Advanced Customization Features
|
||||
|
||||
### `language` Attribute
|
||||
|
||||
In addition to `prompt_file`, the `language` attribute can be used to specify the language for the agent's prompts. This ensures that the prompts are generated in the desired language, further enhancing the internationalization capabilities of CrewAI.
|
||||
|
||||
### Creating Custom Prompt Files
|
||||
|
||||
Custom prompt files should be structured in JSON format and include all necessary prompt templates. Below is a simplified example of a prompt JSON file:
|
||||
|
||||
```json
|
||||
{
|
||||
"system": "You are a system template.",
|
||||
"prompt": "Here is your prompt template.",
|
||||
"response": "Here is your response template."
|
||||
}
|
||||
```
|
||||
|
||||
### Benefits of Custom Prompts
|
||||
|
||||
- **Enhanced Flexibility**: Tailor agent communication to specific project needs.
|
||||
- **Improved Usability**: Supports multiple languages, making it suitable for global projects.
|
||||
- **Consistency**: Ensures uniform prompt structures across different agents and tasks.
|
||||
|
||||
By incorporating these updates, CrewAI provides users with the ability to fully customize and internationalize their agent prompts, making the platform more versatile and user-friendly.
|
||||
@@ -10,7 +10,16 @@ Crafting an efficient CrewAI team hinges on the ability to dynamically tailor yo
|
||||
- **Role**: Specifies the agent's job within the crew, such as 'Analyst' or 'Customer Service Rep'.
|
||||
- **Goal**: Defines what the agent aims to achieve, in alignment with its role and the overarching objectives of the crew.
|
||||
- **Backstory**: Provides depth to the agent's persona, enriching its motivations and engagements within the crew.
|
||||
- **Tools**: Represents the capabilities or methods the agent uses to perform tasks, from simple functions to intricate integrations.
|
||||
- **Tools** *(Optional)*: Represents the capabilities or methods the agent uses to perform tasks, from simple functions to intricate integrations.
|
||||
- **Cache** *(Optional)*: Determines whether the agent should use a cache for tool usage.
|
||||
- **Max RPM**: Sets the maximum number of requests per minute (`max_rpm`). This attribute is optional and can be set to `None` for no limit, allowing for unlimited queries to external services if needed.
|
||||
- **Verbose** *(Optional)*: Enables detailed logging of an agent's actions, useful for debugging and optimization. Specifically, it provides insights into agent execution processes, aiding in the optimization of performance.
|
||||
- **Allow Delegation** *(Optional)*: `allow_delegation` controls whether the agent is allowed to delegate tasks to other agents.
|
||||
- **Max Iter** *(Optional)*: The `max_iter` attribute allows users to define the maximum number of iterations an agent can perform for a single task, preventing infinite loops or excessively long executions. The default value is set to 25, providing a balance between thoroughness and efficiency. Once the agent approaches this number, it will try its best to give a good answer.
|
||||
- **Max Execution Time** *(Optional)*: `max_execution_time` Sets the maximum execution time for an agent to complete a task.
|
||||
- **System Template** *(Optional)*: `system_template` defines the system format for the agent.
|
||||
- **Prompt Template** *(Optional)*: `prompt_template` defines the prompt format for the agent.
|
||||
- **Response Template** *(Optional)*: `response_template` defines the response format for the agent.
|
||||
|
||||
## Advanced Customization Options
|
||||
Beyond the basic attributes, CrewAI allows for deeper customization to enhance an agent's behavior and capabilities significantly.
|
||||
@@ -26,7 +35,7 @@ Adjusting an agent's performance and monitoring its operations are crucial for e
|
||||
- **RPM Limit**: Sets the maximum number of requests per minute (`max_rpm`). This attribute is optional and can be set to `None` for no limit, allowing for unlimited queries to external services if needed.
|
||||
|
||||
### Maximum Iterations for Task Execution
|
||||
The `max_iter` attribute allows users to define the maximum number of iterations an agent can perform for a single task, preventing infinite loops or excessively long executions. The default value is set to 15, providing a balance between thoroughness and efficiency. Once the agent approaches this number, it will try its best to give a good answer.
|
||||
The `max_iter` attribute allows users to define the maximum number of iterations an agent can perform for a single task, preventing infinite loops or excessively long executions. The default value is set to 25, providing a balance between thoroughness and efficiency. Once the agent approaches this number, it will try its best to give a good answer.
|
||||
|
||||
## Customizing Agents and Tools
|
||||
Agents are customized by defining their attributes and tools during initialization. Tools are critical for an agent's functionality, enabling them to perform specialized tasks. The `tools` attribute should be an array of tools the agent can utilize, and it's initialized as an empty list by default. Tools can be added or modified post-agent initialization to adapt to new requirements.
|
||||
@@ -57,7 +66,7 @@ agent = Agent(
|
||||
memory=True, # Enable memory
|
||||
verbose=True,
|
||||
max_rpm=None, # No limit on requests per minute
|
||||
max_iter=15, # Default value for maximum iterations
|
||||
max_iter=25, # Default value for maximum iterations
|
||||
allow_delegation=False
|
||||
)
|
||||
```
|
||||
|
||||
@@ -10,7 +10,7 @@ The hierarchical process in CrewAI introduces a structured approach to task mana
|
||||
The hierarchical process is designed to leverage advanced models like GPT-4, optimizing token usage while handling complex tasks with greater efficiency.
|
||||
|
||||
## Hierarchical Process Overview
|
||||
By default, tasks in CrewAI are managed through a sequential process. However, adopting a hierarchical approach allows for a clear hierarchy in task management, where a 'manager' agent coordinates the workflow, delegates tasks, and validates outcomes for streamlined and effective execution. This manager agent is automatically created by crewAI so you don't need to worry about it.
|
||||
By default, tasks in CrewAI are managed through a sequential process. However, adopting a hierarchical approach allows for a clear hierarchy in task management, where a 'manager' agent coordinates the workflow, delegates tasks, and validates outcomes for streamlined and effective execution. This manager agent can now be either automatically created by CrewAI or explicitly set by the user.
|
||||
|
||||
### Key Features
|
||||
- **Task Delegation**: A manager agent allocates tasks among crew members based on their roles and capabilities.
|
||||
@@ -52,9 +52,10 @@ writer = Agent(
|
||||
project_crew = Crew(
|
||||
tasks=[...], # Tasks to be delegated and executed under the manager's supervision
|
||||
agents=[researcher, writer],
|
||||
manager_llm=ChatOpenAI(temperature=0, model="gpt-4"), # Mandatory for hierarchical process
|
||||
manager_llm=ChatOpenAI(temperature=0, model="gpt-4"), # Mandatory if manager_agent is not set
|
||||
process=Process.hierarchical, # Specifies the hierarchical management approach
|
||||
memory=True, # Enable memory usage for enhanced task execution
|
||||
manager_agent=None, # Optional: explicitly set a specific agent as manager instead of the manager_llm
|
||||
)
|
||||
```
|
||||
|
||||
@@ -64,4 +65,4 @@ project_crew = Crew(
|
||||
3. **Sequential Task Progression**: Despite being a hierarchical process, tasks follow a logical order for smooth progression, facilitated by the manager's oversight.
|
||||
|
||||
## Conclusion
|
||||
Adopting the hierarchical process in crewAI, with the correct configurations and understanding of the system's capabilities, facilitates an organized and efficient approach to project management.
|
||||
Adopting the hierarchical process in CrewAI, with the correct configurations and understanding of the system's capabilities, facilitates an organized and efficient approach to project management. Utilize the advanced features and customizations to tailor the workflow to your specific needs, ensuring optimal task execution and project success.
|
||||
@@ -22,7 +22,7 @@ import os
|
||||
from crewai import Agent, Task, Crew
|
||||
from crewai_tools import SerperDevTool
|
||||
|
||||
os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API key
|
||||
os.environ["SERPER_API_KEY"] = "Your Key" # serper.dev API key
|
||||
os.environ["OPENAI_API_KEY"] = "Your Key"
|
||||
|
||||
# Loading Tools
|
||||
@@ -30,59 +30,59 @@ search_tool = SerperDevTool()
|
||||
|
||||
# Define your agents with roles, goals, tools, and additional attributes
|
||||
researcher = Agent(
|
||||
role='Senior Research Analyst',
|
||||
goal='Uncover cutting-edge developments in AI and data science',
|
||||
backstory=(
|
||||
"You are a Senior Research Analyst at a leading tech think tank."
|
||||
"Your expertise lies in identifying emerging trends and technologies in AI and data science."
|
||||
"You have a knack for dissecting complex data and presenting actionable insights."
|
||||
),
|
||||
verbose=True,
|
||||
allow_delegation=False,
|
||||
tools=[search_tool],
|
||||
max_rpm=100
|
||||
role='Senior Research Analyst',
|
||||
goal='Uncover cutting-edge developments in AI and data science',
|
||||
backstory=(
|
||||
"You are a Senior Research Analyst at a leading tech think tank. "
|
||||
"Your expertise lies in identifying emerging trends and technologies in AI and data science. "
|
||||
"You have a knack for dissecting complex data and presenting actionable insights."
|
||||
),
|
||||
verbose=True,
|
||||
allow_delegation=False,
|
||||
tools=[search_tool]
|
||||
)
|
||||
writer = Agent(
|
||||
role='Tech Content Strategist',
|
||||
goal='Craft compelling content on tech advancements',
|
||||
backstory=(
|
||||
"You are a renowned Tech Content Strategist, known for your insightful and engaging articles on technology and innovation."
|
||||
"With a deep understanding of the tech industry, you transform complex concepts into compelling narratives."
|
||||
),
|
||||
verbose=True,
|
||||
allow_delegation=True,
|
||||
tools=[search_tool],
|
||||
cache=False, # Disable cache for this agent
|
||||
role='Tech Content Strategist',
|
||||
goal='Craft compelling content on tech advancements',
|
||||
backstory=(
|
||||
"You are a renowned Tech Content Strategist, known for your insightful and engaging articles on technology and innovation. "
|
||||
"With a deep understanding of the tech industry, you transform complex concepts into compelling narratives."
|
||||
),
|
||||
verbose=True,
|
||||
allow_delegation=True,
|
||||
tools=[search_tool],
|
||||
cache=False, # Disable cache for this agent
|
||||
)
|
||||
|
||||
# Create tasks for your agents
|
||||
task1 = Task(
|
||||
description=(
|
||||
"Conduct a comprehensive analysis of the latest advancements in AI in 2024."
|
||||
"Identify key trends, breakthrough technologies, and potential industry impacts."
|
||||
"Compile your findings in a detailed report."
|
||||
"Make sure to check with a human if the draft is good before finalizing your answer."
|
||||
),
|
||||
expected_output='A comprehensive full report on the latest AI advancements in 2024, leave nothing out',
|
||||
agent=researcher,
|
||||
human_input=True,
|
||||
description=(
|
||||
"Conduct a comprehensive analysis of the latest advancements in AI in 2024. "
|
||||
"Identify key trends, breakthrough technologies, and potential industry impacts. "
|
||||
"Compile your findings in a detailed report. "
|
||||
"Make sure to check with a human if the draft is good before finalizing your answer."
|
||||
),
|
||||
expected_output='A comprehensive full report on the latest AI advancements in 2024, leave nothing out',
|
||||
agent=researcher,
|
||||
human_input=True
|
||||
)
|
||||
|
||||
task2 = Task(
|
||||
description=(
|
||||
"Using the insights from the researcher's report, develop an engaging blog post that highlights the most significant AI advancements."
|
||||
"Your post should be informative yet accessible, catering to a tech-savvy audience."
|
||||
"Aim for a narrative that captures the essence of these breakthroughs and their implications for the future."
|
||||
),
|
||||
expected_output='A compelling 3 paragraphs blog post formatted as markdown about the latest AI advancements in 2024',
|
||||
agent=writer
|
||||
description=(
|
||||
"Using the insights from the researcher\'s report, develop an engaging blog post that highlights the most significant AI advancements. "
|
||||
"Your post should be informative yet accessible, catering to a tech-savvy audience. "
|
||||
"Aim for a narrative that captures the essence of these breakthroughs and their implications for the future."
|
||||
),
|
||||
expected_output='A compelling 3 paragraphs blog post formatted as markdown about the latest AI advancements in 2024',
|
||||
agent=writer
|
||||
)
|
||||
|
||||
# Instantiate your crew with a sequential process
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[task1, task2],
|
||||
verbose=2
|
||||
agents=[researcher, writer],
|
||||
tasks=[task1, task2],
|
||||
verbose=2,
|
||||
memory=True,
|
||||
)
|
||||
|
||||
# Get your crew to work!
|
||||
|
||||
@@ -12,7 +12,7 @@ Welcome to crewAI! This guide will walk you through the installation process for
|
||||
To install crewAI, you need to have Python >=3.10 and <=3.13 installed on your system:
|
||||
|
||||
```shell
|
||||
# Install the mains crewAI package
|
||||
# Install the main crewAI package
|
||||
pip install crewai
|
||||
|
||||
# Install the main crewAI package and the tools package
|
||||
|
||||
@@ -16,16 +16,20 @@ The `Agent` class is the cornerstone for implementing AI solutions in CrewAI. He
|
||||
- `role`: Defines the agent's role within the solution.
|
||||
- `goal`: Specifies the agent's objective.
|
||||
- `backstory`: Provides a background story to the agent.
|
||||
- `llm`: Indicates the Large Language Model the agent uses. By default, it uses the GPT-4 model defined in the environment variable "OPENAI_MODEL_NAME".
|
||||
- `function_calling_llm` *Optional*: Will turn the ReAct crewAI agent into a function calling agent.
|
||||
- `max_iter`: Maximum number of iterations for an agent to execute a task, default is 15.
|
||||
- `memory`: Enables the agent to retain information during and a across executions. Default is `False`.
|
||||
- `max_rpm`: Maximum number of requests per minute the agent's execution should respect. Optional.
|
||||
- `verbose`: Enables detailed logging of the agent's execution. Default is `False`.
|
||||
- `allow_delegation`: Allows the agent to delegate tasks to other agents, default is `True`.
|
||||
- `cache` *Optional*: Determines whether the agent should use a cache for tool usage. Default is `True`.
|
||||
- `max_rpm` *Optional*: Maximum number of requests per minute the agent's execution should respect. Optional.
|
||||
- `verbose` *Optional*: Enables detailed logging of the agent's execution. Default is `False`.
|
||||
- `allow_delegation` *Optional*: Allows the agent to delegate tasks to other agents, default is `True`.
|
||||
- `tools`: Specifies the tools available to the agent for task execution. Optional.
|
||||
- `step_callback`: Provides a callback function to be executed after each step. Optional.
|
||||
- `cache`: Determines whether the agent should use a cache for tool usage. Default is `True`.
|
||||
- `max_iter` *Optional*: Maximum number of iterations for an agent to execute a task, default is 25.
|
||||
- `max_execution_time` *Optional*: Maximum execution time for an agent to execute a task. Optional.
|
||||
- `step_callback` *Optional*: Provides a callback function to be executed after each step. Optional.
|
||||
- `llm` *Optional*: Indicates the Large Language Model the agent uses. By default, it uses the GPT-4 model defined in the environment variable "OPENAI_MODEL_NAME".
|
||||
- `function_calling_llm` *Optional* : Will turn the ReAct CrewAI agent into a function-calling agent.
|
||||
- `callbacks` *Optional*: A list of callback functions from the LangChain library that are triggered during the agent's execution process.
|
||||
- `system_template` *Optional*: Optional string to define the system format for the agent.
|
||||
- `prompt_template` *Optional*: Optional string to define the prompt format for the agent.
|
||||
- `response_template` *Optional*: Optional string to define the response format for the agent.
|
||||
|
||||
```python
|
||||
# Required
|
||||
@@ -36,13 +40,12 @@ example_agent = Agent(
|
||||
role='Local Expert',
|
||||
goal='Provide insights about the city',
|
||||
backstory="A knowledgeable local guide.",
|
||||
verbose=True,
|
||||
memory=True
|
||||
verbose=True
|
||||
)
|
||||
```
|
||||
|
||||
## Ollama Integration
|
||||
Ollama is preferred for local LLM integration, offering customization and privacy benefits. To integrate Ollama with CrewAI, set the appropriate environment variables as shown below.
|
||||
Ollama is preferred for local LLM integration, offering customization and privacy benefits. To integrate Ollama with CrewAI, set the appropriate environment variables as shown below.
|
||||
|
||||
### Setting Up Ollama
|
||||
- **Environment Variables Configuration**: To integrate Ollama, set the following environment variables:
|
||||
@@ -53,8 +56,8 @@ OPENAI_API_KEY=''
|
||||
```
|
||||
|
||||
## Ollama Integration (ex. for using Llama 2 locally)
|
||||
1. [Download Ollama](https://ollama.com/download).
|
||||
2. After setting up the Ollama, Pull the Llama2 by typing following lines into the terminal ```ollama pull llama2```.
|
||||
1. [Download Ollama](https://ollama.com/download).
|
||||
2. After setting up the Ollama, Pull the Llama2 by typing following lines into the terminal ```ollama pull llama2```.
|
||||
3. Create a ModelFile similar the one below in your project directory.
|
||||
```
|
||||
FROM llama2
|
||||
@@ -70,7 +73,7 @@ PARAMETER stop Result
|
||||
|
||||
SYSTEM """"""
|
||||
```
|
||||
4. Create a script to get the base model, which in our case is llama2, and create a model on top of that with ModelFile above. PS: this will be ".sh" file.
|
||||
4. Create a script to get the base model, which in our case is llama2, and create a model on top of that with ModelFile above. PS: this will be ".sh" file.
|
||||
```
|
||||
#!/bin/zsh
|
||||
|
||||
@@ -84,9 +87,9 @@ ollama pull $model_name
|
||||
#create the model file
|
||||
ollama create $custom_model_name -f ./Llama2ModelFile
|
||||
```
|
||||
5. Go into the directory where the script file and ModelFile is located and run the script.
|
||||
6. Enjoy your free Llama2 model that powered up by excellent agents from crewai.
|
||||
```
|
||||
5. Go into the directory where the script file and ModelFile is located and run the script.
|
||||
6. Enjoy your free Llama2 model that is powered up by excellent agents from CrewAI.
|
||||
```python
|
||||
from crewai import Agent, Task, Crew
|
||||
from langchain_openai import ChatOpenAI
|
||||
import os
|
||||
@@ -102,7 +105,8 @@ general_agent = Agent(role = "Math Professor",
|
||||
allow_delegation = False,
|
||||
verbose = True,
|
||||
llm = llm)
|
||||
task = Task (description="""what is 3 + 5""",
|
||||
|
||||
task = Task(description="""what is 3 + 5""",
|
||||
agent = general_agent,
|
||||
expected_output="A numerical answer.")
|
||||
|
||||
@@ -162,7 +166,7 @@ OPENAI_API_KEY=NA
|
||||
```
|
||||
|
||||
#### LM Studio
|
||||
Launch [LM Studio](https://lmstudio.ai) and go to the Server tab. Then select a model from the dropdown menu then wait for it to load. Once it's loaded, click the green Start Server button and use the URL, port, and API key that's shown (you can modify them). Below is an example of the default settings as of LM Studio 0.2.19:
|
||||
Launch [LM Studio](https://lmstudio.ai) and go to the Server tab. Then select a model from the dropdown menu and wait for it to load. Once it's loaded, click the green Start Server button and use the URL, port, and API key that's shown (you can modify them). Below is an example of the default settings as of LM Studio 0.2.19:
|
||||
```sh
|
||||
OPENAI_API_BASE="http://localhost:1234/v1"
|
||||
OPENAI_API_KEY="lm-studio"
|
||||
@@ -176,15 +180,16 @@ OPENAI_MODEL_NAME="mistral-small"
|
||||
```
|
||||
|
||||
### Solar
|
||||
```sh
|
||||
```python
|
||||
from langchain_community.chat_models.solar import SolarChat
|
||||
# Initialize language model
|
||||
os.environ["SOLAR_API_KEY"] = "your-solar-api-key"
|
||||
llm = SolarChat(max_tokens=1024)
|
||||
|
||||
Free developer API key available here: https://console.upstage.ai/services/solar
|
||||
Langchain Example: https://github.com/langchain-ai/langchain/pull/18556
|
||||
# Free developer API key available here: https://console.upstage.ai/services/solar
|
||||
# Langchain Example: https://github.com/langchain-ai/langchain/pull/18556
|
||||
```
|
||||
|
||||
### text-gen-web-ui
|
||||
```sh
|
||||
OPENAI_API_BASE=http://localhost:5000/v1
|
||||
@@ -193,17 +198,16 @@ OPENAI_API_KEY=NA
|
||||
```
|
||||
|
||||
### Cohere
|
||||
```sh
|
||||
from langchain_community.chat_models import ChatCohere
|
||||
```python
|
||||
from langchain_cohere import ChatCohere
|
||||
# Initialize language model
|
||||
os.environ["COHERE_API_KEY"] = "your-cohere-api-key"
|
||||
llm = ChatCohere()
|
||||
|
||||
Free developer API key available here: https://cohere.com/
|
||||
Langchain Documentation: https://python.langchain.com/docs/integrations/chat/cohere
|
||||
# Free developer API key available here: https://cohere.com/
|
||||
# Langchain Documentation: https://python.langchain.com/docs/integrations/chat/cohere
|
||||
```
|
||||
|
||||
|
||||
### Azure Open AI Configuration
|
||||
For Azure OpenAI API integration, set the following environment variables:
|
||||
```sh
|
||||
@@ -235,4 +239,4 @@ azure_agent = Agent(
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
Integrating CrewAI with different LLMs expands the framework's versatility, allowing for customized, efficient AI solutions across various domains and platforms.
|
||||
Integrating CrewAI with different LLMs expands the framework's versatility, allowing for customized, efficient AI solutions across various domains and platforms.
|
||||
44
docs/how-to/Langtrace-Observability.md
Normal file
44
docs/how-to/Langtrace-Observability.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: CrewAI Agent Monitoring with Langtrace
|
||||
description: How to monitor cost, latency, and performance of CrewAI Agents using Langtrace.
|
||||
---
|
||||
|
||||
# Langtrace Overview
|
||||
Langtrace is an open-source tool that helps you set up observability and evaluations for LLMs, LLM frameworks, and VectorDB. With Langtrace, you can get deep visibility into the cost, latency, and performance of your CrewAI Agents. Additionally, you can log the hyperparameters and monitor for any performance regressions and set up a process to continuously improve your Agents.
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
1. Sign up for [Langtrace](https://langtrace.ai/) by going to [https://langtrace.ai/signup](https://langtrace.ai/signup).
|
||||
2. Create a project and generate an API key.
|
||||
3. Install Langtrace in your code using the following commands.
|
||||
**Note**: For detailed instructions on integrating Langtrace, you can check out the official docs from [here](https://docs.langtrace.ai/supported-integrations/llm-frameworks/crewai).
|
||||
|
||||
```
|
||||
# Install the SDK
|
||||
pip install langtrace-python-sdk
|
||||
|
||||
# Import it into your project
|
||||
from langtrace_python_sdk import langtrace # Must precede any llm module imports
|
||||
langtrace.init(api_key = '<LANGTRACE_API_KEY>')
|
||||
```
|
||||
|
||||
### Features
|
||||
- **LLM Token and Cost tracking**
|
||||
- **Trace graph showing detailed execution steps with latency and logs**
|
||||
- **Dataset curation using manual annotation**
|
||||
- **Prompt versioning and management**
|
||||
- **Prompt Playground with comparison views between models**
|
||||
- **Testing and Evaluations**
|
||||
|
||||

|
||||

|
||||
|
||||
#### Extra links
|
||||
|
||||
<a href="https://x.com/langtrace_ai">🐦 Twitter</a>
|
||||
<span> • </span>
|
||||
<a href="https://discord.com/invite/EaSATwtr4t">📢 Discord</a>
|
||||
<span> • </span>
|
||||
<a href="https://langtrace.ai/">🖇 Website</a>
|
||||
<span> • </span>
|
||||
<a href="https://docs.langtrace.ai/introduction">📙 Documentation</a>
|
||||
@@ -13,6 +13,7 @@ The sequential process ensures tasks are executed one after the other, following
|
||||
- **Linear Task Flow**: Ensures orderly progression by handling tasks in a predetermined sequence.
|
||||
- **Simplicity**: Best suited for projects with clear, step-by-step tasks.
|
||||
- **Easy Monitoring**: Facilitates easy tracking of task completion and project progress.
|
||||
|
||||
## Implementing the Sequential Process
|
||||
Assemble your crew and define tasks in the order they need to be executed.
|
||||
|
||||
|
||||
68
docs/how-to/Your-Own-Manager-Agent.md
Normal file
68
docs/how-to/Your-Own-Manager-Agent.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Ability to Set a Specific Agent as Manager in CrewAI
|
||||
description: Introducing the ability to set a specific agent as a manager instead of having CrewAI create one automatically.
|
||||
|
||||
---
|
||||
|
||||
# Ability to Set a Specific Agent as Manager in CrewAI
|
||||
|
||||
CrewAI now allows users to set a specific agent as the manager of the crew, providing more control over the management and coordination of tasks. This feature enables the customization of the managerial role to better fit the project's requirements.
|
||||
|
||||
## Using the `manager_agent` Attribute
|
||||
|
||||
### Custom Manager Agent
|
||||
|
||||
The `manager_agent` attribute allows you to define a custom agent to manage the crew. This agent will oversee the entire process, ensuring that tasks are completed efficiently and to the highest standard.
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import os
|
||||
from crewai import Agent, Task, Crew, Process
|
||||
|
||||
# Define your agents
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Make the best research and analysis on content about AI and AI agents",
|
||||
backstory="You're an expert researcher, specialized in technology, software engineering, AI and startups. You work as a freelancer and is now working on doing research and analysis for a new customer.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
role="Senior Writer",
|
||||
goal="Write the best content about AI and AI agents.",
|
||||
backstory="You're a senior writer, specialized in technology, software engineering, AI and startups. You work as a freelancer and are now working on writing content for a new customer.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
# Define your task
|
||||
task = Task(
|
||||
description="Come up with a list of 5 interesting ideas to explore for an article, then write one amazing paragraph highlight for each idea that showcases how good an article about this topic could be. Return the list of ideas with their paragraph and your notes.",
|
||||
expected_output="5 bullet points with a paragraph for each idea.",
|
||||
)
|
||||
|
||||
# Define the manager agent
|
||||
manager = Agent(
|
||||
role="Manager",
|
||||
goal="Manage the crew and ensure the tasks are completed efficiently.",
|
||||
backstory="You're an experienced manager, skilled in overseeing complex projects and guiding teams to success. Your role is to coordinate the efforts of the crew members, ensuring that each task is completed on time and to the highest standard.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
# Instantiate your crew with a custom manager
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
process=Process.hierarchical,
|
||||
manager_agent=manager,
|
||||
tasks=[task],
|
||||
)
|
||||
|
||||
# Get your crew to work!
|
||||
crew.kickoff()
|
||||
```
|
||||
|
||||
## Benefits of a Custom Manager Agent
|
||||
|
||||
- **Enhanced Control**: Allows for a more tailored management approach, fitting the specific needs of the project.
|
||||
- **Improved Coordination**: Ensures that the tasks are efficiently coordinated and managed by an experienced agent.
|
||||
- **Customizable Management**: Provides the flexibility to define managerial roles and responsibilities that align with the project's goals.
|
||||
@@ -2,6 +2,7 @@
|
||||
title: Telemetry
|
||||
description: Understanding the telemetry data collected by CrewAI and how it contributes to the enhancement of the library.
|
||||
---
|
||||
|
||||
## Telemetry
|
||||
|
||||
CrewAI utilizes anonymous telemetry to gather usage statistics with the primary goal of enhancing the library. Our focus is on improving and developing the features, integrations, and tools most utilized by our users.
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
|
||||
## Description
|
||||
|
||||
[Browserbase](https://browserbase.com) is a serverless platform for running headless browsers, it offers advanced debugging, session recordings, stealth mode, integrated proxies and captcha solving.
|
||||
[Browserbase](https://browserbase.com) is a developer platform to reliably run, manage, and monitor headless browsers.
|
||||
|
||||
Power your AI data retrievals with:
|
||||
- [Serverless Infrastructure](https://docs.browserbase.com/under-the-hood) providing reliable browsers to extract data from complex UIs
|
||||
- [Stealth Mode](https://docs.browserbase.com/features/stealth-mode) with included fingerprinting tactics and automatic captcha solving
|
||||
- [Session Debugger](https://docs.browserbase.com/features/sessions) to inspect your Browser Session with networks timeline and logs
|
||||
- [Live Debug](https://docs.browserbase.com/guides/session-debug-connection/browser-remote-control) to quickly debug your automation
|
||||
|
||||
## Installation
|
||||
|
||||
- Get an API key from [browserbase.com](https://browserbase.com) and set it in environment variables (`BROWSERBASE_API_KEY`).
|
||||
- Get an API key and Project ID from [browserbase.com](https://browserbase.com) and set it in environment variables (`BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`).
|
||||
- Install the [Browserbase SDK](http://github.com/browserbase/python-sdk) along with `crewai[tools]` package:
|
||||
|
||||
```
|
||||
@@ -25,5 +31,8 @@ tool = BrowserbaseLoadTool()
|
||||
|
||||
## Arguments
|
||||
|
||||
- `api_key`: Optional. Specifies Browserbase API key. Defaults is the `BROWSERBASE_API_KEY` environment variable.
|
||||
- `text_content`: Optional. Load pages as readable text. Default is `False`.
|
||||
- `api_key` Optional. Browserbase API key. Default is `BROWSERBASE_API_KEY` env variable.
|
||||
- `project_id` Optional. Browserbase Project ID. Default is `BROWSERBASE_PROJECT_ID` env variable.
|
||||
- `text_content` Retrieve only text content. Default is `False`.
|
||||
- `session_id` Optional. Provide an existing Session ID.
|
||||
- `proxy` Optional. Enable/Disable Proxies."
|
||||
|
||||
29
docs/tools/CodeInterpreterTool.md
Normal file
29
docs/tools/CodeInterpreterTool.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# CodeInterpreterTool
|
||||
|
||||
## Description
|
||||
This tool is used to give the Agent the ability to run code (Python3) from the code generated by the Agent itself. The code is executed in a sandboxed environment, so it is safe to run any code.
|
||||
|
||||
It is incredible useful since it allows the Agent to generate code, run it in the same environment, get the result and use it to make decisions.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Docker
|
||||
|
||||
## Installation
|
||||
Install the crewai_tools package
|
||||
```shell
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Remember that when using this tool, the code must be generated by the Agent itself. The code must be a Python3 code. And it will take some time for the first time to run because it needs to build the Docker image.
|
||||
|
||||
```python
|
||||
from crewai_tools import CodeInterpreterTool
|
||||
|
||||
Agent(
|
||||
...
|
||||
tools=[CodeInterpreterTool()],
|
||||
)
|
||||
```
|
||||
36
docs/tools/EXASearchTool.md
Normal file
36
docs/tools/EXASearchTool.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# EXASearchTool Documentation
|
||||
|
||||
## Description
|
||||
|
||||
The EXASearchTool is designed to perform a semantic search for a specified query from a text's content across the internet. It utilizes the [exa.ai](https://exa.ai/) API to fetch and display the most relevant search results based on the query provided by the user.
|
||||
|
||||
## Installation
|
||||
|
||||
To incorporate this tool into your project, follow the installation instructions below:
|
||||
|
||||
```shell
|
||||
pip install 'crewai[tools]'
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
The following example demonstrates how to initialize the tool and execute a search with a given query:
|
||||
|
||||
```python
|
||||
from crewai_tools import EXASearchTool
|
||||
|
||||
# Initialize the tool for internet searching capabilities
|
||||
tool = EXASearchTool()
|
||||
```
|
||||
|
||||
## Steps to Get Started
|
||||
|
||||
To effectively use the EXASearchTool, follow these steps:
|
||||
|
||||
1. **Package Installation**: Confirm that the `crewai[tools]` package is installed in your Python environment.
|
||||
2. **API Key Acquisition**: Acquire a [exa.ai](https://exa.ai/) API key by registering for a free account at [exa.ai](https://exa.ai/).
|
||||
3. **Environment Configuration**: Store your obtained API key in an environment variable named `EXA_API_KEY` to facilitate its use by the tool.
|
||||
|
||||
## Conclusion
|
||||
|
||||
By integrating the EXASearchTool into Python projects, users gain the ability to conduct real-time, relevant searches across the internet directly from their applications. By adhering to the setup and usage guidelines provided, incorporating this tool into projects is streamlined and straightforward.
|
||||
@@ -29,7 +29,7 @@ tool = PDFSearchTool(pdf='path/to/your/document.pdf')
|
||||
```
|
||||
|
||||
## Arguments
|
||||
- `pdf`: **Optinal** The PDF path for the search. Can be provided at initialization or within the `run` method's arguments. If provided at initialization, the tool confines its search to the specified document.
|
||||
- `pdf`: **Optional** The PDF path for the search. Can be provided at initialization or within the `run` method's arguments. If provided at initialization, the tool confines its search to the specified document.
|
||||
|
||||
## Custom model and embeddings
|
||||
|
||||
|
||||
@@ -127,21 +127,26 @@ nav:
|
||||
- Crews: 'core-concepts/Crews.md'
|
||||
- Collaboration: 'core-concepts/Collaboration.md'
|
||||
- Memory: 'core-concepts/Memory.md'
|
||||
- Using LangChain Tools: 'core-concepts/Using-LangChain-Tools.md'
|
||||
- Using LlamaIndex Tools: 'core-concepts/Using-LlamaIndex-Tools.md'
|
||||
- How to Guides:
|
||||
- Installing CrewAI: 'how-to/Installing-CrewAI.md'
|
||||
- Getting Started: 'how-to/Creating-a-Crew-and-kick-it-off.md'
|
||||
- Create Custom Tools: 'how-to/Create-Custom-Tools.md'
|
||||
- Using Sequential Process: 'how-to/Sequential.md'
|
||||
- Using Hierarchical Process: 'how-to/Hierarchical.md'
|
||||
- Create your own Manager Agent: 'how-to/Your-Own-Manager-Agent.md'
|
||||
- Connecting to any LLM: 'how-to/LLM-Connections.md'
|
||||
- Customizing Agents: 'how-to/Customizing-Agents.md'
|
||||
- Human Input on Execution: 'how-to/Human-Input-on-Execution.md'
|
||||
- Agent Monitoring with AgentOps: 'how-to/AgentOps-Observability.md'
|
||||
- Agent Monitoring with LangTrace: 'how-to/Langtrace-Observability.md'
|
||||
- Tools Docs:
|
||||
- Google Serper Search: 'tools/SerperDevTool.md'
|
||||
- Browserbase Web Loader: 'tools/BrowserbaseLoadTool.md'
|
||||
- Scrape Website: 'tools/ScrapeWebsiteTool.md'
|
||||
- Directory Read: 'tools/DirectoryReadTool.md'
|
||||
- Exa Serch Web Loader: 'tools/EXASearchTool.md'
|
||||
- File Read: 'tools/FileReadTool.md'
|
||||
- Selenium Scraper: 'tools/SeleniumScrapingTool.md'
|
||||
- Directory RAG Search: 'tools/DirectorySearchTool.md'
|
||||
@@ -174,6 +179,7 @@ extra_css:
|
||||
|
||||
plugins:
|
||||
- social
|
||||
- search
|
||||
|
||||
extra:
|
||||
analytics:
|
||||
|
||||
1757
poetry.lock
generated
1757
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "crewai"
|
||||
version = "0.30.11"
|
||||
version = "0.32.2"
|
||||
description = "Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks."
|
||||
authors = ["Joao Moura <joao@crewai.com>"]
|
||||
readme = "README.md"
|
||||
@@ -19,13 +19,14 @@ openai = "^1.13.3"
|
||||
opentelemetry-api = "^1.22.0"
|
||||
opentelemetry-sdk = "^1.22.0"
|
||||
opentelemetry-exporter-otlp-proto-http = "^1.22.0"
|
||||
instructor = "^0.5.2"
|
||||
instructor = "1.3.3"
|
||||
regex = "^2023.12.25"
|
||||
crewai-tools = { version = "^0.2.6", optional = true }
|
||||
crewai-tools = { version = "^0.3.0", optional = true }
|
||||
click = "^8.1.7"
|
||||
python-dotenv = "^1.0.0"
|
||||
embedchain = "^0.1.98"
|
||||
embedchain = "0.1.109"
|
||||
appdirs = "^1.4.4"
|
||||
jsonref = "^1.1.0"
|
||||
|
||||
[tool.poetry.extras]
|
||||
tools = ["crewai-tools"]
|
||||
@@ -42,7 +43,7 @@ mkdocs-material = { extras = ["imaging"], version = "^9.5.7" }
|
||||
mkdocs-material-extensions = "^1.3.1"
|
||||
pillow = "^10.2.0"
|
||||
cairosvg = "^2.7.1"
|
||||
crewai-tools = "^0.2.6"
|
||||
crewai-tools = "^0.3.0"
|
||||
|
||||
[tool.poetry.group.test.dependencies]
|
||||
pytest = "^8.0.0"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import uuid
|
||||
from copy import deepcopy
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from langchain.agents.agent import RunnableAgent
|
||||
@@ -23,7 +24,9 @@ from pydantic_core import PydanticCustomError
|
||||
from crewai.agents import CacheHandler, CrewAgentExecutor, CrewAgentParser, ToolsHandler
|
||||
from crewai.memory.contextual.contextual_memory import ContextualMemory
|
||||
from crewai.utilities import I18N, Logger, Prompts, RPMController
|
||||
from crewai.utilities.constants import TRAINED_AGENTS_DATA_FILE, TRAINING_DATA_FILE
|
||||
from crewai.utilities.token_counter_callback import TokenCalcHandler, TokenProcess
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
|
||||
|
||||
class Agent(BaseModel):
|
||||
@@ -39,7 +42,7 @@ class Agent(BaseModel):
|
||||
backstory: The backstory of the agent.
|
||||
config: Dict representation of agent configuration.
|
||||
llm: The language model that will run the agent.
|
||||
function_calling_llm: The language model that will the tool calling for this agent, it overrides the crew function_calling_llm.
|
||||
function_calling_llm: The language model that will handle the tool calling for this agent, it overrides the crew function_calling_llm.
|
||||
max_iter: Maximum number of iterations for an agent to execute a task.
|
||||
memory: Whether the agent should have memory or not.
|
||||
max_rpm: Maximum number of requests per minute for the agent execution to be respected.
|
||||
@@ -111,7 +114,7 @@ class Agent(BaseModel):
|
||||
i18n: I18N = Field(default=I18N(), description="Internationalization settings.")
|
||||
llm: Any = Field(
|
||||
default_factory=lambda: ChatOpenAI(
|
||||
model=os.environ.get("OPENAI_MODEL_NAME", "gpt-4")
|
||||
model=os.environ.get("OPENAI_MODEL_NAME", "gpt-4o")
|
||||
),
|
||||
description="Language model that will run the agent.",
|
||||
)
|
||||
@@ -130,6 +133,9 @@ class Agent(BaseModel):
|
||||
response_template: Optional[str] = Field(
|
||||
default=None, description="Response format for the agent."
|
||||
)
|
||||
allow_code_execution: Optional[bool] = Field(
|
||||
default=False, description="Enable code execution for the agent."
|
||||
)
|
||||
|
||||
_original_role: str | None = None
|
||||
_original_goal: str | None = None
|
||||
@@ -224,6 +230,7 @@ class Agent(BaseModel):
|
||||
task_prompt += self.i18n.slice("memory").format(memory=memory)
|
||||
|
||||
tools = tools or self.tools
|
||||
|
||||
parsed_tools = self._parse_tools(tools) # type: ignore # Argument 1 to "_parse_tools" of "Agent" has incompatible type "list[Any] | None"; expected "list[Any]"
|
||||
|
||||
self.create_agent_executor(tools=tools)
|
||||
@@ -233,6 +240,11 @@ class Agent(BaseModel):
|
||||
self.agent_executor.tools_description = render_text_description(parsed_tools)
|
||||
self.agent_executor.tools_names = self.__tools_names(parsed_tools)
|
||||
|
||||
if self.crew and self.crew._train:
|
||||
task_prompt = self._training_handler(task_prompt=task_prompt)
|
||||
else:
|
||||
task_prompt = self._use_trained_data(task_prompt=task_prompt)
|
||||
|
||||
result = self.agent_executor.invoke(
|
||||
{
|
||||
"input": task_prompt,
|
||||
@@ -364,6 +376,28 @@ class Agent(BaseModel):
|
||||
thoughts += f"\n{observation_prefix}{observation}\n{llm_prefix}"
|
||||
return thoughts
|
||||
|
||||
def copy(self):
|
||||
"""Create a deep copy of the Agent."""
|
||||
exclude = {
|
||||
"id",
|
||||
"_logger",
|
||||
"_rpm_controller",
|
||||
"_request_within_rpm_limit",
|
||||
"_token_process",
|
||||
"agent_executor",
|
||||
"tools",
|
||||
"tools_handler",
|
||||
"cache_handler",
|
||||
}
|
||||
|
||||
copied_data = self.model_dump(exclude=exclude)
|
||||
copied_data = {k: v for k, v in copied_data.items() if v is not None}
|
||||
|
||||
copied_agent = Agent(**copied_data)
|
||||
copied_agent.tools = deepcopy(self.tools)
|
||||
|
||||
return copied_agent
|
||||
|
||||
def _parse_tools(self, tools: List[Any]) -> List[LangChainTool]: # type: ignore # Function "langchain_core.tools.tool" is not valid as a type
|
||||
"""Parse tools to be used for the task."""
|
||||
# tentatively try to import from crewai_tools import BaseTool as CrewAITool
|
||||
@@ -376,11 +410,41 @@ class Agent(BaseModel):
|
||||
tools_list.append(tool.to_langchain())
|
||||
else:
|
||||
tools_list.append(tool)
|
||||
|
||||
if self.allow_code_execution:
|
||||
from crewai_tools.code_interpreter_tool import CodeInterpreterTool
|
||||
|
||||
tools_list.append(CodeInterpreterTool)
|
||||
|
||||
except ModuleNotFoundError:
|
||||
for tool in tools:
|
||||
tools_list.append(tool)
|
||||
return tools_list
|
||||
|
||||
def _training_handler(self, task_prompt: str) -> str:
|
||||
"""Handle training data for the agent task prompt to improve output on Training."""
|
||||
if data := CrewTrainingHandler(TRAINING_DATA_FILE).load():
|
||||
agent_id = str(self.id)
|
||||
|
||||
if data.get(agent_id):
|
||||
human_feedbacks = [
|
||||
i["human_feedback"] for i in data.get(agent_id, {}).values()
|
||||
]
|
||||
task_prompt += "You MUST follow these feedbacks: \n " + "\n - ".join(
|
||||
human_feedbacks
|
||||
)
|
||||
|
||||
return task_prompt
|
||||
|
||||
def _use_trained_data(self, task_prompt: str) -> str:
|
||||
"""Use trained data for the agent task prompt to improve output."""
|
||||
if data := CrewTrainingHandler(TRAINED_AGENTS_DATA_FILE).load():
|
||||
if trained_data_output := data.get(self.role):
|
||||
task_prompt += "You MUST follow these feedbacks: \n " + "\n - ".join(
|
||||
trained_data_output["suggestions"]
|
||||
)
|
||||
return task_prompt
|
||||
|
||||
@staticmethod
|
||||
def __tools_names(tools) -> str:
|
||||
return ", ".join([t.name for t in tools])
|
||||
|
||||
@@ -18,8 +18,10 @@ from crewai.memory.long_term.long_term_memory_item import LongTermMemoryItem
|
||||
from crewai.memory.short_term.short_term_memory_item import ShortTermMemoryItem
|
||||
from crewai.tools.tool_usage import ToolUsage, ToolUsageErrorException
|
||||
from crewai.utilities import I18N
|
||||
from crewai.utilities.constants import TRAINING_DATA_FILE
|
||||
from crewai.utilities.converter import ConverterError
|
||||
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
|
||||
|
||||
class CrewAgentExecutor(AgentExecutor):
|
||||
@@ -58,7 +60,7 @@ class CrewAgentExecutor(AgentExecutor):
|
||||
if (
|
||||
self.crew
|
||||
and self.crew.memory
|
||||
and "Action: Delegate work to co-worker" not in output.log
|
||||
and "Action: Delegate work to coworker" not in output.log
|
||||
):
|
||||
memory = ShortTermMemoryItem(
|
||||
data=output.log,
|
||||
@@ -246,12 +248,17 @@ class CrewAgentExecutor(AgentExecutor):
|
||||
# If the tool chosen is the finishing tool, then we end and return.
|
||||
if isinstance(output, AgentFinish):
|
||||
if self.should_ask_for_human_input:
|
||||
human_feedback = self._ask_human_input(output.return_values["output"])
|
||||
|
||||
if self.crew and self.crew._train:
|
||||
self._handle_crew_training_output(output, human_feedback)
|
||||
|
||||
# Making sure we only ask for it once, so disabling for the next thought loop
|
||||
self.should_ask_for_human_input = False
|
||||
human_feedback = self._ask_human_input(output.return_values["output"])
|
||||
action = AgentAction(
|
||||
tool="Human Input", tool_input=human_feedback, log=output.log
|
||||
)
|
||||
|
||||
yield AgentStep(
|
||||
action=action,
|
||||
observation=self._i18n.slice("human_feedback").format(
|
||||
@@ -261,6 +268,9 @@ class CrewAgentExecutor(AgentExecutor):
|
||||
return
|
||||
|
||||
else:
|
||||
if self.crew and self.crew._train:
|
||||
self._handle_crew_training_output(output)
|
||||
|
||||
yield output
|
||||
return
|
||||
|
||||
@@ -305,3 +315,31 @@ class CrewAgentExecutor(AgentExecutor):
|
||||
return input(
|
||||
self._i18n.slice("getting_input").format(final_answer=final_answer)
|
||||
)
|
||||
|
||||
def _handle_crew_training_output(
|
||||
self, output: AgentFinish, human_feedback: str | None = None
|
||||
) -> None:
|
||||
"""Function to handle the process of the training data."""
|
||||
agent_id = str(self.crew_agent.id)
|
||||
|
||||
if (
|
||||
CrewTrainingHandler(TRAINING_DATA_FILE).load()
|
||||
and not self.should_ask_for_human_input
|
||||
):
|
||||
training_data = CrewTrainingHandler(TRAINING_DATA_FILE).load()
|
||||
if training_data.get(agent_id):
|
||||
training_data[agent_id][self.crew._train_iteration][
|
||||
"improved_output"
|
||||
] = output.return_values["output"]
|
||||
CrewTrainingHandler(TRAINING_DATA_FILE).save(training_data)
|
||||
|
||||
if self.should_ask_for_human_input and human_feedback is not None:
|
||||
training_data = {
|
||||
"initial_output": output.return_values["output"],
|
||||
"human_feedback": human_feedback,
|
||||
"agent": agent_id,
|
||||
"agent_role": self.crew_agent.role,
|
||||
}
|
||||
CrewTrainingHandler(TRAINING_DATA_FILE).append(
|
||||
self.crew._train_iteration, agent_id, training_data
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ import click
|
||||
import pkg_resources
|
||||
|
||||
from .create_crew import create_crew
|
||||
from .train_crew import train_crew
|
||||
|
||||
|
||||
@click.group()
|
||||
@@ -27,11 +28,25 @@ def version(tools):
|
||||
|
||||
if tools:
|
||||
try:
|
||||
tools_version = pkg_resources.get_distribution("crewai[tools]").version
|
||||
tools_version = pkg_resources.get_distribution("crewai-tools").version
|
||||
click.echo(f"crewai tools version: {tools_version}")
|
||||
except pkg_resources.DistributionNotFound:
|
||||
click.echo("crewai tools not installed")
|
||||
|
||||
|
||||
@crewai.command()
|
||||
@click.option(
|
||||
"-n",
|
||||
"--n_iterations",
|
||||
type=int,
|
||||
default=5,
|
||||
help="Number of iterations to train the crew",
|
||||
)
|
||||
def train(n_iterations: int):
|
||||
"""Train the crew."""
|
||||
click.echo(f"Training the crew for {n_iterations} iterations")
|
||||
train_crew(n_iterations)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
crewai()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
from {{folder_name}}.crew import {{crew_name}}Crew
|
||||
|
||||
|
||||
@@ -7,4 +8,16 @@ def run():
|
||||
inputs = {
|
||||
'topic': 'AI LLMs'
|
||||
}
|
||||
{{crew_name}}Crew().crew().kickoff(inputs=inputs)
|
||||
{{crew_name}}Crew().crew().kickoff(inputs=inputs)
|
||||
|
||||
|
||||
def train():
|
||||
"""
|
||||
Train the crew for a given number of iterations.
|
||||
"""
|
||||
inputs = {"topic": "AI LLMs"}
|
||||
try:
|
||||
{{crew_name}}Crew().crew().train(n_iterations=int(sys.argv[1]), inputs=inputs)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"An error occurred while training the crew: {e}")
|
||||
|
||||
@@ -6,11 +6,12 @@ authors = ["Your Name <you@example.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<=3.13"
|
||||
crewai = {extras = ["tools"], version = "^0.30.11"}
|
||||
crewai = { extras = ["tools"], version = "^0.32.2" }
|
||||
|
||||
[tool.poetry.scripts]
|
||||
{{folder_name}} = "{{folder_name}}.main:run"
|
||||
train = "{{folder_name}}.main:train"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import subprocess
|
||||
|
||||
import click
|
||||
|
||||
|
||||
def train_crew(n_iterations: int) -> None:
|
||||
"""
|
||||
Train the crew by running a command in the Poetry environment.
|
||||
|
||||
Args:
|
||||
n_iterations (int): The number of iterations to train the crew.
|
||||
"""
|
||||
command = ["poetry", "run", "train", str(n_iterations)]
|
||||
|
||||
try:
|
||||
if n_iterations <= 0:
|
||||
raise ValueError("The number of iterations must be a positive integer.")
|
||||
|
||||
result = subprocess.run(command, capture_output=False, text=True, check=True)
|
||||
|
||||
if result.stderr:
|
||||
click.echo(result.stderr, err=True)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
click.echo(f"An error occurred while training the crew: {e}", err=True)
|
||||
click.echo(e.output, err=True)
|
||||
|
||||
except Exception as e:
|
||||
click.echo(f"An unexpected error occurred: {e}", err=True)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
@@ -26,6 +27,8 @@ from crewai.task import Task
|
||||
from crewai.telemetry import Telemetry
|
||||
from crewai.tools.agent_tools import AgentTools
|
||||
from crewai.utilities import I18N, FileHandler, Logger, RPMController
|
||||
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
|
||||
|
||||
class Crew(BaseModel):
|
||||
@@ -47,10 +50,10 @@ class Crew(BaseModel):
|
||||
max_rpm: Maximum number of requests per minute for the crew execution to be respected.
|
||||
prompt_file: Path to the prompt json file to be used for the crew.
|
||||
id: A unique identifier for the crew instance.
|
||||
full_output: Whether the crew should return the full output with all tasks outputs or just the final output.
|
||||
full_output: Whether the crew should return the full output with all tasks outputs and token usage metrics or just the final output.
|
||||
task_callback: Callback to be executed after each task for every agents execution.
|
||||
step_callback: Callback to be executed after each step for every agents execution.
|
||||
share_crew: Whether you want to share the complete crew infromation and execution with crewAI to make the library better, and allow us to train models.
|
||||
share_crew: Whether you want to share the complete crew information and execution with crewAI to make the library better, and allow us to train models.
|
||||
"""
|
||||
|
||||
__hash__ = object.__hash__ # type: ignore
|
||||
@@ -62,6 +65,8 @@ class Crew(BaseModel):
|
||||
_short_term_memory: Optional[InstanceOf[ShortTermMemory]] = PrivateAttr()
|
||||
_long_term_memory: Optional[InstanceOf[LongTermMemory]] = PrivateAttr()
|
||||
_entity_memory: Optional[InstanceOf[EntityMemory]] = PrivateAttr()
|
||||
_train: Optional[bool] = PrivateAttr(default=False)
|
||||
_train_iteration: Optional[int] = PrivateAttr()
|
||||
|
||||
cache: bool = Field(default=True)
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
@@ -83,7 +88,7 @@ class Crew(BaseModel):
|
||||
)
|
||||
full_output: Optional[bool] = Field(
|
||||
default=False,
|
||||
description="Whether the crew should return the full output with all tasks outputs or just the final output.",
|
||||
description="Whether the crew should return the full output with all tasks outputs and token usage metrics or just the final output.",
|
||||
)
|
||||
manager_llm: Optional[Any] = Field(
|
||||
description="Language model that will run the agent.", default=None
|
||||
@@ -164,7 +169,9 @@ class Crew(BaseModel):
|
||||
"""Set private attributes."""
|
||||
if self.memory:
|
||||
self._long_term_memory = LongTermMemory()
|
||||
self._short_term_memory = ShortTermMemory(crew=self, embedder_config=self.embedder)
|
||||
self._short_term_memory = ShortTermMemory(
|
||||
crew=self, embedder_config=self.embedder
|
||||
)
|
||||
self._entity_memory = EntityMemory(crew=self, embedder_config=self.embedder)
|
||||
return self
|
||||
|
||||
@@ -239,9 +246,42 @@ class Crew(BaseModel):
|
||||
del task_config["agent"]
|
||||
return Task(**task_config, agent=task_agent)
|
||||
|
||||
def kickoff(self, inputs: Optional[Dict[str, Any]] = {}) -> str:
|
||||
def _setup_for_training(self) -> None:
|
||||
"""Sets up the crew for training."""
|
||||
self._train = True
|
||||
|
||||
for task in self.tasks:
|
||||
task.human_input = True
|
||||
|
||||
for agent in self.agents:
|
||||
agent.allow_delegation = False
|
||||
|
||||
def train(self, n_iterations: int, inputs: Optional[Dict[str, Any]] = {}) -> None:
|
||||
"""Trains the crew for a given number of iterations."""
|
||||
self._setup_for_training()
|
||||
|
||||
for n_iteration in range(n_iterations):
|
||||
self._train_iteration = n_iteration
|
||||
self.kickoff(inputs=inputs)
|
||||
|
||||
training_data = CrewTrainingHandler("training_data.pkl").load()
|
||||
|
||||
for agent in self.agents:
|
||||
result = TaskEvaluator(agent).evaluate_training_data(
|
||||
training_data=training_data, agent_id=str(agent.id)
|
||||
)
|
||||
|
||||
CrewTrainingHandler("trained_agents_data.pkl").save_trained_data(
|
||||
agent_id=str(agent.role), trained_data=result.model_dump()
|
||||
)
|
||||
|
||||
def kickoff(
|
||||
self,
|
||||
inputs: Optional[Dict[str, Any]] = {},
|
||||
) -> Union[str, Dict[str, Any]]:
|
||||
"""Starts the crew to work on its assigned tasks."""
|
||||
self._execution_span = self._telemetry.crew_execution_span(self)
|
||||
|
||||
self._interpolate_inputs(inputs) # type: ignore # Argument 1 to "_interpolate_inputs" of "Crew" has incompatible type "dict[str, Any] | None"; expected "dict[str, Any]"
|
||||
self._set_tasks_callbacks()
|
||||
|
||||
@@ -265,7 +305,6 @@ class Crew(BaseModel):
|
||||
elif self.process == Process.hierarchical:
|
||||
result, manager_metrics = self._run_hierarchical_process() # type: ignore # Unpacking a string is disallowed
|
||||
metrics.append(manager_metrics) # type: ignore # Cannot determine type of "manager_metrics"
|
||||
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
f"The process '{self.process}' is not implemented yet."
|
||||
@@ -275,11 +314,52 @@ class Crew(BaseModel):
|
||||
agent._token_process.get_summary() for agent in self.agents
|
||||
]
|
||||
self.usage_metrics = {
|
||||
key: sum([m[key] for m in metrics if m is not None]) for key in metrics[0]
|
||||
key: sum([m[key] for m in metrics if m is not None]) # type: ignore # List comprehension has incompatible type List[Any | str]; expected List[bool]
|
||||
for key in metrics[0]
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
def kickoff_for_each(self, inputs: List[Dict[str, Any]]) -> List:
|
||||
"""Executes the Crew's workflow for each input in the list and aggregates results."""
|
||||
results = []
|
||||
|
||||
for input_data in inputs:
|
||||
crew = self.copy()
|
||||
|
||||
for task in crew.tasks:
|
||||
task.interpolate_inputs(input_data)
|
||||
for agent in crew.agents:
|
||||
agent.interpolate_inputs(input_data)
|
||||
|
||||
output = crew.kickoff()
|
||||
results.append(output)
|
||||
|
||||
return results
|
||||
|
||||
async def kickoff_async(
|
||||
self, inputs: Optional[Dict[str, Any]] = {}
|
||||
) -> Union[str, Dict]:
|
||||
"""Asynchronous kickoff method to start the crew execution."""
|
||||
return await asyncio.to_thread(self.kickoff, inputs)
|
||||
|
||||
async def kickoff_for_each_async(self, inputs: List[Dict]) -> List[Any]:
|
||||
async def run_crew(input_data):
|
||||
crew = self.copy()
|
||||
|
||||
for task in crew.tasks:
|
||||
task.interpolate_inputs(input_data)
|
||||
for agent in crew.agents:
|
||||
agent.interpolate_inputs(input_data)
|
||||
|
||||
return await crew.kickoff_async()
|
||||
|
||||
tasks = [asyncio.create_task(run_crew(input_data)) for input_data in inputs]
|
||||
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
return results
|
||||
|
||||
def _run_sequential_process(self) -> str:
|
||||
"""Executes tasks sequentially and returns the final output."""
|
||||
task_output = ""
|
||||
@@ -303,6 +383,7 @@ class Crew(BaseModel):
|
||||
)
|
||||
|
||||
output = task.execute(context=task_output)
|
||||
|
||||
if not task.async_execution:
|
||||
task_output = output
|
||||
|
||||
@@ -313,9 +394,12 @@ class Crew(BaseModel):
|
||||
self._file_handler.log(agent=role, task=task_output, status="completed")
|
||||
|
||||
self._finish_execution(task_output)
|
||||
return self._format_output(task_output)
|
||||
|
||||
def _run_hierarchical_process(self) -> str:
|
||||
token_usage = task.agent._token_process.get_summary() # type: ignore # Item "None" of "Agent | None" has no attribute "_token_process"
|
||||
|
||||
return self._format_output(task_output, token_usage) # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str")
|
||||
|
||||
def _run_hierarchical_process(self) -> Union[str, Dict[str, Any]]:
|
||||
"""Creates and assigns a manager agent to make sure the crew completes the tasks."""
|
||||
|
||||
i18n = I18N(prompt_file=self.prompt_file)
|
||||
@@ -349,7 +433,7 @@ class Crew(BaseModel):
|
||||
agent=manager, context=task_output, tools=manager.tools
|
||||
)
|
||||
|
||||
self._logger.log("debug", f"[{manager.role}] Task output: {task_output}")
|
||||
self._logger.log("debug", f"[{manager.role}] Task ouptput: {task_output}")
|
||||
|
||||
if self.output_log_file:
|
||||
self._file_handler.log(
|
||||
@@ -357,7 +441,41 @@ class Crew(BaseModel):
|
||||
)
|
||||
|
||||
self._finish_execution(task_output)
|
||||
return self._format_output(task_output), manager._token_process.get_summary() # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str")
|
||||
|
||||
manager_token_usage = manager._token_process.get_summary()
|
||||
return self._format_output( # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str")
|
||||
task_output, manager_token_usage
|
||||
), manager_token_usage
|
||||
|
||||
def copy(self):
|
||||
"""Create a deep copy of the Crew."""
|
||||
|
||||
exclude = {
|
||||
"id",
|
||||
"_rpm_controller",
|
||||
"_logger",
|
||||
"_execution_span",
|
||||
"_file_handler",
|
||||
"_cache_handler",
|
||||
"_short_term_memory",
|
||||
"_long_term_memory",
|
||||
"_entity_memory",
|
||||
"agents",
|
||||
"tasks",
|
||||
}
|
||||
|
||||
cloned_agents = [agent.copy() for agent in self.agents]
|
||||
cloned_tasks = [task.copy() for task in self.tasks]
|
||||
|
||||
copied_data = self.model_dump(exclude=exclude)
|
||||
copied_data = {k: v for k, v in copied_data.items() if v is not None}
|
||||
|
||||
copied_data.pop("agents", None)
|
||||
copied_data.pop("tasks", None)
|
||||
|
||||
copied_crew = Crew(**copied_data, agents=cloned_agents, tasks=cloned_tasks)
|
||||
|
||||
return copied_crew
|
||||
|
||||
def _set_tasks_callbacks(self) -> None:
|
||||
"""Sets callback for every task suing task_callback"""
|
||||
@@ -367,15 +485,28 @@ class Crew(BaseModel):
|
||||
|
||||
def _interpolate_inputs(self, inputs: Dict[str, Any]) -> None:
|
||||
"""Interpolates the inputs in the tasks and agents."""
|
||||
[task.interpolate_inputs(inputs) for task in self.tasks] # type: ignore # "interpolate_inputs" of "Task" does not return a value (it only ever returns None)
|
||||
[
|
||||
task.interpolate_inputs(
|
||||
# type: ignore # "interpolate_inputs" of "Task" does not return a value (it only ever returns None)
|
||||
inputs
|
||||
)
|
||||
for task in self.tasks
|
||||
]
|
||||
|
||||
[agent.interpolate_inputs(inputs) for agent in self.agents] # type: ignore # "interpolate_inputs" of "Agent" does not return a value (it only ever returns None)
|
||||
|
||||
def _format_output(self, output: str) -> str:
|
||||
"""Formats the output of the crew execution."""
|
||||
def _format_output(
|
||||
self, output: str, token_usage: Optional[Dict[str, Any]]
|
||||
) -> Union[str, Dict[str, Any]]:
|
||||
"""
|
||||
Formats the output of the crew execution.
|
||||
If full_output is True, then returned data type will be a dictionary else returned outputs are string
|
||||
"""
|
||||
if self.full_output:
|
||||
return { # type: ignore # Incompatible return value type (got "dict[str, Sequence[str | TaskOutput | None]]", expected "str")
|
||||
"final_output": output,
|
||||
"tasks_outputs": [task.output for task in self.tasks if task],
|
||||
"usage_metrics": token_usage,
|
||||
}
|
||||
else:
|
||||
return output
|
||||
|
||||
@@ -12,7 +12,10 @@ class EntityMemory(Memory):
|
||||
|
||||
def __init__(self, crew=None, embedder_config=None):
|
||||
storage = RAGStorage(
|
||||
type="entities", allow_reset=False, embedder_config=embedder_config, crew=crew
|
||||
type="entities",
|
||||
allow_reset=False,
|
||||
embedder_config=embedder_config,
|
||||
crew=crew,
|
||||
)
|
||||
super().__init__(storage)
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@ class ShortTermMemory(Memory):
|
||||
"""
|
||||
|
||||
def __init__(self, crew=None, embedder_config=None):
|
||||
storage = RAGStorage(type="short_term", embedder_config=embedder_config, crew=crew)
|
||||
storage = RAGStorage(
|
||||
type="short_term", embedder_config=embedder_config, crew=crew
|
||||
)
|
||||
super().__init__(storage)
|
||||
|
||||
def save(self, item: ShortTermMemoryItem) -> None: # type: ignore # BUG?: Signature of "save" incompatible with supertype "Memory"
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
tasks_order = []
|
||||
|
||||
|
||||
def memoize(func):
|
||||
cache = {}
|
||||
|
||||
@@ -10,14 +7,21 @@ def memoize(func):
|
||||
cache[key] = func(*args, **kwargs)
|
||||
return cache[key]
|
||||
|
||||
memoized_func.__dict__.update(func.__dict__)
|
||||
return memoized_func
|
||||
|
||||
|
||||
def task(func):
|
||||
if not hasattr(task, "registration_order"):
|
||||
task.registration_order = []
|
||||
|
||||
func.is_task = True
|
||||
tasks_order.append(func.__name__)
|
||||
func = memoize(func)
|
||||
return func
|
||||
wrapped_func = memoize(func)
|
||||
|
||||
# Append the function name to the registration order list
|
||||
task.registration_order.append(func.__name__)
|
||||
|
||||
return wrapped_func
|
||||
|
||||
|
||||
def agent(func):
|
||||
@@ -32,26 +36,43 @@ def crew(func):
|
||||
instantiated_agents = []
|
||||
|
||||
agent_roles = set()
|
||||
# Iterate over tasks_order to maintain the defined order
|
||||
for task_name in tasks_order:
|
||||
possible_task = getattr(self, task_name)
|
||||
if callable(possible_task):
|
||||
task_instance = possible_task()
|
||||
instantiated_tasks.append(task_instance)
|
||||
if hasattr(task_instance, "agent"):
|
||||
agent_instance = task_instance.agent
|
||||
if agent_instance.role not in agent_roles:
|
||||
instantiated_agents.append(agent_instance)
|
||||
agent_roles.add(agent_instance.role)
|
||||
all_functions = {
|
||||
name: getattr(self, name)
|
||||
for name in dir(self)
|
||||
if callable(getattr(self, name))
|
||||
}
|
||||
tasks = {
|
||||
name: func
|
||||
for name, func in all_functions.items()
|
||||
if hasattr(func, "is_task")
|
||||
}
|
||||
agents = {
|
||||
name: func
|
||||
for name, func in all_functions.items()
|
||||
if hasattr(func, "is_agent")
|
||||
}
|
||||
|
||||
# Sort tasks by their registration order
|
||||
sorted_task_names = sorted(
|
||||
tasks, key=lambda name: task.registration_order.index(name)
|
||||
)
|
||||
|
||||
# Instantiate tasks in the order they were defined
|
||||
for task_name in sorted_task_names:
|
||||
task_instance = tasks[task_name]()
|
||||
instantiated_tasks.append(task_instance)
|
||||
if hasattr(task_instance, "agent"):
|
||||
agent_instance = task_instance.agent
|
||||
if agent_instance.role not in agent_roles:
|
||||
instantiated_agents.append(agent_instance)
|
||||
agent_roles.add(agent_instance.role)
|
||||
|
||||
# Instantiate any additional agents not already included by tasks
|
||||
for attr_name in dir(self):
|
||||
possible_agent = getattr(self, attr_name)
|
||||
if callable(possible_agent) and hasattr(possible_agent, "is_agent"):
|
||||
temp_agent_instance = possible_agent()
|
||||
if temp_agent_instance.role not in agent_roles:
|
||||
instantiated_agents.append(temp_agent_instance)
|
||||
agent_roles.add(temp_agent_instance.role)
|
||||
for agent_name in agents:
|
||||
temp_agent_instance = agents[agent_name]()
|
||||
if temp_agent_instance.role not in agent_roles:
|
||||
instantiated_agents.append(temp_agent_instance)
|
||||
agent_roles.add(temp_agent_instance.role)
|
||||
|
||||
self.agents = instantiated_agents
|
||||
self.tasks = instantiated_tasks
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import inspect
|
||||
import yaml
|
||||
import os
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
from dotenv import load_dotenv
|
||||
from pydantic import ConfigDict
|
||||
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def CrewBase(cls):
|
||||
class WrappedClass(cls):
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
is_crew_class: bool = True
|
||||
is_crew_class: bool = True # type: ignore
|
||||
|
||||
base_directory = None
|
||||
for frame_info in inspect.stack():
|
||||
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
import re
|
||||
import threading
|
||||
import uuid
|
||||
from copy import deepcopy
|
||||
from typing import Any, Dict, List, Optional, Type
|
||||
|
||||
from langchain_openai import ChatOpenAI
|
||||
@@ -201,6 +202,7 @@ class Task(BaseModel):
|
||||
description=self.description,
|
||||
exported_output=exported_output,
|
||||
raw_output=result,
|
||||
agent=agent.role,
|
||||
)
|
||||
|
||||
if self.callback:
|
||||
@@ -241,6 +243,32 @@ class Task(BaseModel):
|
||||
"""Increment the delegations counter."""
|
||||
self.delegations += 1
|
||||
|
||||
def copy(self):
|
||||
"""Create a deep copy of the Task."""
|
||||
exclude = {
|
||||
"id",
|
||||
"agent",
|
||||
"context",
|
||||
"tools",
|
||||
}
|
||||
|
||||
copied_data = self.model_dump(exclude=exclude)
|
||||
copied_data = {k: v for k, v in copied_data.items() if v is not None}
|
||||
|
||||
cloned_context = (
|
||||
[task.copy() for task in self.context] if self.context else None
|
||||
)
|
||||
cloned_agent = self.agent.copy() if self.agent else None
|
||||
cloned_tools = deepcopy(self.tools) if self.tools else None
|
||||
|
||||
copied_task = Task(
|
||||
**copied_data,
|
||||
context=cloned_context,
|
||||
agent=cloned_agent,
|
||||
tools=cloned_tools,
|
||||
)
|
||||
return copied_task
|
||||
|
||||
def _export_output(self, result: str) -> Any:
|
||||
exported_result = result
|
||||
instructions = "I'm gonna convert this raw text into valid JSON."
|
||||
@@ -305,7 +333,7 @@ class Task(BaseModel):
|
||||
if directory and not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
with open(self.output_file, "w", encoding='utf-8') as file: # type: ignore # Argument 1 to "open" has incompatible type "str | None"; expected "int | str | bytes | PathLike[str] | PathLike[bytes]"
|
||||
with open(self.output_file, "w", encoding="utf-8") as file: # type: ignore # Argument 1 to "open" has incompatible type "str | None"; expected "int | str | bytes | PathLike[str] | PathLike[bytes]"
|
||||
file.write(result)
|
||||
return None
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class TaskOutput(BaseModel):
|
||||
exported_output: Union[str, BaseModel] = Field(
|
||||
description="Output of the task", default=None
|
||||
)
|
||||
agent: str = Field(description="Agent that executed the task")
|
||||
raw_output: str = Field(description="Result of the task")
|
||||
|
||||
@model_validator(mode="after")
|
||||
|
||||
@@ -18,14 +18,14 @@ class AgentTools(BaseModel):
|
||||
tools = [
|
||||
StructuredTool.from_function(
|
||||
func=self.delegate_work,
|
||||
name="Delegate work to co-worker",
|
||||
name="Delegate work to coworker",
|
||||
description=self.i18n.tools("delegate_work").format(
|
||||
coworkers=f"[{', '.join([f'{agent.role}' for agent in self.agents])}]"
|
||||
),
|
||||
),
|
||||
StructuredTool.from_function(
|
||||
func=self.ask_question,
|
||||
name="Ask question to co-worker",
|
||||
name="Ask question to coworker",
|
||||
description=self.i18n.tools("ask_question").format(
|
||||
coworkers=f"[{', '.join([f'{agent.role}' for agent in self.agents])}]"
|
||||
),
|
||||
@@ -33,29 +33,55 @@ class AgentTools(BaseModel):
|
||||
]
|
||||
return tools
|
||||
|
||||
def delegate_work(self, task: str, context: str, coworker: Union[str, None] = None, **kwargs):
|
||||
"""Useful to delegate a specific task to a co-worker passing all necessary context and names."""
|
||||
coworker = coworker or kwargs.get("co_worker") or kwargs.get("co-worker")
|
||||
is_list = coworker.startswith("[") and coworker.endswith("]")
|
||||
if is_list:
|
||||
coworker = coworker[1:-1].split(",")[0]
|
||||
def delegate_work(
|
||||
self,
|
||||
task: str,
|
||||
context: Union[str, None] = None,
|
||||
coworker: Union[str, None] = None,
|
||||
**kwargs,
|
||||
):
|
||||
"""Useful to delegate a specific task to a coworker passing all necessary context and names."""
|
||||
coworker = coworker or kwargs.get("co_worker") or kwargs.get("coworker")
|
||||
if coworker:
|
||||
is_list = coworker.startswith("[") and coworker.endswith("]")
|
||||
if is_list:
|
||||
coworker = coworker[1:-1].split(",")[0]
|
||||
return self._execute(coworker, task, context)
|
||||
|
||||
def ask_question(self, question: str, context: str, coworker: Union[str, None] = None, **kwargs):
|
||||
"""Useful to ask a question, opinion or take from a co-worker passing all necessary context and names."""
|
||||
coworker = coworker or kwargs.get("co_worker") or kwargs.get("co-worker")
|
||||
is_list = coworker.startswith("[") and coworker.endswith("]")
|
||||
if is_list:
|
||||
coworker = coworker[1:-1].split(",")[0]
|
||||
def ask_question(
|
||||
self,
|
||||
question: str,
|
||||
context: Union[str, None] = None,
|
||||
coworker: Union[str, None] = None,
|
||||
**kwargs,
|
||||
):
|
||||
"""Useful to ask a question, opinion or take from a coworker passing all necessary context and names."""
|
||||
coworker = coworker or kwargs.get("co_worker") or kwargs.get("coworker")
|
||||
if coworker:
|
||||
is_list = coworker.startswith("[") and coworker.endswith("]")
|
||||
if is_list:
|
||||
coworker = coworker[1:-1].split(",")[0]
|
||||
return self._execute(coworker, question, context)
|
||||
|
||||
def _execute(self, agent, task, context):
|
||||
def _execute(self, agent: Union[str, None], task: str, context: Union[str, None]):
|
||||
"""Execute the command."""
|
||||
try:
|
||||
agent = [
|
||||
if agent is None:
|
||||
agent = ""
|
||||
|
||||
# It is important to remove the quotes from the agent name.
|
||||
# The reason we have to do this is because less-powerful LLM's
|
||||
# have difficulty producing valid JSON.
|
||||
# As a result, we end up with invalid JSON that is truncated like this:
|
||||
# {"task": "....", "coworker": "....
|
||||
# when it should look like this:
|
||||
# {"task": "....", "coworker": "...."}
|
||||
agent_name = agent.casefold().replace('"', "").replace("\n", "")
|
||||
|
||||
agent = [ # type: ignore # Incompatible types in assignment (expression has type "list[Agent]", variable has type "str | None")
|
||||
available_agent
|
||||
for available_agent in self.agents
|
||||
if available_agent.role.casefold().strip() == agent.casefold().strip()
|
||||
if available_agent.role.casefold().replace("\n", "") == agent_name
|
||||
]
|
||||
except Exception as _:
|
||||
return self.i18n.errors("agent_tool_unexsiting_coworker").format(
|
||||
@@ -72,9 +98,9 @@ class AgentTools(BaseModel):
|
||||
)
|
||||
|
||||
agent = agent[0]
|
||||
task = Task(
|
||||
task = Task( # type: ignore # Incompatible types in assignment (expression has type "Task", variable has type "str")
|
||||
description=task,
|
||||
agent=agent,
|
||||
expected_output="Your best answer to your co-worker asking you this, accounting for the context shared.",
|
||||
expected_output="Your best answer to your coworker asking you this, accounting for the context shared.",
|
||||
)
|
||||
return agent.execute_task(task, context)
|
||||
return agent.execute_task(task, context) # type: ignore # "str" has no attribute "execute_task"
|
||||
|
||||
@@ -126,8 +126,8 @@ class ToolUsage:
|
||||
if not result:
|
||||
try:
|
||||
if calling.tool_name in [
|
||||
"Delegate work to co-worker",
|
||||
"Ask question to co-worker",
|
||||
"Delegate work to coworker",
|
||||
"Ask question to coworker",
|
||||
]:
|
||||
self.task.increment_delegations()
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"task": "\nCurrent Task: {input}\n\nBegin! This is VERY important to you, use the tools available and give your best Final Answer, your job depends on it!\n\nThought:",
|
||||
"memory": "\n\n# Useful context: \n{memory}",
|
||||
"role_playing": "You are {role}. {backstory}\nYour personal goal is: {goal}",
|
||||
"tools": "\nYou ONLY have access to the following tools, and should NEVER make up tools that are not listed here:\n\n{tools}\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, only one name of [{tool_names}], just the name, exactly as it's written.\nAction Input: the input to the action, just a simple a python dictionary, enclosed in curly braces, using \" to wrap keys and values.\nObservation: the result of the action\n\nOnce all necessary information is gathered:\n\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n",
|
||||
"tools": "\nYou ONLY have access to the following tools, and should NEVER make up tools that are not listed here:\n\n{tools}\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, only one name of [{tool_names}], just the name, exactly as it's written.\nAction Input: the input to the action, just a simple python dictionary, enclosed in curly braces, using \" to wrap keys and values.\nObservation: the result of the action\n\nOnce all necessary information is gathered:\n\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n",
|
||||
"no_tools": "To give my best complete final answer to the task use the exact following format:\n\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\nYour final answer must be the great and the most complete as possible, it must be outcome described.\n\nI MUST use these formats, my job depends on it!",
|
||||
"format": "I MUST either use a tool (use one at time) OR give my best final answer. To Use the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action, dictionary enclosed in curly braces\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\nYour final answer must be the great and the most complete as possible, it must be outcome described\n\n ",
|
||||
"final_answer_format": "If you don't need to use any more tools, you must give your best complete final answer, make sure it satisfy the expect criteria, use the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\n\n",
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"errors": {
|
||||
"force_final_answer": "Tool won't be use because it's time to give your final answer. Don't use tools and just your absolute BEST Final answer.",
|
||||
"agent_tool_unexsiting_coworker": "\nError executing tool. Co-worker mentioned not found, it must to be one of the following options:\n{coworkers}\n",
|
||||
"agent_tool_unexsiting_coworker": "\nError executing tool. coworker mentioned not found, it must be one of the following options:\n{coworkers}\n",
|
||||
"task_repeated_usage": "I tried reusing the same input, I must stop using this action input. I'll try something else instead.\n\n",
|
||||
"tool_usage_error": "I encountered an error: {error}",
|
||||
"tool_arguments_error": "Error: the Action Input is not a valid key, value dictionary.",
|
||||
@@ -29,7 +29,7 @@
|
||||
"tool_usage_exception": "I encountered an error while trying to use the tool. This was the error: {error}.\n Tool {tool} accepts these inputs: {tool_inputs}"
|
||||
},
|
||||
"tools": {
|
||||
"delegate_work": "Delegate a specific task to one of the following co-workers: {coworkers}\nThe input to this tool should be the co-worker, the task you want them to do, and ALL necessary context to execute the task, they know nothing about the task, so share absolute everything you know, don't reference things but instead explain them.",
|
||||
"ask_question": "Ask a specific question to one of the following co-workers: {coworkers}\nThe input to this tool should be the co-worker, the question you have for them, and ALL necessary context to ask the question properly, they know nothing about the question, so share absolute everything you know, don't reference things but instead explain them."
|
||||
"delegate_work": "Delegate a specific task to one of the following coworkers: {coworkers}\nThe input to this tool should be the coworker, the task you want them to do, and ALL necessary context to execute the task, they know nothing about the task, so share absolute everything you know, don't reference things but instead explain them.",
|
||||
"ask_question": "Ask a specific question to one of the following coworkers: {coworkers}\nThe input to this tool should be the coworker, the question you have for them, and ALL necessary context to ask the question properly, they know nothing about the question, so share absolute everything you know, don't reference things but instead explain them."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
from .converter import Converter, ConverterError
|
||||
from .file_handler import FileHandler
|
||||
from .i18n import I18N
|
||||
from .instructor import Instructor
|
||||
from .logger import Logger
|
||||
from .parser import YamlParser
|
||||
from .printer import Printer
|
||||
from .prompts import Prompts
|
||||
from .rpm_controller import RPMController
|
||||
from .fileHandler import FileHandler
|
||||
from .parser import YamlParser
|
||||
|
||||
__all__ = [
|
||||
"Converter",
|
||||
"ConverterError",
|
||||
"FileHandler",
|
||||
"I18N",
|
||||
"Instructor",
|
||||
"Logger",
|
||||
"Printer",
|
||||
"Prompts",
|
||||
"RPMController",
|
||||
"YamlParser",
|
||||
]
|
||||
|
||||
2
src/crewai/utilities/constants.py
Normal file
2
src/crewai/utilities/constants.py
Normal file
@@ -0,0 +1,2 @@
|
||||
TRAINING_DATA_FILE = "training_data.pkl"
|
||||
TRAINED_AGENTS_DATA_FILE = "trained_agents_data.pkl"
|
||||
@@ -26,6 +26,18 @@ class TaskEvaluation(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
class TrainingTaskEvaluation(BaseModel):
|
||||
suggestions: List[str] = Field(
|
||||
description="Based on the Human Feedbacks and the comparison between Initial Outputs and Improved outputs provide action items based on human_feedback for future tasks."
|
||||
)
|
||||
quality: float = Field(
|
||||
description="A score from 0 to 10 evaluating on completion, quality, and overall performance from the improved output to the initial output based on the human feedback."
|
||||
)
|
||||
final_summary: str = Field(
|
||||
description="A step by step action items to improve the next Agent based on the human-feedback and improved output."
|
||||
)
|
||||
|
||||
|
||||
class TaskEvaluator:
|
||||
def __init__(self, original_agent):
|
||||
self.llm = original_agent.llm
|
||||
@@ -59,3 +71,49 @@ class TaskEvaluator:
|
||||
|
||||
def _is_gpt(self, llm) -> bool:
|
||||
return isinstance(llm, ChatOpenAI) and llm.openai_api_base is None
|
||||
|
||||
def evaluate_training_data(
|
||||
self, training_data: dict, agent_id: str
|
||||
) -> TrainingTaskEvaluation:
|
||||
"""
|
||||
Evaluate the training data based on the llm output, human feedback, and improved output.
|
||||
|
||||
Parameters:
|
||||
- training_data (dict): The training data to be evaluated.
|
||||
- agent_id (str): The ID of the agent.
|
||||
"""
|
||||
|
||||
output_training_data = training_data[agent_id]
|
||||
|
||||
final_aggregated_data = ""
|
||||
for _, data in output_training_data.items():
|
||||
final_aggregated_data += (
|
||||
f"Initial Output:\n{data['initial_output']}\n\n"
|
||||
f"Human Feedback:\n{data['human_feedback']}\n\n"
|
||||
f"Improved Output:\n{data['improved_output']}\n\n"
|
||||
)
|
||||
|
||||
evaluation_query = (
|
||||
"Assess the quality of the training data based on the llm output, human feedback , and llm output improved result.\n\n"
|
||||
f"{final_aggregated_data}"
|
||||
"Please provide:\n"
|
||||
"- Based on the Human Feedbacks and the comparison between Initial Outputs and Improved outputs provide action items based on human_feedback for future tasks\n"
|
||||
"- A score from 0 to 10 evaluating on completion, quality, and overall performance from the improved output to the initial output based on the human feedback\n"
|
||||
)
|
||||
instructions = "I'm gonna convert this raw text into valid JSON."
|
||||
|
||||
if not self._is_gpt(self.llm):
|
||||
model_schema = PydanticSchemaParser(
|
||||
model=TrainingTaskEvaluation
|
||||
).get_schema()
|
||||
instructions = f"{instructions}\n\nThe json should have the following structure, with the following keys:\n{model_schema}"
|
||||
|
||||
converter = Converter(
|
||||
llm=self.llm,
|
||||
text=evaluation_query,
|
||||
model=TrainingTaskEvaluation,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
pydantic_result = converter.to_pydantic()
|
||||
return pydantic_result
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class FileHandler:
|
||||
"""take care of file operations, currently it only logs messages to a file"""
|
||||
|
||||
def __init__(self, file_path):
|
||||
if isinstance(file_path, bool):
|
||||
self._path = os.path.join(os.curdir, "logs.txt")
|
||||
elif isinstance(file_path, str):
|
||||
self._path = file_path
|
||||
else:
|
||||
raise ValueError("file_path must be either a boolean or a string.")
|
||||
|
||||
def log(self, **kwargs):
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
message = f"{now}: ".join([f"{key}={value}" for key, value in kwargs.items()])
|
||||
with open(self._path, "a") as file:
|
||||
file.write(message + "\n")
|
||||
69
src/crewai/utilities/file_handler.py
Normal file
69
src/crewai/utilities/file_handler.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import os
|
||||
import pickle
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class FileHandler:
|
||||
"""take care of file operations, currently it only logs messages to a file"""
|
||||
|
||||
def __init__(self, file_path):
|
||||
if isinstance(file_path, bool):
|
||||
self._path = os.path.join(os.curdir, "logs.txt")
|
||||
elif isinstance(file_path, str):
|
||||
self._path = file_path
|
||||
else:
|
||||
raise ValueError("file_path must be either a boolean or a string.")
|
||||
|
||||
def log(self, **kwargs):
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
message = f"{now}: ".join([f"{key}={value}" for key, value in kwargs.items()])
|
||||
with open(self._path, "a", encoding="utf-8") as file:
|
||||
file.write(message + "\n")
|
||||
|
||||
|
||||
class PickleHandler:
|
||||
def __init__(self, file_name: str) -> None:
|
||||
"""
|
||||
Initialize the PickleHandler with the name of the file where data will be stored.
|
||||
The file will be saved in the current directory.
|
||||
|
||||
Parameters:
|
||||
- file_name (str): The name of the file for saving and loading data.
|
||||
"""
|
||||
self.file_path = os.path.join(os.getcwd(), file_name)
|
||||
self._initialize_file()
|
||||
|
||||
def _initialize_file(self) -> None:
|
||||
"""
|
||||
Initialize the file with an empty dictionary if it does not exist or is empty.
|
||||
"""
|
||||
if not os.path.exists(self.file_path) or os.path.getsize(self.file_path) == 0:
|
||||
self.save({}) # Save an empty dictionary to initialize the file
|
||||
|
||||
def save(self, data) -> None:
|
||||
"""
|
||||
Save the data to the specified file using pickle.
|
||||
|
||||
Parameters:
|
||||
- data (object): The data to be saved.
|
||||
"""
|
||||
with open(self.file_path, "wb") as file:
|
||||
pickle.dump(data, file)
|
||||
|
||||
def load(self) -> dict:
|
||||
"""
|
||||
Load the data from the specified file using pickle.
|
||||
|
||||
Returns:
|
||||
- dict: The data loaded from the file.
|
||||
"""
|
||||
if not os.path.exists(self.file_path) or os.path.getsize(self.file_path) == 0:
|
||||
return {} # Return an empty dictionary if the file does not exist or is empty
|
||||
|
||||
with open(self.file_path, "rb") as file:
|
||||
try:
|
||||
return pickle.load(file)
|
||||
except EOFError:
|
||||
return {} # Return an empty dictionary if the file is empty or corrupted
|
||||
except Exception:
|
||||
raise # Raise any other exceptions that occur during loading
|
||||
@@ -1,3 +1,5 @@
|
||||
from datetime import datetime
|
||||
|
||||
from crewai.utilities.printer import Printer
|
||||
|
||||
|
||||
@@ -13,4 +15,7 @@ class Logger:
|
||||
def log(self, level, message, color="bold_green"):
|
||||
level_map = {"debug": 1, "info": 2}
|
||||
if self.verbose_level and level_map.get(level, 0) <= self.verbose_level:
|
||||
self._printer.print(f"[{level.upper()}]: {message}", color=color)
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self._printer.print(
|
||||
f"[{timestamp}][{level.upper()}]: {message}", color=color
|
||||
)
|
||||
|
||||
31
src/crewai/utilities/training_handler.py
Normal file
31
src/crewai/utilities/training_handler.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from crewai.utilities.file_handler import PickleHandler
|
||||
|
||||
|
||||
class CrewTrainingHandler(PickleHandler):
|
||||
def save_trained_data(self, agent_id: str, trained_data: dict) -> None:
|
||||
"""
|
||||
Save the trained data for a specific agent.
|
||||
|
||||
Parameters:
|
||||
- agent_id (str): The ID of the agent.
|
||||
- trained_data (dict): The trained data to be saved.
|
||||
"""
|
||||
data = self.load()
|
||||
data[agent_id] = trained_data
|
||||
self.save(data)
|
||||
|
||||
def append(self, train_iteration: int, agent_id: str, new_data) -> None:
|
||||
"""
|
||||
Append new data to the existing pickle file.
|
||||
|
||||
Parameters:
|
||||
- new_data (object): The new data to be appended.
|
||||
"""
|
||||
data = self.load()
|
||||
|
||||
if agent_id in data:
|
||||
data[agent_id][train_iteration] = new_data
|
||||
else:
|
||||
data[agent_id] = {train_iteration: new_data}
|
||||
|
||||
self.save(data)
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Test Agent creation and execution basic functionality."""
|
||||
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
@@ -29,7 +30,7 @@ def test_agent_default_values():
|
||||
agent = Agent(role="test role", goal="test goal", backstory="test backstory")
|
||||
|
||||
assert isinstance(agent.llm, ChatOpenAI)
|
||||
assert agent.llm.model_name == "gpt-4"
|
||||
assert agent.llm.model_name == "gpt-4o"
|
||||
assert agent.llm.temperature == 0.7
|
||||
assert agent.llm.verbose is False
|
||||
assert agent.allow_delegation is True
|
||||
@@ -732,7 +733,7 @@ def test_agent_llm_uses_token_calc_handler_with_llm_has_model_name():
|
||||
|
||||
assert len(agent1.llm.callbacks) == 1
|
||||
assert agent1.llm.callbacks[0].__class__.__name__ == "TokenCalcHandler"
|
||||
assert agent1.llm.callbacks[0].model == "gpt-4"
|
||||
assert agent1.llm.callbacks[0].model == "gpt-4o"
|
||||
assert (
|
||||
agent1.llm.callbacks[0].token_cost_process.__class__.__name__ == "TokenProcess"
|
||||
)
|
||||
@@ -842,3 +843,54 @@ Thought:
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@patch("crewai.agent.CrewTrainingHandler")
|
||||
def test_agent_training_handler(crew_training_handler):
|
||||
task_prompt = "What is 1 + 1?"
|
||||
agent = Agent(
|
||||
role="test role",
|
||||
goal="test goal",
|
||||
backstory="test backstory",
|
||||
verbose=True,
|
||||
)
|
||||
crew_training_handler().load.return_value = {
|
||||
f"{str(agent.id)}": {"0": {"human_feedback": "good"}}
|
||||
}
|
||||
|
||||
result = agent._training_handler(task_prompt=task_prompt)
|
||||
|
||||
assert result == "What is 1 + 1?You MUST follow these feedbacks: \n good"
|
||||
|
||||
crew_training_handler.assert_has_calls(
|
||||
[mock.call(), mock.call("training_data.pkl"), mock.call().load()]
|
||||
)
|
||||
|
||||
|
||||
@patch("crewai.agent.CrewTrainingHandler")
|
||||
def test_agent_use_trained_data(crew_training_handler):
|
||||
task_prompt = "What is 1 + 1?"
|
||||
agent = Agent(
|
||||
role="researcher",
|
||||
goal="test goal",
|
||||
backstory="test backstory",
|
||||
verbose=True,
|
||||
)
|
||||
crew_training_handler().load.return_value = {
|
||||
agent.role: {
|
||||
"suggestions": [
|
||||
"The result of the math operatio must be right.",
|
||||
"Result must be better than 1.",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
result = agent._use_trained_data(task_prompt=task_prompt)
|
||||
|
||||
assert (
|
||||
result == "What is 1 + 1?You MUST follow these feedbacks: \n "
|
||||
"The result of the math operatio must be right.\n - Result must be better than 1."
|
||||
)
|
||||
crew_training_handler.assert_has_calls(
|
||||
[mock.call(), mock.call("trained_agents_data.pkl"), mock.call().load()]
|
||||
)
|
||||
|
||||
@@ -55,6 +55,7 @@ def test_ask_question():
|
||||
== "As an AI researcher, I don't have personal feelings or emotions like love or hate. However, I recognize the importance of AI Agents in today's technological landscape. They have the potential to greatly enhance our lives and make tasks more efficient. At the same time, it is crucial to consider the ethical implications and societal impacts that come with their use. My role is to provide objective research and analysis on these topics."
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_ask_question_with_wrong_co_worker_variable():
|
||||
result = tools.ask_question(
|
||||
@@ -68,6 +69,7 @@ def test_ask_question_with_wrong_co_worker_variable():
|
||||
== "No, I don't hate AI agents. In fact, I find them quite fascinating. They are powerful tools that can greatly assist in various tasks, including my research. As a technology researcher, AI and AI agents are subjects of interest to me due to their potential in advancing our understanding and capabilities in various fields. My supposed love for them stems from this professional interest and the potential they hold."
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_delegate_work_withwith_coworker_as_array():
|
||||
result = tools.delegate_work(
|
||||
@@ -105,7 +107,7 @@ def test_delegate_work_to_wrong_agent():
|
||||
|
||||
assert (
|
||||
result
|
||||
== "\nError executing tool. Co-worker mentioned not found, it must to be one of the following options:\n- researcher\n"
|
||||
== "\nError executing tool. coworker mentioned not found, it must be one of the following options:\n- researcher\n"
|
||||
)
|
||||
|
||||
|
||||
@@ -118,5 +120,5 @@ def test_ask_question_to_wrong_agent():
|
||||
|
||||
assert (
|
||||
result
|
||||
== "\nError executing tool. Co-worker mentioned not found, it must to be one of the following options:\n- researcher\n"
|
||||
== "\nError executing tool. coworker mentioned not found, it must be one of the following options:\n- researcher\n"
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@ interactions:
|
||||
the task.\nYour final answer must be the great and the most complete as possible,
|
||||
it must be outcome described.\n\nI MUST use these formats, my job depends on
|
||||
it!\nCurrent Task: do you hate AI Agents?\n\nThis is the expect criteria for
|
||||
your final answer: Your best answer to your co-worker asking you this, accounting
|
||||
your final answer: Your best answer to your coworker asking you this, accounting
|
||||
for the context shared. \n you MUST return the actual complete content as the
|
||||
final answer, not a summary.\n\nThis is the context you''re working with:\nI
|
||||
heard you LOVE them\n\nBegin! This is VERY important to you, use the tools available
|
||||
|
||||
@@ -200797,7 +200797,7 @@ interactions:
|
||||
the task.\nYour final answer must be the great and the most complete as possible,
|
||||
it must be outcome described.\n\nI MUST use these formats, my job depends on
|
||||
it!\nCurrent Task: do you hate AI Agents?\n\nThis is the expect criteria for
|
||||
your final answer: Your best answer to your co-worker asking you this, accounting
|
||||
your final answer: Your best answer to your coworker asking you this, accounting
|
||||
for the context shared. \n you MUST return the actual complete content as the
|
||||
final answer, not a summary.\n\nThis is the context you''re working with:\nI
|
||||
heard you LOVE them\n\nBegin! This is VERY important to you, use the tools available
|
||||
|
||||
@@ -95,7 +95,7 @@ interactions:
|
||||
the task.\nYour final answer must be the great and the most complete as possible,
|
||||
it must be outcome described.\n\nI MUST use these formats, my job depends on
|
||||
it!\nCurrent Task: share your take on AI Agents\n\nThis is the expect criteria
|
||||
for your final answer: Your best answer to your co-worker asking you this, accounting
|
||||
for your final answer: Your best answer to your coworker asking you this, accounting
|
||||
for the context shared. \n you MUST return the actual complete content as the
|
||||
final answer, not a summary.\n\nThis is the context you''re working with:\nI
|
||||
heard you hate them\n\nBegin! This is VERY important to you, use the tools available
|
||||
|
||||
@@ -95,7 +95,7 @@ interactions:
|
||||
the task.\nYour final answer must be the great and the most complete as possible,
|
||||
it must be outcome described.\n\nI MUST use these formats, my job depends on
|
||||
it!\nCurrent Task: share your take on AI Agents\n\nThis is the expect criteria
|
||||
for your final answer: Your best answer to your co-worker asking you this, accounting
|
||||
for your final answer: Your best answer to your coworker asking you this, accounting
|
||||
for the context shared. \n you MUST return the actual complete content as the
|
||||
final answer, not a summary.\n\nThis is the context you''re working with:\nI
|
||||
heard you hate them\n\nBegin! This is VERY important to you, use the tools available
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,19 +3,19 @@ interactions:
|
||||
body: '{"messages": [{"role": "user", "content": "You are test role. test backstory\nYour
|
||||
personal goal is: test goal\n\nYou ONLY have access to the following tools,
|
||||
and should NEVER make up tools that are not listed here:\n\nDelegate work to
|
||||
co-worker: Delegate work to co-worker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following co-workers: [''test role2'']\nThe
|
||||
coworker: Delegate work to coworker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following coworkers: [''test role2'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role2'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -323,19 +323,19 @@ interactions:
|
||||
body: '{"messages": [{"role": "user", "content": "You are test role. test backstory\nYour
|
||||
personal goal is: test goal\n\nYou ONLY have access to the following tools,
|
||||
and should NEVER make up tools that are not listed here:\n\nDelegate work to
|
||||
co-worker: Delegate work to co-worker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following co-workers: [''test role2'']\nThe
|
||||
coworker: Delegate work to coworker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following coworkers: [''test role2'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role2'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -345,23 +345,23 @@ interactions:
|
||||
as the final answer, not a summary.\n\nBegin! This is VERY important to you,
|
||||
use the tools available and give your best Final Answer, your job depends on
|
||||
it!\n\nThought: \nAs this task is very straightforward and doesn''t require
|
||||
any input or help from my co-worker, I should go ahead and complete it myself.\n\nAction:
|
||||
any input or help from my coworker, I should go ahead and complete it myself.\n\nAction:
|
||||
None\n\nAction Input: None\n\nObservation: I encountered an error: Action ''None''
|
||||
don''t exist, these are the only available Actions: Delegate work to co-worker:
|
||||
Delegate work to co-worker(coworker: str, task: str, context: str) - Delegate
|
||||
a specific task to one of the following co-workers: [''test role2'']\nThe input
|
||||
don''t exist, these are the only available Actions: Delegate work to coworker:
|
||||
Delegate work to coworker(coworker: str, task: str, context: str) - Delegate
|
||||
a specific task to one of the following coworkers: [''test role2'']\nThe input
|
||||
to this tool should be the coworker, the task you want them to do, and ALL necessary
|
||||
context to execute the task, they know nothing about the task, so share absolute
|
||||
everything you know, don''t reference things but instead explain them.\nAsk
|
||||
question to co-worker: Ask question to co-worker(coworker: str, question: str,
|
||||
context: str) - Ask a specific question to one of the following co-workers:
|
||||
question to coworker: Ask question to coworker(coworker: str, question: str,
|
||||
context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role2'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\nMoving on then. I MUST either use
|
||||
a tool (use one at time) OR give my best final answer. To Use the following
|
||||
format:\n\nThought: you should always think about what to do\nAction: the action
|
||||
to take, should be one of [Delegate work to co-worker, Ask question to co-worker]\nAction
|
||||
to take, should be one of [Delegate work to coworker, Ask question to coworker]\nAction
|
||||
Input: the input to the action, dictionary\nObservation: the result of the action\n...
|
||||
(this Thought/Action/Action Input/Observation can repeat N times)\nThought:
|
||||
I now can give a great answer\nFinal Answer: my best complete final answer to
|
||||
@@ -1024,19 +1024,19 @@ interactions:
|
||||
body: '{"messages": [{"role": "user", "content": "You are test role. test backstory\nYour
|
||||
personal goal is: test goal\n\nYou ONLY have access to the following tools,
|
||||
and should NEVER make up tools that are not listed here:\n\nDelegate work to
|
||||
co-worker: Delegate work to co-worker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following co-workers: [''test role2'']\nThe
|
||||
coworker: Delegate work to coworker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following coworkers: [''test role2'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role2'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -1046,31 +1046,31 @@ interactions:
|
||||
as the final answer, not a summary.\n\nBegin! This is VERY important to you,
|
||||
use the tools available and give your best Final Answer, your job depends on
|
||||
it!\n\nThought: \nAs this task is very straightforward and doesn''t require
|
||||
any input or help from my co-worker, I should go ahead and complete it myself.\n\nAction:
|
||||
any input or help from my coworker, I should go ahead and complete it myself.\n\nAction:
|
||||
None\n\nAction Input: None\n\nObservation: I encountered an error: Action ''None''
|
||||
don''t exist, these are the only available Actions: Delegate work to co-worker:
|
||||
Delegate work to co-worker(coworker: str, task: str, context: str) - Delegate
|
||||
a specific task to one of the following co-workers: [''test role2'']\nThe input
|
||||
don''t exist, these are the only available Actions: Delegate work to coworker:
|
||||
Delegate work to coworker(coworker: str, task: str, context: str) - Delegate
|
||||
a specific task to one of the following coworkers: [''test role2'']\nThe input
|
||||
to this tool should be the coworker, the task you want them to do, and ALL necessary
|
||||
context to execute the task, they know nothing about the task, so share absolute
|
||||
everything you know, don''t reference things but instead explain them.\nAsk
|
||||
question to co-worker: Ask question to co-worker(coworker: str, question: str,
|
||||
context: str) - Ask a specific question to one of the following co-workers:
|
||||
question to coworker: Ask question to coworker(coworker: str, question: str,
|
||||
context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role2'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\nMoving on then. I MUST either use
|
||||
a tool (use one at time) OR give my best final answer. To Use the following
|
||||
format:\n\nThought: you should always think about what to do\nAction: the action
|
||||
to take, should be one of [Delegate work to co-worker, Ask question to co-worker]\nAction
|
||||
to take, should be one of [Delegate work to coworker, Ask question to coworker]\nAction
|
||||
Input: the input to the action, dictionary\nObservation: the result of the action\n...
|
||||
(this Thought/Action/Action Input/Observation can repeat N times)\nThought:
|
||||
I now can give a great answer\nFinal Answer: my best complete final answer to
|
||||
the task.\nYour final answer must be the great and the most complete as possible,
|
||||
it must be outcome described\n\n \nThought: \nAlthough I initially thought that
|
||||
I could just say hi myself, this system seems to require me to use one of the
|
||||
tools available. Therefore, I''ll delegate this task to my co-worker.\n\nAction:
|
||||
Delegate work to co-worker\n\nAction Input: {\"coworker\": \"test role2\", \"task\":
|
||||
tools available. Therefore, I''ll delegate this task to my coworker.\n\nAction:
|
||||
Delegate work to coworker\n\nAction Input: {\"coworker\": \"test role2\", \"task\":
|
||||
\"Just say hi\", \"context\": \"We need to greet someone. Just say ''hi'' to
|
||||
them.\"}\n\nObservation: Hi there!\n"}], "model": "gpt-4", "n": 1, "stop": ["\nObservation"],
|
||||
"stream": true, "temperature": 0.7}'
|
||||
@@ -1233,19 +1233,19 @@ interactions:
|
||||
body: '{"messages": [{"role": "user", "content": "You are test role. test backstory\nYour
|
||||
personal goal is: test goal\n\nYou ONLY have access to the following tools,
|
||||
and should NEVER make up tools that are not listed here:\n\nDelegate work to
|
||||
co-worker: Delegate work to co-worker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following co-workers: [''test role2'']\nThe
|
||||
coworker: Delegate work to coworker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following coworkers: [''test role2'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role2'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -1482,19 +1482,19 @@ interactions:
|
||||
body: '{"messages": [{"role": "user", "content": "You are test role2. test backstory2\nYour
|
||||
personal goal is: test goal2\n\nYou ONLY have access to the following tools,
|
||||
and should NEVER make up tools that are not listed here:\n\nDelegate work to
|
||||
co-worker: Delegate work to co-worker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following co-workers: [''test role'']\nThe
|
||||
coworker: Delegate work to coworker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following coworkers: [''test role'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -2487,19 +2487,19 @@ interactions:
|
||||
body: '{"messages": [{"role": "user", "content": "You are test role2. test backstory2\nYour
|
||||
personal goal is: test goal2\n\nYou ONLY have access to the following tools,
|
||||
and should NEVER make up tools that are not listed here:\n\nDelegate work to
|
||||
co-worker: Delegate work to co-worker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following co-workers: [''test role'']\nThe
|
||||
coworker: Delegate work to coworker(coworker: str, task: str, context: str)
|
||||
- Delegate a specific task to one of the following coworkers: [''test role'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''test role'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -2511,8 +2511,8 @@ interactions:
|
||||
you, use the tools available and give your best Final Answer, your job depends
|
||||
on it!\n\nThought: \nI need to understand the context better before I can provide
|
||||
a final answer. It seems I''m missing crucial information to proceed. I will
|
||||
ask a question to my co-worker, ''test role'', to gather more details about
|
||||
the situation.\n\nAction: \nAsk question to co-worker\n\nAction Input: \n{\"coworker\":
|
||||
ask a question to my coworker, ''test role'', to gather more details about
|
||||
the situation.\n\nAction: \nAsk question to coworker\n\nAction Input: \n{\"coworker\":
|
||||
\"test role\", \"question\": \"Could you please provide more details about the
|
||||
situation?\", \"context\": \"Hi there!\"}\n\nObservation: Could you please provide
|
||||
more details about the situation?\n"}], "model": "gpt-4", "n": 1, "stop": ["\nObservation"],
|
||||
|
||||
@@ -64,19 +64,19 @@ interactions:
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nmultiplier: multiplier(first_number: int, second_number:
|
||||
int) -> float - Useful for when you need to multiply two numbers together.\nDelegate
|
||||
work to co-worker: Delegate work to co-worker(coworker: str, task: str, context:
|
||||
str) - Delegate a specific task to one of the following co-workers: [''Researcher'']\nThe
|
||||
work to coworker: Delegate work to coworker(coworker: str, task: str, context:
|
||||
str) - Delegate a specific task to one of the following coworkers: [''Researcher'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''Researcher'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [multiplier, Delegate work to co-worker, Ask question to co-worker],
|
||||
name of [multiplier, Delegate work to coworker, Ask question to coworker],
|
||||
just the name, exactly as it''s written.\nAction Input: the input to the action,
|
||||
just a simple a python dictionary using \" to wrap keys and values.\nObservation:
|
||||
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
|
||||
@@ -439,19 +439,19 @@ interactions:
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nmultiplier: multiplier(first_number: int, second_number:
|
||||
int) -> float - Useful for when you need to multiply two numbers together.\nDelegate
|
||||
work to co-worker: Delegate work to co-worker(coworker: str, task: str, context:
|
||||
str) - Delegate a specific task to one of the following co-workers: [''Researcher'']\nThe
|
||||
work to coworker: Delegate work to coworker(coworker: str, task: str, context:
|
||||
str) - Delegate a specific task to one of the following coworkers: [''Researcher'']\nThe
|
||||
input to this tool should be the coworker, the task you want them to do, and
|
||||
ALL necessary context to execute the task, they know nothing about the task,
|
||||
so share absolute everything you know, don''t reference things but instead explain
|
||||
them.\nAsk question to co-worker: Ask question to co-worker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following co-workers:
|
||||
them.\nAsk question to coworker: Ask question to coworker(coworker: str, question:
|
||||
str, context: str) - Ask a specific question to one of the following coworkers:
|
||||
[''Researcher'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [multiplier, Delegate work to co-worker, Ask question to co-worker],
|
||||
name of [multiplier, Delegate work to coworker, Ask question to coworker],
|
||||
just the name, exactly as it''s written.\nAction Input: the input to the action,
|
||||
just a simple a python dictionary using \" to wrap keys and values.\nObservation:
|
||||
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
|
||||
@@ -463,7 +463,7 @@ interactions:
|
||||
Answer, your job depends on it!\n\nThought: \nThe task at hand is to find the
|
||||
product of 2 and 6. Since I have the tool ''multiplier'' which multiplies two
|
||||
numbers, I can directly use it without needing to delegate or ask questions
|
||||
to a co-worker.\n\nAction: multiplier\nAction Input: {\"first_number\": 2, \"second_number\":
|
||||
to a coworker.\n\nAction: multiplier\nAction Input: {\"first_number\": 2, \"second_number\":
|
||||
6}\n\nObservation: 12\n"}], "model": "gpt-4", "n": 1, "stop": ["\nObservation"],
|
||||
"stream": true, "temperature": 0.7}'
|
||||
headers:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -83,20 +83,20 @@ interactions:
|
||||
now working on a new project and want to make sure the content produced is amazing.\nYour
|
||||
personal goal is: Make sure the writers in your company produce amazing content.\n\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nDelegate work to co-worker: Delegate work to co-worker(coworker:
|
||||
are not listed here:\n\nDelegate work to coworker: Delegate work to coworker(coworker:
|
||||
str, task: str, context: str) - Delegate a specific task to one of the following
|
||||
co-workers: [''Senior Writer'']\nThe input to this tool should be the coworker,
|
||||
coworkers: [''Senior Writer'']\nThe input to this tool should be the coworker,
|
||||
the task you want them to do, and ALL necessary context to execute the task,
|
||||
they know nothing about the task, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\nAsk question to co-worker: Ask question
|
||||
to co-worker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following co-workers: [''Senior Writer'']\nThe input to this tool
|
||||
reference things but instead explain them.\nAsk question to coworker: Ask question
|
||||
to coworker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following coworkers: [''Senior Writer'']\nThe input to this tool
|
||||
should be the coworker, the question you have for them, and ALL necessary context
|
||||
to ask the question properly, they know nothing about the question, so share
|
||||
absolute everything you know, don''t reference things but instead explain them.\n\nUse
|
||||
the following format:\n\nThought: you should always think about what to do\nAction:
|
||||
the action to take, only one name of [Delegate work to co-worker, Ask question
|
||||
to co-worker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
the action to take, only one name of [Delegate work to coworker, Ask question
|
||||
to coworker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
to the action, just a simple a python dictionary using \" to wrap keys and values.\nObservation:
|
||||
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
|
||||
I now know the final answer\nFinal Answer: the final answer to the original
|
||||
@@ -1713,20 +1713,20 @@ interactions:
|
||||
now working on a new project and want to make sure the content produced is amazing.\nYour
|
||||
personal goal is: Make sure the writers in your company produce amazing content.\n\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nDelegate work to co-worker: Delegate work to co-worker(coworker:
|
||||
are not listed here:\n\nDelegate work to coworker: Delegate work to coworker(coworker:
|
||||
str, task: str, context: str) - Delegate a specific task to one of the following
|
||||
co-workers: [''Senior Writer'']\nThe input to this tool should be the coworker,
|
||||
coworkers: [''Senior Writer'']\nThe input to this tool should be the coworker,
|
||||
the task you want them to do, and ALL necessary context to execute the task,
|
||||
they know nothing about the task, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\nAsk question to co-worker: Ask question
|
||||
to co-worker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following co-workers: [''Senior Writer'']\nThe input to this tool
|
||||
reference things but instead explain them.\nAsk question to coworker: Ask question
|
||||
to coworker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following coworkers: [''Senior Writer'']\nThe input to this tool
|
||||
should be the coworker, the question you have for them, and ALL necessary context
|
||||
to ask the question properly, they know nothing about the question, so share
|
||||
absolute everything you know, don''t reference things but instead explain them.\n\nUse
|
||||
the following format:\n\nThought: you should always think about what to do\nAction:
|
||||
the action to take, only one name of [Delegate work to co-worker, Ask question
|
||||
to co-worker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
the action to take, only one name of [Delegate work to coworker, Ask question
|
||||
to coworker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
to the action, just a simple a python dictionary using \" to wrap keys and values.\nObservation:
|
||||
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
|
||||
I now know the final answer\nFinal Answer: the final answer to the original
|
||||
@@ -1738,7 +1738,7 @@ interactions:
|
||||
it!\n\nThought: \nI want to ensure that the Senior Writer understands the topic
|
||||
and the standard of quality that we aim to achieve. I''ll provide them with
|
||||
all the information they need to produce an amazing 1 paragraph draft about
|
||||
AI Agents. \n\nAction: Delegate work to co-worker\nAction Input: {\"coworker\":
|
||||
AI Agents. \n\nAction: Delegate work to coworker\nAction Input: {\"coworker\":
|
||||
\"Senior Writer\", \"task\": \"Produce a 1 paragraph draft of an article about
|
||||
AI Agents.\", \"context\": \"We are working on a new project that requires high-quality
|
||||
content about AI Agents. We want to make sure that the content is engaging,
|
||||
|
||||
@@ -63,20 +63,20 @@ interactions:
|
||||
allows you to properly evaluate the work of your team members.\nYour personal
|
||||
goal is: Manage the team to complete the task in the best way possible.\n\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nDelegate work to co-worker: Delegate work to co-worker(coworker:
|
||||
are not listed here:\n\nDelegate work to coworker: Delegate work to coworker(coworker:
|
||||
str, task: str, context: str) - Delegate a specific task to one of the following
|
||||
co-workers: [''Researcher'', ''Senior Writer'']\nThe input to this tool should
|
||||
coworkers: [''Researcher'', ''Senior Writer'']\nThe input to this tool should
|
||||
be the coworker, the task you want them to do, and ALL necessary context to
|
||||
execute the task, they know nothing about the task, so share absolute everything
|
||||
you know, don''t reference things but instead explain them.\nAsk question to
|
||||
co-worker: Ask question to co-worker(coworker: str, question: str, context:
|
||||
str) - Ask a specific question to one of the following co-workers: [''Researcher'',
|
||||
coworker: Ask question to coworker(coworker: str, question: str, context:
|
||||
str) - Ask a specific question to one of the following coworkers: [''Researcher'',
|
||||
''Senior Writer'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -2444,20 +2444,20 @@ interactions:
|
||||
allows you to properly evaluate the work of your team members.\nYour personal
|
||||
goal is: Manage the team to complete the task in the best way possible.\n\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nDelegate work to co-worker: Delegate work to co-worker(coworker:
|
||||
are not listed here:\n\nDelegate work to coworker: Delegate work to coworker(coworker:
|
||||
str, task: str, context: str) - Delegate a specific task to one of the following
|
||||
co-workers: [''Researcher'', ''Senior Writer'']\nThe input to this tool should
|
||||
coworkers: [''Researcher'', ''Senior Writer'']\nThe input to this tool should
|
||||
be the coworker, the task you want them to do, and ALL necessary context to
|
||||
execute the task, they know nothing about the task, so share absolute everything
|
||||
you know, don''t reference things but instead explain them.\nAsk question to
|
||||
co-worker: Ask question to co-worker(coworker: str, question: str, context:
|
||||
str) - Ask a specific question to one of the following co-workers: [''Researcher'',
|
||||
coworker: Ask question to coworker(coworker: str, question: str, context:
|
||||
str) - Ask a specific question to one of the following coworkers: [''Researcher'',
|
||||
''Senior Writer'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -2474,7 +2474,7 @@ interactions:
|
||||
a paragraph for each idea that showcases how good an article about this topic
|
||||
could be. I will delegate the task of coming up with the ideas to the Researcher
|
||||
and the task of writing the paragraphs to the Senior Writer.\n\nAction: \nDelegate
|
||||
work to co-worker\n\nAction Input: \n{\n \"coworker\": \"Researcher\",\n \"task\":
|
||||
work to coworker\n\nAction Input: \n{\n \"coworker\": \"Researcher\",\n \"task\":
|
||||
\"Come up with 5 interesting ideas for an article\",\n \"context\": \"We need
|
||||
to create a list of 5 interesting ideas for an article. These ideas should be
|
||||
unique, engaging, and have the potential to be developed into a full-length
|
||||
@@ -5363,20 +5363,20 @@ interactions:
|
||||
allows you to properly evaluate the work of your team members.\nYour personal
|
||||
goal is: Manage the team to complete the task in the best way possible.\n\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nDelegate work to co-worker: Delegate work to co-worker(coworker:
|
||||
are not listed here:\n\nDelegate work to coworker: Delegate work to coworker(coworker:
|
||||
str, task: str, context: str) - Delegate a specific task to one of the following
|
||||
co-workers: [''Researcher'', ''Senior Writer'']\nThe input to this tool should
|
||||
coworkers: [''Researcher'', ''Senior Writer'']\nThe input to this tool should
|
||||
be the coworker, the task you want them to do, and ALL necessary context to
|
||||
execute the task, they know nothing about the task, so share absolute everything
|
||||
you know, don''t reference things but instead explain them.\nAsk question to
|
||||
co-worker: Ask question to co-worker(coworker: str, question: str, context:
|
||||
str) - Ask a specific question to one of the following co-workers: [''Researcher'',
|
||||
coworker: Ask question to coworker(coworker: str, question: str, context:
|
||||
str) - Ask a specific question to one of the following coworkers: [''Researcher'',
|
||||
''Senior Writer'']\nThe input to this tool should be the coworker, the question
|
||||
you have for them, and ALL necessary context to ask the question properly, they
|
||||
know nothing about the question, so share absolute everything you know, don''t
|
||||
reference things but instead explain them.\n\nUse the following format:\n\nThought:
|
||||
you should always think about what to do\nAction: the action to take, only one
|
||||
name of [Delegate work to co-worker, Ask question to co-worker], just the name,
|
||||
name of [Delegate work to coworker, Ask question to coworker], just the name,
|
||||
exactly as it''s written.\nAction Input: the input to the action, just a simple
|
||||
a python dictionary using \" to wrap keys and values.\nObservation: the result
|
||||
of the action\n\nOnce all necessary information is gathered:\n\nThought: I now
|
||||
@@ -5393,7 +5393,7 @@ interactions:
|
||||
a paragraph for each idea that showcases how good an article about this topic
|
||||
could be. I will delegate the task of coming up with the ideas to the Researcher
|
||||
and the task of writing the paragraphs to the Senior Writer.\n\nAction: \nDelegate
|
||||
work to co-worker\n\nAction Input: \n{\n \"coworker\": \"Researcher\",\n \"task\":
|
||||
work to coworker\n\nAction Input: \n{\n \"coworker\": \"Researcher\",\n \"task\":
|
||||
\"Come up with 5 interesting ideas for an article\",\n \"context\": \"We need
|
||||
to create a list of 5 interesting ideas for an article. These ideas should be
|
||||
unique, engaging, and have the potential to be developed into a full-length
|
||||
@@ -5406,7 +5406,7 @@ interactions:
|
||||
for the article. Now, I need to delegate the task of writing a paragraph for
|
||||
each idea to the Senior Writer. I will provide the Senior Writer with the ideas
|
||||
and ask them to write a paragraph that showcases how good an article about each
|
||||
topic could be.\n\nAction: \nDelegate work to co-worker\n\nAction Input: \n{\n \"coworker\":
|
||||
topic could be.\n\nAction: \nDelegate work to coworker\n\nAction Input: \n{\n \"coworker\":
|
||||
\"Senior Writer\",\n \"task\": \"Write one amazing paragraph highlight for
|
||||
each idea\",\n \"context\": \"We have 5 interesting ideas for an article. They
|
||||
are: 1. ''Demystifying AI: An in-depth exploration of Artificial Intelligence
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -57,20 +57,20 @@ interactions:
|
||||
allows you to properly evaluate the work of your team members.\nYour personal
|
||||
goal is: Manage the team to complete the task in the best way possible.\n\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nDelegate work to co-worker: Delegate work to co-worker(coworker:
|
||||
are not listed here:\n\nDelegate work to coworker: Delegate work to coworker(coworker:
|
||||
str, task: str, context: str) - Delegate a specific task to one of the following
|
||||
co-workers: [''Scorer'']\nThe input to this tool should be the coworker, the
|
||||
coworkers: [''Scorer'']\nThe input to this tool should be the coworker, the
|
||||
task you want them to do, and ALL necessary context to execute the task, they
|
||||
know nothing about the task, so share absolute everything you know, don''t reference
|
||||
things but instead explain them.\nAsk question to co-worker: Ask question to
|
||||
co-worker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following co-workers: [''Scorer'']\nThe input to this tool should
|
||||
things but instead explain them.\nAsk question to coworker: Ask question to
|
||||
coworker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following coworkers: [''Scorer'']\nThe input to this tool should
|
||||
be the coworker, the question you have for them, and ALL necessary context to
|
||||
ask the question properly, they know nothing about the question, so share absolute
|
||||
everything you know, don''t reference things but instead explain them.\n\nUse
|
||||
the following format:\n\nThought: you should always think about what to do\nAction:
|
||||
the action to take, only one name of [Delegate work to co-worker, Ask question
|
||||
to co-worker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
the action to take, only one name of [Delegate work to coworker, Ask question
|
||||
to coworker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
to the action, just a simple a python dictionary using \" to wrap keys and values.\nObservation:
|
||||
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
|
||||
I now know the final answer\nFinal Answer: the final answer to the original
|
||||
@@ -3197,20 +3197,20 @@ interactions:
|
||||
allows you to properly evaluate the work of your team members.\nYour personal
|
||||
goal is: Manage the team to complete the task in the best way possible.\n\nYou
|
||||
ONLY have access to the following tools, and should NEVER make up tools that
|
||||
are not listed here:\n\nDelegate work to co-worker: Delegate work to co-worker(coworker:
|
||||
are not listed here:\n\nDelegate work to coworker: Delegate work to coworker(coworker:
|
||||
str, task: str, context: str) - Delegate a specific task to one of the following
|
||||
co-workers: [''Scorer'']\nThe input to this tool should be the coworker, the
|
||||
coworkers: [''Scorer'']\nThe input to this tool should be the coworker, the
|
||||
task you want them to do, and ALL necessary context to execute the task, they
|
||||
know nothing about the task, so share absolute everything you know, don''t reference
|
||||
things but instead explain them.\nAsk question to co-worker: Ask question to
|
||||
co-worker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following co-workers: [''Scorer'']\nThe input to this tool should
|
||||
things but instead explain them.\nAsk question to coworker: Ask question to
|
||||
coworker(coworker: str, question: str, context: str) - Ask a specific question
|
||||
to one of the following coworkers: [''Scorer'']\nThe input to this tool should
|
||||
be the coworker, the question you have for them, and ALL necessary context to
|
||||
ask the question properly, they know nothing about the question, so share absolute
|
||||
everything you know, don''t reference things but instead explain them.\n\nUse
|
||||
the following format:\n\nThought: you should always think about what to do\nAction:
|
||||
the action to take, only one name of [Delegate work to co-worker, Ask question
|
||||
to co-worker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
the action to take, only one name of [Delegate work to coworker, Ask question
|
||||
to coworker], just the name, exactly as it''s written.\nAction Input: the input
|
||||
to the action, just a simple a python dictionary using \" to wrap keys and values.\nObservation:
|
||||
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
|
||||
I now know the final answer\nFinal Answer: the final answer to the original
|
||||
@@ -3225,8 +3225,8 @@ interactions:
|
||||
it. Since scoring can be subjective, it''s essential to establish clear criteria
|
||||
based on relevance, insightfulness, current interest in the topic, and perhaps
|
||||
its specificity or ability to provoke thought. As I don''t have direct guidelines,
|
||||
I will need to consult with my co-worker, Scorer, who might have a set of criteria
|
||||
or insights on how to approach this task.\n\nAction: Ask question to co-worker\nAction
|
||||
I will need to consult with my coworker, Scorer, who might have a set of criteria
|
||||
or insights on how to approach this task.\n\nAction: Ask question to coworker\nAction
|
||||
Input: {\"coworker\": \"Scorer\", \"question\": \"What criteria should we use
|
||||
to evaluate and score the title ''The impact of AI in the future of work''?\",
|
||||
\"context\": \"We need to assign a score between 1-5 for the title ''The impact
|
||||
|
||||
@@ -1,111 +1,114 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
CqcuCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkS/i0KEgoQY3Jld2FpLnRl
|
||||
bGVtZXRyeRKNAQoQWsK2m2g3VyJHWaXnQym/VhIII86T/ZrUN8EqClRvb2wgVXNhZ2UwATnYaVBJ
|
||||
jjbPF0FYJVFJjjbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKHwoJdG9vbF9uYW1lEhIK
|
||||
EGdldF9maW5hbF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgBegIYARKNAQoQ6Z32Q3lxb6RU5NbYTjLU
|
||||
SxIIqcY2PQT6l3gqClRvb2wgVXNhZ2UwATnAus9KjjbPF0EYU9BKjjbPF0oaCg5jcmV3YWlfdmVy
|
||||
c2lvbhIICgYwLjMwLjZKHwoJdG9vbF9uYW1lEhIKEGdldF9maW5hbF9hbnN3ZXJKDgoIYXR0ZW1w
|
||||
dHMSAhgBegIYARKNAQoQwek7gO4ckm9Jvn6BwHW9QxII3T6AbeLq7EIqClRvb2wgVXNhZ2UwATlY
|
||||
cF9PjjbPF0GoM2BPjjbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKHwoJdG9vbF9uYW1l
|
||||
EhIKEGdldF9maW5hbF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgBegIYARLKAQoQxj4ww0iUXwfHLphC
|
||||
57m2khIIjJFrK75dr+gqEFRvb2wgVXNhZ2UgRXJyb3IwATlQt3hRjjbPF0GIfnlRjjbPF0oaCg5j
|
||||
cmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKZgoDbGxtEl8KXXsibmFtZSI6IG51bGwsICJtb2RlbF9u
|
||||
YW1lIjogImdwdC00LTAxMjUtcHJldmlldyIsICJ0ZW1wZXJhdHVyZSI6IDAuNywgImNsYXNzIjog
|
||||
IkNoYXRPcGVuQUkifXoCGAESygEKEArpOi/Us2A3PpB8Gii7j88SCPzLVYFtDQSsKhBUb29sIFVz
|
||||
YWdlIEVycm9yMAE56MF6Uo42zxdBaH17Uo42zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMC42
|
||||
SmYKA2xsbRJfCl17Im5hbWUiOiBudWxsLCAibW9kZWxfbmFtZSI6ICJncHQtNC0wMTI1LXByZXZp
|
||||
ZXciLCAidGVtcGVyYXR1cmUiOiAwLjcsICJjbGFzcyI6ICJDaGF0T3BlbkFJIn16AhgBEsoBChBt
|
||||
yk7Qq7Sgw6WMHkcEj6WfEgijl4wq3/wt7SoQVG9vbCBVc2FnZSBFcnJvcjABOeAyk1OONs8XQdja
|
||||
k1OONs8XShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzAuNkpmCgNsbG0SXwpdeyJuYW1lIjogbnVs
|
||||
bCwgIm1vZGVsX25hbWUiOiAiZ3B0LTQtMDEyNS1wcmV2aWV3IiwgInRlbXBlcmF0dXJlIjogMC43
|
||||
LCAiY2xhc3MiOiAiQ2hhdE9wZW5BSSJ9egIYARJiChAmBkQ6MDSlxvmv4YVRGzmdEgj1PJQNKV6C
|
||||
sCoQVG9vbCBVc2FnZSBFcnJvcjABOfgzEleONs8XQQjYEleONs8XShoKDmNyZXdhaV92ZXJzaW9u
|
||||
EggKBjAuMzAuNnoCGAESjQEKEAwZ3MFe3tvKT/3fZgpV4ywSCEicyz0QPrdVKgpUb29sIFVzYWdl
|
||||
MAE5CPdvWI42zxdBWLpwWI42zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMC42Sh8KCXRvb2xf
|
||||
bmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4KCGF0dGVtcHRzEgIYAXoCGAESjQEKEGIhNyFGf0X0
|
||||
iubEVUn96JASCCPQkQmTahyuKgpUb29sIFVzYWdlMAE5gFEoWo42zxdBgEspWo42zxdKGgoOY3Jl
|
||||
d2FpX3ZlcnNpb24SCAoGMC4zMC42Sh8KCXRvb2xfbmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4K
|
||||
CGF0dGVtcHRzEgIYAXoCGAESjQEKECluqAOjM96Xcuo2pY/AxrUSCE2CDrSmkuFVKgpUb29sIFVz
|
||||
YWdlMAE5YJvZW442zxdBoLTaW442zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMC42Sh8KCXRv
|
||||
b2xfbmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4KCGF0dGVtcHRzEgIYAXoCGAESYgoQ3rypXzEG
|
||||
OaBuogXtWu23OxIIJU2tAn4rSesqEFRvb2wgVXNhZ2UgRXJyb3IwATmAst9fjjbPF0GgfeBfjjbP
|
||||
F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZ6AhgBEpcBChCoJakn4gJ/bsmLqhOQ+pzJEggZ
|
||||
FE39y55kSSoKVG9vbCBVc2FnZTABOdAenmKONs8XQdAYn2KONs8XShoKDmNyZXdhaV92ZXJzaW9u
|
||||
EggKBjAuMzAuNkopCgl0b29sX25hbWUSHAoaRGVsZWdhdGUgd29yayB0byBjby13b3JrZXJKDgoI
|
||||
YXR0ZW1wdHMSAhgBegIYARKWAQoQbG8DmDglapO/4qWaAMeMhhII+ZHmV8V3pYsqClRvb2wgVXNh
|
||||
Z2UwATlwxGFojjbPF0Goi2JojjbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKKAoJdG9v
|
||||
bF9uYW1lEhsKGUFzayBxdWVzdGlvbiB0byBjby13b3JrZXJKDgoIYXR0ZW1wdHMSAhgBegIYARKL
|
||||
AQoQA3elhWektmDyQtq61PMfARIInyy2MM6Y3gwqClRvb2wgVXNhZ2UwATnoK/drjjbPF0EI9/dr
|
||||
jjbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fi
|
||||
b3V0X0FJSg4KCGF0dGVtcHRzEgIYAXoCGAESiwEKEGOUc3nLZT3TTF1UqTEf3aYSCAIG5j6E1JLk
|
||||
KgpUb29sIFVzYWdlMAE5wIxYbY42zxdBuDRZbY42zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4z
|
||||
MC42Sh0KCXRvb2xfbmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBEmIK
|
||||
ELpJQh4iRyb0LtlYOjZkn+8SCCPJgujx+G0+KhBUb29sIFVzYWdlIEVycm9yMAE5ULmabo42zxdB
|
||||
wE2bbo42zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMC42egIYARLzAQoQFQ74Wok+KKV4rR5E
|
||||
kSYVMRIIJRc3G0tgxY4qClRvb2wgVXNhZ2UwATlYx7FzjjbPF0EYorJzjjbPF0oaCg5jcmV3YWlf
|
||||
dmVyc2lvbhIICgYwLjMwLjZKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0dGVt
|
||||
cHRzEgIYAUpmCgNsbG0SXwpdeyJuYW1lIjogbnVsbCwgIm1vZGVsX25hbWUiOiAiZ3B0LTMuNS10
|
||||
dXJiby0wMTI1IiwgInRlbXBlcmF0dXJlIjogMC43LCAiY2xhc3MiOiAiQ2hhdE9wZW5BSSJ9egIY
|
||||
ARLzAQoQnJMORTVCM7CSablsUBxMJxIIQCKuv5AXvFEqClRvb2wgVXNhZ2UwATl4LDp1jjbPF0EQ
|
||||
5Dp1jjbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKHQoJdG9vbF9uYW1lEhAKDmxlYXJu
|
||||
X2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAUpmCgNsbG0SXwpdeyJuYW1lIjogbnVsbCwgIm1vZGVs
|
||||
X25hbWUiOiAiZ3B0LTMuNS10dXJiby0wMTI1IiwgInRlbXBlcmF0dXJlIjogMC43LCAiY2xhc3Mi
|
||||
OiAiQ2hhdE9wZW5BSSJ9egIYARLzAQoQAfw9BLcOs9bjmKBOkNP2pRII8jFQggGaAhsqClRvb2wg
|
||||
VXNhZ2UwATlAbQJ3jjbPF0HwIAN3jjbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKHQoJ
|
||||
dG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAUpmCgNsbG0SXwpdeyJu
|
||||
YW1lIjogbnVsbCwgIm1vZGVsX25hbWUiOiAiZ3B0LTMuNS10dXJiby0wMTI1IiwgInRlbXBlcmF0
|
||||
dXJlIjogMC43LCAiY2xhc3MiOiAiQ2hhdE9wZW5BSSJ9egIYARKXAQoQuzP2zqalo852qSEZJPoW
|
||||
/RIInedZySqvqygqClRvb2wgVXNhZ2UwATkYAGWujjbPF0Go4mWujjbPF0oaCg5jcmV3YWlfdmVy
|
||||
c2lvbhIICgYwLjMwLjZKKQoJdG9vbF9uYW1lEhwKGkRlbGVnYXRlIHdvcmsgdG8gY28td29ya2Vy
|
||||
Sg4KCGF0dGVtcHRzEgIYAXoCGAESlwEKEATlyOCYjHSp1K3QoCeqMmUSCP/SCa7gOMy+KgpUb29s
|
||||
IFVzYWdlMAE5QKeKuY42zxdBqGaLuY42zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMC42SikK
|
||||
CXRvb2xfbmFtZRIcChpEZWxlZ2F0ZSB3b3JrIHRvIGNvLXdvcmtlckoOCghhdHRlbXB0cxICGAF6
|
||||
AhgBEpcBChDCNHUdgM9SPykW9jZLAszpEgjxF3ox7N4UJyoKVG9vbCBVc2FnZTABOeDPiMqONs8X
|
||||
QdCiicqONs8XShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzAuNkopCgl0b29sX25hbWUSHAoaRGVs
|
||||
ZWdhdGUgd29yayB0byBjby13b3JrZXJKDgoIYXR0ZW1wdHMSAhgBegIYARKHAQoQ79rs2SVt97mT
|
||||
uX/cWDscnBII6rrlGA8RtbMqClRvb2wgVXNhZ2UwATkYFcz6jjbPF0FQ3Mz6jjbPF0oaCg5jcmV3
|
||||
YWlfdmVyc2lvbhIICgYwLjMwLjZKGQoJdG9vbF9uYW1lEgwKCm11bHRpcGxpZXJKDgoIYXR0ZW1w
|
||||
dHMSAhgBegIYARKHAQoQVP9tyrp7Wv9IolbUgao9uBII8inECsdSecYqClRvb2wgVXNhZ2UwATl4
|
||||
JZH8jjbPF0GIyZH8jjbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKGQoJdG9vbF9uYW1l
|
||||
EgwKCm11bHRpcGxpZXJKDgoIYXR0ZW1wdHMSAhgBegIYARJiChCQ/ikD6wODQRRK4sOy00xbEgh3
|
||||
W3X41OAJQSoQVG9vbCBVc2FnZSBFcnJvcjABOXi4pf+ONs8XQeB3pv+ONs8XShoKDmNyZXdhaV92
|
||||
ZXJzaW9uEggKBjAuMzAuNnoCGAESYgoQ53JWAKq1hJb9rscUFhC6GhIIPzTRaeMJnJYqEFRvb2wg
|
||||
VXNhZ2UgRXJyb3IwATkIPJsAjzbPF0GQzJsAjzbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMw
|
||||
LjZ6AhgBEvMBChC/rx/MIKAdxGOMAfLmXNJoEghCqOptNDfKXSoKVG9vbCBVc2FnZTABOaAAQwuP
|
||||
Ns8XQejuQwuPNs8XShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzAuNkodCgl0b29sX25hbWUSEAoO
|
||||
bGVhcm5fYWJvdXRfQUlKDgoIYXR0ZW1wdHMSAhgBSmYKA2xsbRJfCl17Im5hbWUiOiBudWxsLCAi
|
||||
bW9kZWxfbmFtZSI6ICJncHQtMy41LXR1cmJvLTAxMjUiLCAidGVtcGVyYXR1cmUiOiAwLjcsICJj
|
||||
bGFzcyI6ICJDaGF0T3BlbkFJIn16AhgBEsoBChAJc/cdYOh6bOxXLE4BSMa0Egg1m5FL4NyjeCoQ
|
||||
VG9vbCBVc2FnZSBFcnJvcjABOXiAigyPNs8XQZhLiwyPNs8XShoKDmNyZXdhaV92ZXJzaW9uEggK
|
||||
BjAuMzAuNkpmCgNsbG0SXwpdeyJuYW1lIjogbnVsbCwgIm1vZGVsX25hbWUiOiAiZ3B0LTMuNS10
|
||||
dXJiby0wMTI1IiwgInRlbXBlcmF0dXJlIjogMC43LCAiY2xhc3MiOiAiQ2hhdE9wZW5BSSJ9egIY
|
||||
ARLzAQoQIwsE8AeUGx2Zlpsj/8cIpxIIGiYkqh1O8V8qClRvb2wgVXNhZ2UwATmIou0NjzbPF0EI
|
||||
Xu4NjzbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKHQoJdG9vbF9uYW1lEhAKDmxlYXJu
|
||||
X2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAUpmCgNsbG0SXwpdeyJuYW1lIjogbnVsbCwgIm1vZGVs
|
||||
X25hbWUiOiAiZ3B0LTMuNS10dXJiby0wMTI1IiwgInRlbXBlcmF0dXJlIjogMC43LCAiY2xhc3Mi
|
||||
OiAiQ2hhdE9wZW5BSSJ9egIYARLzAQoQzE4sWSyDKyW+MsjMu3qaURII0Ek+EFuG+pQqClRvb2wg
|
||||
VXNhZ2UwATl4knUPjzbPF0FYPnYPjzbPF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKHQoJ
|
||||
dG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0dGVtcHRzEgIYAUpmCgNsbG0SXwpdeyJu
|
||||
YW1lIjogbnVsbCwgIm1vZGVsX25hbWUiOiAiZ3B0LTMuNS10dXJiby0wMTI1IiwgInRlbXBlcmF0
|
||||
dXJlIjogMC43LCAiY2xhc3MiOiAiQ2hhdE9wZW5BSSJ9egIYARKIAQoQV5Ebj7z0WSmnDL6cuEwc
|
||||
aRIIjQwTYaUnU+0qClRvb2wgVXNhZ2UwATmoPboXjzbPF0Eo+boXjzbPF0oaCg5jcmV3YWlfdmVy
|
||||
c2lvbhIICgYwLjMwLjZKGgoJdG9vbF9uYW1lEg0KC3JldHVybl9kYXRhSg4KCGF0dGVtcHRzEgIY
|
||||
AXoCGAESlwEKEC6MfuEYt3qySHDPP/fGhDoSCME60nPc2PP5KgpUb29sIFVzYWdlMAE5kBWpIo82
|
||||
zxdBmOSpIo82zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMC42SikKCXRvb2xfbmFtZRIcChpE
|
||||
ZWxlZ2F0ZSB3b3JrIHRvIGNvLXdvcmtlckoOCghhdHRlbXB0cxICGAF6AhgBEo8BChAW4yhha9hM
|
||||
Bq622l4ljFgrEgiqbqTTWlbblCoKVG9vbCBVc2FnZTABOcgCViiPNs8XQVjlViiPNs8XShoKDmNy
|
||||
ZXdhaV92ZXJzaW9uEggKBjAuMzAuNkohCgl0b29sX25hbWUSFAoSbXVsdGlwbGNhdGlvbl90b29s
|
||||
Sg4KCGF0dGVtcHRzEgIYAXoCGAESjwEKEDMq2VDCq4/7QaQhcHACuUQSCN8bD12jrjruKgpUb29s
|
||||
IFVzYWdlMAE5OAsOKo82zxdBSK8OKo82zxdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMC42SiEK
|
||||
CXRvb2xfbmFtZRIUChJtdWx0aXBsY2F0aW9uX3Rvb2xKDgoIYXR0ZW1wdHMSAhgBegIYARKPAQoQ
|
||||
7Q6do5ZLFG1iUnTRbk8ZOBIISweZORdlmm8qClRvb2wgVXNhZ2UwATngLc4rjzbPF0HY1c4rjzbP
|
||||
F0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMwLjZKIQoJdG9vbF9uYW1lEhQKEm11bHRpcGxjYXRp
|
||||
b25fdG9vbEoOCghhdHRlbXB0cxICGAF6AhgBEo8BChDAqYWXAeTztQaza44KbHvPEgjLnc1ioqFZ
|
||||
2yoKVG9vbCBVc2FnZTABOWAPky2PNs8XQaCrky2PNs8XShoKDmNyZXdhaV92ZXJzaW9uEggKBjAu
|
||||
MzAuNkohCgl0b29sX25hbWUSFAoSbXVsdGlwbGNhdGlvbl90b29sSg4KCGF0dGVtcHRzEgIYAXoC
|
||||
GAE=
|
||||
CvkvCiQKIgoMc2VydmljZS5uYW1lEhIKEGNyZXdBSS10ZWxlbWV0cnkS0C8KEgoQY3Jld2FpLnRl
|
||||
bGVtZXRyeRKTAQoQLqw+EjxvbTuuw2uK+Z1VwBIIQ7i0ygfU4ncqClRvb2wgVXNhZ2UwATmI4vtU
|
||||
X+vcF0HYpfxUX+vcF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMyLjJKHwoJdG9vbF9uYW1lEhIK
|
||||
EGdldF9maW5hbF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABKTAQoQ5gXS9qaPUXIZ
|
||||
HrfMjoNLTBIIbYzD2CnTapMqClRvb2wgVXNhZ2UwATnQkFRWX+vcF0EoKVVWX+vcF0oaCg5jcmV3
|
||||
YWlfdmVyc2lvbhIICgYwLjMyLjJKHwoJdG9vbF9uYW1lEhIKEGdldF9maW5hbF9hbnN3ZXJKDgoI
|
||||
YXR0ZW1wdHMSAhgBegIYAYUBAAEAABKTAQoQ2qhuTH7MsHdQcTba5VsvnhIITr+y+m0u0l8qClRv
|
||||
b2wgVXNhZ2UwATkgFJtaX+vcF0EQ55taX+vcF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMyLjJK
|
||||
HwoJdG9vbF9uYW1lEhIKEGdldF9maW5hbF9hbnN3ZXJKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEA
|
||||
ABLQAQoQqRrtPlT4tPSoyC0r7b4LKxIIQeUfZL/g8XcqEFRvb2wgVXNhZ2UgRXJyb3IwATloU8Fc
|
||||
X+vcF0G4FsJcX+vcF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMyLjJKZgoDbGxtEl8KXXsibmFt
|
||||
ZSI6IG51bGwsICJtb2RlbF9uYW1lIjogImdwdC00LTAxMjUtcHJldmlldyIsICJ0ZW1wZXJhdHVy
|
||||
ZSI6IDAuNywgImNsYXNzIjogIkNoYXRPcGVuQUkifXoCGAGFAQABAAAS0AEKEKBXCmTXjZRJFp2i
|
||||
rTVc0HASCHda+ZbetuNrKhBUb29sIFVzYWdlIEVycm9yMAE5CNWoXV/r3BdBuIipXV/r3BdKGgoO
|
||||
Y3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySmYKA2xsbRJfCl17Im5hbWUiOiBudWxsLCAibW9kZWxf
|
||||
bmFtZSI6ICJncHQtNC0wMTI1LXByZXZpZXciLCAidGVtcGVyYXR1cmUiOiAwLjcsICJjbGFzcyI6
|
||||
ICJDaGF0T3BlbkFJIn16AhgBhQEAAQAAEtABChDRyJwJBHmQbpjeqiqVKVXtEggwlO2x4+8/7SoQ
|
||||
VG9vbCBVc2FnZSBFcnJvcjABOZDWpV5f69wXQXCCpl5f69wXShoKDmNyZXdhaV92ZXJzaW9uEggK
|
||||
BjAuMzIuMkpmCgNsbG0SXwpdeyJuYW1lIjogbnVsbCwgIm1vZGVsX25hbWUiOiAiZ3B0LTQtMDEy
|
||||
NS1wcmV2aWV3IiwgInRlbXBlcmF0dXJlIjogMC43LCAiY2xhc3MiOiAiQ2hhdE9wZW5BSSJ9egIY
|
||||
AYUBAAEAABJoChBYSTS4T56qn9uV/7fuGXJeEghoO+P9EPF9mioQVG9vbCBVc2FnZSBFcnJvcjAB
|
||||
OeC54mFf69wXQVBO42Ff69wXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzIuMnoCGAGFAQABAAAS
|
||||
kwEKEBSvIa1MLNQ87IQBMQO+bJwSCHBHin2QwJ06KgpUb29sIFVzYWdlMAE5SIgZY1/r3BdBuBwa
|
||||
Y1/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySh8KCXRvb2xfbmFtZRISChBnZXRfZmlu
|
||||
YWxfYW5zd2VySg4KCGF0dGVtcHRzEgIYAXoCGAGFAQABAAASkwEKELCH9rRBT8NoumB9Poc1RV8S
|
||||
CAuveHZDPucwKgpUb29sIFVzYWdlMAE5WNIcZV/r3BdBALEdZV/r3BdKGgoOY3Jld2FpX3ZlcnNp
|
||||
b24SCAoGMC4zMi4ySh8KCXRvb2xfbmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4KCGF0dGVtcHRz
|
||||
EgIYAXoCGAGFAQABAAASkwEKEH+Cq1vI2oyP7OvOUhPFEmISCEI78UcGQbDYKgpUb29sIFVzYWdl
|
||||
MAE58H9sZl/r3BdBYBRtZl/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySh8KCXRvb2xf
|
||||
bmFtZRISChBnZXRfZmluYWxfYW5zd2VySg4KCGF0dGVtcHRzEgIYAXoCGAGFAQABAAASaAoQSypk
|
||||
rhDcn8HjHzB1fE06IxII14WesmPDQIIqEFRvb2wgVXNhZ2UgRXJyb3IwATnIf+ZpX+vcF0EgGOdp
|
||||
X+vcF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMyLjJ6AhgBhQEAAQAAEpwBChBcqrWqs8O3kz0u
|
||||
WtxW6Q2PEghUJQXvLBsS3ioKVG9vbCBVc2FnZTABOdDdVWxf69wXQeCBVmxf69wXShoKDmNyZXdh
|
||||
aV92ZXJzaW9uEggKBjAuMzIuMkooCgl0b29sX25hbWUSGwoZRGVsZWdhdGUgd29yayB0byBjb3dv
|
||||
cmtlckoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpsBChAP+DwhzLsJsu/moyVCYJZLEgikfOou
|
||||
Ui5xEyoKVG9vbCBVc2FnZTABOUB0i3Ff69wXQcAvjHFf69wXShoKDmNyZXdhaV92ZXJzaW9uEggK
|
||||
BjAuMzIuMkonCgl0b29sX25hbWUSGgoYQXNrIHF1ZXN0aW9uIHRvIGNvd29ya2VySg4KCGF0dGVt
|
||||
cHRzEgIYAXoCGAGFAQABAAASkQEKEPb3Mf1VqY8Vf6+29dlFhWgSCM1ReYxiVApJKgpUb29sIFVz
|
||||
YWdlMAE5sPqldF/r3BdBeKqmdF/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySh0KCXRv
|
||||
b2xfbmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAF6AhgBhQEAAQAAEpEBChCq
|
||||
FQcV1PqHVRas5I37hdYPEgjBm90KS4QjuioKVG9vbCBVc2FnZTABOfjr3nVf69wXQWiA33Vf69wX
|
||||
ShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzIuMkodCgl0b29sX25hbWUSEAoObGVhcm5fYWJvdXRf
|
||||
QUlKDgoIYXR0ZW1wdHMSAhgBegIYAYUBAAEAABJoChCAUmAdKEw8ldIXchj4l5FTEggACxwRIm8M
|
||||
TioQVG9vbCBVc2FnZSBFcnJvcjABOcgJ/3Zf69wXQZiO/3Zf69wXShoKDmNyZXdhaV92ZXJzaW9u
|
||||
EggKBjAuMzIuMnoCGAGFAQABAAAS+QEKELqY0vdf9nhQ5xC3jQVvMZ0SCDx91QCyVM3EKgpUb29s
|
||||
IFVzYWdlMAE5aALQe1/r3BdBQNnQe1/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySh0K
|
||||
CXRvb2xfbmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAFKZgoDbGxtEl8KXXsi
|
||||
bmFtZSI6IG51bGwsICJtb2RlbF9uYW1lIjogImdwdC0zLjUtdHVyYm8tMDEyNSIsICJ0ZW1wZXJh
|
||||
dHVyZSI6IDAuNywgImNsYXNzIjogIkNoYXRPcGVuQUkifXoCGAGFAQABAAAS+QEKEOvcp2bL70Uh
|
||||
ppRRgSDfGocSCAbAS5eR0Zf0KgpUb29sIFVzYWdlMAE5GLEzfV/r3BdBsGg0fV/r3BdKGgoOY3Jl
|
||||
d2FpX3ZlcnNpb24SCAoGMC4zMi4ySh0KCXRvb2xfbmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghh
|
||||
dHRlbXB0cxICGAFKZgoDbGxtEl8KXXsibmFtZSI6IG51bGwsICJtb2RlbF9uYW1lIjogImdwdC0z
|
||||
LjUtdHVyYm8tMDEyNSIsICJ0ZW1wZXJhdHVyZSI6IDAuNywgImNsYXNzIjogIkNoYXRPcGVuQUki
|
||||
fXoCGAGFAQABAAAS+QEKEJJrId+mXE5JtfjeU884CCASCOokJijVUg9ZKgpUb29sIFVzYWdlMAE5
|
||||
OIzSfl/r3BdB6D/Tfl/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySh0KCXRvb2xfbmFt
|
||||
ZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAFKZgoDbGxtEl8KXXsibmFtZSI6IG51
|
||||
bGwsICJtb2RlbF9uYW1lIjogImdwdC0zLjUtdHVyYm8tMDEyNSIsICJ0ZW1wZXJhdHVyZSI6IDAu
|
||||
NywgImNsYXNzIjogIkNoYXRPcGVuQUkifXoCGAGFAQABAAASnAEKEGbTvSmCEq1hfmW2vRFmS7oS
|
||||
CADTIi8+Q/0uKgpUb29sIFVzYWdlMAE5EFJ9s1/r3BdBYBV+s1/r3BdKGgoOY3Jld2FpX3ZlcnNp
|
||||
b24SCAoGMC4zMi4ySigKCXRvb2xfbmFtZRIbChlEZWxlZ2F0ZSB3b3JrIHRvIGNvd29ya2VySg4K
|
||||
CGF0dGVtcHRzEgIYAXoCGAGFAQABAAASnAEKEKJQrO/iuhlVNO1rDNHiMRcSCPTkQpOzD6cQKgpU
|
||||
b29sIFVzYWdlMAE54DiFvV/r3BdB8NyFvV/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4y
|
||||
SigKCXRvb2xfbmFtZRIbChlEZWxlZ2F0ZSB3b3JrIHRvIGNvd29ya2VySg4KCGF0dGVtcHRzEgIY
|
||||
AXoCGAGFAQABAAASnAEKEEfqaRZKKFFTpce+qADatWsSCC+o088u72sxKgpUb29sIFVzYWdlMAE5
|
||||
iG7ryV/r3BdBqDnsyV/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySigKCXRvb2xfbmFt
|
||||
ZRIbChlEZWxlZ2F0ZSB3b3JrIHRvIGNvd29ya2VySg4KCGF0dGVtcHRzEgIYAXoCGAGFAQABAAAS
|
||||
jQEKEOop1HWbNPE8YlD5deGfOSMSCKmtMdk4L2TXKgpUb29sIFVzYWdlMAE5MIld9F/r3BdBWCle
|
||||
9F/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4yShkKCXRvb2xfbmFtZRIMCgptdWx0aXBs
|
||||
aWVySg4KCGF0dGVtcHRzEgIYAXoCGAGFAQABAAASjQEKEIeyHGVjE8c+y9tC4zDzNYkSCK1EdMCk
|
||||
DinyKgpUb29sIFVzYWdlMAE5yJLx9V/r3BdBgBvy9V/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoG
|
||||
MC4zMi4yShkKCXRvb2xfbmFtZRIMCgptdWx0aXBsaWVySg4KCGF0dGVtcHRzEgIYAXoCGAGFAQAB
|
||||
AAASaAoQkg972Qk74fczD5e/SDXg1BII02eF0/y/vDwqEFRvb2wgVXNhZ2UgRXJyb3IwATnoC8T4
|
||||
X+vcF0FYoMT4X+vcF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMyLjJ6AhgBhQEAAQAAEmgKEK+/
|
||||
ep8MyIKryHi4B9MJgFoSCPmxA6f5KaeDKhBUb29sIFVzYWdlIEVycm9yMAE56Gaa+V/r3BdBuOua
|
||||
+V/r3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4yegIYAYUBAAEAABL5AQoQHOvurczFRHPh
|
||||
zLdotvB2DxIILtVN6gvO/fIqClRvb2wgVXNhZ2UwATlwXUgEYOvcF0F4LEkEYOvcF0oaCg5jcmV3
|
||||
YWlfdmVyc2lvbhIICgYwLjMyLjJKHQoJdG9vbF9uYW1lEhAKDmxlYXJuX2Fib3V0X0FJSg4KCGF0
|
||||
dGVtcHRzEgIYAUpmCgNsbG0SXwpdeyJuYW1lIjogbnVsbCwgIm1vZGVsX25hbWUiOiAiZ3B0LTMu
|
||||
NS10dXJiby0wMTI1IiwgInRlbXBlcmF0dXJlIjogMC43LCAiY2xhc3MiOiAiQ2hhdE9wZW5BSSJ9
|
||||
egIYAYUBAAEAABLQAQoQ1OGo2qdk9xb9UdNmtGuYoBIIRRfFWBesYaYqEFRvb2wgVXNhZ2UgRXJy
|
||||
b3IwATmIP3AFYOvcF0GY43AFYOvcF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMyLjJKZgoDbGxt
|
||||
El8KXXsibmFtZSI6IG51bGwsICJtb2RlbF9uYW1lIjogImdwdC0zLjUtdHVyYm8tMDEyNSIsICJ0
|
||||
ZW1wZXJhdHVyZSI6IDAuNywgImNsYXNzIjogIkNoYXRPcGVuQUkifXoCGAGFAQABAAAS+QEKEGr8
|
||||
23SE3ifiBzkxMmmqLDwSCKa4vwo9iDeyKgpUb29sIFVzYWdlMAE5KEypBmDr3BdB2P+pBmDr3BdK
|
||||
GgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySh0KCXRvb2xfbmFtZRIQCg5sZWFybl9hYm91dF9B
|
||||
SUoOCghhdHRlbXB0cxICGAFKZgoDbGxtEl8KXXsibmFtZSI6IG51bGwsICJtb2RlbF9uYW1lIjog
|
||||
ImdwdC0zLjUtdHVyYm8tMDEyNSIsICJ0ZW1wZXJhdHVyZSI6IDAuNywgImNsYXNzIjogIkNoYXRP
|
||||
cGVuQUkifXoCGAGFAQABAAAS+QEKEKuHQQTWEfqoLrsTS3MWk4ISCNLBrrxWfjj+KgpUb29sIFVz
|
||||
YWdlMAE52CQGCGDr3BdB0MwGCGDr3BdKGgoOY3Jld2FpX3ZlcnNpb24SCAoGMC4zMi4ySh0KCXRv
|
||||
b2xfbmFtZRIQCg5sZWFybl9hYm91dF9BSUoOCghhdHRlbXB0cxICGAFKZgoDbGxtEl8KXXsibmFt
|
||||
ZSI6IG51bGwsICJtb2RlbF9uYW1lIjogImdwdC0zLjUtdHVyYm8tMDEyNSIsICJ0ZW1wZXJhdHVy
|
||||
ZSI6IDAuNywgImNsYXNzIjogIkNoYXRPcGVuQUkifXoCGAGFAQABAAASjgEKEEl2jlSHosTDCf2T
|
||||
kVMJdVoSCFKYTaQ7uA7tKgpUb29sIFVzYWdlMAE5+LNjD2Dr3BdBgERkD2Dr3BdKGgoOY3Jld2Fp
|
||||
X3ZlcnNpb24SCAoGMC4zMi4yShoKCXRvb2xfbmFtZRINCgtyZXR1cm5fZGF0YUoOCghhdHRlbXB0
|
||||
cxICGAF6AhgBhQEAAQAAEpwBChDFje+vrdxywaCpwxd9V7gUEgj/t8gVyNqfXSoKVG9vbCBVc2Fn
|
||||
ZTABOdhv2Bdg69wXQbgb2Rdg69wXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzIuMkooCgl0b29s
|
||||
X25hbWUSGwoZRGVsZWdhdGUgd29yayB0byBjb3dvcmtlckoOCghhdHRlbXB0cxICGAF6AhgBhQEA
|
||||
AQAAEpUBChAEeGlBlALsLna/xMJS3tAVEgjguQVwVm9whyoKVG9vbCBVc2FnZTABOVgP+yBg69wX
|
||||
QYCv+yBg69wXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzIuMkohCgl0b29sX25hbWUSFAoSbXVs
|
||||
dGlwbGNhdGlvbl90b29sSg4KCGF0dGVtcHRzEgIYAXoCGAGFAQABAAASlQEKEArasdHN2QN534bW
|
||||
INqT3I4SCGw3ZpVwofeNKgpUb29sIFVzYWdlMAE5INaDImDr3BdBqGaEImDr3BdKGgoOY3Jld2Fp
|
||||
X3ZlcnNpb24SCAoGMC4zMi4ySiEKCXRvb2xfbmFtZRIUChJtdWx0aXBsY2F0aW9uX3Rvb2xKDgoI
|
||||
YXR0ZW1wdHMSAhgBegIYAYUBAAEAABKVAQoQLSMocWp+gqCwmkQ2VSYxYBII6+65jDuqdT0qClRv
|
||||
b2wgVXNhZ2UwATkozR4kYOvcF0HIWR8kYOvcF0oaCg5jcmV3YWlfdmVyc2lvbhIICgYwLjMyLjJK
|
||||
IQoJdG9vbF9uYW1lEhQKEm11bHRpcGxjYXRpb25fdG9vbEoOCghhdHRlbXB0cxICGAF6AhgBhQEA
|
||||
AQAAEpUBChCcXc1N49pCK+Se0QpX8SNMEgiHCiPHjpZP9CoKVG9vbCBVc2FnZTABOZitsyVg69wX
|
||||
QZBVtCVg69wXShoKDmNyZXdhaV92ZXJzaW9uEggKBjAuMzIuMkohCgl0b29sX25hbWUSFAoSbXVs
|
||||
dGlwbGNhdGlvbl90b29sSg4KCGF0dGVtcHRzEgIYAXoCGAGFAQABAAA=
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
@@ -114,11 +117,11 @@ interactions:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '5930'
|
||||
- '6140'
|
||||
Content-Type:
|
||||
- application/x-protobuf
|
||||
User-Agent:
|
||||
- OTel-OTLP-Exporter-Python/1.24.0
|
||||
- OTel-OTLP-Exporter-Python/1.25.0
|
||||
method: POST
|
||||
uri: https://telemetry.crewai.com:4319/v1/traces
|
||||
response:
|
||||
@@ -130,23 +133,23 @@ interactions:
|
||||
Content-Type:
|
||||
- application/x-protobuf
|
||||
Date:
|
||||
- Tue, 14 May 2024 01:26:13 GMT
|
||||
- Thu, 27 Jun 2024 17:05:57 GMT
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": "You are Scorer. You''re an expert
|
||||
scorer, specialized in scoring titles.\nYour personal goal is: Score the titleTo
|
||||
give my best complete final answer to the task use the exact following format:\n\nThought:
|
||||
I now can give a great answer\nFinal Answer: my best complete final answer to
|
||||
the task.\nYour final answer must be the great and the most complete as possible,
|
||||
it must be outcome described.\n\nI MUST use these formats, my job depends on
|
||||
it!\nCurrent Task: Give me an integer score between 1-5 for the following title:
|
||||
''The impact of AI in the future of work''\n\nThis is the expect criteria for
|
||||
your final answer: The score of the title. \n you MUST return the actual complete
|
||||
content as the final answer, not a summary.\n\nBegin! This is VERY important
|
||||
to you, use the tools available and give your best Final Answer, your job depends
|
||||
on it!\n\nThought:\n"}], "model": "gpt-4", "n": 1, "stop": ["\nObservation"],
|
||||
body: '{"messages": [{"content": "You are Scorer. You''re an expert scorer, specialized
|
||||
in scoring titles.\nYour personal goal is: Score the titleTo give my best complete
|
||||
final answer to the task use the exact following format:\n\nThought: I now can
|
||||
give a great answer\nFinal Answer: my best complete final answer to the task.\nYour
|
||||
final answer must be the great and the most complete as possible, it must be
|
||||
outcome described.\n\nI MUST use these formats, my job depends on it!\nCurrent
|
||||
Task: Give me an integer score between 1-5 for the following title: ''The impact
|
||||
of AI in the future of work''\n\nThis is the expect criteria for your final
|
||||
answer: The score of the title. \n you MUST return the actual complete content
|
||||
as the final answer, not a summary.\n\nBegin! This is VERY important to you,
|
||||
use the tools available and give your best Final Answer, your job depends on
|
||||
it!\n\nThought:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"],
|
||||
"stream": true, "temperature": 0.7}'
|
||||
headers:
|
||||
accept:
|
||||
@@ -156,13 +159,13 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '996'
|
||||
- '997'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- api.openai.com
|
||||
user-agent:
|
||||
- OpenAI/Python 1.29.0
|
||||
- OpenAI/Python 1.35.5
|
||||
x-stainless-arch:
|
||||
- arm64
|
||||
x-stainless-async:
|
||||
@@ -172,277 +175,73 @@ interactions:
|
||||
x-stainless-os:
|
||||
- MacOS
|
||||
x-stainless-package-version:
|
||||
- 1.29.0
|
||||
- 1.35.5
|
||||
x-stainless-runtime:
|
||||
- CPython
|
||||
x-stainless-runtime-version:
|
||||
- 3.11.7
|
||||
- 3.11.9
|
||||
method: POST
|
||||
uri: https://api.openai.com/v1/chat/completions
|
||||
response:
|
||||
body:
|
||||
string: 'data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
|
||||
string: 'data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"After"},"logprobs":null,"finish_reason":null}]}
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
considering"},"logprobs":null,"finish_reason":null}]}
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
the"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
relevance"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
depth"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
and"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
potential"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
interest"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
in"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
the"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
topic"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
as"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
well"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
as"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
the"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
clarity"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
and"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
simplicity"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
of"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
the"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
title"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
''"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
impact"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
of"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
AI"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
in"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
the"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
future"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
of"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
work"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"''.\n\n"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
Answer"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
Based"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
on"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
my"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
evaluation"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
I"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
now"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
can"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
give"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
the"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
title"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
''"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
impact"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
of"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
AI"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
in"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
the"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
future"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
of"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
work"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"''"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
a"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
score"},"logprobs":null,"finish_reason":null}]}
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
great"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
of"},"logprobs":null,"finish_reason":null}]}
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
answer"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
Answer"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"
|
||||
"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}]}
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
out"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
of"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
|
||||
"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"5"},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
|
||||
data: {"id":"chatcmpl-9ObDhPtGi5k6ALX2jaFMR0vwXhSx0","object":"chat.completion.chunk","created":1715649973,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
|
||||
data: {"id":"chatcmpl-9emrFVxBDMfetsihHnas2Fd4viiHB","object":"chat.completion.chunk","created":1719507957,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_4008e3b719","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
|
||||
|
||||
|
||||
data: [DONE]
|
||||
@@ -453,20 +252,20 @@ interactions:
|
||||
CF-Cache-Status:
|
||||
- DYNAMIC
|
||||
CF-RAY:
|
||||
- 8837194f3860a686-MIA
|
||||
- 89a7065b6911228b-SJC
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Type:
|
||||
- text/event-stream; charset=utf-8
|
||||
Date:
|
||||
- Tue, 14 May 2024 01:26:14 GMT
|
||||
- Thu, 27 Jun 2024 17:05:57 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Set-Cookie:
|
||||
- __cf_bm=o_N1eUBbqWWHvbE622tXs5BC9yN1X1bxp3npQXI46JU-1715649974-1.0.1.1-ALOCo.oJW08V4.F5WqVArJDbxakTERtLPfwUlDjTYrrg_WiJox.Pw_n.PnDfEdxa52BbaPI8M80h2S3wdJy2sw;
|
||||
path=/; expires=Tue, 14-May-24 01:56:14 GMT; domain=.api.openai.com; HttpOnly;
|
||||
- __cf_bm=V8sGOl1Y4f5Qu7trvPZAYe7AGA617GLKNhILzT6hbrc-1719507957-1.0.1.1-F.qdQAfjgBjTLxW4ciPK3Nt2jNdXguNNo.4_eOWYBNCmn2rSiWR4AeTxGn2ll2TgaFGHcoh9sWc__bk8cSIa3A;
|
||||
path=/; expires=Thu, 27-Jun-24 17:35:57 GMT; domain=.api.openai.com; HttpOnly;
|
||||
Secure; SameSite=None
|
||||
- _cfuvid=vYif.qp5YND_OTGCG3IgxPXT3sqDTSpeVEIUapP.n.k-1715649974367-0.0.1.1-604800000;
|
||||
- _cfuvid=9ZqY4IoIeegV9WIJ8ejAA9TRZrX2yM.crv4AqhuqVW4-1719507957363-0.0.1.1-604800000;
|
||||
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
@@ -475,37 +274,36 @@ interactions:
|
||||
openai-organization:
|
||||
- crewai-iuxna1
|
||||
openai-processing-ms:
|
||||
- '510'
|
||||
- '87'
|
||||
openai-version:
|
||||
- '2020-10-01'
|
||||
strict-transport-security:
|
||||
- max-age=15724800; includeSubDomains
|
||||
- max-age=31536000; includeSubDomains
|
||||
x-ratelimit-limit-requests:
|
||||
- '10000'
|
||||
x-ratelimit-limit-tokens:
|
||||
- '300000'
|
||||
- '16000000'
|
||||
x-ratelimit-remaining-requests:
|
||||
- '9997'
|
||||
- '9999'
|
||||
x-ratelimit-remaining-tokens:
|
||||
- '299098'
|
||||
- '15999772'
|
||||
x-ratelimit-reset-requests:
|
||||
- 13ms
|
||||
- 6ms
|
||||
x-ratelimit-reset-tokens:
|
||||
- 180ms
|
||||
- 0s
|
||||
x-request-id:
|
||||
- req_26f0f1e02a54a0aaf7e8b96ba7d56837
|
||||
- req_5d3282a4dba2ac63ea035b3bf6a5c13f
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": "Based on my evaluation, I give
|
||||
the title ''The impact of AI in the future of work'' a score of 4 out of 5."},
|
||||
{"role": "system", "content": "I''m gonna convert this raw text into valid JSON."}],
|
||||
"model": "gpt-4", "tool_choice": {"type": "function", "function": {"name": "ScoreOutput"}},
|
||||
"tools": [{"type": "function", "function": {"name": "ScoreOutput", "description":
|
||||
"Correctly extracted `ScoreOutput` with all the required parameters with correct
|
||||
types", "parameters": {"properties": {"score": {"title": "Score", "type": "integer"}},
|
||||
"required": ["score"], "type": "object"}}}]}'
|
||||
body: '{"messages": [{"role": "user", "content": "4"}, {"role": "system", "content":
|
||||
"I''m gonna convert this raw text into valid JSON."}], "model": "gpt-4o", "tool_choice":
|
||||
{"type": "function", "function": {"name": "ScoreOutput"}}, "tools": [{"type":
|
||||
"function", "function": {"name": "ScoreOutput", "description": "Correctly extracted
|
||||
`ScoreOutput` with all the required parameters with correct types", "parameters":
|
||||
{"properties": {"score": {"title": "Score", "type": "integer"}}, "required":
|
||||
["score"], "type": "object"}}}]}'
|
||||
headers:
|
||||
accept:
|
||||
- application/json
|
||||
@@ -514,16 +312,16 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '621'
|
||||
- '519'
|
||||
content-type:
|
||||
- application/json
|
||||
cookie:
|
||||
- __cf_bm=o_N1eUBbqWWHvbE622tXs5BC9yN1X1bxp3npQXI46JU-1715649974-1.0.1.1-ALOCo.oJW08V4.F5WqVArJDbxakTERtLPfwUlDjTYrrg_WiJox.Pw_n.PnDfEdxa52BbaPI8M80h2S3wdJy2sw;
|
||||
_cfuvid=vYif.qp5YND_OTGCG3IgxPXT3sqDTSpeVEIUapP.n.k-1715649974367-0.0.1.1-604800000
|
||||
- __cf_bm=V8sGOl1Y4f5Qu7trvPZAYe7AGA617GLKNhILzT6hbrc-1719507957-1.0.1.1-F.qdQAfjgBjTLxW4ciPK3Nt2jNdXguNNo.4_eOWYBNCmn2rSiWR4AeTxGn2ll2TgaFGHcoh9sWc__bk8cSIa3A;
|
||||
_cfuvid=9ZqY4IoIeegV9WIJ8ejAA9TRZrX2yM.crv4AqhuqVW4-1719507957363-0.0.1.1-604800000
|
||||
host:
|
||||
- api.openai.com
|
||||
user-agent:
|
||||
- OpenAI/Python 1.29.0
|
||||
- OpenAI/Python 1.35.5
|
||||
x-stainless-arch:
|
||||
- arm64
|
||||
x-stainless-async:
|
||||
@@ -533,28 +331,28 @@ interactions:
|
||||
x-stainless-os:
|
||||
- MacOS
|
||||
x-stainless-package-version:
|
||||
- 1.29.0
|
||||
- 1.35.5
|
||||
x-stainless-runtime:
|
||||
- CPython
|
||||
x-stainless-runtime-version:
|
||||
- 3.11.7
|
||||
- 3.11.9
|
||||
method: POST
|
||||
uri: https://api.openai.com/v1/chat/completions
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
g2QBAMTINfMxamd1CeMeEI6KoYFref5vBi4N2oOiMbVNv3QLhr1AppZoAgF1drbOzezQ65E14dmt
|
||||
ADjNKcFsksRMO1Ud3qXHqqnW3c7ZUq/M23vj7mI9eXr198urN1YEQJvOiiz2xGsuBurUGghycvlZ
|
||||
kVOi2W92e53hsN8X3tE2LxQlOHax2qk2es12r9OJnWZFoMSXAIBtaQTw3fsuJRqVVsQLQ6AEfgTQ
|
||||
W1VQgkkI0xATE1kB5MLWTUqYUinhXLRW/WWJUuRQDm7ruUX6a6LU3/3z09v8MH9W3WF6MLi0g3h7
|
||||
/LJO+pyQembtBoV6YJRiUFmdJIwANIme0FtPmfXFXRldGVUYAE38e0pw+22Ab4bM+uKbEp1vs6fq
|
||||
xr2oYz/0+J5iGZUdO2/TsGA4o9YBfzeEjVGCIVpHY+0F8GPJammcS3Teahf/op0XJlCi2ejpBLhp
|
||||
cghsmHJfPJATmc1mVwySYByBlb/R1IwL7/zUrrLYCwMD
|
||||
A2kBAMTvp6ueppr36zWlPDGLEiUMsfWbugkuDdrjfExt05duwbBLw2xhoAkEVJatc7EwOfTJlTXh
|
||||
3r0gQhpCEoLEa4LC6u5SFdV5+fV29lE+PKmz8/L0JMrOLtLbtbedoCOIwH6mgoYT77kYqCkbCHJy
|
||||
+ZoKIWk4Hy6ng/lyuiBeKDhUGpIQ26Y74e5oMJp0B9PucMy8mnAaqBqSvgUR0b41IMLz9x1IGnRG
|
||||
EWcMARL4EhEq1gqS4NV1WjeeadABZKLXjUoyrdbEqYZZO4GntXCoAvf9jK5+9bR2io+zVWZO4tX6
|
||||
5mjtP/jTfBC14dGXTGh6ZmsXhTpiFGJQWpUUGCKC8Qr+p54DrtR929i2yQYRLP0hJGH/gzrgSv1A
|
||||
Tv4xZ+2/6GO/GsL/VTUPmmNbsV8nHFHrAOeGsBFIQt2wFWP+C6JfE5Zbq5yArbiwjdNwrkwNSYsC
|
||||
YM9kANg0ZX54IEPSFlOxRAJRBBacKDWxqmyVmnMDIusEajBfjsfjQQTxLwwD
|
||||
headers:
|
||||
CF-Cache-Status:
|
||||
- DYNAMIC
|
||||
CF-RAY:
|
||||
- 88371965caa0a686-MIA
|
||||
- 89a706621820228b-SJC
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
@@ -562,7 +360,7 @@ interactions:
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 14 May 2024 01:26:18 GMT
|
||||
- Thu, 27 Jun 2024 17:05:58 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
@@ -572,25 +370,25 @@ interactions:
|
||||
openai-organization:
|
||||
- crewai-iuxna1
|
||||
openai-processing-ms:
|
||||
- '994'
|
||||
- '316'
|
||||
openai-version:
|
||||
- '2020-10-01'
|
||||
strict-transport-security:
|
||||
- max-age=15724800; includeSubDomains
|
||||
- max-age=31536000; includeSubDomains
|
||||
x-ratelimit-limit-requests:
|
||||
- '10000'
|
||||
x-ratelimit-limit-tokens:
|
||||
- '300000'
|
||||
- '16000000'
|
||||
x-ratelimit-remaining-requests:
|
||||
- '9999'
|
||||
x-ratelimit-remaining-tokens:
|
||||
- '299944'
|
||||
- '15999969'
|
||||
x-ratelimit-reset-requests:
|
||||
- 6ms
|
||||
x-ratelimit-reset-tokens:
|
||||
- 11ms
|
||||
- 0s
|
||||
x-request-id:
|
||||
- req_a9b61926ad5fdaf004dd4b99738bcadb
|
||||
- req_abc65b2959a9fb14068d5e86757fec87
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
|
||||
59
tests/cli/cli_test.py
Normal file
59
tests/cli/cli_test.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
from crewai.cli.cli import train, version
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def runner():
|
||||
return CliRunner()
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.cli.train_crew")
|
||||
def test_train_default_iterations(train_crew, runner):
|
||||
result = runner.invoke(train)
|
||||
|
||||
train_crew.assert_called_once_with(5)
|
||||
assert result.exit_code == 0
|
||||
assert "Training the crew for 5 iterations" in result.output
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.cli.train_crew")
|
||||
def test_train_custom_iterations(train_crew, runner):
|
||||
result = runner.invoke(train, ["--n_iterations", "10"])
|
||||
|
||||
train_crew.assert_called_once_with(10)
|
||||
assert result.exit_code == 0
|
||||
assert "Training the crew for 10 iterations" in result.output
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.cli.train_crew")
|
||||
def test_train_invalid_string_iterations(train_crew, runner):
|
||||
result = runner.invoke(train, ["--n_iterations", "invalid"])
|
||||
|
||||
train_crew.assert_not_called()
|
||||
assert result.exit_code == 2
|
||||
assert (
|
||||
"Usage: train [OPTIONS]\nTry 'train --help' for help.\n\nError: Invalid value for '-n' / '--n_iterations': 'invalid' is not a valid integer.\n"
|
||||
in result.output
|
||||
)
|
||||
|
||||
|
||||
def test_version_command(runner):
|
||||
result = runner.invoke(version)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "crewai version:" in result.output
|
||||
|
||||
|
||||
def test_version_command_with_tools(runner):
|
||||
result = runner.invoke(version, ["--tools"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "crewai version:" in result.output
|
||||
assert (
|
||||
"crewai tools version:" in result.output
|
||||
or "crewai tools not installed" in result.output
|
||||
)
|
||||
87
tests/cli/train_crew_test.py
Normal file
87
tests/cli/train_crew_test.py
Normal file
@@ -0,0 +1,87 @@
|
||||
import subprocess
|
||||
from unittest import mock
|
||||
|
||||
from crewai.cli.train_crew import train_crew
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.train_crew.subprocess.run")
|
||||
def test_train_crew_positive_iterations(mock_subprocess_run):
|
||||
# Arrange
|
||||
n_iterations = 5
|
||||
mock_subprocess_run.return_value = subprocess.CompletedProcess(
|
||||
args=["poetry", "run", "train", str(n_iterations)],
|
||||
returncode=0,
|
||||
stdout="Success",
|
||||
stderr="",
|
||||
)
|
||||
|
||||
# Act
|
||||
train_crew(n_iterations)
|
||||
|
||||
# Assert
|
||||
mock_subprocess_run.assert_called_once_with(
|
||||
["poetry", "run", "train", str(n_iterations)],
|
||||
capture_output=False,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.train_crew.click")
|
||||
def test_train_crew_zero_iterations(click):
|
||||
train_crew(0)
|
||||
click.echo.assert_called_once_with(
|
||||
"An unexpected error occurred: The number of iterations must be a positive integer.",
|
||||
err=True,
|
||||
)
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.train_crew.click")
|
||||
def test_train_crew_negative_iterations(click):
|
||||
train_crew(-2)
|
||||
click.echo.assert_called_once_with(
|
||||
"An unexpected error occurred: The number of iterations must be a positive integer.",
|
||||
err=True,
|
||||
)
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.train_crew.click")
|
||||
@mock.patch("crewai.cli.train_crew.subprocess.run")
|
||||
def test_train_crew_called_process_error(mock_subprocess_run, click):
|
||||
n_iterations = 5
|
||||
mock_subprocess_run.side_effect = subprocess.CalledProcessError(
|
||||
returncode=1,
|
||||
cmd=["poetry", "run", "train", str(n_iterations)],
|
||||
output="Error",
|
||||
stderr="Some error occurred",
|
||||
)
|
||||
train_crew(n_iterations)
|
||||
|
||||
mock_subprocess_run.assert_called_once_with(
|
||||
["poetry", "run", "train", "5"], capture_output=False, text=True, check=True
|
||||
)
|
||||
click.echo.assert_has_calls(
|
||||
[
|
||||
mock.call.echo(
|
||||
"An error occurred while training the crew: Command '['poetry', 'run', 'train', '5']' returned non-zero exit status 1.",
|
||||
err=True,
|
||||
),
|
||||
mock.call.echo("Error", err=True),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.train_crew.click")
|
||||
@mock.patch("crewai.cli.train_crew.subprocess.run")
|
||||
def test_train_crew_unexpected_exception(mock_subprocess_run, click):
|
||||
# Arrange
|
||||
n_iterations = 5
|
||||
mock_subprocess_run.side_effect = Exception("Unexpected error")
|
||||
train_crew(n_iterations)
|
||||
|
||||
mock_subprocess_run.assert_called_once_with(
|
||||
["poetry", "run", "train", "5"], capture_output=False, text=True, check=True
|
||||
)
|
||||
click.echo.assert_called_once_with(
|
||||
"An unexpected error occurred: Unexpected error", err=True
|
||||
)
|
||||
@@ -1,20 +0,0 @@
|
||||
from click.testing import CliRunner
|
||||
from crewai.cli.cli import version
|
||||
|
||||
|
||||
def test_version_command():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(version)
|
||||
assert result.exit_code == 0
|
||||
assert "crewai version:" in result.output
|
||||
|
||||
|
||||
def test_version_command_with_tools():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(version, ["--tools"])
|
||||
assert result.exit_code == 0
|
||||
assert "crewai version:" in result.output
|
||||
assert (
|
||||
"crewai tools version:" in result.output
|
||||
or "crewai tools not installed" in result.output
|
||||
)
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Test Agent creation and execution basic functionality."""
|
||||
|
||||
import json
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
|
||||
import pydantic_core
|
||||
import pytest
|
||||
@@ -381,9 +383,16 @@ def test_crew_full_ouput():
|
||||
crew = Crew(agents=[agent], tasks=[task1, task2], full_output=True)
|
||||
|
||||
result = crew.kickoff()
|
||||
|
||||
assert result == {
|
||||
"final_output": "Hello! It is a delight to receive your message. I trust this response finds you in good spirits. It's indeed a pleasure to connect with you too.",
|
||||
"final_output": "Hello!",
|
||||
"tasks_outputs": [task1.output, task2.output],
|
||||
"usage_metrics": {
|
||||
"total_tokens": 348,
|
||||
"prompt_tokens": 314,
|
||||
"completion_tokens": 34,
|
||||
"successful_requests": 2,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -445,10 +454,14 @@ def test_async_task_execution():
|
||||
start.return_value = thread
|
||||
with patch.object(threading.Thread, "join", wraps=thread.join()) as join:
|
||||
list_ideas.output = TaskOutput(
|
||||
description="A 4 paragraph article about AI.", raw_output="ok"
|
||||
description="A 4 paragraph article about AI.",
|
||||
raw_output="ok",
|
||||
agent="writer",
|
||||
)
|
||||
list_important_history.output = TaskOutput(
|
||||
description="A 4 paragraph article about AI.", raw_output="ok"
|
||||
description="A 4 paragraph article about AI.",
|
||||
raw_output="ok",
|
||||
agent="writer",
|
||||
)
|
||||
crew.kickoff()
|
||||
start.assert_called()
|
||||
@@ -649,9 +662,9 @@ def test_agent_usage_metrics_are_captured_for_sequential_process():
|
||||
assert result == "Howdy!"
|
||||
assert crew.usage_metrics == {
|
||||
"completion_tokens": 17,
|
||||
"prompt_tokens": 160,
|
||||
"prompt_tokens": 158,
|
||||
"successful_requests": 1,
|
||||
"total_tokens": 177,
|
||||
"total_tokens": 175,
|
||||
}
|
||||
|
||||
|
||||
@@ -672,15 +685,16 @@ def test_agent_usage_metrics_are_captured_for_hierarchical_process():
|
||||
agents=[agent],
|
||||
tasks=[task],
|
||||
process=Process.hierarchical,
|
||||
manager_llm=ChatOpenAI(temperature=0, model="gpt-4"),
|
||||
manager_llm=ChatOpenAI(temperature=0, model="gpt-4o"),
|
||||
)
|
||||
|
||||
result = crew.kickoff()
|
||||
assert result == '"Howdy!"'
|
||||
assert result == "Howdy!"
|
||||
|
||||
assert crew.usage_metrics == {
|
||||
"total_tokens": 1666,
|
||||
"prompt_tokens": 1383,
|
||||
"completion_tokens": 283,
|
||||
"total_tokens": 1383,
|
||||
"prompt_tokens": 1278,
|
||||
"completion_tokens": 105,
|
||||
"successful_requests": 3,
|
||||
}
|
||||
|
||||
@@ -993,3 +1007,107 @@ def test_manager_agent_with_tools_raises_exception():
|
||||
|
||||
with pytest.raises(Exception):
|
||||
crew.kickoff()
|
||||
|
||||
|
||||
@patch("crewai.crew.Crew.kickoff")
|
||||
@patch("crewai.crew.CrewTrainingHandler")
|
||||
@patch("crewai.crew.TaskEvaluator")
|
||||
def test_crew_train_success(task_evaluator, crew_training_handler, kickoff):
|
||||
task = Task(
|
||||
description="Come up with a list of 5 interesting ideas to explore for an article, then write one amazing paragraph highlight for each idea that showcases how good an article about this topic could be. Return the list of ideas with their paragraph and your notes.",
|
||||
expected_output="5 bullet points with a paragraph for each idea.",
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[task],
|
||||
)
|
||||
crew.train(n_iterations=2, inputs={"topic": "AI"})
|
||||
task_evaluator.assert_has_calls(
|
||||
[
|
||||
mock.call(researcher),
|
||||
mock.call().evaluate_training_data(
|
||||
training_data=crew_training_handler().load(),
|
||||
agent_id=str(researcher.id),
|
||||
),
|
||||
mock.call().evaluate_training_data().model_dump(),
|
||||
mock.call(writer),
|
||||
mock.call().evaluate_training_data(
|
||||
training_data=crew_training_handler().load(),
|
||||
agent_id=str(writer.id),
|
||||
),
|
||||
mock.call().evaluate_training_data().model_dump(),
|
||||
]
|
||||
)
|
||||
|
||||
crew_training_handler.assert_has_calls(
|
||||
[
|
||||
mock.call("training_data.pkl"),
|
||||
mock.call().load(),
|
||||
mock.call("trained_agents_data.pkl"),
|
||||
mock.call().save_trained_data(
|
||||
agent_id="Researcher",
|
||||
trained_data=task_evaluator().evaluate_training_data().model_dump(),
|
||||
),
|
||||
mock.call("trained_agents_data.pkl"),
|
||||
mock.call().save_trained_data(
|
||||
agent_id="Senior Writer",
|
||||
trained_data=task_evaluator().evaluate_training_data().model_dump(),
|
||||
),
|
||||
mock.call(),
|
||||
mock.call().load(),
|
||||
mock.call(),
|
||||
mock.call().load(),
|
||||
]
|
||||
)
|
||||
|
||||
kickoff.assert_has_calls(
|
||||
[mock.call(inputs={"topic": "AI"}), mock.call(inputs={"topic": "AI"})]
|
||||
)
|
||||
|
||||
|
||||
def test_crew_train_error():
|
||||
task = Task(
|
||||
description="Come up with a list of 5 interesting ideas to explore for an article",
|
||||
expected_output="5 bullet points with a paragraph for each idea.",
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[task],
|
||||
)
|
||||
|
||||
with pytest.raises(TypeError) as e:
|
||||
crew.train()
|
||||
assert "train() missing 1 required positional argument: 'n_iterations'" in str(
|
||||
e
|
||||
)
|
||||
|
||||
|
||||
def test__setup_for_training():
|
||||
researcher.allow_delegation = True
|
||||
writer.allow_delegation = True
|
||||
agents = [researcher, writer]
|
||||
task = Task(
|
||||
description="Come up with a list of 5 interesting ideas to explore for an article",
|
||||
expected_output="5 bullet points with a paragraph for each idea.",
|
||||
)
|
||||
|
||||
crew = Crew(
|
||||
agents=agents,
|
||||
tasks=[task],
|
||||
)
|
||||
|
||||
assert crew._train is False
|
||||
assert task.human_input is False
|
||||
|
||||
for agent in agents:
|
||||
assert agent.allow_delegation is True
|
||||
|
||||
crew._setup_for_training()
|
||||
|
||||
assert crew._train is True
|
||||
assert task.human_input is True
|
||||
|
||||
for agent in agents:
|
||||
assert agent.allow_delegation is False
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Test Agent creation and execution basic functionality."""
|
||||
|
||||
import json
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
@@ -7,6 +8,7 @@ from pydantic import BaseModel
|
||||
from pydantic_core import ValidationError
|
||||
|
||||
from crewai import Agent, Crew, Process, Task
|
||||
from crewai.tasks.task_output import TaskOutput
|
||||
|
||||
|
||||
def test_task_tool_reflect_agent_tools():
|
||||
@@ -105,6 +107,46 @@ def test_task_callback():
|
||||
task_completed.assert_called_once_with(task.output)
|
||||
|
||||
|
||||
def test_task_callback_returns_task_ouput():
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
goal="Make the best research and analysis on content about AI and AI agents",
|
||||
backstory="You're an expert researcher, specialized in technology, software engineering, AI and startups. You work as a freelancer and is now working on doing research and analysis for a new customer.",
|
||||
allow_delegation=False,
|
||||
)
|
||||
|
||||
task_completed = MagicMock(return_value="done")
|
||||
|
||||
task = Task(
|
||||
description="Give me a list of 5 interesting ideas to explore for an article, what makes them unique and interesting.",
|
||||
expected_output="Bullet point list of 5 interesting ideas.",
|
||||
agent=researcher,
|
||||
callback=task_completed,
|
||||
)
|
||||
|
||||
with patch.object(Agent, "execute_task") as execute:
|
||||
execute.return_value = "exported_ok"
|
||||
task.execute()
|
||||
# Ensure the callback is called with a TaskOutput object serialized to JSON
|
||||
task_completed.assert_called_once()
|
||||
callback_data = task_completed.call_args[0][0]
|
||||
|
||||
# Check if callback_data is TaskOutput object or JSON string
|
||||
if isinstance(callback_data, TaskOutput):
|
||||
callback_data = json.dumps(callback_data.model_dump())
|
||||
|
||||
assert isinstance(callback_data, str)
|
||||
output_dict = json.loads(callback_data)
|
||||
expected_output = {
|
||||
"description": task.description,
|
||||
"exported_output": "exported_ok",
|
||||
"raw_output": "exported_ok",
|
||||
"agent": researcher.role,
|
||||
"summary": "Give me a list of 5 interesting ideas to explore...",
|
||||
}
|
||||
assert output_dict == expected_output
|
||||
|
||||
|
||||
def test_execute_with_agent():
|
||||
researcher = Agent(
|
||||
role="Researcher",
|
||||
@@ -325,6 +367,8 @@ def test_save_task_json_output():
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
def test_save_task_pydantic_output():
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
class ScoreOutput(BaseModel):
|
||||
score: int
|
||||
|
||||
@@ -333,6 +377,7 @@ def test_save_task_pydantic_output():
|
||||
goal="Score the title",
|
||||
backstory="You're an expert scorer, specialized in scoring titles.",
|
||||
allow_delegation=False,
|
||||
llm=ChatOpenAI(model="gpt-4o"),
|
||||
)
|
||||
|
||||
task = Task(
|
||||
@@ -371,13 +416,13 @@ def test_increment_delegations_for_hierarchical_process():
|
||||
agents=[scorer],
|
||||
tasks=[task],
|
||||
process=Process.hierarchical,
|
||||
manager_llm=ChatOpenAI(model="gpt-4-0125-preview"),
|
||||
manager_llm=ChatOpenAI(model="gpt-4o"),
|
||||
)
|
||||
|
||||
with patch.object(Task, "increment_delegations") as increment_delegations:
|
||||
increment_delegations.return_value = None
|
||||
crew.kickoff()
|
||||
increment_delegations.assert_called_once
|
||||
increment_delegations.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.vcr(filter_headers=["authorization"])
|
||||
|
||||
64
tests/utilities/evaluators/test_task_evaluator.py
Normal file
64
tests/utilities/evaluators/test_task_evaluator.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from unittest import mock
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from crewai.utilities.evaluators.task_evaluator import (
|
||||
TaskEvaluator,
|
||||
TrainingTaskEvaluation,
|
||||
)
|
||||
|
||||
|
||||
@patch("crewai.utilities.evaluators.task_evaluator.Converter")
|
||||
def test_evaluate_training_data(converter_mock):
|
||||
training_data = {
|
||||
"agent_id": {
|
||||
"data1": {
|
||||
"initial_output": "Initial output 1",
|
||||
"human_feedback": "Human feedback 1",
|
||||
"improved_output": "Improved output 1",
|
||||
},
|
||||
"data2": {
|
||||
"initial_output": "Initial output 2",
|
||||
"human_feedback": "Human feedback 2",
|
||||
"improved_output": "Improved output 2",
|
||||
},
|
||||
}
|
||||
}
|
||||
agent_id = "agent_id"
|
||||
original_agent = MagicMock()
|
||||
function_return_value = TrainingTaskEvaluation(
|
||||
suggestions=[
|
||||
"The initial output was already good, having a detailed explanation. However, the improved output "
|
||||
"gave similar information but in a more professional manner using better vocabulary. For future tasks, "
|
||||
"try to implement more elaborate language and precise terminology from the beginning."
|
||||
],
|
||||
quality=8.0,
|
||||
final_summary="The agent responded well initially. However, the improved output showed that there is room "
|
||||
"for enhancement in terms of language usage, precision, and professionalism. For future tasks, the agent "
|
||||
"should focus more on these points from the start to increase performance.",
|
||||
)
|
||||
converter_mock.return_value.to_pydantic.return_value = function_return_value
|
||||
result = TaskEvaluator(original_agent=original_agent).evaluate_training_data(
|
||||
training_data, agent_id
|
||||
)
|
||||
|
||||
assert result == function_return_value
|
||||
converter_mock.assert_has_calls(
|
||||
[
|
||||
mock.call(
|
||||
llm=original_agent.llm,
|
||||
text="Assess the quality of the training data based on the llm output, human feedback , and llm "
|
||||
"output improved result.\n\nInitial Output:\nInitial output 1\n\nHuman Feedback:\nHuman feedback "
|
||||
"1\n\nImproved Output:\nImproved output 1\n\nInitial Output:\nInitial output 2\n\nHuman "
|
||||
"Feedback:\nHuman feedback 2\n\nImproved Output:\nImproved output 2\n\nPlease provide:\n- "
|
||||
"Based on the Human Feedbacks and the comparison between Initial Outputs and Improved outputs "
|
||||
"provide action items based on human_feedback for future tasks\n- A score from 0 to 10 evaluating "
|
||||
"on completion, quality, and overall performance from the improved output to the initial output "
|
||||
"based on the human feedback\n",
|
||||
model=TrainingTaskEvaluation,
|
||||
instructions="I'm gonna convert this raw text into valid JSON.\n\nThe json should have the "
|
||||
"following structure, with the following keys:\n- suggestions: List[str]\n- "
|
||||
"quality: float\n- final_summary: str",
|
||||
),
|
||||
mock.call().to_pydantic(),
|
||||
]
|
||||
)
|
||||
41
tests/utilities/test_file_handler.py
Normal file
41
tests/utilities/test_file_handler.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import pytest
|
||||
|
||||
from crewai.utilities.file_handler import PickleHandler
|
||||
|
||||
|
||||
class TestPickleHandler(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.file_name = "test_data.pkl"
|
||||
self.file_path = os.path.join(os.getcwd(), self.file_name)
|
||||
self.handler = PickleHandler(self.file_name)
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.file_path):
|
||||
os.remove(self.file_path)
|
||||
|
||||
def test_initialize_file(self):
|
||||
assert os.path.exists(self.file_path) is True
|
||||
assert os.path.getsize(self.file_path) >= 0
|
||||
|
||||
def test_save_and_load(self):
|
||||
data = {"key": "value"}
|
||||
self.handler.save(data)
|
||||
loaded_data = self.handler.load()
|
||||
assert loaded_data == data
|
||||
|
||||
def test_load_empty_file(self):
|
||||
loaded_data = self.handler.load()
|
||||
assert loaded_data == {}
|
||||
|
||||
def test_load_corrupted_file(self):
|
||||
with open(self.file_path, "wb") as file:
|
||||
file.write(b"corrupted data")
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
self.handler.load()
|
||||
|
||||
assert str(exc.value) == "pickle data was truncated"
|
||||
assert "<class '_pickle.UnpicklingError'>" == str(exc.type)
|
||||
42
tests/utilities/test_training_handler.py
Normal file
42
tests/utilities/test_training_handler.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from crewai.utilities.training_handler import CrewTrainingHandler
|
||||
|
||||
|
||||
class TestCrewTrainingHandler(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.handler = CrewTrainingHandler("trained_data.pkl")
|
||||
|
||||
def tearDown(self):
|
||||
os.remove("trained_data.pkl")
|
||||
del self.handler
|
||||
|
||||
def test_save_trained_data(self):
|
||||
agent_id = "agent1"
|
||||
trained_data = {"param1": 1, "param2": 2}
|
||||
self.handler.save_trained_data(agent_id, trained_data)
|
||||
|
||||
# Assert that the trained data is saved correctly
|
||||
data = self.handler.load()
|
||||
assert data[agent_id] == trained_data
|
||||
|
||||
def test_append_existing_agent(self):
|
||||
train_iteration = 1
|
||||
agent_id = "agent1"
|
||||
new_data = {"param3": 3, "param4": 4}
|
||||
self.handler.append(train_iteration, agent_id, new_data)
|
||||
|
||||
# Assert that the new data is appended correctly to the existing agent
|
||||
data = self.handler.load()
|
||||
assert data[agent_id][train_iteration] == new_data
|
||||
|
||||
def test_append_new_agent(self):
|
||||
train_iteration = 1
|
||||
agent_id = "agent2"
|
||||
new_data = {"param5": 5, "param6": 6}
|
||||
self.handler.append(train_iteration, agent_id, new_data)
|
||||
|
||||
# Assert that the new agent and data are appended correctly
|
||||
data = self.handler.load()
|
||||
assert data[agent_id][train_iteration] == new_data
|
||||
Reference in New Issue
Block a user