Deterministischer Workflow

Erfahren Sie, wie Sie einen deterministischen mehrstufigen Workflow mit Agents erstellen.

Beispiel für mehrstufigen Workflow

In diesem Beispiel wird gezeigt, wie Sie einen deterministischen Workflow mit agentenbezogenen Schritten erstellen, indem Sie einen nativen Kontrollfluss und ein Agent-Framework "Reasoning and Acting" (ReAct) kombinieren.

Im Gegensatz zu vollständig autonomen Agent-Workflows gibt Ihnen ein deterministischer Workflow die Kontrolle über die Abfolge von Schritten, während Sie die Leistungsfähigkeit von Agents für bestimmte Aufgaben nutzen.

Python

mehrstufig-workflow.py

from oci.addons.adk import Agent, AgentClient
from custom_functon_tools import ResearcherToolkit, WriterToolkit

"""
This examples shows how you can build "deterministically orchestrated workflows with agentic steps".
"""

# Your (existing) vanilla python code to be integrated into this agentic workflow
def get_user_preferences():
    # Simulate result you fetched from a DB
    return {
        "email": "your@email.com",
        "style": ["casual", "humorous"],
        "topics": ["ai"]
    }

def main():

    client = AgentClient(
        auth_type="api_key",
        profile="DEFAULT",
        region="us-chicago-1"
    )

    researcher = Agent(
        client=client,
        agent_endpoint_id="ocid1.genaiagentendpoint...",
        name="Researcher",
        instructions="You are a researcher. You research trending keywords based on the user preferences.",
        tools=[ResearcherToolkit()]
    )

    writer = Agent(
        client=client,
        agent_endpoint_id="ocid1.genaiagentendpoint...",
        name="Writer",
        instructions="You are a writer. You write a blog post based on the trending keywords and the user preferences.",
        tools=[WriterToolkit()]
    )

    researcher.setup()
    writer.setup()

    # Step 1: Fetch user preferences or any pre-processing information. (non-agentic step)
    user_preferences = get_user_preferences()

    # Step 2: Research trending keywords using outputs from the previous steps as input. (agentic step)
    topics = user_preferences['topics']
    researcher_prompt = f"Research trending keywords for the following topics: {topics}"
    last_run_response = researcher.run(researcher_prompt)

    # Step 3: Write a blog post using outputs from last two steps as input. (agentic step) 
    keywords = last_run_response.output
    style = user_preferences['style']
    email = user_preferences['email']
    writer_prompt = f"Write a 5 sentences blog post and email it to {email}. Use style: {style}. Blog post should be based on: {keywords}."
    last_run_response = writer.run(writer_prompt)

    # Step 4: Do whatever you want with the last step output. Here we just print it.
    last_run_response.pretty_print()

if __name__ == "__main__":
    main()

Java

AgenticWorkflowDemo.java


package demos.determinsticWorkflow;

import com.oracle.bmc.ConfigFileReader;
import com.oracle.bmc.adk.client.AgentClient;
import com.oracle.bmc.adk.run.RunResponse;
import com.oracle.bmc.auth.BasicAuthenticationDetailsProvider;
import com.oracle.bmc.auth.SessionTokenAuthenticationDetailsProvider;
import com.oracle.bmc.adk.agent.Agent;
import com.oracle.bmc.adk.agent.RunOptions;
import com.oracle.bmc.adk.examples.determinsticWorkflow.tools.ResearcherToolkit;
import com.oracle.bmc.adk.examples.determinsticWorkflow.tools.WriterToolkit;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AgenticWorkflowDemo {

  public static void main(String[] args) throws IOException {
    // Configuration parameters
    final String configLocation = "~/.oci/config";
    final String configProfile = "DEFAULT";
    final String researchAgentEndpointId =
        "ocid1.genaiagentendpoint...";
    final String writerAgentEndpointId =
        "ocid1.genaiagentendpoint...";

    // Initialize AgentClient
    BasicAuthenticationDetailsProvider authProvider =
            new SessionTokenAuthenticationDetailsProvider(
                    ConfigFileReader.parse(configLocation, configProfile));

    AgentClient client =
            AgentClient.builder()
                    .authProvider(authProvider)
                    .region("us-chicago-1")
                    .build();

    // Create researcher agent with its toolkit
    Agent researcher = Agent.builder()
            .client(client)
            .agentEndpointId(researchAgentEndpointId)
            .instructions(
                "You are a researcher. You research trending keywords based on the user preferences.")
            .tools(Arrays.asList(new ResearcherToolkit()))
            .name("Researcher")
            .build();

    // Create writer agent with its toolkit
    Agent writer = Agent.builder()
            .client(client)
            .agentEndpointId(writerAgentEndpointId)
            .instructions(
                "You are a writer. You write a blog post based on the trending keywords and the user preferences.")
            .tools(Arrays.asList(new WriterToolkit()))
            .name("Writer")
            .build();

    // Set up both agents
    researcher.setup();
    writer.setup();

    // Step 1: fetch user preferences (a non-agentic step)
    Map<String, Object> userPreferences = getUserPreferences();

    // Step 2: research trending keywords (agentic step)
    List<String> topics = (List<String>) userPreferences.get("topics");
    String researcherPrompt = "Research trending keywords for the following topics: " + topics;
    final Integer maxSteps = 3;
    RunOptions runOptions = RunOptions.builder().maxSteps(maxSteps).build();
    RunResponse researcherResponse = researcher.run(researcherPrompt, runOptions);
    String keywords = researcherResponse.getOutput();

    // Step 3: write a blog post (agentic step)
    List<String> style = (List<String>) userPreferences.get("style");
    String email = (String) userPreferences.get("delivery_email");
    String writerPrompt =
        "Write a 5 sentences blog post and email it to "
            + email
            + ". Use style: "
            + style
            + ". Blog post should be based on: "
            + keywords;
    RunResponse writerResponse = writer.run(writerPrompt, runOptions);

    // Step 4: print the final output
    writerResponse.prettyPrint();
  }

  // Simulate fetching user preferences (for example, from a database)
  private static Map<String, Object> getUserPreferences() {
    Map<String, Object> preferences = new HashMap<>();
    preferences.put("delivery_email", "j.jing.y.yang@oracle.com");
    preferences.put("style", Arrays.asList("casual", "humorous"));
    preferences.put("topics", Arrays.asList("ai"));
    return preferences;
  }
}

Benutzerdefinierte Funktionstools

In diesem Beispiel werden benutzerdefinierte Toolkits für Forscher und Writer-Agents verwendet. Hier ist eine vereinfachte Version, wie diese aussehen könnten:

Python

custom_functon_tools.py

from typing import Dict, List
from oci.addons.adk import tool, Toolkit

@tool
def get_trending_keywords(topic: str) -> Dict[str, List[str]]:
    """Get trending keywords for a given topic"""
    # In a real implementation, this might call an API or database.
    if topic == "ai":
        return {"topic": topic, "keywords": ["generative AI", "multi-agent systems", "LLM agents"]}
    return {"topic": topic, "keywords": ["unknown"]}

@tool
def send_email(recipient: str, subject: str, body: str) -> str:
    """Send an email with the given subject and body to the recipient"""
    # In a real implementation, this would send an actual email.
    print(f"Sending email to {recipient}")
    print(f"Subject: {subject}")
    print(f"Body: {body}")
    return "Email sent successfully"

class ResearcherToolkit(Toolkit):
    """Toolkit for researching trending topics"""

    def __init__(self):
        super().__init__(name="ResearcherToolkit", description="Tools for researching trending topics")
        self.add_tool(get_trending_keywords)

class WriterToolkit(Toolkit):
    """Toolkit for writing content and sending emails"""

    def __init__(self):
        super().__init__(name="WriterToolkit", description="Tools for writing content and sending emails")
        self.add_tool(send_email)

Java

MultiAgentTools.java

package demos.tools;

import com.oracle.bmc.adk.tools.Param;
import com.oracle.bmc.adk.tools.Tool;
import com.oracle.bmc.adk.tools.Toolkit;

public class MultiAgentTools extends Toolkit {
  @Tool(name = "get_trending_keywords", description = "Get the trending keywords for a given topic")
  public static String getTrendingKeywords(
      @Param(description = "The topic to get trending keywords for") String topic) {
    return "{\"topic\": \"" + topic + "\", \"keywords\": [\"agent\", \"stargate\", \"openai\"]}";
  }

  @Tool(name = "send_email", description = "Send an email to a recipient")
  public static String sendEmail(
      @Param(description = "The recipient email address") String recipient,
      @Param(description = "The email subject") String subject,
      @Param(description = "The email body content") String body) {
    System.out.println(
        "Sending email to " + recipient + " with subject " + subject + " and body " + body);
    return "Sent!";
  }

}

Wann dieses Muster verwendet wird

Dieses Muster ist besonders nützlich, wenn:

  • Sie benötigen eine vorhersehbare, wiederholbare Ausführung.
  • Teile Ihres Workflows hängen von vorhandenen Systemen oder Datenbanken ab.
  • Sie müssen genau steuern, wann und wie Agents aufgerufen werden.
  • Geschäftslogik erfordert bestimmte Sequenzen, die nicht der Entscheidungsfindung von Agents überlassen werden sollten.