RAG for 1C: searching documentation and configuration code with AI
Build an assistant that answers questions about your configuration and internal rules with a source reference. Python code and a per-query cost estimate.
5 min · · бизнес · автоматизация
A typical situation in a company running 1C: accounting rules sit in documents, the logic in tens of thousands of lines of modules, and only one person knows the answer to "where do we calculate the discount". RAG for 1C solves this by first finding the relevant pieces of code and documents, then passing them to the model together with the question, and the model answers with a source reference. Below are the scheme, Python code and a cost estimate, and at the end a word on when RAG is not needed at all.
What RAG is in plain words
A model does not know your configuration, and pasting everything into a request is impossible or expensive. So it is done in two steps:
- Search. For the question, the several best-matching fragments are picked from your knowledge base.
- Answer. The fragments and the question go to the model with the instruction "answer only from these materials and name the source".
This way the neural network for working with 1C gets the context it needs, and you pay only for the few thousand tokens that actually went into the request.
What to index
Decide right away what goes into the index and what must stay out.
Suitable:
- configuration modules (
.bsl) from a dump to files; - descriptions of metadata objects: catalogs, documents, registers and their attributes;
- internal rules and user instructions;
- documentation you have the right to use: check the license terms of reference materials before loading them into a third-party service.
Not suitable:
- the contents of the information base itself: personal data of customers and employees, counterparty prices, salaries;
- passwords, connection strings and access keys from modules and settings.
If the code contains secrets, clean them out before indexing. Questions and the found fragments go to the model provider, and this must be reflected in your security policy.
How to split code: by procedure
Split code not into fixed-length pieces but at the boundaries of procedures and functions. Then a fragment holds complete logic rather than half a condition. Add a header with the file path to each piece: you will use it later to cite the source.
import re
from pathlib import Path
SPLIT = re.compile(r"(?mi)^(?=(?:Процедура|Функция)\s)")
def chunk_bsl(root: str) -> list[dict]:
chunks = []
for path in Path(root).rglob("*.bsl"):
text = path.read_text(encoding="utf-8-sig", errors="ignore")
for part in SPLIT.split(text):
part = part.strip()
if len(part) < 40:
continue
chunks.append({"source": str(path.relative_to(root)), "text": part[:3000]})
return chunksThe cut at 3000 characters guards against gigantic procedures. Rules in text files are split by paragraph or section the same way. (The pattern matches the Russian keywords Процедура and Функция; if your code uses the English keywords Procedure and Function, add them to the pattern.)
Search: start with BM25
Plain text search is useful for 1C code: identifiers, object names and keywords match literally. The BM25 algorithm from the rank_bm25 library is enough to begin with. Russian morphology is roughly compensated by truncating words to five letters:
from rank_bm25 import BM25Okapi
def tokens(s: str) -> list[str]:
return [w[:5] for w in re.findall(r"\w+", s.lower())]
chunks = chunk_bsl("./config_dump")
index = BM25Okapi([tokens(c["source"] + " " + c["text"]) for c in chunks])
def search(question: str, k: int = 6) -> list[dict]:
scores = index.get_scores(tokens(question))
top = sorted(range(len(chunks)), key=lambda i: scores[i], reverse=True)[:k]
return [chunks[i] for i in top]About embeddings. Semantic vector search is useful for rules written in natural language. The gateway's endpoint list (chat completions, responses, messages, models) has no separate embeddings method, so for vector search use a local embeddings model and use the gateway for generating the answer. The most reasonable path: BM25 for code, vector search for texts if needed, and merge the results.
Generating the answer with sources
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_your_key")
SYSTEM = """You are an assistant for a 1C configuration. Answer only from the given fragments.
For every claim, name the source in the format [file path].
If the answer is not in the fragments, say: "The found materials do not contain the answer"
and suggest which search query to try. Do not invent anything."""
def ask(question: str, model: str = "claude-sonnet-5-5") -> str:
found = search(question)
context = "\n\n".join(f"### [{c['source']}]\n{c['text']}" for c in found)
# no temperature: newer Claude models reject values other than 1.0If you want to control answer variation with temperature, check whether the chosen model accepts it: newer Claude models reject values other than 1.0, so the example does not set it.
How to ask questions
- Name objects as in the metadata: "Document РеализацияТоваровУслуг", not "sales".
- One question, one topic. Split compound questions.
- If the answer is "not in the materials", ask the model to suggest another search query and repeat.
- Check the source reference: open the file and make sure the code really says what the model said.
What a query costs
An assumption: 6 fragments of 400 tokens, plus the question and instruction of 400 tokens, so 2800 input tokens and 500 output tokens. Prices as of 18 October 2026, dollars per 1M tokens.
claude-sonnet-5-5 (0.4 / 2):
2800 × 0.4 / 1,000,000 = $0.00112
500 × 2 / 1,000,000 = $0.001
Total $0.00212, a thousand queries about $2.12.
gpt-6.1-sol (0.27 / 1.32):
2800 × 0.27 / 1,000,000 = $0.000756
500 × 1.32 / 1,000,000 = $0.00066
Total $0.001416, a thousand queries about $1.42.
deepseek-v4.1-flash (0.013 / 0.038):
2800 × 0.013 / 1,000,000 = $0.0000364
500 × 0.038 / 1,000,000 = $0.000019
Total $0.0000554, a thousand queries about $0.055.
We do not claim which model answers more accurately on your code: take 20 real questions with known answers and test two or three models. Current prices: GET https://api.zukko.pro/v1/models.
When RAG is not needed
If your corpus is small, it can be put into the request whole: models have contexts up to 1M tokens. For 200,000 tokens of code and documents, the price of one request on claude-sonnet-5-5:
200,000 × 0.4 / 1,000,000 = $0.08 at the input price.
In the Anthropic format, on repeated requests with the same prefix, a cache read costs 0.05: 200,000 × 0.05 / 1,000,000 = $0.01. The first request pays for these tokens as a cache write at 0.5: 200,000 × 0.5 / 1,000,000 = $0.10 instead of $0.08 at the input price. More on the cache in the post on prompt caching. But a long context is harder to control (it is harder to see what the answer relied on), and as the knowledge base grows you will have to return to search. Approaches are compared in the posts on RAG by hand and on long context.
You can connect a key in the dashboard. If you are interested not in search but in direct integration of 1C with a neural network, see the post on 1C integration.
FAQ
Do I need a vector database for RAG?
Not necessarily. For 1C code, BM25 over text often works well enough, and for natural-language rules you can add vector search with a local embeddings model.
Can I index data from the base?
You should not. Index code, metadata and rules, but not records with personal and commercial data: questions and the found fragments go to the model provider.
How do I update the index?
Rebuild it after each configuration dump. For small projects a full rebuild takes seconds because BM25 is built in memory.
How do I reduce invented answers?
The instruction "answer only from the fragments", mandatory source references and a human check of the source.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- AI for testers: test cases, checklists and bug reportsHow a QA engineer can use a model for test cases, checklists and bug reports, check coverage, and avoid requirements the model made up.
- Anonymizing data before sending it to a neural network: a practical wayYou do not have to send personal data to a model for it to process a document. How to replace it with labels, restore it in the answer and check that nothing leaked.
- A neural network for HR: job posts, candidate emails and resume reviewA model can draft job posts and emails and do a first-pass resume review. What to hand over, how to treat candidates' personal data and how to prevent biased decisions.
- Generating an FAQ with a neural network from tickets and a knowledge baseA good FAQ is built on what customers really ask. A pipeline: group the tickets, answer from the knowledge base with a source reference, and verify the result.