Агентський ШІ з LangChain — Частина 5: Агентський RAG з ReAct та
Частина 5 агентського ШІ з LangChain: агентський RAG, де агент ReAct вирішує, коли здійснювати пошук інформації, а крок рефлексії перевіряє відповідь перед її поверненням.
Джерела: Agentic AI with LangChain — Part 5: Agentic RAG with ReAct and Reflection
Використовуйте цей документ як оновлену версію ідей з «Агентні ШІ з LangChain — Частина 5: Агентні RAG із ReAct та Reflection», орієнтовану на операторів: чіткі етапи, впорядковані блоки коду та примітки щодо відновлення, які залишаються при передачі обов’язків. Огляд працює найкраще, якщо його розглядати як вимірювану структуру. Запишіть один ідеальний запис, один випадок збою та примітки щодо скасування змін перед розширенням обсягу роботи. Віддавайте перевагу невеликим, тестованим одиницям перед об’ємними скриптами. Коли якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність дій.
Технічні концепції
Щодо технічних концепцій, необхідно визначити вхідні дані, відповідальну особу за кожен етап та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити етап з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цю стадію як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення роботи. Наводьте конкретні уривки тексту, які лежать в основі відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем із індексуванням.
1. Конфігурації системи
Для 1. Конфігурацій системи необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Записуйте час виконання та витрати на токени або запити поруч із функціональними результатами. Візуалізація витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні. Наводьте конкретні уривки тексту, які лягли в основу відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем з індексуванням.
OPENAI_API_KEY="<Your OpenAI API Key>"
VECTOR_DB=pinecone
PINECONE_API_KEY=<your Pinecone API Key>
PINECONE_ENVIRONMENT=gcp-starter
LANGSMITH_TRACING=true
LANGSMITH_ENDPOINT="https://api.smith.langchain.com"
LANGSMITH_API_KEY="<Your LangSmith API Key"
LANGSMITH_PROJECT="agent-ai"
TAVILY_API_KEY=<Your TAVILY API Key>
class BaseConfig(BaseSettings):
OPENAI_API_KEY: Optional[str]
PINECONE_API_KEY: Optional[str]
TAVILY_API_KEY: Optional[str]
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
2. Структура проекту
Щодо 2. Структури проєкту: перед зміною коду необхідно визначити вхідні дані, відповідальну особу за кожен етап та критерії завершення. Оператори мають мати можливість перезапустити етап з відомої точки контролю, не намагаючись визначити прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функціоналу мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Необхідно наводити конкретні уривки тексту, які лягли в основу відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем з індексуванням.
project/
├── rag_process/ # Pinecone RAG operations
│ ├── __init__.py
│ ├── extractor.py
| └── service.py
│
├── graphs # implement ReAct and Reflection StateGraph
│ ├── nodes.py # graph nodes. Defined as Python functions
│ ├── graph.py # graph workflow
│ ├── consts.py # define node names as constants
│ └── state.py # typed dictionary to store graph states
|
|
├── tools # defines Pinecone retriever and get_weather tools
│ ├── retriever_tools.py # Python function tool to retrieve Pinecone RAG
| └── weather.py # typed dictionary to store graph states
|
|── schemas.py # pydantic data models
|── upload.py # python functions to upload files asynchronously
├── main.py # fastAPI app
├── config.py # pydantic BaseConfig
│── dependencies.py # dependency inject to fastAPI endpoint function
├── .env # environment variable definition
├── client.py # streamlit client
├── .gitignore
└── requirements.txt # package requirements
3. Інтеграція шаблону ReAct
Для розділу 3. Інтеграція шаблону ReAct необхідно визначити вхідні дані, відповідальну особу за крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Необхідно документувати як успішний, так і відновлювальний сценарії роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Наводьте уривки тексту, які фактично лежать в основі відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем з індексуванням.
3.1. Інструмент пошуку RAG
Для інструменту отримання даних RAG 3.1 необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Краще використовувати невеликі, перевірювані одиниці коду замість об’ємних скриптів. Коли крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану структуру обробки даних. Наводьте уривки тексту, які фактично лягли в основу відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем з індексуванням.
@tool
async def search_agentic_docs(query: str) -> str:
"""
Good for questions about generative agents, prompt engineering, and adversarial attacks.
Pass a natural language search query to retrieve context from the agentic ai database.
"""
# Simply invoke your existing vector service retriever
docs = await vector_service.retriever.ainvoke(query)
# Flatten the document content into a single string for the LLM
return "\n\n".join([d.page_content for d in docs])
3.2. GraphState
Для розділу 3.2. GraphState необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цю стадію як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового завершення. Наводьте конкретні уривки, які лежать в основі відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем з індексуванням.
class GraphState(TypedDict):
"""
Represents the state of our graphs.
Attributes:
question: question
generation: LLM generation
acceptable: whether the answer is qualified to be acceptable
messages: list of messages
"""
question: str
generation: str
acceptable: bool
messages: Annotated[list[AnyMessage], add_messages]
loop_count: int
3.3. Вузли ReAct
Для розділу 3.3. вузлів ReAct необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Записуйте час виконання та витрати на токени або запити поруч із функціональними результатами. Чітке відображення витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні. Наводьте конкретні уривки тексту, які лягли в основу відповіді. Без посилань оператори не зможуть відрізнити галюцинації від проблем з індексуванням.
4. Інтеграція шаблону рефлексії
Для пункту 4. Інтеграція шаблону рефлексії необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функціоналу мають знаходитися в одному місці, яке оператори можуть перевірити, не читаючи весь код. Наводьте уривки тексту, які фактично лежать в основі відповіді. Без посилань оператори не зможуть відрізнити галюцинацію від проблем із індексуванням. Для пункту 4. Інтеграція шаблону рефлексії необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Віддавайте перевагу невеликим, тестованим одиницям коду перед об’ємними скриптами. Коли крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану структуру коду.
eline.4.1. Як працює рефлексія
Під час вивчення розділу 4.1. Як працює рефлексія спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допоможе зберегти чесність подальших змін у коді. Розглядайте цей етап як угоду між вхідними даними та перевіреними результатами. Дайте назви елементам, визначте критерії успіху та не допускайте беззвучного часткового виконання завдань. Перед налаштуванням запитів перевірте рівень запам’ятовування на фіксованому наборі запитань. Часта зміна запитів рідко допомагає покращити якість пошуку.
4.2. Запити
Під час роботи над розділом 4.2. Promptи спочатку запишіть умови використання: необхідні дані вхіду, сигнал про успішне виконання та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Запишіть час виконання та витрати на токени або запити поруч із результатами функціональності. Відображення витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Зберігайте у кеші стабільні інструкції системи та схеми інструментів. Повторна передача ідентичних даних є поширеною причиною зайвих витрат.
GENERATE_SYSTEM_PROMPT = f"""You are an assistant for question-answering tasks with access to multiple tools.
use these tools to retrieve context to answer the question. If you don't know the answer,
just say that you don't know. Use three sentences maximum and keep the answer concise.
Tool Use Instructions:
- Use tools as much as possible.
- Chain tools when needed (e.g., search for info, then use that to search
for relevant hotels)
- Be conversational and helpful
- If you choose to answer a question using your internal knowledge instead of a tool,
you must be completely certain of the facts. If there is any ambiguity,
or if the question requires up-to-date or highly specific details, you MUST use a tool to verify.
"""
GRADER_SYSTEM_PROMPT = """""You are a grader assessing whether an LLM generation addresses/resolves a
question using the context. Generate critique and recommendations for LLM that generated the answer.
always provide detailed recommendations, including requests for search more relevant context, generate
answer based on context to reduce hallucination, and generate answer relevant to the question.
The LLM generating this answer has the access to the following tools to obtain context:
**get_weather**: search for weather information given a city name
**search_agentic_docs**: Good for questions about generative agents, prompt engineering, and adversarial attacks
**TavilySearch**: General search tool from the internet.
INSTRUCTIONS:
(a) Evaluate if the context is relevant to the question
Provide recommendation if context is not relevant to the question. You can suggest the LLM to use an
appropriate tool. If there is no context, you must be completely certain of the facts. If the question is
covered by provided tools, or there is any ambiguity,
or if the question requires up-to-date or highly specific details, you MUST suggest to use a tool to verify answer.
(b) Evaluate if the answer is based on the context
if the answer is not based on the context, it is a hallucination. You should suggest to regenerate the answer
based on the context.
(c) Evaluate if the answer resolves the question
if the answer does not resolves the question, suggest to regenerate the answer
The LLM generated this answer is strictly instructed to keep its answer CONCISE (maximum of 3 sentences).
Do NOT penalize the answer for omitting minor details if the core question is answered accurately.
If all the evaluations are passed, no suggestions should be provided.
CRITERIA FOR ACCEPTABLE (True):
- If the answer is accurate, addresses the user's question using the context, and does not hallucinate,
you MUST set acceptable to True, even if it missed some details from the context.
- Only set acceptable to False if there is a fundamental flaw (hallucination, wrong information,
or completely missing the point).
OUTPUT REQUIREMENTS:
You must return a structured output with the following fields:
- acceptable (boolean): True if the answer passed all evaluation,
False if any of the evaluation fails and recommendations are provided
- recommendations (string): recommendations you provide
INPUTS:
question: {question}
answer: {answer}
context: {context}
"""
4.3. Вузли відображення
Під час роботи над розділом 4.3. „Вузли відображення“ спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається при частковій невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретів та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь граф. Вимірюйте рівень відтворення інформації на фіксованому наборі запитань перед налаштуванням підказок. Часта зміна підказок рідко виправляє слабку систему пошуку інформації. Під час роботи над розділом 4.3. „Вузли відображення“ спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається при частковій невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Віддавайте перевагу малим, тестованим одиницям коду перед величезними скриптами. Коли якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність операцій.
5. Повний робочий процес
- Повний робочий процес найкраще функціонує, якщо його розглядати як вимірювану структуру. Збережіть один ідеальний зразок результату, один випадок невдачі та примітку про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як угоду між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового виконання завдань. Розділіть політику розбиття на частини та політику отримання даних. Зміна однієї з них не повинна змушувати переписувати іншу при зміні показників якості.