{"id":484336,"date":"2026-06-19T17:17:13","date_gmt":"2026-06-19T17:17:13","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=484336"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=484336","title":{"rendered":"\u041c\u043e\u0439 \u043b\u0438\u0447\u043d\u044b\u0439 \u0434\u0436\u0443\u043d\u0438\u043e\u0440. \u0427\u0430\u0441\u0442\u044c 2. \u0414\u0430\u0451\u043c \u0430\u0433\u0435\u043d\u0442\u0443 \u043d\u0435\u043c\u043d\u043e\u0436\u0435\u0447\u043a\u043e \u043c\u043e\u0437\u0433\u043e\u0432"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u0438 \u044d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0435\u0440-\u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u0430 LangGraph \u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a MCP-\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c.<\/p>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/articles\/1043348\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u0434\u0430\u043b\u0438 \u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f \u043a MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438, \u043a\u043e\u0434\u043e\u043c Git \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439. \u0412 \u044d\u0442\u043e\u0439 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u043a\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0433\u0435\u043d\u0442\u0443 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0437\u0433\u043e\u0432. \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0433\u043b\u044e\u0447\u0438\u043b GigaChat <\/summary>\n<div class=\"spoiler__content\">\n<p>\u042f \u043d\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a \u043d\u0430\u0433\u043d\u0435\u0442\u0430\u043d\u0438\u044f \u0438\u043d\u0442\u0440\u0438\u0433\u0438. \u041f\u043e-\u044d\u0442\u043e\u043c\u0443, \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0432\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u0430. \u0412\u044b\u0431\u0438\u0440\u0430\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0441\u043a\u0440\u0438\u043d\u043e\u0432 \u044f \u0437\u0430\u043c\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b, \u0445\u043e\u0442\u044f \u0430\u0433\u0435\u043d\u0442 \u043f\u0438\u0448\u0435\u0442, \u0447\u0442\u043e \u0444\u0430\u0439\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d. \u041f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0432 \u0442\u0440\u0435\u0439\u0441 \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043c\u043d\u043e\u0439 \u0434\u043b\u044f \u0447\u0430\u0442\u0430 <a href=\"https:\/\/huggingface.co\/ai-sage\/GigaChat3-10B-A1.8B\" rel=\"noopener noreferrer nofollow\">ai-sage\/GigaChat3-10B-A1.8B<\/a> \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0432 \u043f\u043e\u043b\u0435 <code>content<\/code>. \u0422\u0430\u043a \u0438 \u043d\u0435 \u043f\u043e\u043d\u044f\u0432, \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u044d\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u0438, SGLang, \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u043b\u0438 \u0432\u0441\u0435\u0433\u043e \u0432\u043c\u0435\u0441\u0442\u0435, \u044f \u043f\u0440\u0438\u043d\u044f\u043b \u0441\u0443\u0434\u044c\u0431\u043e\u043d\u043e\u0441\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 &#8212; \u0430 \u0441\u043a\u0430\u0436\u0443-\u043a\u0430 \u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u0447\u0442\u043e \u043e\u043d\u0430 \u043e\u0448\u0438\u0431\u043b\u0430\u0441\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0432\u0435\u0449\u044c &#8212; \u0435\u0441\u043b\u0438 \u0432 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (tool_calls), \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432 \u0441\u0430\u043c\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u044d\u0442\u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b \u0432 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0430 \u201c\u0422\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 JSON \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435\u201d. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u044d\u0442\u043e \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\">if message.response_metadata.get('finish_reason') == 'tool_calls' and not message.tool_calls:    return {'messages': [HumanMessage(load_prompt_from_langfuse('mcp_agent_error_tool_call_prompt'))]}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421 \u044d\u0442\u043e\u0433\u043e \u0438 \u043d\u0430\u0447\u0430\u043b\u0438\u0441\u044c \u043c\u043e\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. GigaChat3-10B \u043d\u0430 \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435\u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e. \u041e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u0437\u043e\u0432\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 <code>write_file<\/code> \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u0432\u044b\u0437\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043a\u043e\u0434\u0430. \u0422\u0430\u043a \u0432\u043e\u0442 &#8212; \u043d\u0430 \u043c\u043e\u0451 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0443\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c-\u0436\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u043b \u043e\u043d \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043a\u043e\u043d\u0447\u0430\u043b\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044f \u0432\u0432\u0451\u043b \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0432 \u0443\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043b \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e \u043d\u0435 \u0440\u0435\u0448\u0438\u043b\u043e, \u043d\u043e \u0445\u043e\u0442\u044c \u0436\u0434\u0430\u0442\u044c \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u044b\u043b\u043e \u043d\u0435 \u043d\u0430\u0434\u043e. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0441\u0442\u0430\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u0422\u0443\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0430 \u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0431\u044f \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0435\u0440\u0435\u0435\u0445\u0430\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e, \u043e\u0442\u043a\u0430\u0437\u0430\u0432\u0448\u0438\u0441\u044c \u043e\u0442 \u0434\u0432\u0443\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439. \u0422\u0430\u043a \u043a\u0430\u043a 32 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438 &#8212; \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u0434\u043b\u044f LLM, \u0447\u0442\u043e-\u0442\u043e \u0441\u0442\u0438\u043b\u044c\u043d\u043e\u0435, \u043c\u043e\u0434\u043d\u043e\u0435, \u043c\u043e\u043b\u043e\u0434\u0451\u0436\u043d\u043e\u0435 \u0438 \u043a\u0432\u0430\u043d\u0442\u043e\u0432\u0430\u043d\u043d\u043e\u0435. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u0431\u044b\u043b\u0430 <a href=\"https:\/\/huggingface.co\/cyankiwi\/Qwen3.6-35B-A3B-AWQ-4bit\" rel=\"noopener noreferrer nofollow\">cyankiwi\/Qwen3.6-35B-A3B-AWQ-4bit<\/a>. \u041d\u043e \u0432 SGLang \u043e\u043d\u0430 \u043c\u043d\u0435 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u044b &#8212; \u043b\u0438\u0431\u043e \u043f\u0443\u0441\u0442\u043e\u0435 \u043f\u043e\u043b\u0435, \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0440\u043e\u0447\u043a\u0438 \u0438\u0437 \u0432\u043e\u0441\u043a\u043b\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u043a\u043e\u0432. \u0414\u0430\u043b\u0435\u0435 \u0431\u044b\u043b\u0430 \u043c\u043e\u0434\u0435\u043b\u044c <a href=\"https:\/\/huggingface.co\/nvidia\/Qwen3.6-35B-A3B-NVFP4\" rel=\"noopener noreferrer nofollow\">nvidia\/Qwen3.6-35B-A3B-NVFP4<\/a> \u0438 \u043f\u0435\u0440\u0435\u0435\u0437\u0434 \u043d\u0430 vLLM.<\/p>\n<\/div>\n<\/details>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0430\u0433\u0435\u043d\u0442\u0430.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u043a\u0430\u043a \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043a \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438? \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u043d \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043b\u0430\u043d \u043f\u043e \u043f\u0443\u043d\u043a\u0442\u0430\u043c (\u0432\u0435\u0434\u044c \u043c\u044b \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0433\u043e \u0438 \u0434\u0435\u043b\u0430\u043b\u0438), \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u0432\u043e\u0435\u0439 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043f\u0443\u043d\u043a\u0442\u043e\u0432, \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435 \u043f\u043b\u043e\u0445\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u0435\u0451 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u0438 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430. \u041a\u0430\u043a \u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440 \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u043e \u0434\u0432\u0435. \u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0439. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u043f\u043b\u0430\u043d, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0448\u0430\u0433\u0438 \u0441 \u043e\u0446\u0435\u043d\u043a\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bda\/e7a\/019\/bdae7a01938d33ca781700e5c81523a8.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430\" title=\"\u0421\u0445\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430\" width=\"1014\" height=\"1173\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/bda\/e7a\/019\/bdae7a01938d33ca781700e5c81523a8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bda\/e7a\/019\/bdae7a01938d33ca781700e5c81523a8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0445\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u0442\u0430\u043a\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0434\u043e\u0439\u0434\u0451\u0442 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u0421 \u043c\u043e\u0435\u0439 \u0436\u0435 (GigaChat \u043d\u0430 \u0442\u043e \u0432\u0440\u0435\u043c\u044f) \u043d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u043c\u0430\u0433\u0438\u044f &#8212; \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u201c\u041d\u0430\u043f\u0438\u0448\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u2026\u201d \u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u043b\u0430 \u043d\u0430 4-5 \u0448\u0430\u0433\u043e\u0432, \u0441\u0430\u043c\u0430 \u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u043f\u0443\u0442\u0430\u043b\u0430\u0441\u044c \u0432 \u043f\u043b\u0430\u043d\u0435. \u0418\u043d\u043e\u0433\u0434\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u043b\u0430 \u043a\u043e\u0434, \u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u043f\u0438\u0441\u0430\u043b\u0430 \u0432 \u0444\u0430\u0439\u043b \u0437\u0430\u043d\u043e\u0432\u043e \u043d\u0430\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043b\u044e\u0441 \u0432\u0441\u043a\u0440\u044b\u0432\u0448\u0438\u0435\u0441\u044f \u0432\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u0435\u043c. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u201c\u043f\u043e\u043b\u0443\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0439\u201d \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u043c\u0435\u0448\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/777\/413\/777\/7774137771336d20e3a7ab9249ef1c9a.png\" alt=\"Human-in-the-Loop \u0430\u0433\u0435\u043d\u0442\" title=\"Human-in-the-Loop \u0430\u0433\u0435\u043d\u0442\" width=\"1258\" height=\"282\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/777\/413\/777\/7774137771336d20e3a7ab9249ef1c9a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/777\/413\/777\/7774137771336d20e3a7ab9249ef1c9a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Human-in-the-Loop \u0430\u0433\u0435\u043d\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0430\u0433\u0435\u043d\u0442.<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0433\u0435\u043d\u0442\u0430<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432 \u0438 \u0440\u0451\u0431\u0435\u0440:<\/p>\n<ul>\n<li>\n<p>\u0443\u0437\u0435\u043b \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a<\/p>\n<\/li>\n<li>\n<p>\u0443\u0437\u043b\u044b \u043e\u0446\u0435\u043d\u0449\u0438\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0443\u0437\u0435\u043b \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0448\u0430\u0433\u0430 \u043f\u043b\u0430\u043d\u0430<\/p>\n<\/li>\n<li>\n<p>\u0443\u0437\u0435\u043b \u0441\u0436\u0430\u0442\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u0443\u0437\u0435\u043b \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0443 \u0438 \u0421\u0442\u0435\u0439\u0442 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0434\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0421 \u043d\u0435\u0433\u043e \u0438 \u043d\u0430\u0447\u043d\u0451\u043c<\/p>\n<h3>AgentState<\/h3>\n<pre><code class=\"python\">class AgentState(MessagesState):    user_request: str    user_input: str    plan: list[dict]    current_step: int    step_iteration: int    history: list[str]    phase: Literal['planning', 'executing', 'done']    is_approved: bool    trace_id: str<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0441\u0442\u0435\u0439\u0442 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438:<\/p>\n<ul>\n<li>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#8212; \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b \u043f\u043e\u0434 \u0440\u0443\u043a\u043e\u0439<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0435 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#8212; \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u043b\u0430\u043d\u0430 \u043e\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0434\u0435\u043a\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430 \u043f\u043b\u0430\u043d\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0441\u0436\u0430\u0442\u0430\u044f)<\/p>\n<\/li>\n<li>\n<p>\u0424\u0430\u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430 &#8212; \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442, \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0448\u0430\u0433 \u043f\u0440\u0438\u043d\u044f\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0435\u0441\u0441\u0438\u0438 (\u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u043c\u044f\u0442\u0438)<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u0433\u0435\u043d\u0442\u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 &#8212; \u043f\u043e\u0440\u043e\u0433 \u043f\u043e\u043f\u044b\u0442\u043e\u043a<\/p>\n<pre><code class=\"python\">class ServiceConfig(BaseModel):    # \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434    max_step_iterations: int = 30<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u0443\u0437\u043b\u0430\u043c<\/p>\n<h3>\u0423\u0437\u0435\u043b \u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a<\/h3>\n<p>\u0423\u0437\u0435\u043b \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u0431\u044b\u043b \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439. \u0420\u0430\u0437 \u043c\u044b \u043c\u043e\u0434\u0435\u0440\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0430\u0433\u0435\u043d\u0442\u0430, \u0442\u043e \u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0443\u0437\u043b\u043e\u0432 \u0443\u0433\u043b\u0443\u0431\u0438\u043c \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043c &#8212; \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0443\u0437\u043b\u044b \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438:<\/p>\n<pre><code class=\"python\">from langchain.chat_models import BaseChatModelfrom langchain_core.output_parsers import PydanticOutputParserclass PlanerNode:    def __init__(            self,            llm: BaseChatModel,            prompt_name: str = 'mcp_agent_planer_prompt',            prompt_label: str = 'production'    ):        self.parser = PydanticOutputParser(pydantic_object=Workflow)        self.llm = llm        self.prompt = load_prompt_from_langfuse(            prompt_name=prompt_name, prompt_label=prompt_label        ).format(format_instructions=self.parser.get_format_instructions())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0443\u0437\u043b\u0430 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u043d\u043a\u0442\u043e\u0432. \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>PydanticOutputParser<\/code> &#8212; \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 Pydantic \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u043f\u0440\u043e\u043c\u043f\u0442\u0443, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435. \u0410 \u043c\u0435\u0442\u043e\u0434 <code>PydanticOutputParser.parse<\/code> \u0432\u0435\u0440\u043d\u0451\u0442 \u043d\u0430\u043c \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 Pydantic-\u043e\u0431\u044a\u0435\u043a\u0442. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u0438\u0434\u0430 \u201c\u0425\u043e\u0440\u043e\u0448\u043e, \u0432\u043e\u0442 \u0447\u0442\u043e \u044f \u043c\u043e\u0433\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043b\u0430\u043d\u0430 \u043d\u0430 \u0442\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u2026\u201d \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u043d\u043a\u0442\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c:<\/p>\n<pre><code class=\"python\">from typing import Annotatedfrom pydantic import BaseModel, Fieldclass Workflow(BaseModel):    plan: Annotated[list[str], Field(description='\u0421\u043f\u0438\u0441\u043e\u043a \u0448\u0430\u0433\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438')]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u043e\u043c\u043f\u0442\u043e\u0432 \u0438\u0437 LangFuse \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f:<\/p>\n<pre><code class=\"python\">def load_prompt_from_langfuse(prompt_name: str, prompt_label: str = 'production') -&gt; str:    try:        return (            settings.langfuse.client            .get_prompt(prompt_name, label=prompt_label)            .get_langchain_prompt())    except Exception as e:        logger.error(f'\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u043c\u043f\u0442 \"{prompt_name}\" \u0438\u0437 Langfuse: {e}')        raise RuntimeError(f'\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u043c\u043f\u0442 \"{prompt_name}\" \u0438\u0437 Langfuse')<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u043c\u043f\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0438 \u0442\u0435\u0433\u0443 (\u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432) \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0443\u044e \u0441 <code>Langchain.PromptTemplate<\/code>.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u0443\u0437\u043b\u0430:<\/p>\n<pre><code class=\"python\">class PlanerNode:    # \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043a\u043e\u0434    async def node(self, state: AgentState) -&gt; dict:        user_input = state.get('user_input', '')        messages = [SystemMessage(content=self.prompt)] + state['messages']        if user_input:            messages += [HumanMessage(content=user_input)]        response = await self.llm.ainvoke(messages)        plan = self.parser.parse(response.content).plan        message = '\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u043b\u0430\u043d \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043f\u043b\u0430\u043d \u0441\u043b\u043e\u0432\u043e\u043c **\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c\"** \u043b\u0438\u0431\u043e \u0432\u043d\u0435\u0441\u0438\u0442\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0438'        for i, item in enumerate(plan, start=1):            message += f'\\n* \u0428\u0430\u0433 {i}: {item}'        return {            'messages': [                HumanMessage(content=user_input), AIMessage(content=message)            ] if user_input else [AIMessage(content=message)],            'plan': plan, 'current_step': 0, 'phase': 'planning', 'is_approved': False,        }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0441\u043d\u043e\u0432\u0430 &#8212; \u0432 \u043f\u0440\u043e\u043c\u043f\u0442\u0435. \u0412 \u043d\u0451\u043c \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b LLM \u0440\u0430\u0437\u0431\u0438\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 (\u0442\u0438\u043f\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0444\u0430\u0439\u043b, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043a\u0441\u0442\u0440\u0438\u043d\u0433 \u0438 \u0442.\u043f.) \u0438 \u0432\u044b\u0434\u0430\u0442\u044c \u0438\u0445 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u043c\u043f\u0442\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0442\u0443\u0442 \u043d\u0435 \u0431\u0443\u0434\u0443, \u043d\u043e \u043a \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0443 \u0441\u0432\u043e\u0439 \u0434\u0430\u043c\u043f \u0441 LangFuse.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>PydanticOutputParser<\/code>, \u043f\u0430\u0440\u0441\u0438\u043c \u043e\u0442\u0432\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0448\u0430\u0433\u0438 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0430.<\/p>\n<p>\u041f\u043e\u044f\u0441\u043d\u044e \u0437\u0430 <code>user_input<\/code> &#8212; \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0434\u0435\u043d\u043e \u043f\u043e\u0434 \u0443\u0442\u043e\u0447\u043d\u044f\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u043a\u0430\u043a &#8212; \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441). \u0415\u0441\u043b\u0438 \u0432 \u043f\u043e\u043b\u0435 \u0447\u0442\u043e-\u0442\u043e \u0435\u0441\u0442\u044c, \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0441\u0438\u0442 \u0447\u0442\u043e-\u0442\u043e \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c, \u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u0442\u043e \u0432 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 \u0443\u0437\u043b\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043b\u0430\u043d, \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u043c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0448\u0430\u0433\u043e\u0432, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u0430\u0437\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430, \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0444\u043b\u0430\u0433 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<h3>\u0418\u043d\u044a\u0435\u043a\u0442\u043e\u0440<\/h3>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b &#8212; \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0448\u0430\u0433 \u0430\u0433\u0435\u043d\u0442\u0443. \u041e\u0434\u043d\u043e \u0432\u0440\u0435\u043c\u044f \u0432 \u0443\u0437\u043b\u0435 \u0447\u0438\u0441\u0442\u0438\u043b \u043f\u043e\u043b\u0435 <code>state['messages']<\/code> \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u043b \u0441\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439. \u041d\u043e \u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 Qwen3.6 \u043e\u0442 Nvidia \u0441\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0451 \u043f\u043e\u0440\u0442\u0438\u043b\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0448\u0430\u0433\u0430 \u043f\u043b\u0430\u043d\u0430:<\/p>\n<pre><code class=\"python\">class StepInjectorNode:    def node(self, state: AgentState) -&gt; dict:        step_text = state['plan'][state['current_step']]        return {'messages': HumanMessage(f'\u0422\u0415\u041a\u0423\u0429\u0418\u0419 \u0428\u0410\u0413, \u041a\u041e\u0422\u041e\u0420\u042b\u0419 \u041d\u0423\u0416\u041d\u041e \u0412\u042b\u041f\u041e\u041b\u041d\u0418\u0422\u042c: {step_text}'),}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442<\/h3>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0443\u0437\u043b\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 (\u0434\u043b\u044f \u043c\u043e\u0438\u0445 \u0443\u0437\u043b\u043e\u0432):<\/p>\n<pre><code class=\"python\">class AgentNode:    def __init__(            self,            llm: BaseChatModel,            prompt_name: str = 'mcp_agent_prompt',            prompt_label: str = 'production'):        self.llm = llm        self.prompt = load_prompt_from_langfuse(prompt_name=prompt_name, prompt_label=prompt_label)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0441\u0430\u043c \u0443\u0437\u0435\u043b. \u0418 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043e\u043d \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<pre><code class=\"python\">from langchain_core.messages import AIMessage, RemoveMessagefrom langgraph.graph.message import REMOVE_ALL_MESSAGESclass AgentNode:    # \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043a\u043e\u0434    async def node(self, state: AgentState) -&gt; dict:        if state.get('step_iteration', 0) &gt; settings.service.max_step_iterations:            msg = '\u041a\u0420\u0418\u0422\u0418\u0427\u0415\u0421\u041a\u0410\u042f \u041e\u0428\u0418\u0411\u041a\u0410! \u0410\u0433\u0435\u043d\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u043b\u0441\u044f \u0438 \u0431\u044b\u043b \u0441\u0431\u0440\u043e\u0448\u0435\u043d \u0432 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435!'            logger.error(msg)            return {                'messages': [RemoveMessage(id=REMOVE_ALL_MESSAGES), AIMessage(msg)],                'history': [], 'step_iteration': 0, 'current_step': 0,}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u043e\u0433\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043e\u0432 \u0447\u0438\u0441\u0442\u0438\u043c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0434\u043d\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.<\/p>\n<p>\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432 <code>[]<\/code> &#8212; \u043e\u043d\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0430 \u043a\u0430\u043a <code>messages: Annotated[list[AnyMessage], add_messages]<\/code>, \u0438 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0441\u044f \u043a \u0438\u0441\u0442\u043e\u0440\u0438\u0438. \u0414\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f <code>RemoveMessage<\/code>. \u0412 \u043f\u043e\u043b\u0435 <code>id<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043b\u0438\u0431\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 <code>langgraph.graph.message.REMOVE_ALL_MESSAGES<\/code> \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0432\u0441\u0435\u0439 \u0438\u0441\u0442\u043e\u0440\u0438\u0438.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 \u0443\u0437\u043b\u0430 \u0447\u0435\u043c-\u0442\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u043f\u043b\u0430\u043d\u0435\u0440 &#8212; \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043f\u0440\u043e\u043c\u043f\u0442, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0441\u0442\u043e\u0440\u0438\u044e, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438):<\/p>\n<pre><code class=\"python\">class AgentNode:    # \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043a\u043e\u0434    async def node(self, state: AgentState) -&gt; dict:        # \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043a\u043e\u0434        messages = [SystemMessage(self.prompt)] + state['messages']        if state['user_input']:            messages += [HumanMessage(state['user_input'])]        response = await self.llm.ainvoke(messages)        return {            'messages': [HumanMessage(state['user_request']), response] if state['user_input'] else [response],            'step_iteration': state.get('step_iteration', 0) + 1, 'phase': 'executing', 'is_approved': False, }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u0432\u0435\u0442 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u0443\u044e &#8212; \u043a\u0432\u0435\u043d\u0443 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0444\u0440\u0430\u0437\u044b \u0432 \u043f\u0440\u043e\u043c\u043f\u0442\u0435 \u201c\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430 \u0441\u043e\u043e\u0431\u0449\u0438, \u0447\u0442\u043e \u0448\u0430\u0433 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d, \u0438 \u0443\u043a\u0430\u0436\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u201d. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0435\u0433\u043e &#8212; \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0438 \u043e\u043d \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u0437\u0435\u043b, \u043a\u0440\u043e\u043c\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442 \u0448\u0430\u0433\u0430, \u0444\u0430\u0437\u0443 \u201c\u0418\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u201d \u0438 \u0441\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0439 \u0444\u043b\u0430\u0433 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<h3>\u0423\u0437\u043b\u044b \u041e\u0446\u0435\u043d\u0449\u0438\u043a\u0438<\/h3>\n<p>\u0422\u0443\u0442 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0437\u043b\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 &#8212; \u043e\u0436\u0438\u0434\u0430\u044e\u0442 \u0441\u043b\u043e\u0432\u043e <code>\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c<\/code>. \u0410 \u0434\u0432\u0430 \u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0433\u0440\u0430\u0444\u0430 \u043f\u0440\u043e\u0449\u0435 \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c<\/p>\n<pre><code class=\"python\">class BaseSolver:    @staticmethod    async def node(state: AgentState) -&gt; dict:        if '\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c' in state['user_input'].lower():            return {'is_approved': True, 'user_input': ''}        return {'is_approved': False}class PlanSolverNode(BaseSolver):    passclass AgentSolverNode(BaseSolver):    pass<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0423\u0437\u0435\u043b \u0421\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u0430\u0442\u043e\u0440<\/h3>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u044b \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u041d\u043e, \u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f, \u201c\u0427\u0442\u043e \u0440\u0443\u0441\u0441\u043a\u043e\u043c\u0443 \u0445\u043e\u0440\u043e\u0448\u043e &#8212; \u043d\u0435\u043c\u0446\u0443 \u0441\u043c\u0435\u0440\u0442\u044c\u201d. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 Qwen, \u0447\u0438\u0442\u0430\u044f \u0441\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c-\u0436\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0435. \u041f\u043e-\u044d\u0442\u043e\u043c\u0443 \u0443\u0437\u0435\u043b \u0435\u0441\u0442\u044c, \u043d\u043e \u0442\u043e\u043b\u043a\u0443 \u043e\u0442 \u043d\u0435\u0433\u043e \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435\u0442 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u043d\u043e\u0433\u043e \u0431\u0443\u043a\u0432 \u0441 \u043a\u043e\u0434\u043e\u043c \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f \u0443\u0437\u043b\u0430 \u0431\u044b\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f &#8212; \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0443\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0446\u0438\u043a\u043b\u043e\u0432 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0437\u0430 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0443\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043c\u0430\u0440\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c <code>id<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c ToolMessage \u0434\u043b\u044f \u043e\u0442\u0447\u0435\u0442\u0430.<\/p>\n<p>\u041a\u043e\u0434 \u0443\u0437\u043b\u0430 \u043d\u0430\u0447\u043d\u0435\u043c \u0441\u043e \u0441\u0432\u043e\u0435\u043e\u0431\u0440\u0430\u0437\u043d\u043e\u0439 \u0437\u0430\u0449\u0438\u0442\u044b &#8212; \u0443\u0437\u043b\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 <code>AIMessage<\/code> \u0438 <code>ToolMessage<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0434\u043e \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0438\u0437 \u043d\u0438\u0445:<\/p>\n<pre><code class=\"python\">class ContextCompressorNode:    @staticmethod    def _extract_text(content) -&gt; str:        if isinstance(content, str):            return content.strip()        if isinstance(content, list):            parts = []            for block in content:                if isinstance(block, dict) and block.get('type') == 'text':                    parts.append(block.get('text', ''))                elif isinstance(block, str):                    parts.append(block)            return '\\n'.join(p for p in parts if p).strip()        return str(content).strip()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u0435\u0442\u043e\u0434 \u0441\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0447\u0435\u0442 \u0432 \u043e\u0434\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"python\">class ContextCompressorNode:    def _build_steps_summary(self, messages: list) -&gt; str:        tool_index = {            m.tool_call_id: m            for m in messages            if getattr(m, 'type', None) == 'tool' and getattr(m, 'tool_call_id', None)        }        lines = []        for msg in messages:            if getattr(msg, 'type', None) != 'ai':                continue            text = self._extract_text(msg.content)            if text:                lines.append(f'[\u041e\u0422\u0412\u0415\u0422 \u0410\u0413\u0415\u041d\u0422\u0410]: {text}')                continue            tool_calls = getattr(msg, 'tool_calls', None) or []            for tc in tool_calls:                tool_msg = tool_index.get(tc.get('id'))                if tool_msg is not None:                    result = self._extract_text(tool_msg.content)                    lines.append(f'[\u0418\u041d\u0421\u0422\u0420\u0423\u041c\u0415\u041d\u0422] \"{tc.get(\"name\", \"unknown\")}\". \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442: {result}')        return '\\n\\n'.join(lines) if lines else '(\u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0443\u0441\u0442\u0430)'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c LangGraph: <code>ToolMessage<\/code> \u0438 \u0432\u044b\u0437\u043e\u0432\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 <code>tool_call_id<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043c\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (<code>ToolMessage<\/code>) \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u044c. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u043e\u0432\u0430\u0440\u0435, \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043d\u043e\u0432\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043e\u0431\u0440\u0430\u0449\u044f\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0430\u0433\u0435\u043d\u0442\u0430. \u0415\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0430\u0433\u0435\u043d\u0442\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 (\u043e\u0442\u0432\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438), \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443. \u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442\u0430 \u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0418\u0418 \u043d\u0435\u0442, \u0437\u043d\u0430\u0447\u0438\u0442, \u0432 \u043d\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0432\u044b\u0437\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (\u043f\u043e\u043b\u0435 <code>tool_calls<\/code>). \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e <code>id<\/code> \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443.<\/p>\n<p>\u0412 \u0443\u0437\u043b\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0438\u0437 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0431\u043e\u0433\u0430\u0442\u0441\u0442\u0432\u0430 AI \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"python\">class ContextCompressorNode:    def node(self, state: AgentState) -&gt; dict:        steps_summary = self._build_steps_summary(state['messages'])        step = state['current_step']        history = state.get('history', []) + [            f\"[\u0420\u0415\u0417\u0423\u041b\u042c\u0422\u0410\u0422 \u0412\u042b\u041f\u041e\u041b\u041d\u0415\u041d\u0418\u042f \u0428\u0410\u0413\u0410 {step + 1}] {state['plan'][step]}.\\n\\n{steps_summary}\"]        return {'history': history, 'current_step': step + 1}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<h2>\u0423\u0437\u0435\u043b \u0424\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440<\/h2>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b \u043f\u043e\u0434\u0432\u043e\u0434\u0438\u0442 \u0438\u0442\u043e\u0433\u0438 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b. \u0412 \u043f\u0440\u043e\u043c\u043f\u0442\u0435 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u043c\u0443 \u043f\u043b\u0430\u043d, \u0441\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u0438\u0437 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u0438 \u043f\u0440\u043e\u0441\u0438\u043c \u043f\u043e\u0434\u0432\u0435\u0441\u0442\u0438 \u0438\u0442\u043e\u0433:<\/p>\n<pre><code class=\"python\">class FinalizerNode:    def __init__(            self,            llm: BaseChatModel,            prompt_name: str = 'mcp_agent_finalize_prompt',            prompt_label: str = 'production'):        self.llm = llm        self.prompt = load_prompt_from_langfuse(prompt_name=prompt_name, prompt_label=prompt_label)    async def node(self, state: AgentState) -&gt; dict:        plan = '\\n'.join(f\"{i}. {s}\" for i, s in enumerate(state.get('plan', []), start=1))        steps_summary = '\\n\\n'.join(state.get('history', []))        msg = (            f'\u041f\u043b\u0430\u043d: \\n{plan}\\n\\n'            f'\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f:\\n{steps_summary}\\n\\n'            f'\u0421\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0439 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.')        response = await self.llm.ainvoke([SystemMessage(content=self.prompt), HumanMessage(content=msg),])        message = f'\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e:\\n\\n{response.content}'        return {'messages': [message], 'phase': 'done', 'is_approved': False}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421 \u0443\u0437\u043b\u0430\u043c\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438. \u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u0431\u043e\u0440\u043a\u0435 \u0433\u0440\u0430\u0444\u0430, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0432\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 LangGraph, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c: \u0447\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0435\u0440 \u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h3>\u0427\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0435\u0440<\/h3>\n<p>\u0427\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0435\u0440 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0443 \u0433\u0440\u0430\u0444\u0430 \u043a\u0440\u0430\u0442\u043a\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c, \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u0440\u0430\u0444\u0430 \u0438\u0437 \u043b\u044e\u0431\u043e\u0439 \u0442\u043e\u0447\u043a\u0438. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0447\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0435\u0440\u0430 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u0433\u0440\u0430\u0444 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0435\u0441\u0441\u0438\u0438:<\/p>\n<pre><code class=\"python\">config = {'configurable': {'thread_id': 'my-thread'}}graph.invoke(inputs, config)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u0431\u0430\u0437\u0435 Postgres (\u043d\u0443\u0436\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/pypi.org\/project\/langgraph-checkpoint-postgres\/\" rel=\"noopener noreferrer nofollow\">langgraph-checkpoint-postgres<\/a>). \u0414\u043b\u044f \u043f\u0440\u043e\u0434\u0430 LangGraph \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e Postgres \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043d\u043e \u043d\u0430\u043c \u0445\u0432\u0430\u0442\u0438\u0442 \u0438 <code>langgraph.checkpoint.memory.InMemorySaver<\/code><\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0435\u0440 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u043a \u0433\u0440\u0430\u0444\u0443 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<pre><code class=\"python\">checkpointer = InMemorySaver()graph = workflow.compile(checkpointer=checkpointer)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u041f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>\u041f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0433\u0440\u0430\u0444\u0430<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3a8\/f25\/cf4\/3a8f25cf4eefdd2eca05bc7377a6dcc1.png\" width=\"400\" height=\"400\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/3a8\/f25\/cf4\/3a8f25cf4eefdd2eca05bc7377a6dcc1.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3a8\/f25\/cf4\/3a8f25cf4eefdd2eca05bc7377a6dcc1.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u043e, \u0432\u043d\u0443\u0442\u0440\u0438 \u0438 \u043f\u043e\u0441\u043b\u0435 \u0443\u0437\u043b\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u0442\u0438\u043f \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0433\u0440\u0430\u0444\u0430, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u043b\u0435 \u0443\u0437\u043b\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 <code>langgraph.types.interrupt<\/code>.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0438 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0441\u043f\u0438\u0441\u043a\u0438 \u0438\u043c\u0451\u043d \u0443\u0437\u043b\u043e\u0432 \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440:<\/p>\n<pre><code class=\"python\">graph = workflow.compile(    checkpointer=checkpointer,    interrupt_before=['before_node'],    interrupt_after=['after_node'],)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435:<\/p>\n<pre><code class=\"python\">def ask_user(state: State):    answer = interrupt('\u041a\u0430\u043a \u0432\u0430\u0441 \u0437\u043e\u0432\u0443\u0442?')  # \u0413\u0440\u0430\u0444 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u0434\u0435\u0441\u044c \u0438 \u0436\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0430    return {'user_answer': answer}  # \u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u0432\u0435\u0442\u0438\u0442, \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0441\u044f<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0434\u043b\u044f \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0433\u0440\u0430\u0444\u0430 \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u0433\u0440\u0430\u0444 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 <code>langgraph.types.Command<\/code> \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <code>update<\/code> \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0435\u0439\u0442\u0430 \u0438\u043b\u0438 <code>resume<\/code> \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0411\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u0433\u0440\u0430\u0444 \u043d\u0430\u0447\u043d\u0435\u0442 \u0441\u0432\u043e\u0451 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u043e\u0432\u043e.<\/p>\n<blockquote>\n<p>\u0412\u0430\u0436\u043d\u043e\u0435 \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u0435: \u043d\u0435 \u043f\u043e\u043d\u044f\u043b, \u0431\u0430\u0433 \u044d\u0442\u043e \u0438\u043b\u0438 \u0444\u0438\u0447\u0430, \u043d\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u0443\u0437\u043b\u0430 \u0438\u0434\u0451\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0435 \u0440\u0435\u0431\u0440\u043e, \u0442\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u043e\u043d\u043e, \u0430 \u0443\u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043c\u0435\u0440\u0442\u0432\u043e \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u0433\u0440\u0430\u0444, \u0435\u0441\u043b\u0438 \u0440\u0435\u0431\u0440\u043e \u0440\u0435\u0448\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u201c\u041f\u043e\u0432\u0442\u043e\u0440\/\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c\u201d<\/p>\n<\/blockquote>\n<h2>\u0420\u0430\u0437\u0440\u044b\u0432 \u043b\u043e\u043d\u0433\u0440\u0438\u0434\u0430<\/h2>\n<p>\u0423 \u043d\u0430\u0441 \u0433\u043e\u0442\u043e\u0432\u044b \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a &#8212; \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430 \u0448\u0430\u0433\u0438<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0436\u0435\u043a\u0442\u043e\u0440 &#8212; \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u0430\u0433\u0435\u043d\u0442\u0443 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0448\u0430\u0433<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c &#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0448\u0430\u0433\u0438<\/p>\n<\/li>\n<li>\n<p>\u041e\u0446\u0435\u043d\u0449\u0438\u043a\u0438 &#8212; \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/p>\n<\/li>\n<li>\n<p>\u0421\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u0430\u0442\u043e\u0440 &#8212; \u0441\u0436\u0438\u043c\u0430\u0435\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0424\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 &#8212; \u043f\u043e\u0434\u0432\u043e\u0434\u0438\u0442 \u0438\u0442\u043e\u0433\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u2014 \u044d\u0442\u043e \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435. \u041d\u043e \u043f\u043e\u043a\u0430 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041e\u043d\u0438 \u043d\u0435 \u0437\u043d\u0430\u044e\u0442 \u0434\u0440\u0443\u0433 \u043e \u0434\u0440\u0443\u0433\u0435, \u043d\u0435 \u0443\u043c\u0435\u044e\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0412 <span>\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438<\/span> \u043c\u044b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043c \u044d\u0442\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u0443\u0437\u043b\u043e\u0432 \u0432 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0433\u0440\u0430\u0444.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1049772\/\">https:\/\/habr.com\/ru\/articles\/1049772\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u0438 \u044d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0435\u0440-\u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u0430 LangGraph \u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u043a MCP-\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c.\u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u0434\u0430\u043b\u0438 \u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f \u043a MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438, \u043a\u043e\u0434\u043e\u043c Git \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439. \u0412 \u044d\u0442\u043e\u0439 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u043a\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0433\u0435\u043d\u0442\u0443 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0437\u0433\u043e\u0432. \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0433\u043b\u044e\u0447\u0438\u043b GigaChat \u042f \u043d\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a \u043d\u0430\u0433\u043d\u0435\u0442\u0430\u043d\u0438\u044f \u0438\u043d\u0442\u0440\u0438\u0433\u0438. \u041f\u043e-\u044d\u0442\u043e\u043c\u0443, \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0432\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u0430. \u0412\u044b\u0431\u0438\u0440\u0430\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0441\u043a\u0440\u0438\u043d\u043e\u0432 \u044f \u0437\u0430\u043c\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b, \u0445\u043e\u0442\u044f \u0430\u0433\u0435\u043d\u0442 \u043f\u0438\u0448\u0435\u0442, \u0447\u0442\u043e \u0444\u0430\u0439\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d. \u041f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0432 \u0442\u0440\u0435\u0439\u0441 \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043c\u043d\u043e\u0439 \u0434\u043b\u044f \u0447\u0430\u0442\u0430 ai-sage\/GigaChat3-10B-A1.8B \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0432 \u043f\u043e\u043b\u0435 content. \u0422\u0430\u043a \u0438 \u043d\u0435 \u043f\u043e\u043d\u044f\u0432, \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u044d\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u0438, SGLang, \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u043b\u0438 \u0432\u0441\u0435\u0433\u043e \u0432\u043c\u0435\u0441\u0442\u0435, \u044f \u043f\u0440\u0438\u043d\u044f\u043b \u0441\u0443\u0434\u044c\u0431\u043e\u043d\u043e\u0441\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 &#8212; \u0430 \u0441\u043a\u0430\u0436\u0443-\u043a\u0430 \u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u0447\u0442\u043e \u043e\u043d\u0430 \u043e\u0448\u0438\u0431\u043b\u0430\u0441\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0432\u0435\u0449\u044c &#8212; \u0435\u0441\u043b\u0438 \u0432 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (tool_calls), \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432 \u0441\u0430\u043c\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u044d\u0442\u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b \u0432 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0430 \u201c\u0422\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 JSON \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435\u201d. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u044d\u0442\u043e \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:if message.response_metadata.get(&#8216;finish_reason&#8217;) == &#8216;tool_calls&#8217; and not message.tool_calls:    return {&#8216;messages&#8217;: [HumanMessage(load_prompt_from_langfuse(&#8216;mcp_agent_error_tool_call_prompt&#8217;))]}\u0421 \u044d\u0442\u043e\u0433\u043e \u0438 \u043d\u0430\u0447\u0430\u043b\u0438\u0441\u044c \u043c\u043e\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. GigaChat3-10B \u043d\u0430 \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435\u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e. \u041e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u0437\u043e\u0432\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 write_file \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u0432\u044b\u0437\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043a\u043e\u0434\u0430. \u0422\u0430\u043a \u0432\u043e\u0442 &#8212; \u043d\u0430 \u043c\u043e\u0451 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0443\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c-\u0436\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u043b \u043e\u043d \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043a\u043e\u043d\u0447\u0430\u043b\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044f \u0432\u0432\u0451\u043b \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0432 \u0443\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043b \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e \u043d\u0435 \u0440\u0435\u0448\u0438\u043b\u043e, \u043d\u043e \u0445\u043e\u0442\u044c \u0436\u0434\u0430\u0442\u044c \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u044b\u043b\u043e \u043d\u0435 \u043d\u0430\u0434\u043e. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0441\u0442\u0430\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u0422\u0443\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0430 \u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0431\u044f \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0435\u0440\u0435\u0435\u0445\u0430\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e, \u043e\u0442\u043a\u0430\u0437\u0430\u0432\u0448\u0438\u0441\u044c \u043e\u0442 \u0434\u0432\u0443\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439. \u0422\u0430\u043a \u043a\u0430\u043a 32 \u0413\u0411 \u043f\u0430\u043c\u044f\u0442\u0438 &#8212; \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u0434\u043b\u044f LLM, \u0447\u0442\u043e-\u0442\u043e \u0441\u0442\u0438\u043b\u044c\u043d\u043e\u0435, \u043c\u043e\u0434\u043d\u043e\u0435, \u043c\u043e\u043b\u043e\u0434\u0451\u0436\u043d\u043e\u0435 \u0438 \u043a\u0432\u0430\u043d\u0442\u043e\u0432\u0430\u043d\u043d\u043e\u0435. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u0431\u044b\u043b\u0430 cyankiwi\/Qwen3.6-35B-A3B-AWQ-4bit. \u041d\u043e \u0432 SGLang \u043e\u043d\u0430 \u043c\u043d\u0435 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u044b &#8212; \u043b\u0438\u0431\u043e \u043f\u0443\u0441\u0442\u043e\u0435 \u043f\u043e\u043b\u0435, \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0440\u043e\u0447\u043a\u0438 \u0438\u0437 \u0432\u043e\u0441\u043a\u043b\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u043a\u043e\u0432. \u0414\u0430\u043b\u0435\u0435 \u0431\u044b\u043b\u0430 \u043c\u043e\u0434\u0435\u043b\u044c nvidia\/Qwen3.6-35B-A3B-NVFP4 \u0438 \u043f\u0435\u0440\u0435\u0435\u0437\u0434 \u043d\u0430 vLLM.\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0430\u0433\u0435\u043d\u0442\u0430.\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u043a\u0430\u043a \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043a \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438? \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u043d \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043b\u0430\u043d \u043f\u043e \u043f\u0443\u043d\u043a\u0442\u0430\u043c (\u0432\u0435\u0434\u044c \u043c\u044b \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0433\u043e \u0438 \u0434\u0435\u043b\u0430\u043b\u0438), \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u0432\u043e\u0435\u0439 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043f\u0443\u043d\u043a\u0442\u043e\u0432, \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435 \u043f\u043b\u043e\u0445\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u0435\u0451 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u0438 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430. \u041a\u0430\u043a \u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440 \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u043e \u0434\u0432\u0435. \u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0439. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u043f\u043b\u0430\u043d, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0448\u0430\u0433\u0438 \u0441 \u043e\u0446\u0435\u043d\u043a\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f:\u0421\u0445\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430\u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u0442\u0430\u043a\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0434\u043e\u0439\u0434\u0451\u0442 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u0421 \u043c\u043e\u0435\u0439 \u0436\u0435 (GigaChat \u043d\u0430 \u0442\u043e \u0432\u0440\u0435\u043c\u044f) \u043d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u043c\u0430\u0433\u0438\u044f &#8212; \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u201c\u041d\u0430\u043f\u0438\u0448\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u2026\u201d \u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u043b\u0430 \u043d\u0430 4-5 \u0448\u0430\u0433\u043e\u0432, \u0441\u0430\u043c\u0430 \u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u043f\u0443\u0442\u0430\u043b\u0430\u0441\u044c \u0432 \u043f\u043b\u0430\u043d\u0435. \u0418\u043d\u043e\u0433\u0434\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u043b\u0430 \u043a\u043e\u0434, \u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u043f\u0438\u0441\u0430\u043b\u0430 \u0432 \u0444\u0430\u0439\u043b \u0437\u0430\u043d\u043e\u0432\u043e \u043d\u0430\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u043b\u044e\u0441 \u0432\u0441\u043a\u0440\u044b\u0432\u0448\u0438\u0435\u0441\u044f \u0432\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u0435\u043c. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u201c\u043f\u043e\u043b\u0443\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0439\u201d \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u043c\u0435\u0448\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:Human-in-the-Loop \u0430\u0433\u0435\u043d\u0442\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0430\u0433\u0435\u043d\u0442.\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0433\u0435\u043d\u0442\u0430\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u043e\u0432\u044b\u0445 \u0443\u0437\u043b\u043e\u0432 \u0438 \u0440\u0451\u0431\u0435\u0440:\u0443\u0437\u0435\u043b \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0443\u0437\u043b\u044b \u043e\u0446\u0435\u043d\u0449\u0438\u043a\u0438\u0443\u0437\u0435\u043b \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0448\u0430\u0433\u0430 \u043f\u043b\u0430\u043d\u0430\u0443\u0437\u0435\u043b \u0441\u0436\u0430\u0442\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430\u0443\u0437\u0435\u043b \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\u041d\u0443 \u0438 \u0421\u0442\u0435\u0439\u0442 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0434\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0421 \u043d\u0435\u0433\u043e \u0438 \u043d\u0430\u0447\u043d\u0451\u043cAgentStateclass AgentState(MessagesState):    user_request: str    user_input: str    plan: list[dict]    current_step: int    step_iteration: int    history: list[str]    phase: Literal[&#8216;planning&#8217;, &#8216;executing&#8217;, &#8216;done&#8217;]    is_approved: bool    trace_id: str\u0412 \u0441\u0442\u0435\u0439\u0442 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438:\u0417\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#8212; \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b \u043f\u043e\u0434 \u0440\u0443\u043a\u043e\u0439\u041f\u043e\u043b\u0435 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#8212; \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u0449\u0435\u043d\u0438\u044f\u041c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u043b\u0430\u043d\u0430 \u043e\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u0418\u043d\u0434\u0435\u043a\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430 \u043f\u043b\u0430\u043d\u0430\u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0441\u0436\u0430\u0442\u0430\u044f)\u0424\u0430\u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430 &#8212; \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442, \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0448\u0430\u0433 \u043f\u0440\u0438\u043d\u044f\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c.\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0435\u0441\u0441\u0438\u0438 (\u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u043c\u044f\u0442\u0438)\u0414\u043b\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u0433\u0435\u043d\u0442\u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 &#8212; \u043f\u043e\u0440\u043e\u0433 \u043f\u043e\u043f\u044b\u0442\u043e\u043aclass ServiceConfig(BaseModel):    # \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434    max_step_iterations: int = 30\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u0443\u0437\u043b\u0430\u043c\u0423\u0437\u0435\u043b \u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0423\u0437\u0435\u043b \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u0431\u044b\u043b \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439. \u0420\u0430\u0437 \u043c\u044b \u043c\u043e\u0434\u0435\u0440\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0430\u0433\u0435\u043d\u0442\u0430, \u0442\u043e \u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0443\u0437\u043b\u043e\u0432 \u0443\u0433\u043b\u0443\u0431\u0438\u043c \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043c &#8212; \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0443\u0437\u043b\u044b \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438:from langchain.chat_models import BaseChatModelfrom langchain_core.output_parsers import PydanticOutputParserclass PlanerNode:    def __init__(            self,            llm: BaseChatModel,            prompt_name: str = &#8216;mcp_agent_planer_prompt&#8217;,            prompt_label: str = &#8216;production&#8217;    ):        self.parser = PydanticOutputParser(pydantic_object=Workflow)        self.llm = llm        self.prompt = load_prompt_from_langfuse(            prompt_name=prompt_name, prompt_label=prompt_label        ).format(format_instructions=self.parser.get_format_instructions())\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0443\u0437\u043b\u0430 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u043d\u043a\u0442\u043e\u0432. \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043c\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c PydanticOutputParser &#8212; \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 Pydantic \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u043f\u0440\u043e\u043c\u043f\u0442\u0443, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435. \u0410 \u043c\u0435\u0442\u043e\u0434 PydanticOutputParser.parse \u0432\u0435\u0440\u043d\u0451\u0442 \u043d\u0430\u043c \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 Pydantic-\u043e\u0431\u044a\u0435\u043a\u0442. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u0438\u0434\u0430 \u201c\u0425\u043e\u0440\u043e\u0448\u043e, \u0432\u043e\u0442 \u0447\u0442\u043e \u044f \u043c\u043e\u0433\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043b\u0430\u043d\u0430 \u043d\u0430 \u0442\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u2026\u201d \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u043d\u043a\u0442\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c:from typing import Annotatedfrom pydantic import BaseModel, Fieldclass Workflow(BaseModel):    plan: Annotated[list[str], Field(description=&#8217;\u0421\u043f\u0438\u0441\u043e\u043a \u0448\u0430\u0433\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438&#8217;)]\u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u043e\u043c\u043f\u0442\u043e\u0432 \u0438\u0437 LangFuse \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f:def load_prompt_from_langfuse(prompt_name: str, prompt_label: str = &#8216;production&#8217;) -&gt; str:    try:        return (            settings.langfuse.client            .get_prompt(prompt_name, label=prompt_label)            .get_langchain_prompt())    except Exception as e:        logger.error(f&#8217;\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u043c\u043f\u0442 &#171;{prompt_name}&#187; \u0438\u0437 Langfuse: {e}&#8217;)        raise RuntimeError(f&#8217;\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u043c\u043f\u0442 &#171;{prompt_name}&#187; \u0438\u0437 Langfuse&#8217;)\u041f\u0440\u043e\u043c\u043f\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0438 \u0442\u0435\u0433\u0443 (\u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432) \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0443\u044e \u0441 Langchain.PromptTemplate.\u0414\u0430\u043b\u044c\u0448\u0435 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u0443\u0437\u043b\u0430:class PlanerNode:    # \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043a\u043e\u0434    async def node(self, state: AgentState) -&gt; dict:        user_input = state.get(&#8216;user_input&#8217;, &#187;)        messages = [SystemMessage(content=self.prompt)] + state[&#8216;messages&#8217;]        if user_input:            messages += [HumanMessage(content=user_input)]        response = await self.llm.ainvoke(messages)        plan = self.parser.parse(response.content).plan        message = &#8216;\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u043b\u0430\u043d \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043f\u043b\u0430\u043d \u0441\u043b\u043e\u0432\u043e\u043c **&#187;\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c&#187;** \u043b\u0438\u0431\u043e \u0432\u043d\u0435\u0441\u0438\u0442\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0438&#8217;        for i, item in enumerate(plan, start=1):            message += f&#8217;\\n* \u0428\u0430\u0433 {i}: {item}&#8217;        return {            &#8216;messages&#8217;: [                HumanMessage(content=user_input), AIMessage(content=message)            ] if user_input else [AIMessage(content=message)],            &#8216;plan&#8217;: plan, &#8216;current_step&#8217;: 0, &#8216;phase&#8217;: &#8216;planning&#8217;, &#8216;is_approved&#8217;: False,        }\u041e\u0441\u043d\u043e\u0432\u0430 &#8212; \u0432 \u043f\u0440\u043e\u043c\u043f\u0442\u0435. \u0412 \u043d\u0451\u043c \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b LLM \u0440\u0430\u0437\u0431\u0438\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 (\u0442\u0438\u043f\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0444\u0430\u0439\u043b, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043a\u0441\u0442\u0440\u0438\u043d\u0433 \u0438 \u0442.\u043f.) \u0438 \u0432\u044b\u0434\u0430\u0442\u044c \u0438\u0445 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u043c\u043f\u0442\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0442\u0443\u0442 \u043d\u0435 \u0431\u0443\u0434\u0443, \u043d\u043e \u043a \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0443 \u0441\u0432\u043e\u0439 \u0434\u0430\u043c\u043f \u0441 LangFuse.\u0414\u0430\u043b\u044c\u0448\u0435, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PydanticOutputParser, \u043f\u0430\u0440\u0441\u0438\u043c \u043e\u0442\u0432\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0448\u0430\u0433\u0438 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0430.\u041f\u043e\u044f\u0441\u043d\u044e \u0437\u0430 user_input &#8212; \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0434\u0435\u043d\u043e \u043f\u043e\u0434 \u0443\u0442\u043e\u0447\u043d\u044f\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u043a\u0430\u043a &#8212; \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441). \u0415\u0441\u043b\u0438 \u0432 \u043f\u043e\u043b\u0435 \u0447\u0442\u043e-\u0442\u043e \u0435\u0441\u0442\u044c, \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0441\u0438\u0442 \u0447\u0442\u043e-\u0442\u043e \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c, \u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u0442\u043e \u0432 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 \u0443\u0437\u043b\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043b\u0430\u043d, \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u043c \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0448\u0430\u0433\u043e\u0432, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u0430\u0437\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430, \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0444\u043b\u0430\u0433 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.\u0418\u043d\u044a\u0435\u043a\u0442\u043e\u0440\u0414\u0430\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b &#8212; \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0448\u0430\u0433 \u0430\u0433\u0435\u043d\u0442\u0443. \u041e\u0434\u043d\u043e \u0432\u0440\u0435\u043c\u044f \u0432 \u0443\u0437\u043b\u0435 \u0447\u0438\u0441\u0442\u0438\u043b \u043f\u043e\u043b\u0435 state[&#8216;messages&#8217;] \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u043b \u0441\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439. \u041d\u043e \u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 Qwen3.6 \u043e\u0442 Nvidia \u0441\u0443\u043c\u043c\u0430\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0451 \u043f\u043e\u0440\u0442\u0438\u043b\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0448\u0430\u0433\u0430 \u043f\u043b\u0430\u043d\u0430:class StepInjectorNode:    def node(self, state: AgentState) -&gt; dict:        step_text = state[&#8216;plan&#8217;][state[&#8216;current_step&#8217;]]        return {&#8216;messages&#8217;: HumanMessage(f&#8217;\u0422\u0415\u041a\u0423\u0429\u0418\u0419 \u0428\u0410\u0413, \u041a\u041e\u0422\u041e\u0420\u042b\u0419 \u041d\u0423\u0416\u041d\u041e \u0412\u042b\u041f\u041e\u041b\u041d\u0418\u0422\u042c: {step_text}&#8217;),}\u0423\u0437\u0435\u043b-\u0430\u0433\u0435\u043d\u0442\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0443\u0437\u043b\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 (\u0434\u043b\u044f \u043c\u043e\u0438\u0445 \u0443\u0437\u043b\u043e\u0432):class AgentNode:    def __init__(            self,            llm: BaseChatModel,            prompt_name: str = &#8216;mcp_agent_prompt&#8217;,            prompt_label: str = &#8216;production&#8217;):        self.llm = llm        self.prompt = load_prompt_from_langfuse(prompt_name=prompt_name, prompt_label=prompt_label)\u0414\u0430\u043b\u044c\u0448\u0435 \u0441\u0430\u043c \u0443\u0437\u0435\u043b. \u0418 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u043e\u043d \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438:from langchain_core.messages import AIMessage, RemoveMessagefrom langgraph.graph.message import REMOVE_ALL_MESSAGESclass AgentNode:    # \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043a\u043e\u0434    async def node(self, state: AgentState) -&gt; dict:        if state.get(&#8216;step_iteration&#8217;, 0) &gt; settings.service.max_step_iterations:            msg = &#8216;\u041a\u0420\u0418\u0422\u0418\u0427\u0415\u0421\u041a\u0410\u042f \u041e\u0428\u0418\u0411\u041a\u0410! \u0410\u0433\u0435\u043d\u0442 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u043b\u0441\u044f \u0438 \u0431\u044b\u043b \u0441\u0431\u0440\u043e\u0448\u0435\u043d \u0432 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435!&#8217;            logger.error(msg)            return {                &#8216;messages&#8217;:&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-484336","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/484336","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=484336"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/484336\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=484336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=484336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=484336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}