Home

Awesome

TaskGen (Simbian) v3.3.4

A Task-based agentic framework building on StrictJSON outputs by LLM agents

An Open Source Initiative Led by John Tan Chong Min, Supported by Simbian AI

As of 15 Oct 2024, John Tan Chong Min has left Simbian and is maintaining his own version of TaskGen at https://github.com/tanchongmin/taskgen

TaskGen Overview

Creator's Preamble

Happy to share that the task-based agentic framework I have been working on - TaskGen - is largely complete!

Noteable features include:

I am quite sure that this is the best open-source agentic framework for task-based execution out there! Existing frameworks like AutoGen rely too much on conversational text which is lengthy and not targeted. TaskGen uses StrictJSON (JSON parser with type checking and more!) as the core, and agents are efficient and are able to do Chain of Thought natively using JSON keys and descriptions as a guide.

I can't wait to see what this new framework can do for you!

Benefits of JSON messaging over agentic frameworks using conversational free-text like AutoGen

Creator Info

How do I use this?

  1. Download package via command line pip install taskgen-ai==3.3.4
  2. Set up your LLM and provide any API keys if needed
  3. Import the required functions from taskgen and use them!

Differences in LLM for Agentic Framework

1. Agent Basics

Example Agent Creation

my_agent = Agent('Helpful assistant', 'You are a generalist agent', llm = llm)

Example Agent Task Running - Split the assigned task into subtasks and execute each of them

output = my_agent.run('Give me 5 words rhyming with cool, and make a 4-sentence poem using them')

Subtask identified: Find 5 words that rhyme with 'cool'

Getting LLM to perform the following task: Find 5 words that rhyme with 'cool'

pool, rule, fool, tool, school

Subtask identified: Compose a 4-sentence poem using the words 'pool', 'rule', 'fool', 'tool', and 'school'

Getting LLM to perform the following task: Compose a 4-sentence poem using the words 'pool', 'rule', 'fool', 'tool', and 'school'

In the school, the golden rule is to never be a fool. Use your mind as a tool, and always follow the pool.

Task completed successfully!

Check Agent's Status

my_agent.status()

Agent Name: Helpful assistant

Agent Description: You are a generalist agent

Available Functions: ['use_llm', 'end_task']

Task: Give me 5 words rhyming with cool, and make a 4-sentence poem using them

Subtasks Completed:

Subtask: Find 5 words that rhyme with 'cool'

pool, rule, fool, tool, school

Subtask: Compose a 4-sentence poem using the words 'pool', 'rule', 'fool', 'tool', and 'school'

In the school, the golden rule is to never be a fool. Use your mind as a tool, and always follow the pool.

Is Task Completed: True

Example Agent Reply to User - Reference the subtasks' output to answer the user's query

output = my_agent.reply_user()

Here are 5 words that rhyme with "cool": pool, rule, fool, tool, school. Here is a 4-sentence poem using these words: "In the school, the golden rule is to never be a fool. Use your mind as a tool, and always follow the pool."

2. Power Up your Agents - Bring in Functions (aka Tools)

# This is an example of an LLM-based function (see Tutorial 0)
sentence_style = Function(fn_description = 'Output a sentence with words <var1> and <var2> in the style of <var3>', 
                         output_format = {'output': 'sentence'},
                         fn_name = 'sentence_with_objects_entities_emotion',
                         llm = llm)

# This is an example of an external user-defined function (see Tutorial 0)
def binary_to_decimal(binary_number: str) -> int:
    '''Converts binary_number to integer of base 10'''
    return int(str(binary_number), 2)

# Initialise your Agent
my_agent = Agent('Helpful assistant', 'You are a generalist agent')

# Assign the functions
my_agent.assign_functions([sentence_style, binary_to_decimal])

# Run the Agent
output = my_agent.run('First convert binary string 1001 to a number, then generate me a happy sentence with that number and a ball')

Subtask identified: Convert the binary number 1001 to decimal Calling function binary_to_decimal with parameters {'x': '1001'}

{'output1': 9}

Subtask identified: Generate a happy sentence with the decimal number and a ball Calling function sentence_with_objects_entities_emotion with parameters {'obj': '9', 'entity': 'ball', 'emotion': 'happy'}

{'output': 'I am so happy with my 9 balls.'}

Task completed successfully!

3. AsyncAgent

Example LLM in Async Mode

async def llm_async(system_prompt: str, user_prompt: str):
    ''' Here, we use OpenAI for illustration, you can change it to your own LLM '''
    # ensure your LLM imports are all within this function
    from openai import AsyncOpenAI
    
    # define your own LLM here
    client = AsyncOpenAI()
    response = await client.chat.completions.create(
        model='gpt-4o-mini',
        temperature = 0,
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt}
        ]
    )
    return response.choices[0].message.content

Example Agentic Workflow

# This is an example of an LLM-based function (see Tutorial 0)
sentence_style = AsyncFunction(fn_description = 'Output a sentence with words <var1> and <var2> in the style of <var3>', 
                         output_format = {'output': 'sentence'},
                         fn_name = 'sentence_with_objects_entities_emotion', # you must define fn_name for LLM-based functions
                         llm = llm_async) # use an async LLM function

# This is an example of an external user-defined function (see Tutorial 0)
def binary_to_decimal(binary_number: str) -> int:
    '''Converts binary_number to integer of base 10'''
    return int(str(binary_number), 2)

# Initialise your Agent
my_agent = AsyncAgent('Helpful assistant', 'You are a generalist agent')

# Assign the functions
my_agent.assign_functions([sentence_style, binary_to_decimal])

# Run the Agent
output = await my_agent.run('Generate me a happy sentence with a number and a ball. The number is b1001 converted to decimal')

4. Shared Variables

"Because text is not enough" - Anonymous

Example External Function using shared_variables

# Use shared_variables as input to your external function to access and modify the shared variables
def generate_quotes(shared_variables, number_of_quotes: int, category: str):
    ''' Generates number_of_quotes quotes about category '''
    # Retrieve from shared variables
    my_quote_list = shared_variables['Quote List']
    
    # Generate the quotes
    res = strict_json(system_prompt = f'''Generate {number_of_quotes} sentences about {category}. 
Do them in the format "<Quote> - <Person>", e.g. "The way to get started is to quit talking and begin doing. - Walt Disney"
Ensure your quotes contain only ' within the quote, and are enclosed by " ''',
                      user_prompt = '',
                      output_format = {'Quote List': f'list of {number_of_quotes} quotes, type: List[str]'},
                      llm = llm)
    
    my_quote_list.extend([f'Category: {category}. '+ x for x in res['Quote List']])
    
    # Store back to shared variables
    shared_variables['Quote List'] = my_quote_list

5. Global Context

Example for global_context : Inventory Manager

def add_item_to_inventory(shared_variables, item: str) -> str:
    ''' Adds item to inventory, and returns outcome of action '''
    shared_variables['Inventory'].append(item)
    return f'{item} successfully added to Inventory'
    
def remove_item_from_inventory(shared_variables, item: str) -> str:
    ''' Removes item from inventory and returns outcome of action '''
    if item in shared_variables['Inventory']:
        shared_variables['Inventory'].remove(item)
        return f'{item} successfully removed from Inventory'
    else:
        return f'{item} not found in Inventory, unable to remove'
    
agent = Agent('Inventory Manager', 
              'Adds and removes items in Inventory. Only able to remove items if present in Inventory',
              shared_variables = {'Inventory': []},
              global_context = 'Inventory: <Inventory>', # Add in Global Context here with shared_variables Inventory
              llm = llm).assign_functions([add_item_to_inventory, remove_item_from_inventory])

Other Features

Known Limitations

  1. Other Known Limitations - Do test the framework out extensively and note its failure cases. We will see if we can address them, if not we will put them in Known Limitations.
  2. (For the prompt engineer). If you could find a better way to make the prompts work, let us know directly - we do need to test this out across all Tutorial Jupyter Notebooks to make sure that it really works with existing datasets. Also, if you are using other LLMs beside OpenAI, and find the prompts do not work as well - try to rejig your own prompts and let us know as well!