|
1 | 1 | """ |
2 | 2 | Compaction example: run RLM with compaction enabled and a low threshold |
3 | | -to trigger summarization on gpt-5-nano. |
| 3 | +to trigger summarization. |
4 | 4 |
|
5 | | -Uses a low compaction_threshold_pct so compaction runs after several iterations. |
6 | | -The task forces many separate REPL turns with substantial output so the root |
7 | | -context grows and compaction definitely triggers. The REPL variable `history` |
8 | | -holds trajectory segments and summaries. |
| 5 | +The task uses random data so earlier results are impossible to recompute — |
| 6 | +the model *must* recover them from `history` after compaction fires. |
| 7 | +
|
| 8 | +Phase 1: Generate random datasets and compute statistics (fills context). |
| 9 | +Phase 2: Compaction fires, summarizing the conversation. |
| 10 | +Phase 3: Combine the earlier statistics into a final answer. Since the data |
| 11 | + was random, the model cannot just re-derive the numbers. |
| 12 | +
|
| 13 | +Usage: |
| 14 | + PORTKEY_API_KEY=... python examples/compaction_example.py |
9 | 15 | """ |
10 | 16 |
|
11 | 17 | import os |
|
17 | 23 |
|
18 | 24 | load_dotenv() |
19 | 25 |
|
20 | | -# Low threshold so compaction triggers after a few iterations (~2% of context). |
| 26 | +# Low threshold so compaction triggers after a few iterations. |
21 | 27 | # Use 0.85 in production. |
22 | | -COMPACTION_THRESHOLD_PCT = 0.03 |
| 28 | +COMPACTION_THRESHOLD_PCT = 0.02 |
23 | 29 |
|
24 | 30 | logger = RLMLogger() |
25 | 31 | rlm = RLM( |
|
31 | 37 | environment="local", |
32 | 38 | environment_kwargs={}, |
33 | 39 | max_depth=1, |
34 | | - max_iterations=10, |
| 40 | + max_iterations=12, |
35 | 41 | compaction=True, |
36 | 42 | compaction_threshold_pct=COMPACTION_THRESHOLD_PCT, |
37 | 43 | verbose=True, |
38 | 44 | logger=logger, |
39 | 45 | ) |
40 | 46 |
|
41 | | -# Hard task that forces many iterations: find the 50th prime using at least 8 |
42 | | -# separate REPL blocks, one per turn. Each block must produce visible output. |
43 | | -# This grows message history (long reasoning + code + execution results) so |
44 | | -# compaction triggers. |
45 | 47 | prompt = ( |
46 | | - "Find the 50th prime number. You MUST use at least 8 separate REPL blocks, " |
47 | | - "each in its own response (one block per message). Do NOT combine steps.\n\n" |
48 | | - "Required structure: " |
49 | | - "Block 1: Define a function is_prime(n) and test it on a few numbers; print the results. " |
50 | | - "Block 2: Write a loop that counts primes and print the first 10 primes. " |
51 | | - "Block 3: Extend to count up to 20 primes and print them. " |
52 | | - "Block 4: Count up to 30 primes and print the 25th. " |
53 | | - "Block 5: Count up to 40 primes and print the 35th. " |
54 | | - "Block 6: Count up to 50 primes and print the 45th. " |
55 | | - "Block 7: Print the full list of the first 50 primes (so we see all 50). " |
56 | | - "Block 8: Set answer = (the 50th prime) and call FINAL_VAR(answer).\n\n" |
57 | | - "Each block must run alone. Show your reasoning briefly before each block. " |
58 | | - "After each block, wait for the execution result before writing the next block." |
| 48 | + "Complete the following steps, each in its own REPL block (one block per message). " |
| 49 | + "Do NOT combine steps.\n\n" |
| 50 | + "Step 1: Use `import random; random.seed(42)` then generate a list of 50 random " |
| 51 | + "integers between 1 and 1000. Print ALL of them. Store as `data_a`.\n\n" |
| 52 | + "Step 2: Generate another 50 random integers (continuing the same RNG stream) " |
| 53 | + "between 1 and 1000. Print ALL of them. Store as `data_b`.\n\n" |
| 54 | + "Step 3: Compute and print the mean, median, min, max, and standard deviation " |
| 55 | + "of `data_a`. Store the mean as `mean_a`.\n\n" |
| 56 | + "Step 4: Compute and print the mean, median, min, max, and standard deviation " |
| 57 | + "of `data_b`. Store the mean as `mean_b`.\n\n" |
| 58 | + "Step 5: You previously computed `mean_a` and `mean_b`. " |
| 59 | + "Compute final_answer = round(mean_a + mean_b, 2) and call FINAL_VAR(final_answer)." |
59 | 60 | ) |
60 | 61 |
|
61 | 62 | result = rlm.completion(prompt, root_prompt=prompt) |
62 | 63 |
|
63 | | -print("Response:", result.response) |
64 | | -print("Execution time:", result.execution_time) |
65 | | -print("Metadata:", result.metadata) |
| 64 | +print("\n" + "=" * 60) |
| 65 | +print("RESULT") |
| 66 | +print("=" * 60) |
| 67 | +print(f"Response: {result.response}") |
| 68 | +print(f"Execution time: {result.execution_time:.2f}s") |
0 commit comments