Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process Execution ADR #8925

Open
wants to merge 5 commits into
base: feature-processes
Choose a base branch
from

Conversation

alliscode
Copy link
Member

Description

ADR for Semantic Kernel Process feature.

Contribution Checklist

- Processes should be able to support short lived transient business processes as well as long lived business processes.
- Processes should be able to be run locally, deployed as a single process or or deployed to a distributed service.
- Processes should be able to run and debug locally without additional software or infrastructure.
- Processes should be stateful and able resume from a paused state or a recoverable error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Processes should be stateful and able resume from a paused state or a recoverable error.
- Processes should be stateful and able to resume from a paused state or a recoverable error.

Copy link
Contributor

@moonbox3 moonbox3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work on this!

### Options #1:

**_Build existing samples on top of existing workflow frameworks_**:
This option was explored with frameworks such as Dapr Workflows, Argo, Durable Tasks, and others. Among the subset or these options that can support the technical requirements listed above, the main concern is the amount of overhead required to work with them. Many of these frameworks require a lot of code and infrastructure to get up and running and require special emulators to run locally which is undesirable. It's important to call out that this option is not mutually exclusive with the others, we may choose to build samples showing SK integrating with other workflow engines even if we choose to also go a different route.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This option was explored with frameworks such as Dapr Workflows, Argo, Durable Tasks, and others. Among the subset or these options that can support the technical requirements listed above, the main concern is the amount of overhead required to work with them. Many of these frameworks require a lot of code and infrastructure to get up and running and require special emulators to run locally which is undesirable. It's important to call out that this option is not mutually exclusive with the others, we may choose to build samples showing SK integrating with other workflow engines even if we choose to also go a different route.
This option was explored with frameworks such as Dapr Workflows, Argo, Durable Tasks, and others. Among the subset of these options that can support the technical requirements listed above, the main concern is the amount of overhead required to work with them. Many of these frameworks require a lot of code and infrastructure to get up and running and require special emulators to run locally which is undesirable. It's important to call out that this option is not mutually exclusive with the others, we may choose to build samples showing SK integrating with other workflow engines even if we choose to also go a different route.

## Decision Outcome

**_Chosen option - #4_**: Build platform agnostic SK Process library with connectors for existing workflow frameworks.
This was the only option that was ale to meet all the technical and scenario driven requirements. This option should allow for a simple and well-integrated interface into Semantic Kernel as well as the ability to support many existing distributed runtimes that will give our customers the flexibility to use their existing infrastructure and expertise.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This was the only option that was ale to meet all the technical and scenario driven requirements. This option should allow for a simple and well-integrated interface into Semantic Kernel as well as the ability to support many existing distributed runtimes that will give our customers the flexibility to use their existing infrastructure and expertise.
This was the only option that was able to meet all the technical and scenario driven requirements. This option should allow for a simple and well-integrated interface into Semantic Kernel as well as the ability to support many existing distributed runtimes that will give our customers the flexibility to use their existing infrastructure and expertise.

Starting from the ground up, the components of a processes are:

1. **_KernelFunctions_**: The same KernelFunctions that our customers already know and use. Nothing new here.
1. **_Steps_**: Steps group one ore more KernelFunctions together into an object with optional user defined state. A step represents one unit of work within a process. Steps make the output of their work visible to other steps in the process by emitting events. This event based structure allows steps to be created without needing to know which process they are used in, allowing them to be reusable across multiple processes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. **_Steps_**: Steps group one ore more KernelFunctions together into an object with optional user defined state. A step represents one unit of work within a process. Steps make the output of their work visible to other steps in the process by emitting events. This event based structure allows steps to be created without needing to know which process they are used in, allowing them to be reusable across multiple processes.
1. **_Steps_**: Steps group one or more KernelFunctions together into an object with optional user defined state. A step represents one unit of work within a process. Steps make the output of their work visible to other steps in the process by emitting events. This event based structure allows steps to be created without needing to know which process they are used in, allowing them to be reusable across multiple processes.

Starting from the ground up, the components of a processes are:

1. **_KernelFunctions_**: The same KernelFunctions that our customers already know and use. Nothing new here.
1. **_Steps_**: Steps group one ore more KernelFunctions together into an object with optional user defined state. A step represents one unit of work within a process. Steps make the output of their work visible to other steps in the process by emitting events. This event based structure allows steps to be created without needing to know which process they are used in, allowing them to be reusable across multiple processes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we highlight that inputs and outputs of steps are strongly typed, thereby ensuring type safety across different processes?

Something like:

"Steps group one or more strongly-typed KernelFunctions together into an object with optional user-defined state, ensuring that inputs and outputs are type-safe. A step represents one unit of work..."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about non-deterministic data (ai generated) that comes as input of a step?
Maybe it would be worth adding a validator of some kind that verifies that the data is compliant with the "business rules"?

Ie, checking that the:

  • text generated has the intended meaning and purpose and does not include jailbreaking intents.
  • json generated has the intended structure, proper data...
  • validate strongly typed inputs

Maybe implement a middleware pattern where we have some custom implemented validator middleware implemented ready to use classes - and is extensible, ideally (love extensibility, sorry about that...)


A key thing to notice is that the event emitted by the `ChatBotResponseStep` within the processes was also be emitted from the processes itself which allows us to register a handler for it. All events within a process will bubble up out of the process to the parent which may be the program running the process or may be another process. This pattern allows for nested processes where an existing process can be used as a step in another process.

#### Step 4 - Process object model:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a requirement that processes should be transferable between SK languages?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO as a developer I will use a single language and stick to it... homogeneity is crucial... other thing is that the in-memory construct and the set of instructions match in all languages, then theoretically it could be ported or have a compatibility layer...

Just thinking loud without having seen the internals, so might be talking nonsense :P

@joslat
Copy link
Contributor

joslat commented Sep 20, 2024

This is simply awesome!

I would highlight the composability of the Process and Step.
I would suggest enabling that a Process could be used or wrapped as a step, enabling "templating" or simplifying a graph and editing "component" steps like reusable lego pieces.
I would add :

  • Processes and Steps should be resilient and if they fail, should be able to recover and if they cannot be recovered be able to be re-started from the begining. (bulkhead pattern)

I also understand that inside a Step we can put code, API, Agents or human in the loop too... would be great to see this in the ADR.

And yes, a designer, having this as a graph with this composability means we can get a graph representation, validate the graph, identify any possible issue... and design the agentic workflow with agents, steps, processes in VS Code and Visual Studio... that would be a dream come true :)

Again, fantastic work!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants