Skip to content

Commit

Permalink
Merge branch 'microsoft:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ttthree authored Sep 14, 2023
2 parents adedf52 + 2afc0cc commit 2d2b5b2
Show file tree
Hide file tree
Showing 35 changed files with 783 additions and 101 deletions.
313 changes: 313 additions & 0 deletions docs/how-to-guides/develop-a-flow/develop-standard-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
# Develop standard flow

:::{admonition} Experimental feature
This is an experimental feature, and may change at any time. Learn [more](../faq.md#stable-vs-experimental).
:::

From this document, you can learn how to develop a standard flow by writing a flow yaml from scratch. You can
find additional information about flow yaml schema in [Flow YAML Schema](../../reference/flow-yaml-schema-reference.md).

## Flow input data
The flow input data is the data that you want to process in your flow.
::::{tab-set}
:::{tab-item} CLI
:sync: CLI
You can add a flow input in inputs section of flow yaml.
```yaml
inputs:
url:
type: string
default: https://www.microsoft.com/en-us/d/xbox-wireless-controller-stellar-shift-special-edition/94fbjc7h0h6h
```
:::
:::{tab-item} VS Code Extension
:sync: VS Code Extension
When unfolding Inputs section in the authoring page, you can set and view your flow inputs, including input schema (name and type),
and the input value.
![flow_input](../../media/how-to-guides/develop-standard-flow/flow_input.png)
:::
::::
For Web Classification sample as shown the screenshot above, the flow input is a url of string type. We also support
the input type of `int`, `bool`, `double`, `list` and `object`.

## Develop the flow using different tools
In one flow, you can consume different kinds of tools. We now support built-in tool like
[LLM](../../reference/tools-reference/llm-tool.md), [Python](../../reference/tools-reference/python-tool.md) and
[Prompt](../../reference/tools-reference/prompt-tool.md) and
third-party tool like [Serp API](../../reference/tools-reference/serp-api-tool.md),
[Vector Search](../../reference/tools-reference/vector_db_lookup_tool.md), etc.

### Add tool as your need
::::{tab-set}
:::{tab-item} CLI
:sync: CLI
You can add a tool node in nodes section of flow yaml. For example, yaml below shows how to add a Python tool node in the flow.

```yaml
nodes:
- name: fetch_text_content_from_url
type: python
source:
type: code
path: fetch_text_content_from_url.py
inputs:
url: ${inputs.url}
```
:::

:::{tab-item} VS Code Extension
:sync: VS Code Extension
By selecting the tool card on the very top, you'll add a new tool node to flow.

![add_tool](../../media/how-to-guides/develop-standard-flow/add_tool.png)
:::

::::

### Edit tool
::::{tab-set}
:::{tab-item} CLI
:sync: CLI
You can edit the tool by simply opening the source file and making edits. For example, we provide a simple Python tool code below.

```python
from promptflow import tool
# The inputs section will change based on the arguments of the tool function, after you save the code
# Adding type to arguments and return value will help the system show the types properly
# Please update the function name/signature per need
@tool
def my_python_tool(input1: str) -> str:
return 'hello ' + input1
```

We also provide an LLM tool prompt below.

```jinja
Please summarize the following text in one paragraph. 100 words.
Do not add any information that is not in the text.
Text: {{text}}
Summary:
```
:::

:::{tab-item} VS Code Extension
:sync: VS Code Extension
When a new tool node is added to flow, it will be appended at the bottom of flatten view with a random name by default.
At the top of each tool node card, there's a toolbar for adjusting the tool node. You can move it up or down, you can delete or rename it too.
For a python tool node, you can edit the tool code by clicking the code file. For a LLM tool node, you can edit the
tool prompt by clicking the prompt file and adjust input parameters like connection, api and etc.
![edit_tool](../../media/how-to-guides/develop-standard-flow/edit_tool.png)
:::

::::

### Create connection
Please refer to the [Create necessary connections](../quick-start.md#create-necessary-connections) for details.

## Chain your flow - link nodes together
Before linking nodes together, you need to define and expose an interface.

### Define LLM node interface
LLM node has only one output, the completion given by LLM provider.

As for inputs, we offer a templating strategy that can help you create parametric prompts that accept different input
values. Instead of fixed text, enclose your input name in `{{}}`, so it can be replaced on the fly. We use Jinja as our
templating language. For example:

```jinja
Your task is to classify a given url into one of the following types:
Movie, App, Academic, Channel, Profile, PDF or None based on the text content information.
The classification will be based on the url, the webpage text content summary, or both.
Here are a few examples:
{% for ex in examples %}
URL: {{ex.url}}
Text content: {{ex.text_content}}
OUTPUT:
{"category": "{{ex.category}}", "evidence": "{{ex.evidence}}"}
{% endfor %}
For a given URL : {{url}}, and text content: {{text_content}}.
Classify above url to complete the category and indicate evidence.
OUTPUT:
```

### Define Python node interface
Python node might have multiple inputs and outputs. Define inputs and outputs as shown below.
If you have multiple outputs, remember to make it a dictionary so that the downstream node can call each key separately.
For example:

```python
import json
from promptflow import tool
@tool
def convert_to_dict(input_str: str, input_str2: str) -> dict:
try:
print(input_str2)
return json.loads(input_str)
except Exception as e:
print("input is not valid, error: {}".format(e))
return {"category": "None", "evidence": "None"}
```

### Link nodes together
After the interface is defined, you can use:

- ${inputs.key} to link with flow input.
- ${upstream_node_name.output} to link with single-output upstream node.
- ${upstream_node_name.output.key} to link with multi-output upstream node.

Below are common scenarios for linking nodes together.

### Scenario 1 - Link LLM node with flow input and single-output upstream node
After you add a new LLM node and edit the prompt file like [Define LLM node interface](#define-llm-node-interface),
three inputs called `url`, `examples` and `text_content` are created in inputs section.

::::{tab-set}
:::{tab-item} CLI
:sync: CLI
You can link the LLM node input with flow input by `${inputs.url}`.
And you can link `examples` to the upstream `prepare_examples` node and `text_content` to the `summarize_text_content` node
by `${prepare_examples.output}` and `${summarize_text_content.output}`.
```yaml
- name: classify_with_llm
type: llm
source:
type: code
path: classify_with_llm.jinja2
inputs:
deployment_name: text-davinci-003
suffix: ""
max_tokens: 128
temperature: 0.2
top_p: 1
echo: false
presence_penalty: 0
frequency_penalty: 0
best_of: 1
url: ${inputs.url} # Link with flow input
examples: ${prepare_examples.output} # Link LLM node with single-output upstream node
text_content: ${summarize_text_content.output} # Link LLM node with single-output upstream node
```
:::

:::{tab-item} VS Code Extension
:sync: VS Code Extension
In the value drop-down, select `${inputs.url}`, `${prepare_examples.output}` and `${summarize_text_content.output}`, then
you'll see in the graph view that the newly created LLM node is linked to the flow input, upstream `prepare_examples` and `summarize_text_content` node.

![link_llm_with_flow_input_single_output_node](../../media/how-to-guides/develop-standard-flow/link_llm_with_flow_input_single_output_node.png)
:::

::::
When running the flow, the `url` input of the node will be replaced by flow input on the fly, and the `examples` and
`text_content` input of the node will be replaced by `prepare_examples` and `summarize_text_content` node output on the fly.

### Scenario 2 - Link LLM node with multi-output upstream node
Suppose we want to link the newly created LLM node with `covert_to_dict` Python node whose output is a dictionary with two keys: `category` and `evidence`.
::::{tab-set}
:::{tab-item} CLI
:sync: CLI
You can link `examples` to the `evidence` output of upstream `covert_to_dict` node by `${convert_to_dict.output.evidence}` like below:
```yaml
- name: classify_with_llm
type: llm
source:
type: code
path: classify_with_llm.jinja2
inputs:
deployment_name: text-davinci-003
suffix: ""
max_tokens: 128
temperature: 0.2
top_p: 1
echo: false
presence_penalty: 0
frequency_penalty: 0
best_of: 1
text_content: ${convert_to_dict.output.evidence} # Link LLM node with multi-output upstream node
```
:::

:::{tab-item} VS Code Extension
:sync: VS Code Extension
In the value drop-down, select `${convert_to_dict.output}`, then manually append `evidence`, then you'll see in the graph
view that the newly created LLM node is linked to the upstream `convert_to_dict node`.

![link_llm_with_multi_output_node](../../media/how-to-guides/develop-standard-flow/link_llm_with_multi_output_node.png)
:::
::::
When running the flow, the `text_content` input of the node will be replaced by `evidence` value from `convert_to_dict node` output dictionary on the fly.

### Scenario 3 - Link Python node with upstream node/flow input
After you add a new Python node and edit the code file like [Define Python node interface](#define-python-node-interface)],
two inputs called `input_str` and `input_str2` are created in inputs section. The linkage is the same as LLM node,
using `${flow.input_name}` to link with flow input or `${upstream_node_name.output}` to link with upstream node.

::::{tab-set}
:::{tab-item} CLI
:sync: CLI
```yaml
- name: prepare_examples
type: python
source:
type: code
path: prepare_examples.py
inputs:
input_str: ${inputs.url} # Link Python node with flow input
input_str2: ${fetch_text_content_from_url.output} # Link Python node with single-output upstream node
```
:::

:::{tab-item} VS Code Extension
:sync: VS Code Extension

![link_python_with_flow_node_input](../../media/how-to-guides/develop-standard-flow/link_python_with_flow_node_input.png)
:::

::::
When running the flow, the `input_str` input of the node will be replaced by flow input on the fly and the `input_str2`
input of the node will be replaced by `fetch_text_content_from_url` node output dictionary on the fly.

## Set flow output
When the flow is complicated, instead of checking outputs on each node, you can set flow output and check outputs of
multiple nodes in one place. Moreover, flow output helps:

- Check bulk test results in one single table.
- Define evaluation interface mapping.
- Set deployment response schema.

::::{tab-set}
:::{tab-item} CLI
:sync: CLI
You can add flow outputs in outputs section of flow yaml . The linkage is the same as LLM node,
using `${convert_to_dict.output.category}` to link `category` flow output with with `category` value of upstream node
`convert_to_dict`.

```yaml
outputs:
category:
type: string
reference: ${convert_to_dict.output.category}
evidence:
type: string
reference: ${convert_to_dict.output.evidence}
```
:::

:::{tab-item} VS Code Extension
:sync: VS Code Extension
First define flow output schema, then select in drop-down the node whose output you want to set as flow output.
Since `convert_to_dict` has a dictionary output with two keys: `category` and `evidence`, you need to manually append
`category` and `evidence` to each. Then run flow, after a while, you can check flow output in a table.

![flow_output](../../media/how-to-guides/develop-standard-flow/flow_output.png)
:::

::::
9 changes: 9 additions & 0 deletions docs/how-to-guides/develop-a-flow/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Develop a flow
We provide guides on how to develop a flow by writing a flow yaml from scratch in this section.

```{toctree}
:maxdepth: 1
:hidden:
develop-standard-flow
```
1 change: 1 addition & 0 deletions docs/how-to-guides/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Simple and short articles grouped by topics, each introduces a core feature of p
```{toctree}
:maxdepth: 1
develop-a-flow/index
init-and-test-a-flow
run-and-evaluate-a-flow
tune-prompts-with-variants
Expand Down
2 changes: 2 additions & 0 deletions docs/how-to-guides/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ inputs:
default: https://play.google.com/store/apps/details?id=com.twitter.android
...
```
See more details of this topic in [Develop a flow](./develop-a-flow/index.md).

### Create necessary connections

Expand Down Expand Up @@ -283,6 +284,7 @@ See more details of this topic in [Initialize and test a flow](./init-and-test-a
## Next steps

Learn more on how to:
- [Develop a flow](./develop-a-flow/index.md): details on how to develop a flow by writing a flow yaml from scratch.
- [Initialize and test a flow](./init-and-test-a-flow.md): details on how develop a flow from scratch or existing code.
- [Run and evaluate a flow](./run-and-evaluate-a-flow.md): run and evaluate the flow using multi line data file.
- [Deploy a flow](./deploy-a-flow/index.md): how to deploy the flow as a web app.
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ This documentation site contains guides for prompt flow [sdk, cli](https://pypi.
- header: "📒 How-to Guides"
content: "
Articles guide user to complete a specific task in prompt flow.<br/><br/>
- [Develop a flow](how-to-guides/develop-a-flow/index.md)<br/>
- [Initialize and test a flow](how-to-guides/init-and-test-a-flow.md)<br/>
- [Run and evaluate a flow](how-to-guides/run-and-evaluate-a-flow.md)<br/>
- [Tune prompts using variants](how-to-guides/tune-prompts-with-variants.md)<br/>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2d2b5b2

Please sign in to comment.