Практычныя прытамулкі: RAG без адгадванняў: стандартызаваны LangGraph +
Практычныя прыказкі: RAG без адгадванняў — стандартызаваны LangGraph +: контракты, перакрыцчы і слоты для коду для команд, якія викорыстоўваюць гэты патэрн.
У гэтым керавану практычным крокам перакладзена схема працы ад сыр'ёчных матэрыялаў да готовай системы для: RAG Без адгадванняў: Стандартызаваныя шаблоны LangGraph + LlamaIndex. Акцэнт ставіцца на практычныя крокі, чыстае перакананне ў правильнасці дзействаў і код, які можна проста дадаць у репазітарый без неабязковасці адгадваць намеры. Для загальнага абзору, перш чым зменяць код, неабходна визначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аператары должны магчымае перадзваніць крок з вядомай точкі контролю, не адгадваючы схованы стан. Неабходна аддактуваць документацыю як пра успішны ход роботы, так і пра способы ўстранення проблем. Перапрыбуткі, людзкія пераконтролы і обработка некоректных паведамленняў є частью самага продукту, а не пасляднім элементам дапрацоўкі.
Чаму існуе гэтыя статті
Калі працюеце над раздзелам «Чаму існуе гэты стацыянт», спачатку запісайце умовы: неабяжлівыя даны, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список контроля дапамагае заліцвачыць змяны ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, неудача должна вказваць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Перад налаштаваннем запитоў пераканайцеся, што система правільна запам’ятаўае інфармацыю, выканаўшы тэст на фіксаванай сэтке запитаў. Частыя змены запитоў рэдка калі вядуць да павышэння якасці пошуку.
Частка А: Розумеў LlamaIndex (Спачатку концэпцыя)
Калі вы працуеце над частю А: Розумэнне LlamaIndex (Спачатку — канцэпцыя), спачатку запісайце умовы кантракту: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у разе частковага нэуспеху. Такі список дапамагае заліцьварыцца пад пазнейшыя змены коду. Спрэцьвуйце да гэтага этапу як да кантракту межу вхіднымі даннымі і пераканаленымі выходнымі рэзультатамі. Дайце назвы элементам, задаце критэрыі успеху і не прымайце часткова завершэння без паведамлення. Змяроўваце рэкалі на фіксаванай сэтке запытаў прычым падбір прамптав. Частае змена прамптав рэдка калі вярнуе слабую эфектыўнасць пошуку.
Што на самай працы робіць LlamaIndex
Калі працуеце над матэрыялам «Што на самай працоўнае робі LlamaIndex», спачатку запісайце умовы викорыстоўвання: неабходныя данні, сігнал успеху і тое, што выходзіць на падчасныя неудачы. Такі чарткі дапамагае заставіць пазнейшыя змены коду быць чыстымі. Запісвайце час выконання і вартасьць токенав або запытак праза функцыйнае рэзультат. Відразліва візуалізацыя вартасцей запобегае неспакою, калі працэс пераходзіць з дамовай версіі ў спяльныя сераўы. Замерьце рэкалі на фіксаванай сэтке запытаў прычым регулюванню прамптав. Частае змена прамптав рэдка калі-небудзь выправляе слабыя аспекты пошуку інфармацыі. Калі працуеце над матэрыялам «Што на самай працоўнае робі LlamaIndex», спачатку запісайце умовы викорыстоўвання: неабходныя данні, сігнал успеху і тое, што выходзіць на падчасныя неудачы. Такі чарткі дапамагае заставіць пазнейшыя змены коду быць чыстымі. Дакументавайце як шлях успеху, так і шлях вярнення да нормы. Перапрыбуткі, людзкія контролі і обработка некоректных запытаў ёсць частью продукту, а не пазнейшым дапрацоўкам.
Пяцьступенчатая схема RAG
Пятыядцястапенны працэс RAG работае наўжоўды лепш, калі яго розглядаць як мерыемую структуру. Зберагучы адну ідеальную транскрыпцію, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану, перш чым расширваць масштабы. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выходзіць, прычына неудачы павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны працэс. Раздзеляйце правіла часткавання інфармацыі ад правіл яе выкарыстоўвання. Змена адных не павінна вымагаць перапісву іншых, калі зменяюцыся показнікі якосці.
1. LOAD → Read raw files (PDF, Word, web pages, databases) into Documents
2. CHUNK → Split Documents into small, retrievable Nodes
3. EMBED → Convert each Node's text into a vector (a list of numbers
representing meaning)
4. STORE → Save those vectors in a Vector Index for fast lookup
5. RETRIEVE → At query time, embed the user's question, find the most
similar Nodes, and return them as context
Ключовыя словы, якія вам неабходна знать
«Ключовыя фразы, якія вам трэба знать», працюе найэфектывней калі яго розглядаць як мерыемую плошчу. Запісаўце адна ідеальная транскрыпцыя, адзін прыклад неудачы і прыметку па адвярненню змян перш чым расширваць масштаб. Разглядзіце гэты этап як кантракт межа вхіднымі даннымі і падтвердзенымі выхіднымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху і адмовіцеся ад тыхнай мовчанкавай частковай завершэння. Раздзеліце політыку частковай обробкі данных ад політыки ўзяць іх. Змена адной з яных не должна прымусваць перапісванне другой, калі зменяюцца паказнікі якосці.
Частка B: Стварэнне самостойной базы знаёмых LlamaIndex
Частка B: Стварэнне самостойнай базы знаёмасцей LlamaIndex работае найкраща, калі яе спрыяюць як меркаваную плошчу. Зафіксавайце адны ідеальны прымер, адзін кейс неудачы і прыметкі па адвярненне перад расшырэнням масштабаў. Запісвайце часы выканання і кост токенав або запита праза функцыональнымі рэзультатамі. Відразлівае паказанне костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмавайнага режыма ў спяльныя среды. Раздзеліце політыку часткавання дадзеных ад політыки ўзяць іх. Змена адной з яных не павінна вымагаць перапісвання другой, калі зменяюцыся паказнікі якосці. Частка B: Стварэнне самостойнай базы знаёмасцей LlamaIndex работае найкраща, калі яе спрыяюць як меркаваную плошчу. Зафіксавайце адны ідеальны прымер, адзін кейс неудачы і прыметкі па адвярненне перад расшырэнням масштабаў. Дакументавайце як успішны, так і вярнучыся парадоксы разам. Перапрыбуткі, людзкія контрольныя пункты і обработка непрацюючых паведамленняў є часткай продукту, а не чымсь, што дадаецца пазней.
Шаг 1: Установка
Для першага: інсталляцыі, неабяжна паказаць параметры вхідных дадзеных, адпаведнага адпаведальнага за шаг і крэтарыя выходу пры зміне коду. Аператары должны магчымаць перзапуск шага з вядомай точкі контролю, не прабуючы спадарацца прыватны стан. Лепш выбіраць маленькія, тэставаныя елементы замест амаль неконтрольваных скрыптав. Калі шаг не выконваецца, прычына неудачы должна вказываць на адзін конкрэтны элемент, а не на заплутаны ланцюг задач. Неабяжна цітаваць тые часткі тексту, якія фактычна служылі падставай для адпаведнага адказу. Без цітатаў аператары не зможаць разлічыць галюцинацію ад працягу праз прычыны, зв’язаныя з індэксаванням.
# Core package + OpenAI LLM and embedding integrations (the common starting setup)
pip install llama-index-core llama-index-llms-openai llama-index-embeddings-openai
# Readers for common file types (PDF, Word, etc.)
pip install llama-index-readers-file pypdf
Шаг 2: Глобальная настройка з Settings
Для 2-го крока: глобальная настройка за дапамогай Settings; пярэд тым, калі зменяецца код, неабходна ўзначэнне вхідных дадзеных, адпаведальнага за крок і крэтарыяў завершэння. Аперацыйныя працавнікі должны магчымае запускаць крок з вядомай точкі контролю, не прабуючы спадарацца прыватнага стану.
Спрыяйце гэтаму этапу як кантракту межа вхіднымі дадзенымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, узначыце крэтарыяў успеху і адмовіцеся ад беззвучнага частковага завершэння.
Цітавайце тыя часткі, якія фактычна лежалі в основе адпаведнай адказы. Без цітатаў аперацыйныя працавнікі не зможуць адразніць галюцинацыю ад прасоў у індэксаванні.
# ── llamaindex_config.py ─────────────────────────────────────
import os
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
# Settings is global - configure once, used everywhere in LlamaIndex
Settings.llm = OpenAI(
model="gpt-4o-mini", # Used for generating final answers from retrieved context
temperature=0.1, # Low temperature: factual, not creative
)
Settings.embed_model = OpenAIEmbedding(
model="text-embedding-3-small", # Used to convert text into vectors
)
# Controls how documents are split into Nodes (chunks)
Settings.chunk_size = 512 # Max tokens per chunk
Settings.chunk_overlap = 50 # Overlap between consecutive chunks, to preserve context across boundaries
3-й крок: Завантажыць → Індексавацыя → Запит (Аўтонамны пайплайн)
Для трэцьяго крока: Завантажыце → Індэксацыя → Запит (Аўтанонны пайплайн), перад змянай коду неабходна задаць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Запісвайце час выконання і вартасьць токенаў або запытача разам з функцыйнальнымі рэзультатамі. Візуабельнае паказанне вартасцей з самага пачатку запобегае неспакоўным рахункам, калі процес пераходзіць з дэмовай среды ў спакульнаныя сераўсы. Указвайце тыя часткі тексту, якія фактычна ляглі в основу адпаведнай адказы. Без цых цітатаў аператары не можуць розразліць галюцинацію ад прычыны, вызванай прасоцем індэксацыі.
# ── build_knowledge_base.py ──────────────────────────────────
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
# ── LOAD: Read all files in a folder into Document objects ──
documents = SimpleDirectoryReader("./data").load_data()
print(f"Loaded {len(documents)} documents")
# ── CHUNK + EMBED + STORE: all three happen inside this one call ──
# VectorStoreIndex automatically:
# 1. Splits each Document into Nodes (using Settings.chunk_size)
# 2. Embeds each Node (using Settings.embed_model)
# 3. Stores the vectors in an in-memory index
index = VectorStoreIndex.from_documents(documents, show_progress=True)
# ── RETRIEVE + GENERATE: ask a question ──────────────────────
query_engine = index.as_query_engine(
similarity_top_k=3, # Retrieve the 3 most relevant chunks for each query
)
response = query_engine.query("What is our refund policy for enterprise customers?")
print(response)
Для 3-й ступені: Завантажыць → Індэкс → Запит (Автонамны пайплайн), неабяжна задаць вхідныя даны, адміністратара ступеня і крэтыры завершэння пры перадзеіснавленні коду. Аператары должны магчымаць перзапуск ступеня з вядомай точкі контролю, не падозрываючы прыхованы стан. Неабяжна задокументаваць як шлях успеху, так і шлях вярнення. Перапрыбуткі, людзкі контроль і обработка некоректных паведамленняў є часткай продукту, а не чымсь, што дадаецца пазней.
4-я ступень: Зберагчэнне індэкса (Не прабавайце занова ўбудоўваць яго ў кожны раз)
Калі вы працуеце над крокам 4: Зберагчыць індэкс (Не прабавайце занова ўбудоўваць яго кожны раз), спачатку запісайце умовы викорыстоўвання: неабходныя данні, сігнал успеху і тое, што выканаецца у разе частковага невыпання. Такі список контроля дапамагае заліцьваты змяны ў кодзе пазнейша. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшоў, прычына невыпання павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Перад налаштаваннем запитоў пераканайцеся, наскількі эфектыва система адпаведзае на фіксаваны набор запитанняў. Частае зміненне запитоў рэдка калі-небудзь выправляе слабкую эфектывацыю пошуку.
# ── Save the index after building it ─────────────────────────
index.storage_context.persist(persist_dir="./storage")
# ── Load it back later without re-embedding anything ──────────
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
Крок 5: Выкарыстоўванне зовнішняй базы дадзеных вектараў (Chroma)
Калі вы працюеце над 5-м крокам: викорыстоўванне зовнішней базы дадзеных вектораў (Chroma), спачатку запісайце угоду: неабходныя даны, сигнал успеху і тое, што выканаецца у разы частковага невялікога браку. Такі чарткі спамагаюць залічываць змяны ў кодзе пазнейша. Спрэцьвачайце гэты этап як угоду межаў вхідных дадзеных і перакананыя выходныя рэзультаты. Дайце назвы артыфактам, задаць правіла пераканання ў успех і не падтрымайце частковае завершэння без адпаведных падтверджэнняў. Замерайце рівень вярнага аднаходжэння на фіксаванай сэтцы запытаў прычым регулювання підказак. Частае змена підказак рэдка калі вялікі эфект даўае на слабую систему аднаходжэння дадзеных.
# ── Using Chroma as a persistent, production-grade vector store ──
# pip install llama-index-vector-stores-chroma chromadb
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import StorageContext, VectorStoreIndex
chroma_client = chromadb.PersistentClient(path="./chroma_db")
chroma_collection = chroma_client.get_or_create_collection("my_knowledge_base")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# Build the index directly into Chroma
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context
)
# Later, in a different process, reconnect without re-indexing:
index = VectorStoreIndex.from_vector_store(vector_store=vector_store)
Частка C: З’яўленне LlamaIndex з LangGraph
Калі працюеце над часткай C: падзьяздзе LlamaIndex да LangGraph, спачатку запісайце умовы вярбунка: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список дапамагае заліцьваты пазнейшыя змены коду. Запісуйце час выканання і кост токеноў або запытаў разам з функцыйнальнымі рэзултатамі. Відразы костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя среды. Замерайце рэкалі на фіксаванай сэтке запытаў прычымо да налаштавання прапазаў. Частыя змены прапазаў рэдка калі лепшаюць слабую систему пошуку. Калі працюеце над часткай C: падзьяздзе LlamaIndex да LangGraph, спачатку запісайце умовы вярбунка: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список дапамагае заліцьваты пазнейшыя змены коду. Дакументавайце як шлях успеху, так і шлях вяснавання проблем. Перапрыбуткі, людзкія контралі і обработка нераспакаваных паведамленняў є часткай продукту, а не пазнейшым дапрацоўкам.
„The Bridge“: Адаптаванне двайніка запытаў як інструмента
„The Bridge“: Адаптаванне двайніка запытаў як інструмента працюе наяўна, калі яго розглядаць як меркаваную структуру. Перш чым расширваць масштаб, неабходна зафіксаваць адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс па кроках для вярнення да пачатковага стану. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выходзіць, прычына неудачы павінна вказываць на адную конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Неабходна раздзеліць правілы частковай обработкі дадзеных і правілы ўтрымання іх. Змена адных не павінна вымагаць перапісвання іншых, калі змянююцца паказнікі якосці.
# ── MODULE 3: TOOLS (LlamaIndex-backed) ─────────────────────
from langchain_core.tools import tool
# The query_engine built in Part B - created once, at startup
# (In a real app, you'd load this from persisted storage, not rebuild it every time)
@tool
def search_knowledge_base(query: str) -> str:
"""Search the internal knowledge base for company policies, product
documentation, and internal procedures. Use this whenever the user asks
a question that might be answered by internal company documents rather
than general knowledge.
Args:
query: A natural-language question to search for.
Returns:
A synthesized answer based on the most relevant retrieved documents.
"""
response = query_engine.query(query)
return str(response)
Полная інтеграцыя: Модулі 1 да 7
Пэўнае інтеграцыя: Модулі 1 да 7 работаюць наўзям лепш, калі іх расследжваць як мерыябельную структуру. Запісаўце адна ідеальная версія, адзін прыклад неудачы і прыметкі па адвярненню змян пры расшырэнні масштаба. Расследжвайце гэты этап як кантракт межа вхіднымі дадзеннямі і перакананымі выхіднымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху і адмовіцеся ад тыхоўскага частковага завершэння. Раздзеліце правілы частковай обробкі дадзенняў ад правілаў ўтрыманні інформацыі. Змена адных не павінна прыводзіць да перапісвы іншых, калі змянююцца паказнікі якосці.
# ============================================================
# LANGGRAPH + LLAMAINDEX RAG AGENT — COMPLETE TEMPLATE
# Extends: Part 1 (core structure)
# ============================================================
# ── MODULE 1: IMPORTS & CONFIGURATION ───────────────────────
import os
from typing import Literal
# LangChain / LangGraph imports (the orchestration layer)
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage, BaseMessage
from langchain_core.tools import tool
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import MemorySaver
# LlamaIndex imports (the retrieval / data layer)
from llama_index.core import (1
Settings, SimpleDirectoryReader, VectorStoreIndex,
StorageContext, load_index_from_storage
)
from llama_index.llms.openai import OpenAI as LlamaOpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
# LangGraph's chat model - used by the agent's reasoning
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# LlamaIndex's model config - used internally by the query engine
# Note: these are SEPARATE from the LangGraph llm above. Each framework
# manages its own model instances; they don't share state.
Settings.llm = LlamaOpenAI(model="gpt-4o-mini", temperature=0.1)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.chunk_size = 512
# ── MODULE 2: STATE ──────────────────────────────────────────
class State(MessagesState):
pass # messages field inherited; extend if your agent needs more
# ── MODULE 3: TOOLS (RAG-backed) ─────────────────────────────
# Build or load the LlamaIndex knowledge base ONCE, at startup
PERSIST_DIR = "./storage"
if os.path.exists(PERSIST_DIR):
# Reload existing index - no re-embedding, fast startup
storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
index = load_index_from_storage(storage_context)
else:
# First run - build the index and persist it
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents, show_progress=True)
index.storage_context.persist(persist_dir=PERSIST_DIR)
query_engine = index.as_query_engine(similarity_top_k=3)
@tool
def search_knowledge_base(query: str) -> str:
"""Search internal company documents for policies, product specs,
procedures, and other domain-specific information. Use this for any
question that requires knowledge specific to this organization rather
than general world knowledge."""
response = query_engine.query(query)
return str(response)
tools = [search_knowledge_base]
llm_with_tools = llm.bind_tools(tools)
tool_node = ToolNode(tools)
# ── MODULE 4: NODES ──────────────────────────────────────────
def agent_node(state: State) -> dict:
"""The reasoning node. Decides whether to answer directly or
search the knowledge base first."""
system_prompt = SystemMessage(content=(
"You are a helpful assistant with access to an internal knowledge base. "
"Use the search_knowledge_base tool when the user asks about company-specific "
"information. For general questions, answer directly."
))
messages = [system_prompt] + state["messages"]
response = llm_with_tools.invoke(messages)
return {"messages": [response]}
# ── MODULE 5: ROUTING ────────────────────────────────────────
def should_continue(state: State) -> Literal["tools", "__end__"]:
last_message = state["messages"][-1]
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return "tools"
return "__end__"
# ── MODULE 6: GRAPH ASSEMBLY ─────────────────────────────────
graph_builder = StateGraph(State)
graph_builder.add_node("agent", agent_node)
graph_builder.add_node("tools", tool_node)
graph_builder.add_edge(START, "agent")
graph_builder.add_conditional_edges(
"agent", should_continue,
{"tools": "tools", "__end__": END}
)
graph_builder.add_edge("tools", "agent")
graph = graph_builder.compile(checkpointer=MemorySaver())
# ── MODULE 7: ENTRYPOINT ──────────────────────────────────────
if __name__ == "__main__":
config = {"configurable": {"thread_id": "session-001"}}
print("RAG agent ready. Ask about your documents, or anything else.\n")
while True:
user_text = input("You: ").strip()
if not user_text or user_text.lower() == "exit":
break
response = graph.invoke(
{"messages": [HumanMessage(content=user_text)]},
config=config
)
print(f"Agent: {response['messages'][-1].content}\n")
Што на самай працэ практычна адбываецца, калі вы гэта запускаеце
Што на самай працоўны спосаб дзеяеся, калі вы запускаеце гэта, — калі яго спрыята як мерыемая сфера. Зафіксавайце адну ідеальную транскрыпцыю, адзін прыклад неудачы і прыметку па абратанні рэзультатаў прычым расшырэнні масштаба. Запісвайце часы выканання і косты токеноў або запытак па боку функцыйнальных рэзультатаў. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмовай среды ў спяльнаныя сераўы. Раздзеліце політыку часткавага оброблэння дадзеных ад політыкі ўтрымання іх. Змена адной з яных не павінна вымагаць перапісвання другой, калі зменяюцыся паказнікі якосці. Што на самай працоўны спосаб дзеяеся, калі вы запускаеце гэта, — калі яго спрыята як мерыемая сфера. Зафіксавайце адну ідеальную транскрыпцыю, адзін прыклад неудачы і прыметку па абратанні рэзультатаў прычым расшырэнні масштаба. Дакументавайце як успешны, так і вярнучы паты. Перапрыбуткі, людзкія контрольныя пункты і обробка некоректных дадзеных ўжо є частью продукту, а не чымсь, што дадаецца пазней.
User: "What's our policy on remote work?"
↓
[agent_node] — LangGraph's LLM reads the message, recognizes this needs
internal info, decides to call search_knowledge_base
↓
[tools] — ToolNode executes search_knowledge_base("What's our policy on remote work?")
↓
Inside the tool: query_engine.query(...) runs —
this is 100% LlamaIndex, invisible to LangGraph:
1. Embeds the query
2. Searches the vector index for the 3 closest chunks
3. Feeds those chunks + the question to Settings.llm
4. Returns a synthesized answer string
↓
[agent_node] — LangGraph's LLM receives the tool's string result,
and crafts the final response shown to the user
↓
Response to user
Частка D: Адзін рэвень глыбей — толькі режым Retriever (большая кантролля)
Для часткі D: Адзін рэвень глыбей — толькі режым Retriever (большая кантролля) неабяжна практычна апісацыя вхідных дадзенняў, адпаведальнага за крок і крэтарыяў выходу пры перадзеі коду. Аператары павінны магчымаецца перзапускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест абмежлівых скрыптав. Калі крок не выйшае, прычына неудачы павінна вказываць на адзін конкрэтны элемент адпаведальнасці, а не на заплутаны ланцужок задач. Прыкладзіце фрагменты, якія насправдзе ляглі в основу адпаведнай адказы. Без цых праменаванняў аператары не зможаць разлічыць галюцинацію ад працягу ў індэксаванні.
# ── Retriever-only tool: returns raw chunks, not a synthesized answer ──
retriever = index.as_retriever(similarity_top_k=3)
@tool
def retrieve_documents(query: str) -> str:
"""Retrieve relevant document excerpts from the internal knowledge base.
Returns raw excerpts for you to read and reason over yourself -
use this when you need to cite specific sources or combine information
from multiple documents."""
nodes = retriever.retrieve(query)
# Format each retrieved chunk with its source for transparency
formatted_chunks = []
for i, node in enumerate(nodes):
source = node.metadata.get("file_name", "unknown source")
formatted_chunks.append(f"[Excerpt {i+1} from {source}]\n{node.text}")
return "\n\n---\n\n".join(formatted_chunks)
Калі вжываць QueryEngine проты Retriever
Ёнколі трэба выкарыстоўваць QueryEngine чы не Retriever, перш чым зменіць код, неабходна задаць вхідныя даны, абавесця крока і крэтыры завершэння. Аперацыяныя працавнікі павінны магчымае перазапускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан.
Спрыяйце гэтаму этапу як кантракту межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Даць назвы артыфактам, задаць перакананні на успех і адмовіцца ад тыхняе частковага завершэння без паведамлення.
Цітаваць тыя часткі, якія фактычна сталі падставай для адпаведнай адказы. Без цітатаў аперацыяныя працавнікі не зможуць адразніць галюцинацыю ад прасоў у індэксаванні.
Апдаўленая карточка справакі з ключоўымі словамі
Для апдэйтаванага карточкі прыказоў ключоўых слова неабходна праказаць вхідныя даны, адпаведальнага за крок і крэтарыя выходу пры змены коду. Аператары должны магчымае перзапускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выконання і кост токенаў або запытаў праза функцыйнае рэзультаты. Відкрытыя данні пра косцы запобегаюць неспакойным рахункам, калі процес пераходзіць з дэмавайнага режыма ў спакульнае сераўерское сэрвіса. Указывайце тыя часткі тексту, якія фактычна лежалі в основе адпаведнай адказу. Без цых цітатаў аператары не можаць разлічыць галюцинацію ад прасоўкі ў індэксаванні. Для апдэйтаванага карточкі прыказоў ключоўых слова неабходна праказаць вхідныя даны, адпаведальнага за крок і крэтарыя выходу пры змены коду. Аператары должны магчымае перзапускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Дакументавайце як «шчаслівы» шлях, так і шлях вяснавання проблем. Перапрыбуткі, людзкія контрольныя пункты і обработка некоректных запытаў є часткай продукту, а не пасляднім дапрацоўкам.
Канал прыямоў: Калі вам насправдэй патрэбна гэта?
Працюючы з Каналам прыямоў: Калі вам насправдэй патрэбна гэта?, спачатку запісайце контракт: неабходныя даны, сігнал успеху і тое, што выканаецца у разы частковага нявыпалення. Такі список контроля дапамагае залічыць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптаў. Калі якісьць крок не выйшоў, нявыпаленне павінна вказваць на адную адпаведальнасць, а не на заплутаны ланцюг задач. Перад налаштаваннем запитоў пераканайцеся, як працуе система з фіксаваным наборам запитанняў. Частае змена запитоў рэдка калі вярнайце слабкую эфектыўнасць адзысквання інформаціі.
Вывык: Два кантэйнеры, адна целаснасць
Калі працуеце над раздзелам «Заключэнне: два кантрэкты, адна ўзлегласць», спачатку запісайце умовы кантракту: неабяжныя вхідныя даны, сигнал успеху і тое, што выходзіць пад частым нявыпаннем. Такі список пераконтроўкаў дапамагае заліцьваты змяны ў кодзе пазнейша. Спрыймайце гэты этап як кантракт межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаць правіла пераканання успеху і адмовіцеся ад мовчкавага частковага завершэння. Замерайце рівень запам’ятовання на фіксаванай сэтцы пытанняў прычым регулюванні запрошэнняў. Частае змены запрошэнняў рэдка калі вылечваюць слабкую структуру адзысквання інформаціі.
Чэк-ліст для эксплуатацыі
Чэк-ліст для эксплуатацыі працюе найэфектывней, калі яго спрыймаюць як мерыябельную структуру. Запісайце адна ідеальная транскрыпцыя, адзін прыклад нявыпання і прыметкі па адкату перш чым расширваць масштаб. Зберагайце настройкі параду ад коду прыемліка. Файлы сяродавішча, хранільнікі секрэтных дадзенняў і флагі функций должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць без неабяжнага чытання всіх элементаў структуры.
Адміністрацыю разбівання на часткі трэба аддзержваць разам з адміністрацыяю выкарыстання. Змена адной з іх не павінна прымусваць перапісванне другой, калі зменяюцыся показнікі якосці.
Неабяжна людская апрацоўка для тых крокаў, якія выкорыстоўваюць грошы чыму зменяюць данні праработкі. Працэс на час компілявання не ўзроўнаважваецца з повнасцю бізнес-процэсаў.
Напісце кароткі посібнік: як роўнаць клучы, як спрачыслаць чергу, як анулюваць пярэдніе дадзеныя.
Спрыятлівае ставленне да гэтага этапу як да кантракту межа вхіднымі дадзеннямі і перакананымі выходнымі рэзультатамі. Назваце всі элементы, задаце критэрыя успеху і не падтрымвайце частковае завершэнне без паведамлення.
Перад апраноўкай вэрсій заморозьце іх, зафіксуйце ідеальны варыянт для критычнага маршруту і падтвердзіце крокі анулювання. У спадзяльных средах неабяжны ліміты частоты, перакананні ў правільнасці власніка і чыстае прадзелванне клучоў. Валіце простую надзяйнасць над крэатыўнымі, адзінразовымі дамэ.
Запіскі для пакета bcaf14f9c811: не трэба кантрацаваць ключы прадастоўцаў у репазітарые, задаць максімальную кантроль на токены за сесію, а таксама зберагчы транскрыпціі праза фіксатурамі адлічэння, каб пазнейшыя замены моделяў заставаліся пораўнанымі.