Guide 05 rebuilt in English: transcription tool with English recording and screenshots
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@@ -2,7 +2,7 @@
|
||||
FOR THE EDITOR
|
||||
|
||||
Guide 5: transcription tool, from recording to minutes. Screenshots in screenshots/, captured on
|
||||
20 September 2026 (Dify cloud, Dutch build of the same app, with the Dutch test recording).
|
||||
20 and 21 September 2026 (Dify cloud, English interface, English test recording).
|
||||
|
||||
Convert to HTML, PDF and Word: python3 build.py
|
||||
(python-markdown, google-chrome and libreoffice; layout and logo in _tools/build_guide.py)
|
||||
@@ -17,20 +17,23 @@ Formatting conventions (see also README.md):
|
||||
Files in this folder:
|
||||
department-meeting-script.txt the fictional meeting (about 500 words), in English
|
||||
make_recording.py turns the script into an mp3 with computer voices (needs OPENAI_API_KEY)
|
||||
sample-meeting-dutch-small.mp3 the Dutch recording used in the screenshots (32 kbps mono, 707 kB), works as a test file
|
||||
Published example app (Dutch): https://udify.app/workflow/7N5dNg8fD9qXHA80
|
||||
department-meeting.mp3 the English recording (tts-1, alloy, 128 kbps, 2.7 MB): too big for the tool, used for the error in step 6
|
||||
department-meeting-small.mp3 the same recording at 32 kbps mono (668 kB): the test file
|
||||
sample-meeting-dutch-small.mp3 the Dutch recording from the Dutch edition (32 kbps mono, 707 kB), works as a second test file
|
||||
Published example app: https://udify.app/workflow/EPAc3PPeD3E4764l
|
||||
DSL export: transcription-tool.dify.yml
|
||||
-->
|
||||
|
||||
# Building in Dify: from recording to minutes
|
||||
|
||||
**Guide 5 for the AI Agents workshop**
|
||||
LeX Consultancy B.V. · 20 September 2026
|
||||
LeX Consultancy B.V. · 21 September 2026
|
||||
|
||||
You build a workflow that turns an audio recording of a meeting into text and writes minutes from it: a summary, decisions, action points with owner and date, and what was deferred. At the end you have a web address where a colleague uploads an mp3 and gets the minutes and the full transcript back within two minutes.
|
||||
|
||||
Compared with guides 1 and 3 two things are new: a **file as input** instead of text, and a **tool node** (Speech To Text) instead of only LLM nodes. The rest you know.
|
||||
|
||||
This guide follows the cloud version of Dify as it looked on 20 September 2026. Dify changes fast: if your screen differs, follow what you see, not what is written here. The screenshots show the Dutch build of this app, tested with a Dutch recording; the screens and clicks are the same.
|
||||
This guide follows the cloud version of Dify as it looked on 21 September 2026. Dify changes fast: if your screen differs, follow what you see, not what is written here.
|
||||
|
||||
**How to read this guide**
|
||||
|
||||
@@ -87,7 +90,7 @@ In short: what you build here is a working prototype to learn how it works. The
|
||||
## Preparation
|
||||
|
||||
- A Dify account with your own OpenAI key, set to **Usage priority: API key** (Integrations → Model Provider → OpenAI → Config). Without your own key the Speech To Text tool does not work: Dify's free credits only cover text models.
|
||||
- A test recording. Two options: run `make_recording.py` in the folder of this guide with your OpenAI key (it reads the English script `department-meeting-script.txt` with a computer voice and produces `department-meeting-small.mp3`), or use `sample-meeting-dutch-small.mp3`, the Dutch recording from the screenshots; the tool transcribes Dutch just as well and the minutes come out in the language of your prompt.
|
||||
- A test recording: `department-meeting-small.mp3` from the folder of this guide, the fictional English department meeting read by a computer voice (2 min 47 s, 668 kB). It was made with the Text To Speech tool in Dify, see appendix A; `make_recording.py` does the same from the command line with your own OpenAI key. `sample-meeting-dutch-small.mp3` is the Dutch version; the tool transcribes Dutch just as well and the minutes come out in the language of your prompt.
|
||||
- Cost per run through your own key: transcription about 2 cents, minutes less than 1 cent.
|
||||
|
||||
---
|
||||
@@ -115,9 +118,7 @@ In short: what you build here is a working prototype to learn how it works. The
|
||||
|
||||

|
||||
|
||||
3. Open **Field Type**. You see the kinds of fields.
|
||||
|
||||

|
||||
3. Open **Field Type**. You see the kinds of fields: Short Text, Paragraph, Select, Number, Checkbox, and at the bottom **Single File** and **File List**.
|
||||
|
||||
4. Choose **Single File**. The window gets longer: file types appear.
|
||||
|
||||
@@ -134,11 +135,11 @@ In short: what you build here is a working prototype to learn how it works. The
|
||||
|
||||
> Image is on by default. Switch it off, otherwise someone can upload a photo later and the workflow gets stuck at the transcription step.
|
||||
|
||||

|
||||

|
||||
|
||||
6. Click **Save**.
|
||||
|
||||

|
||||

|
||||
|
||||
## Step 3. Add the transcription step
|
||||
|
||||
@@ -155,7 +156,7 @@ This is the new building block: not an LLM node but a **tool**. Dify has a built
|
||||
|
||||
4. Choose **Speech To Text**.
|
||||
|
||||

|
||||

|
||||
|
||||
5. Under **Audio File** click **Set variable** and choose the variable **recording** under USER INPUT.
|
||||
|
||||
@@ -163,17 +164,17 @@ This is the new building block: not an LLM node but a **tool**. Dify has a built
|
||||
|
||||
6. Under **Model** click the drop-down. You see the speech models available through your key.
|
||||
|
||||

|
||||

|
||||
|
||||
7. Choose **gpt-4o-transcribe-diarize**. "Diarize" means the model separates speakers; that helps with a meeting. If you want cheaper, choose **whisper-1**.
|
||||
|
||||

|
||||

|
||||
|
||||
## Step 4. Add the minutes step
|
||||
|
||||
1. Click **SELECT NEXT STEP** and under **Nodes** choose the **LLM** node.
|
||||
|
||||

|
||||

|
||||
|
||||
2. Click the model name **gpt-5** and choose **gpt-5-mini**.
|
||||
3. Click in the **SYSTEM** field and type the instruction.
|
||||
@@ -207,12 +208,12 @@ Transcript:
|
||||
|
||||
4. Right after "Transcript:" type a forward slash `/`. At the top of the list is now **SPEECH TO TEXT** with the variable **text**.
|
||||
|
||||

|
||||

|
||||
|
||||
5. Choose **text** under SPEECH TO TEXT.
|
||||
6. Click the name **LLM** at the top of the panel, replace it with `Minutes` and press Enter.
|
||||
|
||||

|
||||

|
||||
|
||||
> **Your choice: the structure of the minutes.** The headings in the prompt are the structure a department meeting often has. A staff council meeting may want "Advice and consent", a team day wants "Agreements" and "Parking lot", a student review wants a block per student (but that is the scenario that needs an impact assessment first). Change only the headings and their explanation; keep the rules above them (speech recognition errors, invent nothing). Want two versions, for example full minutes and a five-line message for the team? Add a second LLM node with the same variable **text** as input.
|
||||
|
||||
@@ -222,7 +223,7 @@ Transcript:
|
||||
|
||||
1. Click **SELECT NEXT STEP** and choose **Output**.
|
||||
|
||||

|
||||

|
||||
|
||||
2. Click the plus sign next to **OUTPUT VARIABLE** and create two variables.
|
||||
|
||||
@@ -231,25 +232,25 @@ Transcript:
|
||||
| `minutes` | Minutes / text |
|
||||
| `transcript` | Speech To Text / text |
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
3. Close the panel and press Ctrl+1. You see the whole workflow: four nodes.
|
||||
|
||||

|
||||

|
||||
|
||||
## Step 6. Test with the recording
|
||||
|
||||
1. Click **Test Run** at the top right.
|
||||
|
||||

|
||||

|
||||
|
||||
2. Click **Local upload** and choose your small test recording (`department-meeting-small.mp3` or `sample-meeting-dutch-small.mp3`).
|
||||
2. Click **Local upload** and choose your small test recording (`department-meeting-small.mp3`).
|
||||
|
||||
> Use the file with "small" in its name. A recording at 128 kbps is about 2.8 MB for three minutes and that is too big: the tool sends audio as text (base64) to the provider, which doubles the size, and the limit is 5 MB. You then get the error below.
|
||||
> Use the file with "small" in its name. The full recording `department-meeting.mp3` at 128 kbps is 2.7 MB for less than three minutes and that is too big: the tool sends audio as text (base64) to the provider, which doubles the size, and the limit is 5 MB (payload 5,344,460 bytes against a maximum of 5,242,880 in our test). You then get the error below.
|
||||
|
||||

|
||||

|
||||
|
||||
Rule of thumb: **3 MB per recording**. Half an hour of meeting only fits if you shrink the recording first: mono, 16 kHz, 32 kbps gives about 250 kB per minute. Any audio program can do that, or ffmpeg:
|
||||
|
||||
@@ -257,37 +258,33 @@ Rule of thumb: **3 MB per recording**. Half an hour of meeting only fits if you
|
||||
ffmpeg -i recording.m4a -ac 1 -ar 16000 -b:a 32k recording-small.mp3
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
3. Click **Start Run**. Transcribing three minutes of audio takes about a minute.
|
||||
3. Click **Start Run**. Transcribing three minutes of audio takes about a minute and a quarter; the minutes take another 45 seconds.
|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
4. Read the result under **RESULT**.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Check against the script (`department-meeting-script.txt`) whether it is right. In our test: two decisions found, five action points with the right owners and dates, the reading scheme under "Deferred" with the reason, and the coffee machine neatly left out.
|
||||
Check against the script (`department-meeting-script.txt`) whether it is right. In our test: the combined test and the deferral found, the action points with the right owners and dates (the publishers' email without a date, which the model marks "not mentioned"), the reading scheme under "Deferred" with the reason. Two things to notice. The model listed five "decisions" where the meeting took two; the open day roster and the coffee machine are not decisions. And the coffee machine, which the prompt says to leave out, appeared as an action point "not mentioned, not mentioned". A second run through the webapp (step 7) left it out. The prompt rule works most of the time, not always; the question marks and the "not mentioned" cells are the model saying "check this".
|
||||
|
||||
### Recognising speakers: what the model does and does not do
|
||||
|
||||
The model is called gpt-4o-transcribe-**diarize**, and "diarisation" is telling speakers apart. To see what that gives you in Dify, we ran the same script read by three different computer voices (`make_recording.py --three`).
|
||||
The model is called gpt-4o-transcribe-**diarize**, and "diarisation" is telling speakers apart. To see what that gives you in Dify, look at what the tool returns.
|
||||
|
||||
5. Run the workflow once more with a three-voice recording.
|
||||
5. In the test panel click the **TRACING** tab and expand **SPEECH TO TEXT**. Under OUTPUT is what the tool returns: one field `text`. Our recording has one voice for all three speakers, and still the text is split into paragraphs at the turns; with a recording of three different voices (`make_recording.py --three` makes one) there is a line break wherever another voice starts.
|
||||
|
||||

|
||||
|
||||
6. Afterwards look in **Logs** at the run, tab **TRACING**, and expand **SPEECH TO TEXT**. Under OUTPUT is what the tool returns: one field `text`, with a line break wherever another voice starts.
|
||||
|
||||

|
||||

|
||||
|
||||
That is the honest answer: the model **splits** the text at speaker changes, but Dify's Speech To Text tool passes on **no labels** (Speaker 1, Speaker 2). Who said what is inferred by the Minutes node from the content, and that works well here because the opening names the people ("Present are Karen, Bram and Fatima") and because people address each other in a meeting. In a meeting without such an opening the action points end up as "not mentioned".
|
||||
|
||||
Two more things stood out. The transcription of the three voices contains more errors than that of the single voice: the computer voices read with a slight accent and the speech model hears it. Real speakers do better. And the run time was the same, a good minute for three minutes of audio.
|
||||
Two more things stood out in the Dutch edition of this test, where we did run three voices. The transcription of three computer voices contains more errors than that of one: the voices read with a slight accent and the speech model hears it. Real speakers do better. And the run time was the same, a good minute for three minutes of audio.
|
||||
|
||||
> **Your choice: real speaker labels.** If you want "Karen:" and "Bram:" in the transcript, there are two routes. The easy one: put in the prompt of the Minutes node "The lines in the transcript are speaker changes. Put the speaker's name before each line if it is clear from the content, otherwise Speaker 1, 2, 3." The precise one: replace the Speech To Text tool with an **HTTP Request** node to OpenAI's speech API with `response_format=diarized_json`; that gives a speaker number and a time per sentence. That needs a key in the node (through an environment variable, never in the text) and is a next guide.
|
||||
|
||||
@@ -297,25 +294,25 @@ Two more things stood out. The transcription of the three voices contains more e
|
||||
|
||||

|
||||
|
||||
2. Open the menu again and click **Open webapp**.
|
||||
2. Open the menu again and click **Open web app**. The web app has two tabs, **Run Once** and **Run Batch** (several recordings from a spreadsheet in one go).
|
||||
|
||||

|
||||

|
||||
|
||||
3. Click **Local upload**, choose the small recording and click **Execute**.
|
||||
|
||||
> After the upload the Execute button moves down a little. Check where it is before you click.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
At the top right of the table there is a copy button and a download button. With those a colleague puts the action points straight into an email or a spreadsheet.
|
||||
|
||||
The Dutch example from this guide: <https://udify.app/workflow/7N5dNg8fD9qXHA80>.
|
||||
The example from this guide: <https://udify.app/workflow/EPAc3PPeD3E4764l>.
|
||||
|
||||
---
|
||||
|
||||
@@ -390,35 +387,35 @@ The recording is invented and the structure of the minutes is our choice. This c
|
||||
|
||||
## Appendix A. Making a test recording without real voices
|
||||
|
||||
For a prototype you need a recording without personal data. The easiest route is to have a fictional script read out by the same Audio tool, but the other way round: **Text To Speech**. That is how the recording for this guide was made (the script `make_recording.py` does the same from the command line).
|
||||
For a prototype you need a recording without personal data. The easiest route is to have a fictional script read out by the same Audio tool, but the other way round: **Text To Speech**. That is how `department-meeting.mp3` for this guide was made (the script `make_recording.py` does the same from the command line, with your own OpenAI key).
|
||||
|
||||
1. Make a workflow with a **User Input** with one field: type **Paragraph**, variable `text`.
|
||||
1. Make a workflow called `Recording maker` with a **User Input** with one field: type **Paragraph**, variable `text`.
|
||||
2. Choose as next step **Tools** → **Audio** → **Text To Speech**.
|
||||
|
||||

|
||||
|
||||
3. Under **Text** click in the field, type `/` and choose **text**.
|
||||
|
||||

|
||||

|
||||
|
||||
4. Under **Model** choose a speech model; **tts-1** is the cheapest.
|
||||
|
||||

|
||||

|
||||
|
||||
5. Under **Voice of tts-1** choose a voice, for example **Alloy**.
|
||||
|
||||

|
||||

|
||||
|
||||
6. Add an **Output** node with variable `audio` → Text To Speech / **files**.
|
||||
|
||||

|
||||
|
||||
7. Click **Test Run**, paste the script (`department-meeting-script.txt`) and click **Start Run**. After half a minute an mp3 is in the result.
|
||||
7. Click **Test Run**, paste the script (`department-meeting-script.txt`) and click **Start Run**. After half a minute an mp3 is in the result: 2.55 MB, 128 kbps, mono, 2 min 47 s.
|
||||
|
||||

|
||||

|
||||
|
||||
8. Click the file name straight away and save the file. The link works for five minutes.
|
||||
8. Click the file name straight away and save the file. The link works for five minutes. The file is too big for the Speech To Text tool (step 6); shrink it first with ffmpeg as shown there, or with any audio program, to 32 kbps mono.
|
||||
|
||||
Cost: about 4 cents for three minutes of speech. The result is one voice reading all the speakers; for a test of transcription and minutes that is enough. A sandbox account has room for five apps, so delete this helper workflow afterwards, or rebuild it into the Transcription tool as done in this guide.
|
||||
|
||||

|
||||

|
||||
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 61 KiB |
@@ -3,8 +3,9 @@
|
||||
Dify changes fast. Every guide states on its title page on which day the screens were captured.
|
||||
This is what changed per release.
|
||||
|
||||
## 2026-09-21, guides 04 and 06 in English
|
||||
## 2026-09-21, guides 04, 05 and 06 in English
|
||||
|
||||
- Guide 05 rebuilt with the English interface and an English test recording (department-meeting.mp3 and the small version, made with the Text To Speech tool from appendix A). The test now shows the size error and the real minutes; the three-voice run is described from the Dutch edition. Live app in the README.
|
||||
- Guide 06 rebuilt in the Agent Console with the English interface, the OERSI search tool and the English agent Materials check (link in the README). The test shows a turn that ended without text and how to get the answer anyway.
|
||||
- Export of the agent as `06-inclusive-materials/materials-check.dify.yml`, with import instructions in the README.
|
||||
- Guide 04 rebuilt in the Agent Console with the English interface and the English agent Test week planner (link in the README). The test now shows the agent checking the student's request instead of refusing it; the text explains why the same prompt can do both.
|
||||
|
||||
@@ -4,9 +4,7 @@ Step-by-step guides, appendices and a two-hour workshop on building AI agents in
|
||||
education. Made by LeX Consultancy B.V. All examples play at Example College (fictional);
|
||||
screens captured on Dify cloud, 20 September 2026.
|
||||
|
||||
The screenshots show the English Dify interface and the English build of each app. Guides
|
||||
whose screenshots still come from the Dutch build say so on their first page; those are being
|
||||
replaced one by one.
|
||||
The screenshots show the English Dify interface and the English build of each app.
|
||||
|
||||
Licence: CC BY-SA 4.0 (documents, slides, images) and MIT (scripts), see LICENSE.md.
|
||||
Owner and contact: Guido van Dijk, guido@l-e-x.nl.
|
||||
@@ -59,7 +57,7 @@ The apps are live to try out:
|
||||
- Parent letter assistant (03): https://udify.app/chat/oB2H2mLaoKR6d4IC
|
||||
- School news (03 and 07): https://udify.app/workflow/E2CHtVPKe3PLg7GF
|
||||
- Test week planner (04): https://udify.app/agent/x0yjuGoRIVdZaVZe
|
||||
- Transcription tool (05; Dutch build): https://udify.app/workflow/7N5dNg8fD9qXHA80
|
||||
- Transcription tool (05): https://udify.app/workflow/EPAc3PPeD3E4764l
|
||||
- Materials check (06): https://udify.app/agent/BIKJSPHj1JnCRzAp
|
||||
- Study coach biology (08): https://udify.app/chat/mgvtZPbDVAIp5gbh
|
||||
|
||||
|
||||