RAG-система для документации 1С: архитектура MCP-серверов documents1c и metadata1c

01.04.26

Интеграция - Нейросети

Когда разработчик 1С задаёт вопрос AI-ассистенту, ему нужен точный, актуальный ответ со ссылкой на источник — документацию по 1С или описание объекта конфигурации. Именно для этого созданы два MCP-сервера: documents1c (поиск по документации 1С) и metadata1c (поиск по конфигурациям 1С). Оба сервера реализуют многоуровневую RAG-систему с несколькими слоями ранжирования. В этой статье я разберу каждый слой: почему он появился, как работает и какой код за ним стоит. И на какие грабли наступил при построении системы.

Почему не векторная база с деревом

Первый вопрос, который возникает при проектировании RAG: почему не использовать специализированную векторную базу (Qdrant, Weaviate, Pinecone) с иерархическим деревом документов?

Причина 1: документ 1С не самодостаточен без контекста.

Например, статья из документации о конфигурации Зарплата и управление персоналом может называться «Настройка» — а в контексте статьи нет отсылки, о чем она. Объект конфигурации Справочник.Сотрудники имеет смысл только в связке с реквизитами, табличными частями и модулями. Дерево в векторной базе не решает эту проблему — оно лишь добавляет навигацию, но не контекст внутри чанка.

Также стоить отметить, что дерево в векторной базе хорошо для статичной информации, когда нет постоянных изменений, обновлений информации, а уж тем более конфигураций 1С. Например, “Библиотека стандартных подсистем” - множество релизов, или описание синтаксиса языка 1С (новые методы, свойства, обработчики постоянно добавляются с выходом платформы).

Решение: хлебные крошки прямо в тексте чанка — heading_path вшивается в начало каждого чанка при индексировании, и модель эмбеддингов сразу видит полный контекст. Они могут быть как перечнем структуры разделов, текстовым ключом для связки, ключ описания объекта метаданных.

Причина 2: стоимость обновления.

Документация по 1С обновляется регулярно. При изменении статьи нужно пересчитать эмбеддинги затронутых чанков. В специализированной векторной базе это дополнительные затраты пересборки дерева. В нашем случае PostgreSQL с расширением pgvector уже используется как основная БД — добавить колонку embedding halfvec(1024) к таблице article_chunks значительно дешевле.


Слой 1: Построение чанков с хлебными крошками

Первый и самый важный слой — правильное разбиение статей на чанки. Плохой чанк испортит всё последующее ранжирование.

 

Алгоритм split_markdown_into_chunks

 

def split_markdown_into_chunks(
    text: str,
    max_len: int = 800,
    overlap: int = 220,
    include_heading_path: str = "full_path",
) -> list[str]:
    """
    Markdown-aware разбиение текста на чанки для RAG.
    1. Убирает YAML frontmatter
    2. Разбивает по заголовкам (#, ##, ###)
    3. Секции > max_len разбиваются по абзацам
    4. Блоки кода не разрываются
    5. Добавляет overlap между соседними чанками
    """
    body = _strip_frontmatter(text)
    sections = _split_by_headers(body)
    chunks: list[str] = []

    for section, heading_path, current_heading in sections:
        # heading_path = ["Зарплата", "Начисление", "Настройка НДФЛ"]
        context_heading = " > ".join(heading_path)  # режим full_path
        section_with_context = f"{context_heading}\n\n{section}"

        if len(section_with_context) <= max_len:
            chunks.append(section_with_context)
        else:
            sub_chunks = _split_section_by_paragraphs(section_with_context, max_len)
            chunks.extend(sub_chunks)

    return _add_overlap(chunks, overlap)

Ключевое решение — режим full_path: в начало каждого чанка добавляется полная цепочка заголовков. Например:

Зарплата и управление персоналом > Начисление зарплаты > Настройка НДФЛ

Для корректного расчёта НДФЛ необходимо указать ставку налога...

Это позволяет модели эмбеддингов понять контекст даже для коротких технических фрагментов.

 

Индексирование с хлебными крошками

 

При сохранении чанка в БД heading_path сохраняется отдельно в поле meta — для последующей фильтрации и формирования ссылок:

embed_input = (
    f"{chunk_record['heading_path']}\n\n{chunk_text}"
    if chunk_record["heading_path"]
    else chunk_text
)
chunk_embedding = await embed_text(embed_input)

chunk_obj = ArticleChunk(
    article_id=article_id,
    chunk_text=chunk_text,
    embedding=chunk_embedding,
    meta={
        "chunk_index": idx,
        "total_chunks": total_chunks,
        "heading_path": chunk_record["heading_path"],
        "heading_level": chunk_record["heading_level"],
    },
)

Обратите внимание: в эмбеддинг подаётся heading_path + chunk_text, а в БД хранится только chunk_text.

Это позволяет при поиске использовать семантику заголовков, не раздувая хранимый текст.


Слой 2: Redis — кеш эмбеддингов запросов

Генерация эмбеддинга через локальную LM Studio модель (text-embedding-qwen3-embedding-4b) занимает 50–200 мс. При повторяющихся запросах (а в RAG-системе агенты часто задают похожие вопросы) это накапливается.

Решение: Redis-кеш эмбеддингов с TTL.

def _cache_key(text: str, model: str, dimensions: int | None) -> str:
    """SHA256 от model:dimensions:text — инвалидируется при смене модели."""
    payload = f"{model}:{dimensions}:{text}"
    return "embed:" + hashlib.sha256(payload.encode()).hexdigest()


async def cache_get(text: str, model: str, dimensions: int | None) -> list[float] | None:
    r = get_redis()
    if r is None:
        return None
    try:
        data = await r.get(_cache_key(text, model, dimensions))
        return json.loads(data) if data else None
    except Exception:
        return None

Интеграция в embed_text:

async def embed_text(text: str) -> list[float]:
    model = _get_embed_model_name()
    dims = _get_embed_dimensions()

    # Проверяем Redis-кеш перед вызовом API
    if _cache_enabled():
        cached = await cache_get(input_text, model, dims)
        if cached is not None:
            return cached  # cache hit — 0 мс вместо 100+ мс

    response = await to_thread(client.embeddings.create, model=model, input=input_text)
    vector = response.data[0].embedding

    if _cache_enabled():
        await cache_set(input_text, model, dims, vector, _cache_ttl())

    return vector

Ключ кеша включает имя модели и размерность — при смене модели эмбеддингов старые записи автоматически становятся невалидными.


Слой 3: Векторный поиск (pgvector)

Основной поиск — косинусное расстояние через оператор <=> расширения pgvector. Используется тип halfvec для экономии памяти (16-битные float вместо 32-битных):

SELECT
    ac.id,
    ac.article_id,
    ac.chunk_text,
    ac.meta,
    ac.embedding::halfvec(1024) <=> CAST(:query_embedding AS halfvec(1024)) AS distance
FROM article_chunks ac
INNER JOIN articles a ON ac.article_id = a.id
WHERE a.job_id IN (
    SELECT id FROM jobs WHERE load_mode IN ('hbk', 'docs')
)
AND a.destination = :destination
ORDER BY distance
LIMIT :limit;

score = 1 - distance — чем ближе к 1, тем релевантнее чанк.


Слой 4: RRF (Reciprocal Rank Fusion)

Векторный поиск хорошо находит семантически близкие тексты, но плохо работает с точными терминами — например, &НаКлиентеНаСервере или УстановитьПривилегированныйРежим. Для таких запросов нужен полнотекстовый поиск (FTS).

RRF объединяет два ранжированных списка — векторный и FTS — без необходимости нормализовывать их оценки к единой шкале:

@staticmethod
def _rrf_merge(
    vector_results: list[dict],
    fts_results: list[dict],
    top_k: int,
    k: int = 60,
) -> list[dict]:
    """
    score_rrf = 1/(k + rank_vector) + 1/(k + rank_fts)
    k=60
    """
    scores: dict[int, float] = {}
    items: dict[int, dict] = {}

    for rank, item in enumerate(vector_results, start=1):
        chunk_id = item["id"]
        scores[chunk_id] = scores.get(chunk_id, 0.0) + 1.0 / (k + rank)
        items[chunk_id] = item

    for rank, item in enumerate(fts_results, start=1):
        chunk_id = item["id"]
        scores[chunk_id] = scores.get(chunk_id, 0.0) + 1.0 / (k + rank)
        if chunk_id not in items:
            items[chunk_id] = item

    sorted_ids = sorted(scores, key=lambda cid: scores[cid], reverse=True)

    # Нормализация min-max для совместимости со шкалой cosine score
    s_min, s_max = min(scores.values()), max(scores.values())
    score_range = s_max - s_min if s_max > s_min else 1.0

    result = []
    for cid in sorted_ids[:top_k]:
        entry = dict(items[cid])
        entry["score"] = round((scores[cid] - s_min) / score_range, 6)
        result.append(entry)
    return result

Документ, найденный обоими методами, получает два слагаемых и поднимается выше. Документ только из одного списка — одно слагаемое.

 

Подмешивание чанков встроенного языка 1С (HBK-буст)

 

Если агент вызвал инструмент без фильтра по разделам статей к результатам RRF добавляются топ-чанки из описания встроенного языка 1С (load_mode='hbk'). Это критично: если агент спрашивает «как работает ТаблицаЗначений», он хочет увидеть описание из синтакс-помощника, а не только сводные статьи 1С.

# При поиске без destination подмешиваем HBK-чанки
if destination is None:
    hbk_items = self._hbk_boost_search(query, query_emb, hbk_limit, release)
    existing_ids = {item["id"] for item in merged}
    boost_items = [item for item in hbk_items if item["id"] not in existing_ids]
    merged = boost_items[:boost_count] + merged  # HBK-чанки в начало

 

Слой 5: BM25 Reranking (опционально)

После RRF у нас есть 50–100 кандидатов. BM25 reranker уточняет их порядок, учитывая точное совпадение терминов запроса с текстом чанка.

Когда BM25 помогает

 

BM25 особенно эффективен, когда:

  • Запрос содержит специфические термины 1С (ОбщийМодульРегистрСведений&НаСервере)

  • Запрос содержит точные имена объектов (Справочник.Номенклатура)

  • Векторная модель «размывает» смысл коротких технических запросов

 

Токенизация для 1С

 

Стандартная токенизация не подходит для технической документации 1С. Реализована специальная:

GUID_RE = re.compile(r"\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b", re.I)
VERSION_RE = re.compile(r"\bv?8\.\d+(?:\.\d+){1,3}\b", re.I)
DIRECTIVE_RE = re.compile(r"[&\#][А-ЯA-Z][А-ЯёA-Za-z0-9_]*", re.I)

def _tokenize(self, text: str, expand_query: bool = False) -> list[str]:
    """
    Токенизация для русского языка и технической документации 1С.
    - GUID и версии платформы как «якорные» токены
    - Директивы препроцессора (&НаКлиенте, #Если)
    - Разбивка CamelCase, snake_case, dotted.names
    - Расширение по словарю сокращений 1С (только для запроса)
    """
    text = _norm_text(text)  # ёU94;е, 1cU94;1с, унификация тире
    out = []

    # Якорные токены — важны для точного матча
    for g in GUID_RE.findall(text):
        out.append(g.lower())
    for v in VERSION_RE.findall(text):
        out.append(v.lower())
    for d in DIRECTIVE_RE.findall(text):
        out.append(d.lower())

    for t in TOKEN_RE.findall(text):
        if t in RU_STOP or (len(t) == 1 and not t.isdigit()):
            continue
        # Разбиваем идентификаторы: ОбщийМодуль.Процедура U94; ["общиймодуль", "процедура"]
        for p in _split_identifier(t):
            out.append(p.lower())

    return out

 

Комбинирование векторного и BM25 score

def rerank(self, query: str, candidates: list[dict], top_k: int,
           vector_weight: float = 0.6, bm25_weight: float = 0.4) -> list[dict]:
    query_tokens = self._tokenize(query, expand_query=True)
    bm25_scores = self.bm25.get_scores(query_tokens)

    # Нормализация BM25 к [0, 1]
    max_bm25 = max(bm25_scores) if len(bm25_scores) > 0 else 1.0
    normalized_bm25 = [
        min(s / max(max_bm25, 10.0), 1.0) if s > 0 else 0.0
        for s in bm25_scores
    ]

    reranked = []
    for i, candidate in enumerate(candidates):
        vector_score = candidate.get("score", 0.0)
        bm25_score = normalized_bm25[i]
        # Взвешенное среднее: 60% вектор + 40% BM25
        combined = vector_weight * vector_score + bm25_weight * bm25_score
        reranked.append({**candidate, "score": combined,
                         "vector_score": vector_score, "bm25_score": bm25_score})

    reranked.sort(key=lambda x: x["score"], reverse=True)
    return reranked[:top_k]

Веса 1.2 / 1.0 подобраны эмпирически на тестовых запросах. При необходимости настраиваются через переменные окружения VECTOR_SCORE_WEIGHT и BM25_SCORE_WEIGHT.


Слой 6: Cross-encoder реранжинг по эмбеддингам

После BM25 reranking (опционально) применяется более дорогой, но точный cross-encoder — модель (bge-reranker-v2-m3), которая оценивает пару (запрос, чанк) совместно, а не по отдельности.

Когда используется: На слабом железе этот шаг опционален — он добавляет 200–500 мс на запрос.

Когда помогает: cross-encoder видит взаимодействие между запросом и текстом и лучше оценивает релевантность для длинных, многосмысловых запросов.

# Применяется после BM25, к топ-N кандидатам
if use_embed_reranker and self.embed_reranker:
    embed_opts = get_embed_rerank_settings(self.db)
    if embed_opts["enable_embed_reranker"] and embed_opts["model"]:
        results = await self.embed_reranker.rerank(
            query=query,
            candidates=results[:embed_opts["candidates"]],
            top_k=top_k,
            model=embed_opts["model"],
            base_url=embed_opts["base_url"],
            endpoint=embed_opts.get("endpoint", "rerank"),
        )

 

Слой 7: Постобработка через рассуждающую модель

Финальный слой — RagPostprocessor. Он принимает топ-K чанков и формирует структурированный ответ через LLM с рассуждением.

Зачем нужен: чанки — это фрагменты документации. Пользователь хочет готовый ответ, а не список отрывков. Постпроцессор:

  • Синтезирует ответ из нескольких чанков

  • Выделяет ключевые тезисы (key_points)

  • Формирует список источников (sources) со ссылками

  • Добавляет предупреждения (warnings) при противоречиях

Контракт ответа:

def normalize_rag_to_contract(semantic_result: dict, postprocess_used: bool = False) -> dict:
    """
    Контракт: {
        "answer": str,
        "key_points": list,
        "sources": list,
        "warnings": list,
        "postprocess_used": bool
    }
    """

Для длинных ответов используется стратегия Map-Reduce:

  1. Map: каждый батч чанков обрабатывается отдельно

  2. Reduce: промежуточные ответы объединяются в финальный

Зачем кешировать результаты постобработки:

Постобработка — самый дорогой шаг, поэтому лучше кешировать результаты запрос-ответ

def build_cache_key(
    query: str,
    rag_result: dict,
    rag_postprocess_model: str,
    rag_postprocess_temperature: float,
    rag_postprocess_context_window: int,
) -> str:
    """
    Детерминированный ключ: SHA256 от (запрос + чанки + параметры модели).
    При изменении любого параметра — промах кеша.
    """
    payload = {
        "query": query.strip(),
        "rag_result": _normalize_rag_result(rag_result),
        "rag_postprocess_model": rag_postprocess_model.strip(),
        "rag_postprocess_temperature": float(rag_postprocess_temperature),
        "rag_postprocess_context_window": int(rag_postprocess_context_window),
    }
    raw = json.dumps(payload, sort_keys=True, ensure_ascii=False)
    return hashlib.sha256(raw.encode("utf-8")).hexdigest()

Ключ кеша включает параметры модели — при смене модели или температуры старые записи автоматически инвалидируются.


Полная схема RAG-пайплайна

 

 

 

Итоги

Каждый слой решает конкретную проблему:

Слой

Проблема

Решение

Хлебные крошки

Чанк без контекста непонятен

heading_path в начале чанка

Redis-кеш эмбеддингов

Повторные запросы медленные

TTL-кеш по SHA256 от текста+модели

pgvector

Семантический поиск

halfvec + cosine distance

RRF

Точные термины теряются

Объединение векторного + FTS

HBK-буст

Синтаксис 1С не находится

Подмешивание чанков из синтакс-помощника

BM25

Неточное ранжирование терминов

Взвешенное среднее vector+BM25

Cross-encoder

Многосмысловые запросы

Совместная оценка пары (запрос, чанк)

Постобработка

Чанки ≠ готовый ответ

Map-Reduce через рассуждающую LLM

Кеш постобработки

LLM медленная

SHA256 от (запрос + чанки + параметры)

 

Всё это работает на ноутбуке MSI Katana HX: Intel Core i5-14450HX (2.40 GHz), ОЗУ 32 ГБ, NVidia GeForce RTX 4060 (8 Гб) Ti Laptop GPU. — локальная модель для эмбеддингов (text-embedding-qwen3-embedding-4b) через LM Studio.

  • PostgreSQL v17 в Docker.

  • модель для Cross-encoder (bge-reranker-v2-m3) в Docker с отдельным эндпойнтом /v1/reranker.

  • Redis для кеша в Docker.

  • модель для Постобработки (qwen3.6-plus-preview) через openrouter.ai.

В базе:

  • разделов ~ 30: загруженные книги, встроенный синтаксис помощник, полное руководство платформы 1С, различные библиотеки (Библиотека стандартных подсистем, Библиотека интернет-поддержки пользователей и.т.п.), разнородная информация с профильных сайтов, различные конфигурации 1С.

  • статей ~ 80, 000

  • чанков ~ 1 500 000

  • информация о кодовой базе различных конфигураций ~ 5 000 000.

На вопрос “какой latency?” - мне хватает)

  • для documents1c ~ 25 секунд по всему пайплайну, основная боль это постобработка.

  • для metadata1c ~ 6 секунд, т.к. там урезанный пайплайн.

Ну и не забываем, это все крутится на ноутбуке.

Всем удачи при проектировании RAG для 1С!

Вступайте в нашу телеграмм-группу Инфостарт

rag mcp

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Инструментарий разработчика Нейросети Платные (руб)

Первые попытки разработки на 1С с использованием больших языковых моделей (LLM) могут разочаровать. LLMки сильно галлюцинируют, потому что не знают устройства конфигураций 1С, не знают нюансов синтаксиса. Но если дать им подсказки с помощью MCP, то результат получается кардинально лучше. Далее в публикации: MCP для поиска по метаданым 1С, справке синтакс-помошника и проверки синтаксиса.

15250 руб.

25.08.2025    51104    103    29    

115

Нейросети 1С:Предприятие 8 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 Платные (руб)

Умный Excel" - ИИ-супердвигатель, который превращает часы работы в минуты! Технологии будущего уже здесь: загрузил Excel "магия ИИ" готовый результат

8540 руб.

02.07.2025    3832    2    0    

6

Нейросети Пользователь 1С:Предприятие 8 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 Оптовая торговля, дистрибуция, логистика Россия Управленческий учет Платные (руб)

Расширение "Искусственный интеллект и нейросети в 1С: Работа с отзывами маркетплейсов" предназначено для применения искусственного интеллекта в повседневной деятельности селлеров на маркетплейсах. Среди функций - работа с отзывами, вопросами и чатами покупателей, диалог с нейросетями, генерация картинок, заполнение описаний номенклатуры и другое.

6100 руб.

03.04.2024    15005    8    0    

12

Мастера заполнения Нейросети 1С:Предприятие 8 1C:Бухгалтерия 1С:Управление торговлей 11 Платные (руб)

Расширение для заполнения описания товара (номенклатуры) с помощью модели ИИ ChatGPT с ключевыми словами. Расширение формирует продающее описание товара по его наименованию с помощью модели искусственного интеллекта. Будет полезно для владельцев интернет магазинов, каталогов товаров и продающих через маркетплейсы. Адаптировано для основных конфигураций: УТ, ЕРП, КА, УНФ. Прошло аудит на 1cfresh.com. Версия для автоматического заполнения

5084 руб.

13.03.2023    22579    52    50    

80

Нейросети Программист 1С 8.3 Бесплатно (free)

Статья описывает первый практический опыт использования искусственного интеллекта для разработки на платформе 1С:Предприятие 8.3. Я, изначально скептически настроенный к применению ИИ в программировании, столкнулся с задачей срочного переноса функционала Telegram-бота на электронную почту из-за блокировки Telegram. В условиях ограниченного доступа к инструментам был использован доступный ИИ-сервис для анализа существующего кода, проектирования архитектуры решения и генерации нового модуля отправки писем. В статье подробно показан процесс постановки задач, уточнения требований, генерации кода, исправления ошибок и финального внедрения решения. В результате был создан полноценный модуль на 1С объемом около 2000 строк кода, успешно внедренный и использованный для автоматической рассылки отчетов.

15.04.2026    3232    apatyukov    76    

20

Инструментарий разработчика Управление знаниями (Knowledge Base) Нейросети Программист 1С 8.3 Абонемент ($m)

Чеширский кот - это база знаний html-страниц, автоматически формируемых из markdown-разметки. Формат markdown, используемый в "Чеширском коте", дополнен картинками из базы знаний и диаграммами PlantUML. Доступно использование нейросети Sber GigaChat для диалога по содержимому базы знаний.

2 стартмани

13.04.2026    590    2    chuprina_as    2    

4

Инструментарий разработчика Нейросети Программист Абонемент ($m)

Superlanguage — это элегантный мост между текстовым описанием и готовым продуктом. Он демонстрирует, насколько далеко продвинулись большие языковые модели в генерации не просто текста, а полностью интерактивных интерфейсов. Для разработчиков 1С и автоматизаторов это ещё один инструмент в арсенале быстрого прототипирования и создания вспомогательных мобильных утилит.

2 стартмани

11.04.2026    740    2    exitone    7    

3

Нейросети Программист Бесплатно (free)

Вы всё ещё сохраняете промпты в файл и просите Claude записать что-то в memory, тогда мы идём к вам! Представьте - вы час работали с ИИ-ассистентом, решили сложную задачу, разобрались в хитром механизме — и всё это осталось только в истории чата. На следующий день приходится начинать с нуля, объяснять контекст заново. Сlaude-note решает эту проблему: фоновый сервис автоматически перехватывает каждую сессию Claude Code, анализирует её и складывает структурированные знания в вашу базу заметок (Obsidian).

10.04.2026    1536    Ibrogim    15    

13
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ksnik 677 01.04.26 09:16 Сейчас в теме
Показано, почему каждый слой появился и какую конкретную проблему решает. Это делает архитектуру не абстрактной, а инженерно обоснованной.

Зафиксированы грабли, на которые наступили - это важнее успешных решений — они показывают, где система может сломаться.

«ИИ заставляет формализовать». Не пытаться скормить ИИ всю документацию целиком, а построить слои, каждый из которых отвечает за свой тип неопределённости:
хлебные крошки — чтобы чанк не потерял контекст
RRF — чтобы точные термины не утонули в семантике
BM25 — чтобы технические запросы не «размывались»
cross-encoder — чтобы длинные многосмысловые запросы не давали случайных совпадений
постобработка — чтобы чанки превращались в ответ, а не в список фрагментов
И каждый слой — это ответ на вопрос: «в каком месте наивный подход сломается?»
2. Angoleiro 02.04.26 04:51 Сейчас в теме
Очень не хватает примеров (запрос - ответ) с использованием такого подхода.
3. andrew.ab 239 02.04.26 08:25 Сейчас в теме
(2) примеры из кеша RAG системы

Запросов агентов.

Запрос: использование криптографии

Ответ в json формате:

{
  "answer": "Механизм криптографии в «1С:Предприятии» не реализует алгоритмы шифрования самостоятельно, а предоставляет объекты для взаимодействия с внешними модулями сторонних производителей (Microsoft CryptoAPI в Windows, КриптоПРО CSP в Linux/macOS). Основные сценарии использования: шифрование/расшифровка данных и создание/проверка электронной подписи (ЭЦП). Работа базируется на асимметричном шифровании (пара открытый/закрытый ключ) и симметричном шифровании.\n\nАрхитектурные особенности: на сервере применяются синхронные методы, на клиенте — асинхронные. Для веб-клиента требуется установка расширения работы с криптографией и интерактивное разрешение пользователя на доступ к файловой системе и закрытому ключу. Базовой операцией является создание объекта `МенеджерКриптографии`. Для российских модулей параметр `ТипМодуляКриптографии` равен 80.\n\n```bsl\nМенеджерКриптографии = Новый МенеджерКриптографии(\"\", \"\", 80);\n```\nДанный код создает менеджер криптографии для работы с российскими криптографическими модулями.\n\n```bsl\nДляИнициализации = Новый МенеджерКриптографии();\nОбещание = ДляИнициализации.ИнициализироватьАсинх(ИспользованиеИнтерактивногоРежимаКриптографии.Использовать);\nМенеджерКриптографии = Ждать Обещание;\n```\nПример асинхронной инициализации менеджера криптографии с использованием интерактивного режима при неизвестных параметрах модуля.\n\n```bsl\nМенеджерКриптографии = Новый МенеджерКриптографии(\"\", \"\", 80);\nХранилище = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.КорневыеСертификаты);\nСертификатыХранилища = Хранилище.ПолучитьВсе();\nДля Каждого Сертификат Из СертификатыХранилища Цикл\n    Сообщение = \"\";\n    ИмяСубъекта = \"\";\n    Если Не Сертификат.Субъект.Свойство(\"CN\", ИмяСубъекта) Тогда\n   Если Не Сертификат.Субъект.Свойство(\"O\", ИмяСубъекта) Тогда\n    ИмяСубъекта = \"??\";\n   КонецЕсли;\n    КонецЕсли;\n    Действителен = \"\";\n    Если ТекущаяДатаСеанса() > Сертификат.ДатаОкончания Тогда\n   Действителен = \"просрочен (\" + Формат(Сертификат.ДатаОкончания, \"ДФ=dd.MM.yyyy\") + \")\";\n    Иначе\n   Действителен = Формат(Сертификат.ДатаНачала, \"ДФ=dd.MM.yyyy\") + \" - \" + Формат(Сертификат.ДатаОкончания, \"ДФ=dd.MM.yyyy\")\n    КонецЕсли;\n    Сообщение = Сообщение + \"Сертификат \"\"\" + ИмяСубъекта + \"\"\" - \";\n    Сообщение = Сообщение + \" алгоритм ключа: \" + Сертификат.АлгоритмОткрытогоКлюча;\n    Сообщение = Сообщение + \" алгоритм подписи: \" + Сертификат.АлгоритмПодписи;\n    Сообщение = Сообщение + \" действителен: \" + Действителен;\n    Сообщить(Сообщение);\nКонецЦикла;\n```\nПример перебора корневых сертификатов, проверки их срока действия и вывода информации об алгоритмах ключа и подписи.\n\n```bsl\nНаКлиенте\nПроцедура Команда(Команда)\n    Подключить(Истина);\nКонецПроцедуры\nНаКлиенте\nПроцедура Подключить(УстановитьЕслиНеПодключено) Экспорт\n    НачатьПодключениеРасширенияРаботыСКриптографией(\n        Новый ОписаниеОповещения(\n            \"ПослеПодключения\",\n            ЭтотОбъект,\n            УстановитьЕслиНеПодключено));\nКонецПроцедуры\nНаКлиенте\nПроцедура ПослеПодключения(Подключено, УстановитьЕслиНеПодключено) Экспорт\n    Если Подключено Тогда\n        // Расширение работы с криптографией подключено\n    ИначеЕсли УстановитьЕслиНеПодключено Тогда\n        НачатьУстановкуРасширенияРаботыСКриптографией(\n            Новый ОписаниеОповещения(\n                \"Подключить\",\n                ЭтотОбъект,\n                Ложь));\n    Иначе\n        // Не удалось установить или подключить\n        // расширение работы с криптографией\n    КонецЕсли;\nКонецПроцедуры\n```\nПример асинхронного подключения и установки расширения работы с криптографией в веб-клиенте.\n\nПроверка сертификатов выполняется методами `ПроверитьСертификат()` или `ПроверитьСертификатАсинх()` с указанием режимов (например, `ИгнорироватьВремяДействия`, `ИгнорироватьПроверкуВСпискеОтозванныхСертификатов`). Доступ к криптографии на сервере регулируется свойством `ДоступККриптографии` профиля безопасности.",
  "sources": [
    {
      "ref": "its:Платформа_1С:Предприятие_8.3.27:md",
      "score": 0.73
    },
    {
      "ref": "its:Платформа_1С:Предприятие_8.3.27:md",
      "score": 0.73
    },
    {
      "ref": "its:Платформа_1С:Предприятие_8.3.27:md",
      "score": 0.72
    },
    {
      "ref": "its:Платформа_1С:Предприятие_8.3.27:md",
      "score": 0.72
    },
    {
      "ref": "its:Платформа_1С:Предприятие_8.3.27:md",
      "score": 0.71
    },
    {
      "ref": "its:Платформа_1С:Предприятие_8.3.27:md",
      "score": 0.67
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:МенеджерКриптографии",
      "score": 0.7
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:Глобальныйконтекст",
      "score": 0.69
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:Глобальныйконтекст",
      "score": 0.69
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:АдминистрированиеПрофильБезопасности",
      "score": 0.61
    }
  ],
  "warnings": [
    "Не рекомендуется получать несколько хранилищ сертификатов с одинаковыми характеристиками через `МенеджерКриптографии`, так как модификация одного может привести к разному поведению другого.",
    "Механизм криптографии платформы не реализует алгоритмы самостоятельно, а обеспечивает взаимодействие с внешними модулями.",
    "В веб-клиенте выполнение криптографических операций требует запроса разрешения пользователя на доступ к файловой системе и закрытому ключу.",
    "Асинхронная схема работы доступна только на стороне клиентского приложения; на сервере следует использовать синхронные методы."
  ],
  "key_points": [
    "Два основных варианта использования: шифрование/расшифровка и подпись/проверка подписи данных.",
    "Платформа не содержит встроенных алгоритмов, а взаимодействует с внешними модулями (CryptoAPI, КриптоПРО).",
    "На сервере используются синхронные методы, на клиенте — асинхронные.",
    "Веб-клиент требует установки расширения и интерактивного разрешения пользователя на доступ к ключам и файловой системе.",
    "Инициализация выполняется через `МенеджерКриптографии` (параметр 80 для российских модулей).",
    "Доступ на сервере контролируется профилем безопасности (`ДоступККриптографии`)."
  ],
  "postprocess_used": true,
  "postprocess_stats": {
    "map_usage": [
      {
        "total_tokens": 22653,
        "prompt_tokens": 16972,
        "completion_tokens": 5681
      }
    ],
    "reduce_used": false,
    "reduce_usage": null,
    "total_tokens": 22653,
    "chunks_per_batch": [
      10
    ],
    "map_batches_count": 1,
    "total_prompt_tokens": 16972,
    "total_completion_tokens": 5681
  }
}
Показать


Запрос: установка фильтра при выборе значений из справочника с использованием ПараметрыВыбора

Ответ в json формате:

{
  "answer": "В платформе 1С:Предприятие 8.3.27 существует механизм параметров выбора для фильтрации значений при открытии формы выбора. Параметры выбора передаются в открываемую форму через структуру Параметры. Свойство Связи параметров выбора позволяет указать список реквизитов, которые будут поставлять значения для фильтрации. Приоритет отдается элементу из свойства Связи параметров выбора, если значение поля заполнено.\n\nДля ограничения выбора в библиотеке стандартных подсистем используется событие ПриОпределенииПараметровВыбора.\n\n```bsl\n   1. Для всех настроек типа СправочникСсылка.Пользователи скрыть и не разрешать выбирать помеченных на удаление, \n   недействительных и служебных пользователей.\n   Если СвойстваНастройки.ОписаниеТипов.СодержитТип(Тип(\"СправочникСсылка.Пользователи\")) Тогда\n     СвойстваНастройки.ОграничиватьВыборУказаннымиЗначениями = Истина;\n     СвойстваНастройки.ЗначенияДляВыбора.Очистить();\n     СвойстваНастройки.ЗапросЗначенийВыбора.Текст =\n       \"ВЫБРАТЬ Ссылка ИЗ Справочник.Пользователи\n       |ГДЕ НЕ ПометкаУдаления И НЕ Недействителен И НЕ Служебный\";\n   КонецЕсли;\n   2. Для настройки \"Размер\" предусмотреть дополнительное значение для выбора.\n   Если СвойстваНастройки.ПолеКД = Новый ПолеКомпоновкиДанных(\"ПараметрыДанных.Размер\") Тогда\n     СвойстваНастройки.ЗначенияДляВыбора.Добавить(10000000, НСтр(\"ru = 'Больше 10 Мб'\"));\n   КонецЕсли;\n```\n\nПри выборе значения из справочника можно использовать метод Выборка с отбором.\n\n```bsl\n Номенклатура = Справочники.Номенклатура;\nОтбор = Новый Структура(\"ТипНоменклатуры\");\nПусто = Перечисления.ТипыНоменклатуры.ПустаяСсылка();\nОтбор.ТипНоменклатуры = Пусто;\nВыборка = Номенклатура.Выбрать(,,Отбор, \"Наименование Убыв\");\nПока Выборка.Следующий()  Цикл\n    Объект = Выборка.ПолучитьОбъект();\n    Объект.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Товар;\n    Попытка\n        Объект.Записать();\n    Исключение\n        Предупреждение(НСтр(\"ru = 'Невозможно записать объект';\"\n           + \" en = 'Can't write object'\")\n           +\" '\" + Объект + '\" \n           |\" + ОписаниеОшибки(),60);\n    КонецПопытки;\nКонецЦикла;\n```\n\nВ управляемой форме при выборе значения используются свойства:\n- ПараметрыВыбора — значения, по которым проверяется возможность выбора.\n- РежимВыбора — признак режима выбора.\n- ВыборДоступен — признак того, что значения реквизитов объекта соответствуют параметрам выбора.\n\nПеред закрытием формы вызывается обработчик ВыборЗначения. Если параметр СтандартнаяОбработка установлен в значение Истина и ВыборДоступен — Истина, выполняется выбор созданного элемента.",
  "sources": [
    {
      "ref": "its:Платформа_1С:Предприятие_8.3.27:md",
      "score": 0.71
    },
    {
      "ref": "its:Библиотека_стандартных_подсистем_3.1.11:md",
      "score": 0.66
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:СправочникМенеджер",
      "score": 0.66
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:Расширение формы клиентского приложения для справочника",
      "score": 0.62
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:Расширение табличного поля списка справочника",
      "score": 0.55
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:СправочникСписок",
      "score": 0.54
    }
  ],
  "warnings": [],
  "key_points": [
    "Параметры выбора передаются в форму через структуру Параметры.",
    "Связи параметров выбора имеют приоритет над параметрами выбора при заполненных значениях.",
    "Свойство ВыборДоступен определяет возможность выбора созданного элемента.",
    "Обработчик ПриОпределенииПараметровВыбора позволяет ограничить выбор."
  ],
  "postprocess_used": true,
  "postprocess_stats": {
    "map_usage": [
      {
        "total_tokens": 38805,
        "prompt_tokens": 29222,
        "completion_tokens": 9583
      }
    ],
    "reduce_used": false,
    "reduce_usage": null,
    "total_tokens": 38805,
    "chunks_per_batch": [
      10
    ],
    "map_batches_count": 1,
    "total_prompt_tokens": 29222,
    "total_completion_tokens": 9583
  }
}
Показать


Запрос: использование индексов в запросах

Ответ в json формате:

{
  "answer": "Использование индексов в запросах 1С:Предприятия требует соблюдения определенных правил для обеспечения производительности. Индексы должны содержать поля, перечисленные в условии, в самом начале и идти подряд без вклинивания других полей. Платформа автоматически создает индексы для ссылок, периодов и измерений регистров, но при необходимости можно создавать дополнительные индексы, избегая индексации первого измерения регистра или низкоселективных полей.\n\nДля оптимизации запросов с соединениями подзапросов рекомендуется использовать временные таблицы с явным индексированием через выражение ИНДЕКСИРОВАТЬ ПО. Это упрощает работу оптимизатора СУБД и обеспечивает стабильную производительность.\n\nПример использования временных таблиц с индексированием:\n\n```bsl\nМенеджерВТ = Новый МенеджерВременныхТаблиц;\nЗапрос = Новый Запрос;\nЗапрос.МенеджерВременныхТаблиц = МенеджерВТ;\n// Текст пакетного запроса\nЗапрос.Текст = \"\n  // Заполняем временную таблицу. Запрос к регистру лимитов.\n   | ВЫБРАТЬ ...\n   | ПОМЕСТИТЬ Лимиты\n   | ИЗ РегистрСведений.Лимиты\n   | ГДЕ ...\n   | СГРУППИРОВАТЬ ПО ...\n   | ИНДЕКСИРОВАТЬ ПО ...;\n\n// Выполняем основной запрос с использованием временной таблицы\n   ВЫБРАТЬ ...\n   ИЗ Документ.РеализацияТоваровУслуг\n   ЛЕВОЕ СОЕДИНЕНИЕ Лимиты\n   ПО ...;\";\n```\n\nКаждый блок кода выше демонстрирует создание менеджера временных таблиц и формирование пакетного запроса с индексированием временной таблицы для ускорения соединения.\n\nПример запроса, нарушающего требования к индексам (отсутствует отбор по первому полю индекса):\n\n```bsl\nЗапрос.Текст = \"ВЫБРАТЬ  \n| ТоварыНаСкладахОстатки.Склад,  \n| ТоварыНаСкладахОстатки.Номенклатура,  \n| ТоварыНаСкладахОстатки.Качество  \n|ИЗ  \n| РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОстатки\";\n```\n\nВ данном случае запрос не сможет выполниться оптимально, так как отсутствует отбор по первому полю индекса (Склад), что приведет к сканированию таблицы.\n\nkey_points\": [\n  \"Индексы должны содержать поля условия в начале и идти подряд\",\n  \"Временные таблицы следует индексировать через ИНДЕКСИРОВАТЬ ПО\",\n  \"Избегать соединений с подзапросами, использовать временные таблицы\",\n  \"Не индексировать первое измерение регистра повторно\",\n  \"Автоматические индексы создаются платформой для ссылок и периодов\"\n],\n\"sources\": [\n  {\n    \"ref\": \"its:Методическая_поддержка_для_разработчиков_и_администраторов_1С:Предприятия_8:md\",\n    \"score\": 0.7263852953910828\n  },\n  {\n    \"ref\": \"its:Система_стандартов_и_методик_разработки_конфигураций:md\",\n    \"score\": 0.7232416868209839\n  },\n  {\n    \"ref\": \"its:Описание_встроенного_языка_1С:ЗапросВыбораСхемыЗапроса\",\n    \"score\": 0.7125225067138672\n  }\n],\n\"warnings\": []\n}",
  "sources": [
    {
      "ref": "its:Методическая_поддержка_для_разработчиков_и_администраторов_1­С:Предприятия_8:md",
      "score": 0.73
    },
    {
      "ref": "its:Система_стандартов_и_методик_разработки_конфигураций:md",
      "score": 0.72
    },
    {
      "ref": "its:Описание_встроенного_языка_1С:ЗапросВыбораСхемыЗапроса",
      "score": 0.71
    }
  ],
  "warnings": [],
  "key_points": [],
  "postprocess_used": true,
  "postprocess_stats": {
    "map_usage": [
      {
        "total_tokens": 40377,
        "prompt_tokens": 33295,
        "completion_tokens": 7082
      }
    ],
    "reduce_used": false,
    "reduce_usage": null,
    "total_tokens": 40377,
    "chunks_per_batch": [
      10
    ],
    "map_batches_count": 1,
    "total_prompt_tokens": 33295,
    "total_completion_tokens": 7082
  }
}
Показать


Запрос: примеры работы с криптографией в платформе 8.5.1

Ответ в json формате:

{
  "answer": "В платформе 1С:Предприятие 8.5.1 механизм криптографии базируется на асимметричном шифровании (открытый и закрытый ключи). На стороне сервера используются синхронные методы, на стороне клиента — асинхронные. Для работы с модулями криптографии в ОС Windows используется Microsoft CryptoAPI, в Linux/macOS — КриптоПРО CSP (значение параметра ТипМодуляКриптографии равно 80).\n\nПример создания менеджера криптографии:\n```bsl\nМенеджерКриптографии = Новый МенеджерКриптографии(\"\", \"\", 80);\n```\n\nПример асинхронной инициализации:\n```bsl\nДляИнициализации = Новый МенеджерКриптографии();\nОбещание = ДляИнициализации.ИнициализироватьАсинх(ИспользованиеИнтерактивногоРежимаКриптографии.Использовать);\nМенеджерКриптографии = Ждать Обещание;\n```\n\nПример получения списка сертификатов (корневые):\n```bsl\nМенеджерКриптографии = Новый МенеджерКриптографии(\"\", \"\", 80);\nХранилище = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.КорневыеСертификаты);\nСертификатыХранилища = Хранилище.ПолучитьВсе();\nДля Каждого Сертификат Из СертификатыХранилища Цикл\n    Сообщение = \"\";\n    ИмяСубъекта = \"\";\n    Если Не Сертификат.Субъект.Свойство(\"CN\", ИмяСубъекта) Тогда\n   Если Не Сертификат.Субъект.Свойство(\"O\", ИмяСубъекта) Тогда\n    ИмяСубъекта = \"??\";\n   КонецЕсли;\n    КонецЕсли;\n    Действителен = \"\";\n    Если ТекущаяДатаСеанса() > Сертификат.ДатаОкончания Тогда\n   Действителен = \"просрочен (\" + Формат(Сертификат.ДатаОкончания, \"ДФ=dd.MM.yyyy\") + \")\";\n    Иначе\n\nКонецЕсли;\n    КонецЕсли;\n    Действителен = \"\";\n    Если ТекущаяДатаСеанса() > Сертификат.ДатаОкончания Тогда\n   Действителен = \"просрочен (\" + Формат(Сертификат.ДатаОкончания, \"ДФ=dd.MM.yyyy\") + \")\";\n    Иначе\n   Действителен = Формат(Сертификат.ДатаНачала, \"ДФ=dd.MM.yyyy\") + \" - \" + Формат(Сертификат.ДатаОкончания, \"ДФ=dd.MM.yyyy\")\n    КонецЕсли;\n    Сообщение = Сообщение + \"Сертификат \"\"\" + ИмяСубъекта + \"\"\" - \";\n    Сообщение = Сообщение + \" алгоритм ключа: \" + Сертификат.АлгоритмОткрытогоКлюча;\n    Сообщение = Сообщение + \" алгоритм подписи: \" + Сертификат.АлгоритмПодписи;\n    Сообщение = Сообщение + \" действителен: \" + Действителен;\n    Сообщить(Сообщение);\nКонецЦикла;\n```\n\nПример асинхронного получения списка сертификатов:\n```bsl\nАсинх Функция ПолучитьСписокСертификатов(ТипМенеджераКриптографии, МассивТипов, ПроверятьДатуОкончания)\n    СписокСертификатов = Новый Массив;\n    МенеджерКриптографии = Новый МенеджерКриптографии(\"\", \"\", ТипМенеджераКриптографии);\n    Для Каждого ТипХранилища Из МассивТипов Цикл\n   // Получаем сертификаты для каждого типа хранилища сертификатов\n   Хранилище = Ждать МенеджерКриптографии.ПолучитьХранилищеСертификатовАсинх(ТипХранилища);\n   // Выбираем все сертификаты\n   СертификатыХранилища = Ждать Хранилище.ПолучитьВсеАсинх();\n   ТекущаяДата = ТекущаяДата();\n   Для Каждого Сертификат Из СертификатыХранилища Цикл\n    // Проверим, что дата окончания сертификата еще не наступила\n    Если ПроверятьДатуОкончания И Сертификат.ДатаОкончания < ТекущаяДата Тогда\n     Продолжить;\n    КонецЕсли;\n\nСертификат Из СертификатыХранилища Цикл\n    // Проверим, что дата окончания сертификата еще не наступила\n    Если ПроверятьДатуОкончания И Сертификат.ДатаОкончания < ТекущаяДата Тогда\n     Продолжить;\n    КонецЕсли;\n    СписокСертификатов.Добавить(Сертификат);\n   КонецЦикла;\n    КонецЦикла;\n    Возврат СписокСертификатов;\nКонецФункции\n&НаКлиенте\nАсинх Процедура ВыполнитьКоманду(Команда)\n    ТипыХранилищ = Новый Массив;\n    ТипыХранилищ.Добавить(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты);\n    ТипыХранилищ.Добавить(ТипХранилищаСертификатовКриптографии.СертификатыПолучателей);\n    Список = Ждать ПолучитьСписокСертификатов(80, ТипыХранилищ, Истина);\n    // …\nКонецПроцедуры\n```\n\nПример шифрования файла:\n```bsl\n&НаСервере\nФункция ЗашифроватьНаСервере(АдресДанных, ДанныеСертификатов)\n    // Создадим сертификаты на основании двоичных данных сертификатов с клиента\n    Сертификаты = Новый Массив();\n    Для Каждого ДанныеСертификата Из ДанныеСертификатов Цикл\n   Сертификаты.Добавить(Новый СертификатКриптографии(ДанныеСертификата));\n    КонецЦикла;\n    МенеджерКриптографии = Новый МенеджерКриптографии(\"\", \"\", 80);\n    // Получим файл для шифрования из временного хранилища\n    Данные = ПолучитьИзВременногоХранилища(АдресДанных);\n    Если ТипЗнч(Данные) <> Тип(\"ДвоичныеДанные\") Тогда\n   Возврат Ложь;\n    КонецЕсли;\n    // Шифруем двоичные данные\n    ЗашифрованныеДвоичныеДанные = МенеджерКриптографии.Зашифровать(Данные, Сертификаты);\n    // Сохраняем во временное хранилище\n\nТип(\"ДвоичныеДанные\") Тогда\n   Возврат Ложь;\n    КонецЕсли;\n    // Шифруем двоичные данные\n    ЗашифрованныеДвоичныеДанные = МенеджерКриптографии.Зашифровать(Данные, Сертификаты);\n    // Сохраняем во временное хранилище\n    АдресДанных = ПоместитьВоВременноеХранилище(ЗашифрованныеДвоичныеДанные);\n    Возврат Истина;\nКонецФункции\n&НаКлиенте\nАсинх Процедура ВыполнитьКоманду(Команда)\n    ПомещенныйФайл = Ждать ПоместитьФайлНаСерверАсинх(, , , Новый ПараметрыДиалогаПомещенияФайлов);\n    Если ПомещенныйФайл = Неопределено Тогда\n   Возврат;\n    КонецЕсли;\n    Адрес = ПомещенныйФайл.Адрес;\n    ТипыСертификатов = Новый Массив;\n    ТипыСертификатов.Добавить(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты);\n    Список = Ждать ПолучитьСписокСертификатов(80, ТипыСертификатов, Истина);\n    // В примере всегда шифруем с помощью первого по порядку сертификата\n    // В реальной жизни это может не сработать и\n    // надо выбирать сертификат по другим критериям\n    Сертификаты = Новый Массив;\n\nИстина);\n    // В примере всегда шифруем с помощью первого по порядку сертификата\n    // В реальной жизни это может не сработать и\n    // надо выбирать сертификат по другим критериям\n    Сертификаты = Новый Массив;\n    Сертификаты.Добавить(Ждать Список[0].ВыгрузитьАсинх());\n    // Шифруем файл\n    РезультатШифрования = ЗашифроватьНаСервере(Адрес, Сертификаты);\n    Если Не РезультатШифрования Тогда\n   Возврат;\n    КонецЕсли;\n    // Интерактивно сохраняем зашифрованный файл на диск\n    ПолучитьФайлССервераАсинх(Адрес, ПомещенныйФайл.СсылкаНаФайл.Файл.ПолноеИмя + \".signed\", Новый ПараметрыДиалогаПолученияФайлов);\nКонецПроцедуры\n```",
  "sources": [
    {
      "ref": "its:Платформа_1С:Предприятие_8.5.1:md",
      "score": 0.72
    },
    {
      "ref": "its:Платформа_1С:Предприятие_8.5.1:md",
      "score": 0.71
    },
    {
      "ref": "its:Платформа_1С:Предприятие_8.5.1:md",
      "score": 0.71
    }
  ],
  "warnings": [],
  "key_points": [
    "Механизм криптографии базируется на асимметричном шифровании (открытый и закрытый ключи).",
    "На стороне сервера используются синхронные методы, на стороне клиента — асинхронные.",
    "Для работы с модулями криптографии в ОС Windows используется Microsoft CryptoAPI, в Linux/macOS — КриптоПРО CSP (значение параметра ТипМодуляКриптографии равно 80).",
    "Закрытый ключ хранится в контейнере, защищенном паролем, и не представлен в объектной модели системы.",
    "Приведены примеры создания менеджера криптографии, получения списка сертификатов и шифрования файла."
  ],
  "postprocess_used": true,
  "postprocess_stats": {
    "map_usage": [
      {
        "total_tokens": 75819,
        "prompt_tokens": 66601,
        "completion_tokens": 9218
      }
    ],
    "reduce_used": false,
    "reduce_usage": null,
    "total_tokens": 75819,
    "chunks_per_batch": [
      10
    ],
    "map_batches_count": 1,
    "total_prompt_tokens": 66601,
    "total_completion_tokens": 9218
  }
}
Показать


Запрос: ПолучитьСотрудниковОрганизаций отбор подразделение

Ответ в json формате:

{
  "answer": "Для получения сотрудников организации в 1С:ЗУП 3.1 используется метод КадровыйУчет.СотрудникиОрганизации. Перед вызовом необходимо сконфигурировать параметры вызова, используя программный интерфейс. Для этого можно использовать методы с предустановками из программного интерфейса общего модуля КадровыйУчет или метод КадровыйУчет.ПараметрыПолученияСотрудниковОрганизаций. Через свойство «Отборы» параметра получения данных можно использовать отборы по кадровым данным сотрудников используя операторы сравнения.\n\nПример кода, для получения всех сотрудников организации, принятых с определенной даты:\n\n```bsl\nПараметрыСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизацийПоСпискуФизическихЛи­ц();\n\nПараметрыПолучения.Организация = Организация;\n\nЗарплатаКадрыОбщиеНаборыДанных.ДобавитьВКоллекциюОтбор(\nПараметрыСотрудников.Отборы, \"ДатаПриема\", \">=\", ПериодОтбора);\n\nСотрудники = КадровыйУчет.СотрудникиОрганизации(Истина, ПараметрыСотрудников);\n```\n\nПример получения кадровых данных сотрудников за период с использованием временных таблиц:\n\n```bsl\nМенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;\n\nЗарплатаКадрыОбщиеНаборыДанных.СоздатьВТПериоды(МенеджерВременныхТаблиц,\nНачалоПериода,\nОкончаниеПериода,\n\"День\",,,Истина);\n\nЗапрос = Новый Запрос;\n\nЗапрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;\n\nЗапрос.УстановитьПараметр(\"МассивСотрудников\", МассивСотрудников);\n\nЗапрос.Текст =\n\"ВЫБРАТЬ РАЗЛИЧНЫЕ\n|\tВТПериоды.Период КАК Период,\n|\tДанныеСотрудников.Ссылка КАК Сотрудник\n|ПОМЕСТИТЬ ВТСписокСотрудников\n|ИЗ\n|\tСправочник.Сотрудники КАК ДанныеСотрудников,\n|\tВТПериоды КАК ВТПериоды\n|ГДЕ\n|\tДанныеСотрудников.Ссылка В(&МассивСотрудников)\";\n\nЗапрос.Выполнить();\n\nОписательВременныхТаблиц = КадровыйУчет.ОписательВременныхТаблицДляСоздатьВТКадровыеДанныеСотруднико­в(\nМенеджерВременныхТаблиц, \"ВТСписокСотрудников\");\n\nКадровыеДанные = \"Должность\";\n\nКадровыйУчет.СоздатьВТКадровыеДанныеСотрудников(ОписательВременныхТаблиц, Истина, КадровыеДанные, , Ложь);\n```",
  "sources": [
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.67
    }
  ],
  "warnings": [],
  "key_points": [
    "Использование метода КадровыйУчет.СотрудникиОрганизации для получения списка сотрудников",
    "Конфигурация параметров вызова через программный интерфейс КадровыйУчет",
    "Применение свойства Отборы для фильтрации кадровых данных сотрудников"
  ],
  "postprocess_used": true,
  "postprocess_stats": {
    "map_usage": [
      {
        "total_tokens": 52884,
        "prompt_tokens": 47659,
        "completion_tokens": 5225
      }
    ],
    "reduce_used": false,
    "reduce_usage": null,
    "total_tokens": 52884,
    "chunks_per_batch": [
      10
    ],
    "map_batches_count": 1,
    "total_prompt_tokens": 47659,
    "total_completion_tokens": 5225
  }
}
Показать


Запрос: КадровыеДанныеСотрудниковПоТаблицеЗначений ФизическоеЛицо

Ответ в json формате:

{
  "answer": "В конфигурации 1С:ЗУП 3.1 для получения кадровых данных физических лиц и сотрудников используются методы общего модуля КадровыйУчет. Методы КадровыеДанныеФизическихЛиц и КадровыеДанныеСотрудников возвращают данные в виде таблицы значений. Для получения данных за период используются методы СоздатьВТКадровыеДанныеФизическихЛиц и СоздатьВТКадровыеДанныеСотрудников.\n\nПример получения сотрудников с фильтрацией:\n```bsl\nПараметрыСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизацийПоСпискуФизическихЛи­ц();\n\nПараметрыПолучения.Организация = Организация;\n\nЗарплатаКадрыОбщиеНаборыДанных.ДобавитьВКоллекциюОтбор(\nПараметрыСотрудников.Отборы, \"ДатаПриема\", \">=\", ПериодОтбора);\n\nСотрудники = КадровыйУчет.СотрудникиОрганизации(Истина, ПараметрыСотрудников);\n```\n\nПример создания временной таблицы кадровых данных за период:\n```bsl\nМенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;\n\nЗарплатаКадрыОбщиеНаборыДанных.СоздатьВТПериоды(МенеджерВременныхТаблиц,\nНачалоПериода,\nОкончаниеПериода,\n\"День\",,,Истина);\n\nЗапрос = Новый Запрос;\nЗапрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;\nЗапрос.УстановитьПараметр(\"МассивСотрудников\", МассивСотрудников);\nЗапрос.Текст =\n\"ВЫБРАТЬ РАЗЛИЧНЫЕ\n|\tВТПериоды.Период КАК Период,\n|\tДанныеСотрудников.Ссылка КАК Сотрудник\n|ПОМЕСТИТЬ ВТСписокСотрудников\n|ИЗ\n|\tСправочник.Сотрудники КАК ДанныеСотрудников,\n|\tВТПериоды КАК ВТПериоды\n|ГДЕ\n|\tДанныеСотрудников.Ссылка В(&МассивСотрудников)\";\n\nЗапрос.Выполнить();\n\nОписательВременныхТаблиц = КадровыйУчет.ОписательВременныхТаблицДляСоздатьВТКадровыеДанныеСотруднико­в(\nМенеджерВременныхТаблиц, \"ВТСписокСотрудников\");\n\nКадровыеДанные = \"Должность\";\n\nКадровыйУчет.СоздатьВТКадровыеДанныеСотрудников(ОписательВременныхТаблиц, Истина, КадровыеДанные, , Ложь);\n```",
  "sources": [
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.68
    }
  ],
  "warnings": [],
  "key_points": [
    "Методы КадровыеДанныеФизическихЛиц и КадровыеДанныеСотрудников возвращают данные в виде таблицы значений",
    "Для получения данных за период используются методы СоздатьВТКадровыеДанныеФизическихЛиц и СоздатьВТКадровыеДанныеСотрудников",
    "Параметры отбора настраиваются через КадровыйУчет.ПараметрыПолученияСотрудниковОрганизаций"
  ],
  "postprocess_used": true,
  "postprocess_stats": {
    "map_usage": [
      {
        "total_tokens": 55934,
        "prompt_tokens": 48163,
        "completion_tokens": 7771
      }
    ],
    "reduce_used": false,
    "reduce_usage": null,
    "total_tokens": 55934,
    "chunks_per_batch": [
      10
    ],
    "map_batches_count": 1,
    "total_prompt_tokens": 48163,
    "total_completion_tokens": 7771
  }
}
Показать


Запрос: СтажСотрудника расчет стажа

Ответ в json формате:

{
  "answer": "В предоставленных фрагментах документации ЗУП 3.1 описан программный интерфейс для работы с кадровыми данными и периодами, однако конкретная логика расчета стажа через объект 'СтажСотрудника' в тексте не приведена. Приведены примеры использования методов для получения данных сотрудников за период и формирования временных таблиц.\n\nПример получения должности заданного списка сотрудников за месяц, на каждый день:\n\n```bsl\nМенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;\n\nЗарплатаКадрыОбщиеНаборыДанных.СоздатьВТПериоды(МенеджерВременныхТаблиц,\nНачалоПериода,\nОкончаниеПериода,\n\"День\",,,Истина);\n\nЗапрос = Новый Запрос;\nЗапрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;\n\nЗапрос.УстановитьПараметр(\"МассивСотрудников\", МассивСотрудников);\nЗапрос.Текст =\n\"ВЫБРАТЬ РАЗЛИЧНЫЕ\n|\tВТПериоды.Период КАК Период,\n|\tДанныеСотрудников.Ссылка КАК Сотрудник\n|ПОМЕСТИТЬ ВТСписокСотрудников\n|ИЗ\n|\tСправочник.Сотрудники КАК ДанныеСотрудников,\n|\tВТПериоды КАК ВТПериоды\n|ГДЕ\n|\tДанныеСотрудников.Ссылка В(&МассивСотрудников)\";\n\nЗапрос.Выполнить();\n```\n\nПример заполнения значений по умолчанию типового документа Отпуск:\n\n```bsl\nЕсли ЭтоИсправление Тогда\nЗначенияДляЗаполнения = Новый Структура(\"Месяц\",\n\"Объект.ПериодРегистрации\");\nИначе\nЗначенияДляЗаполнения = Новый Структура(\"Организация, Ответственный, \t\tМесяц\",\n\"Объект.Организация\",\n\"Объект.Ответственный\",\n\"Объект.ПериодРегистрации\");\nКонецЕсли;\n\nЗарплатаКадры.ЗаполнитьПервоначальныеЗначенияВФорме(ЭтаФорма, ЗначенияДляЗаполнения);\n```",
  "sources": [
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.51
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.49
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.48
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.47
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.47
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.47
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.46
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.45
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.44
    },
    {
      "ref": "its:Особенности_конфигурации_Зарплата_и_Управление_персоналом_3.1:docx",
      "score": 0.44
    }
  ],
  "warnings": [],
  "key_points": [
    "Программный интерфейс ЗУП 3.1 (КадровыйУчет, ЗарплатаКадрыОбщиеНаборыДанных) для работы с кадровыми данными",
    "Методы создания временных таблиц периодов (СоздатьВТПериоды)",
    "Использование интервальных регистров для анализа кадровых данных",
    "Механизм заполнения значений по умолчанию в формах документов"
  ],
  "postprocess_used": true,
  "postprocess_stats": {
    "map_usage": [
      {
        "total_tokens": 58322,
        "prompt_tokens": 49859,
        "completion_tokens": 8463
      }
    ],
    "reduce_used": false,
    "reduce_usage": null,
    "total_tokens": 58322,
    "chunks_per_batch": [
      10
    ],
    "map_batches_count": 1,
    "total_prompt_tokens": 49859,
    "total_completion_tokens": 8463
  }
}
Показать
Aleskey_K; ksnik; +2 Ответить
4. andrew.ab 239 02.04.26 08:45 Сейчас в теме
(2) из примеров видно что даже этот пайплайн не идеален. Сейчас, в свободное время, работаю на новым функционалом по оценке системных промтов и результата моделью судьей.

На скрине видно что по запросу "установка фильтра при выборе значений из справочника с использованием ПараметрыВыбора" был получен смешанный ответ из разнородной информации, т.е. на этапе postprocess модель впихнула все в один ответ.
Прикрепленные файлы:
Для отправки сообщения требуется регистрация/авторизация