diff --git a/stream-agent/assignment_description.txt b/stream-agent/assignment_description.txt new file mode 100644 index 0000000..d978f7e --- /dev/null +++ b/stream-agent/assignment_description.txt @@ -0,0 +1,82 @@ +# Assignment Description (English) + +## Goal + +Upgrade the agent from the previous assignment: replace the single `.invoke()` call with streaming output via `.stream()`, so that the response appears in the console token‑by‑token instead of after the entire generation. + +--- + +## Background + +In the previous assignment the agent was invoked with `.invoke()`, which returned the result only after the agent finished all its work. For long answers or when the agent calls several tools this can look like a hang. + +**Stream mode** allows receiving the answer token by token in real time, just like ChatGPT or any other chat interface. + +--- + +## What to do + +1. **Replace `.invoke()` with `.stream()`** + ```python + # before + answer = agent.invoke({"messages": [{"role": "human", "content": "..."}]}) + # after + stream = agent.stream({"messages": [{"role": "human", "content": "..."}]}, stream_mode=["messages", "updates"]) + ``` + `stream_mode` is a list of modes. You can pass one or both: + * `'messages'` – each token of the text as it is generated. + * `'updates'` – events about state changes (tool calls, step finishes). + +2. **Iterate over the chunks** + ```python + for chunk in stream: + chunk_type, chunk_data = chunk + if chunk_type == 'messages': + # token stream + elif chunk_type == 'updates': + # state update + ``` + +3. **Handle `'messages'` chunks** + ```python + message, meta = chunk_data + if meta['langgraph_step'] != step: + step = meta['langgraph_step'] + print('\n---\n') + if message.content: + print(message.content, end='', flush=True) + ``` + +4. **Handle `'updates'` chunks** + ```python + if chunk_type == 'updates' and chunk_data.get('model'): + last_message = chunk_data['model']['messages'][-1] + print(format_message(last_message)) + ``` + The helper `format_message` is the same as used for `.invoke()`. + +--- + +## Final script structure + +```python +# import LLM and tools +# define the tool +# create the agent +# run the stream +# iterate over chunks and print +# finally print the full result +``` + +--- + +## Expected output + +The console should show the text gradually, with each new agent step separated by a divider. For example: +``` +--- +get_price({'product': 'milk', 'city': 'Kazan'}) +--- +Milk in Kazan: 89 rub. +--- +``` \ No newline at end of file