Головна / Статті / Практичні зауваження: Місцевий агент підтримки з SmolLM3: режим мислення, інструменти та

Практичні зауваження: Місцевий агент підтримки з SmolLM3: режим мислення, інструменти та

Покрокове керівництво з практичних нотаток: Агент локальної підтримки з SmolLM3: режим мислення, інструменти, а також контракти, перевірки та слоти для коду для команд, які використовують цю схему.

1641 слів

Використовуйте цей документ як оновлену версію ідей з книги “A Local Support Agent with SmolLM3: Think Mode, Tools, and When Not to Reason” для працівників операторів: чіткі етапи, впорядковані блоки коду та примітки щодо відновлення, які зберігаються після передачі обов’язків. Етап Огляду найкраще функціонує, якщо його розглядати як вимірювану основу. Запишіть один ідеальний запис розмови, один випадок збою та примітки щодо скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як угоду між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не погоджуйтесь на мовчазне часткове виконання завдань.

Налаштування

На етапі налаштування необхідно визначити вхідні дані, виконавця кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Чітке відображення витрат заздалегідь запобігає несподіваним рахункам під час переходу від демо-середовища до спільних середовищ. У разі, коли наступним кроком є написання коду чи виклик інструменту, краще використовувати структуровані результати з перевіркою схеми, ніж вільний текст.

Використання модуля Think vs no_think — це рішення продукту

Для етапу «Мислення проти немислення» необхідно перед зміною коду визначити вхідні дані, власника кроку та критерії завершення. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функціоналу мають знаходитися в одному місці, яке оператори можуть перевірити, не читаючи весь алгоритм. Коли наступним кроком є код або виклик інструменту, краще використовувати структуровані результати з перевіркою схеми, ніж вільний текст.

messages = [
    {"role": "system", "content": "/no_think"},
    {"role": "user", "content": prompt},
]
tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True,
    enable_thinking=False,  # the /no_think flag in the system prompt wins if both are set
)
<|im_start|>assistant
<think>

</think>
final = re.sub(r"<think>.*?</think>", "", raw, flags=re.DOTALL).strip()
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>
TOOLS = [
    {
        "name": "lookup_order_status",
        "description": (
            "Look up the current status, estimated delivery date, and carrier "
            "for a specific customer order. Call this when the customer mentions "
            "an order number or asks where their order is."
        ),
        "parameters": {
            "type": "object",
            "properties": {
                "order_id": {
                    "type": "string",
                    "description": "The order ID, usually in the format ORD-XXXXXX.",
                }
            },
            "required": ["order_id"],
        },
    }
]
ORDERS = {
    "ORD-4821": {"status": "shipped", "eta": "June 18, 2026", "carrier": "DHL"},
    "ORD-3307": {"status": "processing", "eta": "June 20, 2026", "carrier": None},
    "ORD-1190": {"status": "delivered", "eta": None, "carrier": "FedEx"},
}
def respond_with_tools(user_message: str) -> str:
    messages = [{"role": "user", "content": user_message}]
    turn1 = generate_reply(messages)
    name, args = parse_tool_call(turn1)
    if name == "lookup_order_status":
        result = lookup_order_status(**args)
        messages += [
            {"role": "assistant", "content": turn1},
            {"role": "tool", "content": json.dumps(result), "name": name},
        ]
        return generate_reply(messages)
    return turn1
<tool_call>
{"name": "lookup_order_status", "arguments": {"order_id": "ORD-4821"}}
</tool_call>

Саме тут помирає наївний цикл у роботі з електронними листами

На цьому етапі, коли йдеться про електронний тикет, необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Необхідно документувати як шлях успішного виконання, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. У разі, коли наступним кроком є код або виклик інструменту, краще використовувати структуровані результати з перевіркою схеми, ніж вільний текст. На цьому етапі, коли йдеться про електронний тикет, необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.

<tool_call>
{"name": "lookup_order_status", "arguments": {"order_id": "your_order_id"}}
</tool_call>

Охоронці, які не піддаються деталізованій налаштуванню

Під час роботи з охоронцями, які не є етапними, спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та наслідки часткової невдачі. Такий перелік допомагає зберігати чесність у подальших змінах коду. Запишіть час виконання та витрати на токени або запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні. Зберігайте в кеші стабільні інструкції системи та схеми інструментів. Повторна передача ідентичних даних є поширеною причиною зайвих витрат.

ORDER_RE = re.compile(r"^ORD-\d{4,}quot;)
PURE_TOOL_RE = re.compile(r"^\s*<tool_call>(.*?)</tool_call>\s*quot;, re.DOTALL)

def parse_executable_tool_call(output: str):
    cleaned = re.sub(r"<think>.*?</think>", "", output, flags=re.DOTALL).strip()
    match = PURE_TOOL_RE.match(cleaned)
    if not match:
        return None
    payload = json.loads(match.group(1).strip())
    order_id = str(payload.get("arguments", {}).get("order_id", "")).strip()
    if not ORDER_RE.match(order_id):
        return None
    return payload

Що це не доводить

Під час роботи над розділом «Що це не підтримує», спочатку запишіть умови контракту: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Зберігайте у кеші стабільні інструкції системи та схеми інструментів. Повторна передача ідентичних даних є поширеною причиною витрат ресурсів.

Запустіть його

Під час роботи на етапі «Запустити» спочатку запишіть умови виконання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Одночасно задокументуйте шлях успішного виконання та шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Зберігайте у кеші стабільні інструкції системи та схеми інструментів. Повторна передача ідентичних даних є поширеною причиною витрат ресурсів. Під час роботи на етапі «Запустити» спочатку запишіть умови виконання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Розглядайте цей етап як угоду між вхідними даними та перевіреними результатами. Дайте назви елементам, визначте критерії успіху та не допускайте безповідомного часткового завершення.

python llm-learning/smollm3-local-support-agent/code/think_vs_nothink.py
python llm-learning/smollm3-local-support-agent/code/support_agent.py
python llm-learning/smollm3-local-support-agent/code/support_agent_guarded.py

Перелік операційних кроків

Під час роботи над етапом перевірки операційного процесу спочатку запишіть умови контракту: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової несправності. Такий перелік допомагає зберігати чесність подальших змін у коді.

Віддавайте перевагу невеликим, тестованим одиницям коду перед складними скриптами. Якщо якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність дій.

Зберігайте у кеші стабільні інструкції системи та схеми інструментів. Повторна передача ідентичних даних є поширеною причиною непотрібних витрат.

Робіть інструменти з вузькими схемами та чіткими позначеннями побічних ефектів доступними. Хостам потрібно знати, які виклики змінюють стан системи, перш ніж вони автоматично схвалюють їх.

Встановіть людське схвалення для операцій, які призводять до витрат грошей чи змінюють дані у продакшені. Компіляційне підключення елементів не гарантує повноти бізнес-функціоналу.

Напишіть короткий посібник: як змінювати ключі, як спорожнювати чергу, як скасовувати останню операцію імпорту.

Перш ніж запускати стек у продакшн, заморозьте версії, створіть «золотий» запис для критичного шляху виконання та підтвердьте кроки для скасування змін. У спільних середовищах необхідні обмеження на частоту запитів, перевірки прав доступу та чіткий власник для заміни секретів. Віддавайте перевагу надійності перед креативними одноразовими демонстраціями.

Примітка до пакету 0e44ad944ff5: не зберігайте ключі постачальника у репозиторії, встановіть ліміт токенів на сеанс та зберігайте записи поруч із фікстурами для оцінки, щоб подальша заміна моделей залишалася порівнянною.

Під час роботи над пунктом посилення безпеки 0 спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успіх та наслідки часткової невдачі. Цей перелік допоможе зберегти чесність у подальших змінах коду. Документуйте як успішний, так і відновлювальний шляхи роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації.

Деталь посилення безпеки 0/868: виміряйте час виконання, клас помилки та кількість витрачених токенів для цього запису, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі запитань, а не на окремих випадках.

Етап 1 посилення безпеки найкраще функціонує, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та запис про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового виконання.

Деталь посилення безпеки 1/868: виміряйте час виконання, клас помилки та кількість витрачених токенів для цього запису, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі запитань, а не на окремих випадках.

Для другого етапу посилення безпеки необхідно визначити вхідні дані, відповідальну особу за крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не здогадуючись про прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код.

Деталь посилення безпеки 2/868: вимірюйте час виконання, клас помилки та кількість витрачених токенів для цього етапу, а потім вирішуйте, чи залишити зміни, ґрунтуючись на фіксованому наборі питань, а не на індивідуальних спостереженнях.

Під час виконання третього етапу додаткових заходів зпрочнення спочатку запишіть умови контракту: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Краще використовувати невеликі, перевірювані одиниці коду замість об’ємних скриптів. Якщо якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність дій.

Деталь 3/868 щодо зпрочнення: виміряйте час виконання, клас помилки та кількість витрачених токенів для цього пункту, а потім вирішіть, чи залишити зміни, ґрунтуючись на фіксованому наборі критеріїв, а не на індивідуальних спостереженнях.