# function to create augmented memory objects
def create_augmented_mem_objs(output_previous_turn: dict) -> str:
    """Function to convert the output of a ReAct agent to a compact and interpretable representation"""
    all_steps_info = []
    # loop though the steps of the previous turns
    for i, step in enumerate(output_previous_turn['intermediate_steps']):
        # remove failed attempts
        if "error" not in step[1].lower():
            # collect the relevant info
            step_info = {'tool': step[0].tool,
                         'tool_input': step[0].tool_input}
            all_steps_info.append(step_info)
    # format the memory object in an interpretable way
    augmented_mem_obj = "This is the sequence of tools you used in the previous turn:\n"
    for i, item in enumerate(all_steps_info):
        augmented_mem_obj = augmented_mem_obj + f"\nSTART TOOL {i} NAME:\n{item['tool']}\nEND TOOL {i} NAME" \
                                                f"\n\nSTART INPUT {i} NAME:\n{item['tool_input']}\nEND INPUT {i} NAME\n"
    # add the final output generated by the agent
    augmented_mem_obj = augmented_mem_obj + f"\n\nThis is the output you produced in the previous turn:\nSTART OUTPUT\n{output_previous_turn['output']}\nEND OUTPUT"

    return augmented_mem_obj
```

```python PYTHON
augmented_mem_obj_a1 = create_augmented_mem_objs(a1)
augmented_mem_obj_a2 = create_augmented_mem_objs(a2_mem_ai_hum)
```

Below, an example of the augmented memory object generated by the model. You can see that the agent now has full visibility on what it did in the previous step.

```python PYTHON
print(augmented_mem_obj_a2)
```

```txt title="Output"
This is the sequence of tools you used in the previous turn:

START TOOL 0 NAME:
python_interpreter
END TOOL 0 NAME

START INPUT 0 NAME:
{'code': "import pandas as pd\nimport matplotlib.pyplot as plt\n\ndata = pd.read_csv('modified_revenue_table.csv')\n\n# Plot the revenue numbers\nplt.plot(data['revenue'])\n\nplt.savefig('revenue_plot.png')"}
END INPUT 0 NAME


This is the output you produced in the previous turn:
START OUTPUT
Here's a plot of the revenue numbers:
! [Revenue plot]("revenue_plot.png")
END OUTPUT
```

```python PYTHON
a3_mem_ai_hum_amo = agent_executor.invoke({
    "input": q3,
    "chat_history": [SystemMessage(content=augmented_mem_obj_a1),
                     SystemMessage(content=augmented_mem_obj_a2)]
})

```

```txt title="Output"
[1m> Entering new AgentExecutor chain...[0m
[32;1m[1;3m
I will copy and paste the previous code, and modify the y axis limits as requested.
{'tool_name': 'python_interpreter', 'parameters': {'code': "import pandas as pd\nimport matplotlib.pyplot as plt\n\ndata = pd.read_csv('modified_revenue_table.csv')\n\n# Plot the revenue numbers\nplt.plot(data['revenue'])\n\n# Set y axis limits\nplt.ylim(0, 1000)\n\nplt.savefig('revenue_plot.png')"}}
[0m[36;1m[1;3m[0m[32;1m[1;3mRelevant Documents: 0
Cited Documents: 0
Answer: Here's the plot with the requested y axis limits:

<img alt="Revenue plot" revenue_plot.png""="" src=""/>
Grounded answer: Here's the plot with the requested y axis limits:

<co: 0="">! [Revenue plot]("revenue_plot.png")</co:>[0m

[1m> Finished chain.[0m
```

We can see that, now, the plot only includes the modification we asked for, and nothing else. This is possible because we are now providing the Agent with the code it previously generated, and the Agent re-uses that code, making only the necessary modifications. This is fundamentally different from what we observed before, when the Agent had to re-create from scratch the code.

In sum, by providing the Agent with the information about its previous Reasoning Chain, we make it more robust and able to generate consistent outputs.

In a future post, we will explore how to handle really long historical context using vector databases.