Skip to content

Commit e3159ed

Browse files
docs: add documentation for function-level and runtime customization of thought messages
Signed-off-by: Patrick Chin <8509935+thepatrickchin@users.noreply.github.com>
1 parent a398da7 commit e3159ed

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

docs/source/build-workflows/workflow-configuration.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,23 @@ From the above we see that it is divided into four sections: `functions`, `llms`
7171
### `functions`
7272
The `functions` section contains the tools used in the workflow, in our example we have two `webpage_query` and `current_datetime`. By convention, the key matches the `_type` value, however this is not a strict requirement, and can be used to include multiple instances of the same tool.
7373

74+
#### Thought process description
75+
76+
Agent responses in the NeMo Agent Toolkit UI include a thought process display which shows a step-by-step view of what the workflow is doing.
77+
78+
To customize the text shown for a function in the thought process display, set `thought_description` in that function's configuration. Unlike `description`, which provides the tool's help text that the agent uses to decide when and how to call the tool, `thought_description` only affects the label shown in the thought process display. For example:
79+
80+
```yaml
81+
functions:
82+
webpage_query:
83+
_type: webpage_query
84+
thought_description: "Searching internal documentation"
85+
webpage_url: https://docs.smith.langchain.com
86+
description: "Search for information about LangSmith. For any questions about LangSmith, you must use this tool!"
87+
embedder_name: nv-embedqa-e5-v5
88+
chunk_size: 512
89+
```
90+
If `thought_description` is not set, NeMo Agent Toolkit uses a default thought description. For runtime customization of the thought process display from within your function code, refer to [Customizing Thought Process Display](../extend/custom-components/custom-functions/functions.md#customizing-thought-process-display).
7491

7592
### `llms`
7693
This section contains the models used in the workflow. The `_type` value refers to the API hosting the model, in this case `nim` refers to an NIM model hosted on [`build.nvidia.com`](https://build.nvidia.com).

docs/source/extend/custom-components/custom-functions/functions.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,80 @@ async def my_function(config: MyFunctionConfig, builder: Builder):
558558

559559
Every function has its own set of converters and are independent of the converters used by other functions. This allows for functions to convert between common types such as `str` -> `dict` or `int` -> `float` without breaking the type safety of other functions.
560560

561+
## Customizing Thought Process Display
562+
563+
Agent responses in the NeMo Agent Toolkit UI include a thought process display that shows a step-by-step view of what the workflow is doing. You can customize what appears in this display at two levels:
564+
565+
* **Function-level customization** - Set a custom label for the entire function using `thought_description` in the configuration
566+
* **Runtime customization** - Emit custom thoughts from within your function code for fine-grained progress updates
567+
568+
### Function-Level Customization
569+
570+
The simplest way to customize the thought process display is by setting `thought_description` in your function's YAML configuration. Refer to the [Workflow Configuration](../../../build-workflows/workflow-configuration.md#thought-process-description) documentation for details.
571+
572+
### Runtime Customization with Custom Thoughts
573+
574+
For fine-grained control during function execution, you can emit custom thoughts that appear as steps in the thought process display. NeMo Agent Toolkit provides helper functions in {py:mod}`nat.builder.thought` for emitting thoughts:
575+
576+
* {py:func}`~nat.builder.thought.emit_thought` - Emit a complete thought (appears immediately)
577+
* {py:func}`~nat.builder.thought.emit_thought_start` - Start a streaming thought
578+
* {py:func}`~nat.builder.thought.emit_thought_chunk` - Update a streaming thought
579+
* {py:func}`~nat.builder.thought.emit_thought_end` - Complete a streaming thought
580+
581+
#### Emitting Complete Thoughts
582+
Each call to {py:func}`~nat.builder.thought.emit_thought` in the example below appears as a completed step in the thought process display.
583+
584+
```python
585+
from nat.builder.context import Context
586+
from nat.builder.thought import emit_thought
587+
588+
async def process_data(dataset_name: str) -> dict:
589+
ctx = Context.get()
590+
591+
emit_thought(ctx, f"Loading dataset: {dataset_name}")
592+
data = await load_dataset(dataset_name)
593+
594+
emit_thought(ctx, "Validating data schema")
595+
validate_data(data)
596+
597+
emit_thought(ctx, "Applying transformations")
598+
result = transform_data(data)
599+
600+
emit_thought(ctx, f"Successfully processed {len(result)} records")
601+
602+
return {"records_processed": len(result), "status": "complete"}
603+
```
604+
605+
#### Emitting Streaming Thoughts
606+
The streaming thought lifecycle consists of three steps:
607+
1. {py:func}`~nat.builder.thought.emit_thought_start` - Creates the thought and returns a UUID
608+
2. {py:func}`~nat.builder.thought.emit_thought_chunk` - Updates the thought text (call multiple times)
609+
3. {py:func}`~nat.builder.thought.emit_thought_end` - Marks the thought as complete
610+
611+
```python
612+
from nat.builder.thought import emit_thought_start, emit_thought_chunk, emit_thought_end
613+
614+
async def process_batch(items: list[str]) -> dict:
615+
ctx = Context.get()
616+
617+
thought_id = emit_thought_start(ctx, "Processing batch: 0%")
618+
619+
processed = 0
620+
total = len(items)
621+
622+
for item in items:
623+
await process_item(item)
624+
processed += 1
625+
626+
progress = int((processed / total) * 100)
627+
emit_thought_chunk(ctx, thought_id, f"Processing batch: {progress}%")
628+
629+
emit_thought_end(ctx, thought_id, f"Batch processing complete: {total} items")
630+
631+
return {"items_processed": total}
632+
```
633+
634+
561635
## Related Documentation
562636

563637
- [Writing Custom Function Groups](./function-groups.md) - Learn how to bundle related functions that can share configuration, resources, and runtime context.

0 commit comments

Comments
 (0)