Дослідницький агент LangGraph із функціями пошуку LlamaIndex та кодуванням HITL
Розбиття на частини з урахуванням формату, структуроване спрямування намірів, паралельні спеціалізовані засоби пошуку та кодування CLI з функцією переривань дозволяють безпечно перетворювати наукові статті на виконувані експерименти.
Перетворення академічних статей на функціональні експерименти зазвичай є повільним процесом, який включає читання, узагальнення, програмування та виправлення помилок. Система з кількома агентами може взяти на себе більшу частину цього тягаря: LangGraph для маршрутизації, LlamaIndex для спеціалізованого пошуку та інструмент програмування через командний рядок після схвалення людини.
1. Розумне отримання даних: не всі фрагменти однакові
Сліпе розділення PDF-файлів, коду на Python та CSV-файлів за однією стратегією погіршує якість пошуку. Перед індексацією в ChromaDB застосовуйте розділення з урахуванням формату — фрагменти для прози, логічні блоки для коду, фрагменти рядків для таблиць:
# 5. Setup Chunkers
pdf_chunker = SentenceSplitter(chunk_size=512, chunk_overlap=50)
python_chunker = CodeSplitter(language='python')
csv_reader = CSVReader(concat_rows=False)
# 6. Route and Chunk Data
for doc in documents:
file_name = doc.metadata.get("file_name", "")
if file_name.endswith(".pdf"):
nodes = pdf_chunker.get_nodes_from_documents([doc])
elif file_name.endswith(".py"):
nodes = python_chunker.get_nodes_from_documents([doc])
elif file_name.endswith(".csv"):
# CSVs are chunked row-by-row by our custom reader
all_nodes.append(doc)
Ембеддинги (наприклад, all-minilm від Ollama) тоді відображають структуру, а не довільні вікна символів.
2. „Мозок“ LangGraph: класифікація намірів
LangChain надає моделі, запити та інструменти; LangGraph керує потоком виконання. Спільний словник State передається через кожну вершину. Маршрутизація за ключовими словами у вільному тексті є нестабільною, тому структуровані результати за допомогою Pydantic змушують локальну модель, таку як llama3.2:3b, використовувати Literal інтент:
class IntentClassifier(BaseModel):
message_intent: Literal['chat', 'code', 'knowledge'] = Field(
...,
description="Classify the user intent. 'code' for implementation, 'knowledge' for research details, 'chat' for general tasks."
)
Умовні краї потім надійно розподіляють завдання без необхідності обробки незрозумілого тексту.
3. Шлях знань: паралельний пошук
Складні дослідницькі запитання рідко піддаються обробці за допомогою одного пошуку на основі схожості. Розширте Шлях знань до чотирьох агентів LlamaIndex одночасно — abstract_agent, methodology_agent, limitations_agent та conclusion_agent — кожен з яких має спеціалізований запит. Об’єднайте часткові результати за допомогою функції operator.add від LangGraph, щоб автори не перекривали один одного:
class State(TypedDict):
messages: Annotated[list, add_messages]
message_intent: str | None
next_node: str | None
context: Annotated[list[str], operator.add] # Safely appends parallel findings
analyst_agent читає об’єднаний контекст та синтезує переваги, недоліки та прогалини.
4. Переход від досліджень до дій: програмування з участю людини
Шлях програмування перетворює намір на команду для CLI-інструменту програмування через підпроцес. Неконтрольований доступ до оболонки є небезпечним, тому LangGraph використовує функцію interrupt(), щоб зупинити виконання та отримати схвалення:
def accept_coding(state: State):
user_prompt = state['messages'][-1].content
decision = interrupt(f'About to run Claude Code with request:\n\n{user_prompt}\n\nApprove? (yes/no, or type a revised request)')
text = str(decision).strip().lower()
if text in ['y', 'yes', 'approve', 'ok']:
return {'next_node': 'coding_agent'}
if text in ['n', 'no', 'deny', 'cancel']:
return {'messages': [{'role': 'assistant', 'content': 'Coding request denied.'}], 'next_node': 'denied'}
# Allows the user to dynamically edit the prompt mid-flight
return {'messages': [{'role': 'user', 'content': text}], 'next_node': 'accept_coding'}
Після схвалення виконання відбувається у ізольованому робочому просторі, а результати відправляються назад у чат.
Підсумок
Розділення процесу отримання інформації (LlamaIndex) від керування станом та маршрутизації (LangGraph) дозволяє створити модульну структуру, яка може здійснювати дослідження та дії, поки людина контролює критичні етапи схвалення.
Уроки з експлуатації
- Розділення тексту з урахуванням формату окуповує себе вже після першого разу, коли процес отримання коду більше не повертає неповні функції.
Граф є кінцевим продуктом: вузли можна замінювати, але саме контракт стану та механізми схвалення роблять процес переходу від досліджень до коду достатньо безпечним для щоденної роботи.
Поетапний огляд
- Завантажуйте документи та нотбуки за допомогою розділювача, пристосованого до конкретного формату; перебудуйте колекцію Chroma, якщо змінюються джерела.
- Класифікуйте висловлювання користувача як належні до категорії „Знання“ чи „Кодування“ (або за більш детальними критеріями у міру зростання обсягу продукту).
operator.add, а потім синтезуйте інформацію за допомогою аналітика.Цього циклу достатньо, щоб замінити купу спорадичних нотатників на один стабільний інструмент для роботи агентів.