Представьте: бухгалтер получает сотни писем с документами — счетами-фактурами, актами, накладными. Каждое нужно открыть, проверить, вручную перенести данные в 1С. Это занимает часы, а ошибки стоят дорого.
Что если нейросеть будет делать это за секунды?
В этой статье я покажу, как построить локального AI-агента, который:
Всё работает локально, без облаков, без передачи данных наружу.
Конвейер состоит из четырех последовательных этапов:
Для решения задачи я использовал уже знакомую нам модель Qwen3-30b-a3b-instruct через OpenAI-совместимый API. Почему она:
Агент подключается к почтовому ящику через IMAP и ищет письма с вложениями.
Аналогичный принцип используют корпоративные решения: агенты O2C отслеживают общие почтовые ящики финансового отдела (например, ar@company.com, billing@company.com) и обрабатывают входящие письма в реальном времени [citation:2].
import imaplib
import email
from email.policy import default
def fetch_invoices_from_mailbox(host, user, password):
mail = imaplib.IMAP4_SSL(host)
mail.login(user, password)
mail.select('inbox')
status, messages = mail.search(None, 'UNSEEN')
if status != 'OK':
return []
invoices = []
for msg_id in messages[0].split():
_, data = mail.fetch(msg_id, '(RFC822)')
raw = data[0][1]
msg = email.message_from_bytes(raw, policy=default)
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get_content_disposition() is None:
continue
filename = part.get_filename()
if filename and (filename.endswith('.pdf') or filename.endswith(('.jpg', '.jpeg', '.png'))):
content = part.get_payload(decode=True)
invoices.append({
'from': msg['From'],
'subject': msg['Subject'],
'filename': filename,
'content': content,
'date': msg['Date']
})
mail.close()
mail.logout()
return invoices
Ключевая фишка — вызов инструментов (function calling). Модель возвращает строгий JSON, который можно сразу передавать в 1С через API.
{
"type": "function",
"function": {
"name": "save_invoice_to_1c",
"description": "Создает JSON для загрузки счета-фактуры в 1С",
"parameters": {
"type": "object",
"properties": {
"vendor": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "Название контрагента"},
"inn": {"type": "string", "description": "ИНН контрагента"},
"kpp": {"type": "string", "description": "КПП контрагента"}
}
},
"invoice": {
"type": "object",
"properties": {
"number": {"type": "string", "description": "Номер счета-фактуры"},
"date": {"type": "string", "description": "Дата счета-фактуры (YYYY-MM-DD)"},
"total": {"type": "number", "description": "Итоговая сумма"},
"nds": {"type": "number", "description": "Сумма НДС"},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "Наименование товара"},
"quantity": {"type": "number", "description": "Количество"},
"price": {"type": "number", "description": "Цена за единицу"},
"total": {"type": "number", "description": "Сумма по позиции"}
}
}
}
}
}
},
"required": ["vendor", "invoice"]
}
}
}
{
"vendor": {
"name": "ООО Техно-Плюс",
"inn": "7708123456",
"kpp": "770801001"
},
"invoice": {
"number": "СФ-2026-0042",
"date": "2026-07-20",
"total": 124580.00,
"nds": 20763.33,
"items": [
{"name": "Системный блок", "quantity": 3, "price": 28500.00, "total": 85500.00},
{"name": "Монитор 27\"", "quantity": 2, "price": 19540.00, "total": 39080.00}
]
}
}
Используем визуально-языковую модель qwen3-vl:30b-a3b-instruct [citation:1].
Она умеет распознавать как текстовые PDF, так и сканы документов [citation:5].
ollama pull qwen3-vl:30b-a3b-instruct
Qwen3-VL поддерживает работу с изображениями через Ollama, начиная с версии 0.12.7 [citation:1][citation:9].
import base64
import json
from ollama import chat # библиотека для работы с Ollama
def process_invoice(file_content, filename):
# Кодируем файл в base64 для передачи в модель
b64 = base64.b64encode(file_content).decode('utf-8')
response = chat(
model='qwen3-vl:30b-a3b-instruct',
messages=[{
'role': 'user',
'content': 'Извлеки данные из счета-фактуры. Верни JSON с полями: vendor (name, inn, kpp), invoice (number, date, total, nds, items).',
'images': [b64] # передаём изображение или скан
}]
)
# Парсим ответ модели в JSON
return json.loads(response.message.content)
# Основной цикл
for invoice in fetch_invoices_from_mailbox('imap.yandex.ru', 'user', 'pass'):
result = process_invoice(invoice['content'], invoice['filename'])
if result:
print(json.dumps(result, indent=2, ensure_ascii=False))
# Отправляем JSON в 1С через API
# requests.post('http://1c-server/hs/Invoice', json=result)
На сервере с CPU (60 ГБ RAM) модель показывает:
Мы построили полностью локального AI-агента, который:
Это не просто концепция — аналогичные решения уже внедряются в российских компаниях. Например, Smart Engines разработала ИИ-агента, который за час выполняет месячную работу 10 бухгалтеров [citation:15].
Комментарии
Пока нет комментариев. Будьте первым!