В этом руководстве мы рассмотрим, как создать агента Context-Folding LLM, который эффективно решает длинные и сложные задачи, разумно управляя ограниченным контекстом. Мы разработаем агента, способного разбивать большие задачи на более мелкие подзадачи, выполнять рассуждения или вычисления при необходимости, а затем сворачивать каждую завершённую подзадачу в краткие резюме.
Подготовка среды и загрузка модели
Мы начинаем с настройки нашей среды и загрузки облегчённой модели Hugging Face. Мы используем эту модель для генерации и обработки текста локально, обеспечивая бесперебойную работу агента в Google Colab без каких-либо зависимостей от API.
«`python
import os, re, sys, math, random, json, textwrap, subprocess, shutil, time
from typing import List, Dict, Tuple
try:
import transformers
except:
subprocess.run([sys.executable, «-m», «pip», «install», «-q», «transformers», «accelerate», «sentencepiece»], check=True)
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, pipeline
MODELNAME = os.environ.get(«CFMODEL», «google/flan-t5-small»)
tokenizer = AutoTokenizer.frompretrained(MODELNAME)
model = AutoModelForSeq2SeqLM.frompretrained(MODELNAME)
llm = pipeline(«text2text-generation», model=model, tokenizer=tokenizer, device_map=»auto»)
def llmgen(prompt: str, maxnew_tokens=160, temperature=0.0) -> str:
out = llm(prompt, maxnewtokens=maxnewtokens, dosample=temperature>0.0, temperature=temperature)[0][«generatedtext»]
return out.strip()
«`
Определение простого калькулятора и системы памяти
Мы определяем простой калькулятор для выполнения базовых арифметических операций и создаём систему памяти, которая динамически сворачивает прошлый контекст в краткие резюме. Это помогает нам поддерживать управляемую активную память, сохраняя при этом важную информацию.
«`python
import ast, operator as op
OPS = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.truediv, ast.Pow: op.pow, ast.USub: op.neg, ast.FloorDiv: op.floordiv, ast.Mod: op.mod}
def evalnode(n):
if isinstance(n, ast.Num): return n.n
if isinstance(n, ast.UnaryOp) and type(n.op) in OPS: return OPS[type(n.op)](evalnode(n.operand))
if isinstance(n, ast.BinOp) and type(n.op) in OPS: return OPS[type(n.op)](evalnode(n.left), evalnode(n.right))
raise ValueError(«Unsafe expression»)
def calc(expr: str):
node = ast.parse(expr, mode=’eval’).body
return evalnode(node)
class FoldingMemory:
def init(self, max_chars:int=800):
self.active=[]; self.folds=[]; self.maxchars=maxchars
def add(self,text:str):
self.active.append(text.strip())
while len(self.activetext())>self.maxchars and len(self.active)>1:
popped=self.active.pop(0)
fold=f»- Folded: {popped[:120]}…»
self.folds.append(fold)
def fold_in(self,summary:str): self.folds.append(summary.strip())
def active_text(self)->str: return «\n».join(self.active)
def folded_text(self)->str: return «\n».join(self.folds)
def snapshot(self)->Dict: return {«activechars»:len(self.activetext()),»n_folds»:len(self.folds)}
«`
Разработка шаблонов подсказок
Мы разрабатываем шаблоны подсказок, которые направляют агента в разложении задач, решении подзадач и обобщении результатов. Эти структурированные подсказки обеспечивают чёткую коммуникацию между этапами рассуждений и ответами модели.
«`python
def parse_bullets(text:str)->List[str]:
return [ln[2:].strip() for ln in text.splitlines() if ln.strip().startswith(«- «)]
def runsubtask(task:str, subtask:str, memory:FoldingMemory, maxtool_iters:int=3)->Tuple[str,str,List[str]]:
# …
return final, summary_bullets, trace
class ContextFoldingAgent:
def init(self,maxactivechars:int=800):
self.memory=FoldingMemory(maxchars=maxactive_chars)
self.metrics={«subtasks»:0,»toolcalls»:0,»charssaved_est»:0}
# …
«`
Мы реализуем основную логику агента, в которой каждая подзадача выполняется, обобщается и возвращается в память. Этот шаг демонстрирует, как сворачивание контекста позволяет агенту рассуждать итеративно, не теряя след предыдущих рассуждений.
Запуск агента на тестовых задачах
Мы запускаем агента на тестовых задачах, чтобы наблюдать, как он планирует, выполняет и синтезирует конечные результаты. Через эти примеры мы видим полный процесс сворачивания контекста в действии, производя краткие и связные выходные данные.
«`python
DEMO_TASKS=[
«Plan a 3-day study schedule for ML with daily workouts and simple meals; include time blocks.»,
«Compute a small project budget with 3 items (laptop 799.99, course 149.5, snacks 23.75), add 8% tax and 5% buffer, and present a one-paragraph recommendation.»
]
def pretty(d): return json.dumps(d, indent=2, ensure_ascii=False)
if name==»main«:
agent=ContextFoldingAgent(maxactivechars=700)
for i,task in enumerate(DEMO_TASKS,1):
print(«=»*70)
print(f»DEMO #{i}: {task}»)
res=agent.run(task)
print(«\n— Folded Summaries —\n»+(res[«folded_summaries»] or «(none)»))
print(«\n— Final Answer —\n»+res[«final»])
print(«\n— Diagnostics —«)
diag={k:res[k] for k in [«activecontextchars»,»runtime_sec»]}
diag[«n_subtasks»]=len(agent.decompose(task))
print(pretty(diag))
«`
В заключение мы демонстрируем, как сворачивание контекста позволяет решать сложные задачи, избегая перегрузки памяти. Мы видим, как каждая подзадача планируется, выполняется, обобщается и преобразуется в компактные знания, имитируя то, как интеллектуальный агент обрабатывал бы сложные рабочие процессы с течением времени.
1. Какие инструменты и библиотеки используются для создания агента Context-Folding LLM?
В статье используется облегчённая модель Hugging Face для генерации и обработки текста локально. Для работы с моделью применяются библиотеки `transformers`, `accelerate`, `sentencepiece`.
2. Как работает система памяти в контексте управления ограниченным объёмом данных?
Система памяти представлена классом `FoldingMemory`, который динамически сворачивает прошлый контекст в краткие резюме. Это помогает поддерживать управляемую активную память, сохраняя при этом важную информацию.
3. Какие этапы включает в себя разработка шаблонов подсказок для агента?
Разработка шаблонов подсказок включает в себя создание структурированных подсказок, которые направляют агента в разложении задач, решении подзадач и обобщении результатов. Эти подсказки обеспечивают чёткую коммуникацию между этапами рассуждений и ответами модели.
4. Какие параметры используются для инициализации класса `ContextFoldingAgent`?
Для инициализации класса `ContextFoldingAgent` используется параметр `maxactivechars`, который определяет максимальный объём активных символов в памяти агента.
5. Какие тестовые задачи используются для демонстрации работы агента?
Для демонстрации работы агента используются две тестовые задачи:
1. План 3-дневного учебного расписания для ML с ежедневными тренировками и простыми приёмами пищи; включение временных блоков.
2. Расчёт бюджета небольшого проекта с тремя позициями (ноутбук 799,99, курс 149,5, закуски 23,75), добавление 8% налога и 5% буфера, и представление рекомендации в одном абзаце.