Multi agents: sequential workflow#

After creating agents, for example, through the Creating and using a Code Agent or Creating a custom agent tutorials, you can use them and have various daily usages. You will need several agents to work together to handle more complex use cases.

Prerequisites#

  • Dataiku >= 13.4

  • An OpenAI connection

  • Python >= 3.9

Introduction#

When solving a problem using multiple agents, keeping dedicated agents for well-delimited tasks is useful. You will then articulate a multi-agent system to tackle the global topic. You will implement a first agent to call the different agents with the appropriate prompt and parameters according to a sequential workflow. This tutorial will elaborate on a multi-agent system that will produce the HTML code needed for your website from a product description. It will use two agents. The first will extract the key features, target audience, and unique selling points. The second one will format that information with the proper HTML code.

The Concept Extractor Agent#

The Concept Extractor is in charge of the description analysis from a marketing perspective. It extracts a list of key features from a product’s textual description. It will also estimate the target audience for such a product. Lastly, the description analysis will provide a list of potential selling points that would be helpful.

To create this agent, follow the Creating and using a Code Agent tutorial and use Code 1 below.

Code 1: Concept Extractor Agent code#
import dataiku
from dataiku.llm.python import BaseLLM

LLM_ID = "REPLACE_WITH_YOUR_LLM_ID"

class MyLLM(BaseLLM):
    def __init__(self):
        pass

    def process(self, query, settings, trace):
        llm = dataiku.api_client().get_default_project().get_llm(LLM_ID)

        user_query = query["messages"][0]["content"]

        concept_extractor = """You are working in a marketing team.
        Your role is to read a product description and find the key features, target audience, and unique selling points.
        Start with the product name mentioned as PRODUCT"""

        extract = llm.new_completion()
        extract.settings["temperature"] = 0.1
        extract.with_message(message=concept_extractor, role='system')
        extract.with_message(message=user_query, role='user')
        resp = extract.execute()


        return {"text": resp.text}

You can test your Concept Extractor Agent in the Quick test tabs by entering the following test query:

Quick test concept extractor

You can use the following suggestion as a test query:

{
     "messages": [
        {
           "role": "user",
           "content": "Smart Water Bottle designed to help you stay hydrated throughout the day. ability to track water intake. sync with your smartphone. LED reminders. eco-friendly material. long-lasting battery life"
        }
     ],
     "context": {}
}

Depending on the model you chose, the result will looks like the following:

**Product Name:** Smart Water Bottle

**Key Features:**
1. Tracks water intake
2. Syncs with smartphone
3. LED reminders for hydration
4. Made from eco-friendly materials
5. Long-lasting battery life

**Target Audience:**
- Health-conscious individuals
- Tech-savvy users
- Environmentally conscious consumers
- Busy professionals and students
- Fitness enthusiasts

**Unique Selling Points:**
- Integration with smartphone for easy tracking and reminders
- Eco-friendly construction appealing to sustainable living advocates
- LED reminders to ensure consistent hydration throughout the day
- Durable battery life reducing the need for frequent charging

The Web Writer Agent#

The Web Writer Agent is in charge of formatting the elements analyzed by the concept extractor. It will use a predefined HTML format enforced in the system prompt with a detailed example. This system prompt is the part you need to adapt and refine to have a reliable answer from the LLM you chose to use. Once again, you can follow the Creating and using a Code Agent tutorial and use Code 2 below.

Code 2: Web Writer Agent code#
import dataiku
from dataiku.llm.python import BaseLLM

LLM_ID = "REPLACE_WITH_YOUR_LLM_ID"

class MyLLM(BaseLLM):
    def __init__(self):
        pass

    def process(self, query, settings, trace):
        llm = dataiku.api_client().get_default_project().get_llm(LLM_ID)

        user_query = query["messages"][0]["content"]

        web_writer = """You are working in a web writer team.
        Your role is to read a description containing a list with the key features, target audience, and unique selling points.
        You then output a HTML code to list all categories and its sub elements as a list.
        For example, if you receive the following description:
        "
            **PRODUCT:** Smart Water Bottle

            **Key Features:**
            1. Ability to track water intake
            2. Syncs with your smartphone
            3. LED reminders
            4. Made from eco-friendly material
            5. Long-lasting battery life

            **Target Audience:**
            - Health-conscious individuals
            - Tech-savvy users
            - People with busy lifestyles
            - Environmentally conscious consumers
            - Fitness enthusiasts

            **Unique Selling Points:**
            - Integration with smartphone for easy tracking and monitoring
            - Eco-friendly materials appeal to environmentally conscious buyers
            - LED reminders provide a convenient way to ensure regular hydration
            - Long-lasting battery life reduces the need for frequent charging
        "
        You will output the following HTML code:
        "
        <section>
            <h2>Smart Water Bottle</h2>

            <h3>Key Features:</h3>
            <ul>
                <li>Ability to track water intake</li>
                <li>Syncs with your smartphone</li>
                <li>LED reminders</li>
                <li>Made from eco-friendly material</li>
                <li>Long-lasting battery life</li>
            </ul>

            <h3>Target Audience:</h3>
            <ul>
                <li>Health-conscious individuals</li>
                <li>Tech-savvy users</li>
                <li>People with busy lifestyles</li>
                <li>Environmentally conscious consumers</li>
                <li>Fitness enthusiasts</li>
            </ul>

            <h3>Unique Selling Points:</h3>
            <ul>
                <li>Integration with smartphone for easy tracking and monitoring</li>
                <li>Eco-friendly materials appeal to environmentally conscious buyers</li>
                <li>LED reminders provide a convenient way to ensure regular hydration</li>
                <li>Long-lasting battery life reduces the need for frequent charging</li>
            </ul>
        </section>
        "
        Do not add anything before and after the section markup tag.
        """

        write = llm.new_completion()
        write.settings["temperature"] = 0.1
        write.with_message(message=web_writer, role='system')
        write.with_message(message=user_query, role='user')
        resp = write.execute()


        return {"text": resp.text}

You can test your Web Writer Agent in the Quick test tabs. You can use the following suggestion as a test query:

{
   "messages": [
      {
         "role": "user",
         "content": "**PRODUCT:** Smart Water Bottle\n\n**Key Features:**\n1. Ability to track water intake\n2. Syncs with your smartphone\n3. LED reminders\n4. Made from eco-friendly material\n5. Long-lasting battery life\n\n**Target Audience:**\n- Health-conscious individuals\n- Tech-savvy users\n- People with busy lifestyles\n- Environmentally conscious consumers\n- Fitness enthusiasts\n\n**Unique Selling Points:**\n- Integration with smartphone for easy tracking and monitoring\n- Eco-friendly materials appeal to environmentally conscious buyers\n- LED reminders provide a convenient way to ensure regular hydration\n- Long-lasting battery life reduces the need for frequent charging"
      }
   ],
   "context": {}
}

Your result will looks like the following:

<section>
    <h2>Smart Water Bottle</h2>

    <h3>Key Features:</h3>
    <ul>
        <li>Ability to track water intake</li>
        <li>Syncs with your smartphone</li>
        <li>LED reminders</li>
        <li>Made from eco-friendly material</li>
        <li>Long-lasting battery life</li>
    </ul>

    <h3>Target Audience:</h3>
    <ul>
        <li>Health-conscious individuals</li>
        <li>Tech-savvy users</li>
        <li>People with busy lifestyles</li>
        <li>Environmentally conscious consumers</li>
        <li>Fitness enthusiasts</li>
    </ul>

    <h3>Unique Selling Points:</h3>
    <ul>
        <li>Integration with smartphone for easy tracking and monitoring</li>
        <li>Eco-friendly materials appeal to environmentally conscious buyers</li>
        <li>LED reminders provide a convenient way to ensure regular hydration</li>
        <li>Long-lasting battery life reduces the need for frequent charging</li>
    </ul>
</section>

The Query Agent#

The Query Agent will describe a product as defined in the input prompt and handle the call between the two agents. Code 3 shows how to get a handle on each agent.

Code 3: Query agent code#
import dataiku
from dataiku.llm.python import BaseLLM


class MyLLM(BaseLLM):
    def __init__(self):
        pass

    def process_stream(self, query, settings, trace):
        pass

    def process(self, query, settings, trace):
        prompt = query["messages"][0]["content"]

        project = dataiku.api_client().get_default_project()

        # call concept extractor
        EXTRACTOR_AGENT_ID = "<YOUR EXTRACTOR AGENT ID>"
        agent_extractor = project.get_llm(EXTRACTOR_AGENT_ID)

        completion = agent_extractor.new_completion()
        completion.with_message(prompt)
        resp = completion.execute()
        extractor_answer = resp.text

        # call web writer
        WEB_AGENT_ID = "<YOUR WEB WRITER AGENT ID>"
        agent_webwriter = project.get_llm(WEB_AGENT_ID)

        completion = agent_webwriter.new_completion()
        completion.with_message(extractor_answer)
        resp = completion.execute()
        webwriter_answer = resp.text

        return {"text": webwriter_answer}

This agent will first call the concept extractor agent to obtain a list of the key features, identify the potential target audience, and develop a list of selling points for this product. It will then call the web writer agent. This one will take the concept list as input and provide a piece of HTML code representing that data.

To test the whole sequence of multi agent calls, you can input the test query we used for the Concept Extractor Agent:

{
     "messages": [
        {
           "role": "user",
           "content": "Smart Water Bottle designed to help you stay hydrated throughout the day. ability to track water intake. sync with your smartphone. LED reminders. eco-friendly material. long-lasting battery life"
        }
     ],
     "context": {}
}

Your result will looks like the result from the Web Writer Agent test:

<section>
    <h2>Smart Water Bottle</h2>

    <h3>Key Features:</h3>
    <ul>
        <li>Ability to track water intake</li>
        <li>Syncs with your smartphone</li>
        <li>LED reminders</li>
        <li>Made from eco-friendly material</li>
        <li>Long-lasting battery life</li>
    </ul>

    <h3>Target Audience:</h3>
    <ul>
        <li>Health-conscious individuals</li>
        <li>Tech-savvy users</li>
        <li>People with busy lifestyles</li>
        <li>Environmentally conscious consumers</li>
        <li>Fitness enthusiasts</li>
    </ul>

    <h3>Unique Selling Points:</h3>
    <ul>
        <li>Integration with smartphone for easy tracking and monitoring</li>
        <li>Eco-friendly materials appeal to environmentally conscious buyers</li>
        <li>LED reminders provide a convenient way to ensure regular hydration</li>
        <li>Long-lasting battery life reduces the need for frequent charging</li>
    </ul>
</section>

Wrapping up#

Congratulations! You now have a sequential workflow to define a multi-agent system. Once you have well-delimited Agents and Tools, you can build different workflows to suit your needs. You may implement a system in which the queries to each agent are done in parallel and then collected and correctly assembled to answer the user’s question.

Reference documentation#

Classes#

dataikuapi.DSSClient(host[, api_key, ...])

Entry point for the DSS API client

dataikuapi.dss.project.DSSProject(client, ...)

A handle to interact with a project on the DSS instance.

dataikuapi.dss.llm.DSSLLM(client, ...)

A handle to interact with a DSS-managed LLM.

dataikuapi.dss.llm.DSSLLMCompletionQuery(llm)

A handle to interact with a completion query.

Functions#

get_default_project()

Get a handle to the current default project, if available (i.e.

get_llm(llm_id)

Get a handle to interact with a specific LLM

new_completion()

Create a new completion query.

with_message(message[, role])

Add a message to the completion query.

execute()

Run the completion query and retrieve the LLM response.