{"id":452504,"date":"2025-03-20T21:32:12","date_gmt":"2025-03-20T21:32:12","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=452504"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=452504","title":{"rendered":"<span>\u041e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0447\u0430\u0442\u043e\u0432 LLM \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 Redis<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434, \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435,\u00a0<a href=\"https:\/\/github.com\/tripolskypetr\/agent-swarm-kit\/blob\/master\/demo\/redis-persist-chat\/src\/config\/persist.ts\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>  <\/p>\n<\/blockquote>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u043c\u0438 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0447\u0430\u0441\u0442\u044b\u043c \u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u0438 &#8212; \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u0451\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0445 \u0432\u044b\u0432\u043e\u0434. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0430\u043c\u0438 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0440\u0430\u0436\u0434\u0430\u0435\u0442 \u0432\u0430\u0436\u043d\u044b\u0435 \u043d\u044e\u0430\u043d\u0441\u044b, \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bb8\/ef1\/cfb\/bb8ef1cfb6bdc13dceb8d15392dc4e4c.png\" alt=\"\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 NVidia Nemotron Mini \u043d\u0430 Ollama\" title=\"\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 NVidia Nemotron Mini \u043d\u0430 Ollama\" width=\"1539\" height=\"928\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bb8\/ef1\/cfb\/bb8ef1cfb6bdc13dceb8d15392dc4e4c.png\"\/><\/p>\n<div><figcaption>\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 NVidia Nemotron Mini \u043d\u0430 Ollama<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u0439, \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d \u0435\u0434\u0438\u043d\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432: \u0448\u0430\u0431\u043b\u043e\u043d XML, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0437\u044b\u043a\u043e\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u043c\u0438. \u041d\u0430 \u0444\u043e\u0442\u043e \u0432\u044b\u0448\u0435, \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0433\u043e\u0434\u044b, \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 XML \u0441 \u0442\u0435\u0433\u043e\u043c <code>&lt;toolcall&gt;<\/code> \u0432 \u043b\u0438\u0447\u043a\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e<\/p>\n<h2>\u0412\u0430\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c<\/h2>\n<ol>\n<li>\n<p><strong>\u041d\u0435\u043b\u044c\u0437\u044f \u0434\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u044f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c ID \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430<\/strong><\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432, \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430, \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <code>seed <\/code>\u0438 <code>temperature <\/code>&#8212; \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043f\u0441\u0435\u0432\u0434\u043e\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0438 \u043f\u0440\u043e\u0446\u0435\u043d\u0442, \u0432 \u043a\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u043d \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e.<\/p>\n<p>\u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043c\u043e\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432\u0430\u043c \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u0439 ID \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0444\u043e\u0440\u043c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u0441\u0430\u043c\u0430 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0438<\/strong><\/p>\n<p>\u0412\u043e \u043f\u0435\u0440\u0432\u044b\u0445, Open Source \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u044b \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0444\u043e\u0440\u043c. \u0412\u043e \u0432\u0442\u043e\u0440\u044b\u0445, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0440\u043e\u0442\u0430\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0438. \u0412 \u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0435\u0441\u043b\u0438 \u0431\u044b\u043b\u0430 \u0432\u044b\u044f\u0432\u043b\u0435\u043d\u0430 \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, XML \u043a\u043e\u0434 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0438<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0438 \u0440\u043e\u0442\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432\u0430\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u043b system prompt<\/strong><\/p>\n<p>\u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 OpenAI, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c role, \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044e: <code>\"assistant\"<\/code> &#8212; \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u044f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438,  <code>\"system\" <\/code>&#8212; \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u043a\u0430\u043a \u0441\u0435\u0431\u044f \u0432\u0435\u0441\u0442\u0438, <code>\"tool\"<\/code> &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430, <code>\"user\"<\/code> &#8212; \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u041f\u0440\u0438 \u0440\u043e\u0442\u0430\u0446\u0438\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 <code>\"system\"<\/code> \u0441\u043b\u043e\u043c\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0443 \u0430\u0433\u0435\u043d\u0442\u0430, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<code> \"tool\"<\/code> \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438 <code>\"assistant\"<\/code> \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442<\/p>\n<\/li>\n<\/ol>\n<h2>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0438\u0442\u044c \u0432\u044b\u0448\u0435\u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0435 \u043f\u0443\u043d\u043a\u0442\u044b, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/p>\n<ul>\n<li>\n<p><strong>PersistStorage<\/strong><\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 ID \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043a\u0430\u043a \u0444\u0438\u043b\u044c\u0442\u0440 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u043e <code>similarity score<\/code> \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 \u043f\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0447\u0435\u0440\u0435\u0437<code> vector search<\/code><\/p>\n<\/li>\n<li>\n<p><strong>PersistState<\/strong><\/p>\n<p>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u043e\u0440\u043c\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043e\u0431\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u043d\u043e\u0435 \u043e\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430\u0447\u043d\u0435\u0442 \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/li>\n<li>\n<p><strong>PersistEmbedding<\/strong><\/p>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <a href=\"https:\/\/platform.openai.com\/docs\/guides\/embeddings\" rel=\"noopener noreferrer nofollow\">vector embeddings<\/a> \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 &#8212; \u043f\u043b\u0430\u0442\u043d\u044b\u0439. \u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 similarity score \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a \u0432 RAG \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0434\u043b\u044f \u0434\u0432\u0443\u0445 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0441\u0442\u0440\u043e\u043a \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u0432 (\u043f\u043e \u0440\u0430\u0437\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443), \u0434\u0430\u043b\u0435\u0435 \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u043d\u043e\u0435 \u0441\u0445\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043e\u0442 0.0 \u0434\u043e 1.0. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043b\u043e\u0434\u0438\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u0443\u0436\u0435 \u0432\u044b\u0447\u0435\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u044c, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447\u044c &#8212; \u0445\u0435\u0448 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438<\/p>\n<\/li>\n<\/ul>\n<h3>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/h3>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u043c, \u043d\u0443\u0436\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/p>\n<ul>\n<li>\n<p><strong>PersistAlive<\/strong><\/p>\n<p>\u0424\u043b\u0430\u0436\u043e\u043a, \u043e\u043d\u043b\u0430\u0439\u043d \u043b\u0438 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043d\u0438\u043a \u044f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u041a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0445\u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/p>\n<\/li>\n<li>\n<p><strong>PersistMemory<\/strong><\/p>\n<p>\u041f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c HTTP \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u043a\u043b\u044e\u0447\u044c-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/p>\n<\/li>\n<li>\n<p><strong>PersistPolicy<\/strong><\/p>\n<p>\u0415\u0441\u043b\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u0437\u0430\u0434\u0430\u0451\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 &#171;\u0427\u0435\u0439 \u041a\u0440\u044b\u043c&#187;, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0431\u0430\u043d\u0438\u0442\u044c, \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0434\u0435\u043d\u044c\u0433\u0438 \u043e\u043d \u043d\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d. <s>\u042f \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u044e, \u0447\u0442\u043e ChatGPT &#8212; \u044d\u0442\u043e OpenAI \u0438 \u044f \u043f\u043b\u0430\u0447\u0443 \u0438\u043c \u0437\u0430 \u0442\u043e\u043a\u0435\u043d\u044b<\/s><\/p>\n<\/li>\n<li>\n<p><strong>PersistSwarm<\/strong><\/p>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e \u0440\u043e\u044e \u0430\u0433\u0435\u043d\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0442\u0435\u043a \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0434\u043b\u044f <code>navigate back<\/code> \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u0435\u0437 \u0440\u0430\u0441\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430<\/h2>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3f2\/053\/dd4\/3f2053dd4980ef16faa4fafd8fc4330e.png\" alt=\"Another Redis Desktop Manager, \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u043e \u0431\u0435\u0437 \u0444\u043b\u0430\u0433\u0430\" title=\"Another Redis Desktop Manager, \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u043e \u0431\u0435\u0437 \u0444\u043b\u0430\u0433\u0430\" width=\"1920\" height=\"1039\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3f2\/053\/dd4\/3f2053dd4980ef16faa4fafd8fc4330e.png\"\/><\/p>\n<div><figcaption>Another Redis Desktop Manager, <s>\u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u043e \u0431\u0435\u0437 \u0444\u043b\u0430\u0433\u0430<\/s><\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0443\u0431\u043b\u0438\u0440\u0443\u044e \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e<a href=\"https:\/\/github.com\/tripolskypetr\/agent-swarm-kit\/blob\/master\/demo\/redis-persist-chat\/src\/config\/persist.ts\" rel=\"noopener noreferrer nofollow\"> \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435<\/a>. \u0422\u0430\u043c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0447\u0430\u0442, \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0440\u0430\u0431\u043e\u0447\u0430\u044f<\/p>\n<pre><code class=\"typescript\">import {   PersistAlive,   PersistMemory,   PersistPolicy,   PersistState,   PersistStorage,   PersistSwarm,   PersistEmbedding,   History,   type IHistoryInstance,   type IModelMessage,   type IPersistBase,   type IPersistActiveAgentData,   type IPersistNavigationStackData,   type IPersistStateData,   type IPersistStorageData,   type IPersistMemoryData,   type IPersistPolicyData,   type IPersistAliveData,   type IPersistEmbeddingData,   setConfig, } from \"agent-swarm-kit\"; import { singleshot } from \"functools-kit\"; import Redis from \"ioredis\";  setConfig({   CC_PERSIST_EMBEDDING_CACHE: true, });  declare function parseInt(s: unknown): number;  const EMBEDDING_REDIS_TTL = 604800; \/\/ 1 week const HISTORY_REDIS_TTL = 86400; \/\/ 24 hours const ALIVE_REDIS_TTL = 3600; \/\/ 1 hour  const getRedis = singleshot(   () =&gt;     new Promise&lt;Redis&gt;((res) =&gt; {       const redis = new Redis({         host: process.env.CC_REDIS_HOST || \"127.0.0.1\",         port: parseInt(process.env.CC_REDIS_PORT) || 6379,         password: process.env.CC_REDIS_PASSWORD || \"\",       });       redis.on(\"connect\", () =&gt; {         res(redis);       });       redis.on(\"error\", (error) =&gt; {         throw error;       });       redis.on(\"close\", () =&gt; {         throw new Error(\"redis connection closed\");       });       return redis;     }) );  History.useHistoryAdapter(   class implements IHistoryInstance {     private _redis: Redis = null as never;     private _messages: IModelMessage[] = [];      async *iterate(): AsyncIterableIterator&lt;IModelMessage&gt; {       for await (const message of this._messages) {         yield message;       }     }      constructor(public readonly clientId: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();       const messages = await this._redis.lrange(         `history:${this.clientId}:messages`,         0,         -1       );       this._messages = messages.map((msg) =&gt; JSON.parse(msg) as IModelMessage);     });      async push(value: IModelMessage): Promise&lt;void&gt; {       const key = `history:${this.clientId}:messages`;       await this._redis.rpush(key, JSON.stringify(value));       await this._redis.expire(key, HISTORY_REDIS_TTL);       this._messages.push(value);     }      async pop(): Promise&lt;IModelMessage | null&gt; {       const key = `history:${this.clientId}:messages`;       await this._redis.lpop(key);       return this._messages.pop() ?? null;     }      async dispose() {       this._messages = [];     }   } );  PersistSwarm.usePersistActiveAgentAdapter(   class implements IPersistBase&lt;IPersistActiveAgentData&gt; {     private _redis: Redis = null as never;      constructor(private readonly swarmName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistActiveAgentData&gt; {       const key = `swarm:${this.swarmName}:active_agent:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistActiveAgent ${clientId} not found.`);       }       return JSON.parse(value) as IPersistActiveAgentData;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `swarm:${this.swarmName}:active_agent:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistActiveAgentData     ): Promise&lt;void&gt; {       const key = `swarm:${this.swarmName}:active_agent:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistSwarm.usePersistNavigationStackAdapter(   class implements IPersistBase&lt;IPersistNavigationStackData&gt; {     private _redis: Redis = null as never;      constructor(private readonly swarmName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistNavigationStackData&gt; {       const key = `swarm:${this.swarmName}:navigation_stack:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistNavigationStack ${clientId} not found.`);       }       return JSON.parse(value) as IPersistNavigationStackData;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `swarm:${this.swarmName}:navigation_stack:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistNavigationStackData     ): Promise&lt;void&gt; {       const key = `swarm:${this.swarmName}:navigation_stack:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistState.usePersistStateAdapter(   class implements IPersistBase&lt;IPersistStateData&gt; {     private _redis: Redis = null as never;      constructor(private readonly stateName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistStateData&lt;unknown&gt;&gt; {       const key = `state:${this.stateName}:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistState ${clientId} not found.`);       }       return JSON.parse(value) as IPersistStateData&lt;unknown&gt;;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `state:${this.stateName}:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistStateData&lt;unknown&gt;     ): Promise&lt;void&gt; {       const key = `state:${this.stateName}:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistStorage.usePersistStorageAdapter(   class implements IPersistBase&lt;IPersistStorageData&gt; {     private _redis: Redis = null as never;      constructor(private readonly storageName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistStorageData&gt; {       const key = `storage:${this.storageName}:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistStorage ${clientId} not found.`);       }       return JSON.parse(value) as IPersistStorageData;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `storage:${this.storageName}:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistStorageData     ): Promise&lt;void&gt; {       const key = `storage:${this.storageName}:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistMemory.usePersistMemoryAdapter(   class implements IPersistBase&lt;IPersistMemoryData&gt; {     private _redis: Redis = null as never;      constructor(private readonly memoryName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistMemoryData&lt;unknown&gt;&gt; {       const key = `memory:${this.memoryName}:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistMemory ${clientId} not found.`);       }       return JSON.parse(value) as IPersistMemoryData&lt;unknown&gt;;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `memory:${this.memoryName}:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistMemoryData&lt;unknown&gt;     ): Promise&lt;void&gt; {       const key = `memory:${this.memoryName}:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistPolicy.usePersistPolicyAdapter(   class implements IPersistBase&lt;IPersistPolicyData&gt; {     private _redis: Redis = null as never;      constructor(private readonly swarmName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(policyName: string): Promise&lt;IPersistPolicyData&gt; {       const key = `policy:${this.swarmName}:${policyName}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistPolicy ${policyName} not found.`);       }       return JSON.parse(value) as IPersistPolicyData;     }      async hasValue(policyName: string): Promise&lt;boolean&gt; {       const key = `policy:${this.swarmName}:${policyName}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       policyName: string,       entity: IPersistPolicyData     ): Promise&lt;void&gt; {       const key = `policy:${this.swarmName}:${policyName}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistAlive.usePersistAliveAdapter(   class implements IPersistBase&lt;IPersistAliveData&gt; {     private _redis: Redis = null as never;      constructor(private readonly swarmName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();       const pattern = `alive:${this.swarmName}:*`;       const keys = await this._redis.keys(pattern);       if (keys.length &gt; 0) {         await this._redis.del(...keys);       }     });      async readValue(clientId: string): Promise&lt;IPersistAliveData&gt; {       const key = `alive:${this.swarmName}:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         return { online: false };       }       return JSON.parse(value) as IPersistAliveData;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `alive:${this.swarmName}:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistAliveData     ): Promise&lt;void&gt; {       const key = `alive:${this.swarmName}:${clientId}`;       if (!entity.online) {         await this._redis.del(key);         return;       }       await this._redis.set(key, JSON.stringify(entity));       await this._redis.expire(key, ALIVE_REDIS_TTL);     }   } );  PersistEmbedding.usePersistEmbeddingAdapter(   class implements IPersistBase&lt;IPersistEmbeddingData&gt; {     private _redis: Redis = null as never;      constructor(private readonly embeddingName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(stringHash: string): Promise&lt;IPersistEmbeddingData&gt; {       const key = `embedding:${this.embeddingName}:${stringHash}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistEmbedding ${stringHash} not found.`);       }       const buffer = Buffer.from(value, \"base64\");       const embeddings = Array.from(new Float64Array(buffer.buffer));       return { embeddings };     }      async hasValue(stringHash: string): Promise&lt;boolean&gt; {       const key = `embedding:${this.embeddingName}:${stringHash}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       stringHash: string,       entity: IPersistEmbeddingData     ): Promise&lt;void&gt; {       const key = `embedding:${this.embeddingName}:${stringHash}`;       const buffer = Buffer.from(new Float64Array(entity.embeddings).buffer);       await this._redis.set(key, buffer.toString(\"base64\"));       await this._redis.expire(key, EMBEDDING_REDIS_TTL);     }   } ); <\/code><\/pre>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/892866\/\"> https:\/\/habr.com\/ru\/articles\/892866\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434, \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435,\u00a0<a href=\"https:\/\/github.com\/tripolskypetr\/agent-swarm-kit\/blob\/master\/demo\/redis-persist-chat\/src\/config\/persist.ts\" rel=\"noopener noreferrer nofollow\">\u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>  <\/p>\n<\/blockquote>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u043c\u0438 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0447\u0430\u0441\u0442\u044b\u043c \u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u0438 &#8212; \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u0451\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0445 \u0432\u044b\u0432\u043e\u0434. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0430\u043c\u0438 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0440\u0430\u0436\u0434\u0430\u0435\u0442 \u0432\u0430\u0436\u043d\u044b\u0435 \u043d\u044e\u0430\u043d\u0441\u044b, \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 NVidia Nemotron Mini \u043d\u0430 Ollama<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u0439, \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d \u0435\u0434\u0438\u043d\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432: \u0448\u0430\u0431\u043b\u043e\u043d XML, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0437\u044b\u043a\u043e\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u043c\u0438. \u041d\u0430 \u0444\u043e\u0442\u043e \u0432\u044b\u0448\u0435, \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0433\u043e\u0434\u044b, \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 XML \u0441 \u0442\u0435\u0433\u043e\u043c <code>&lt;toolcall&gt;<\/code> \u0432 \u043b\u0438\u0447\u043a\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e<\/p>\n<h2>\u0412\u0430\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c<\/h2>\n<ol>\n<li>\n<p><strong>\u041d\u0435\u043b\u044c\u0437\u044f \u0434\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u044f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c ID \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430<\/strong><\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432, \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430, \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <code>seed <\/code>\u0438 <code>temperature <\/code>&#8212; \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043f\u0441\u0435\u0432\u0434\u043e\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0438 \u043f\u0440\u043e\u0446\u0435\u043d\u0442, \u0432 \u043a\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u043d \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e.<\/p>\n<p>\u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043c\u043e\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432\u0430\u043c \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u0439 ID \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0444\u043e\u0440\u043c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u0441\u0430\u043c\u0430 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0438<\/strong><\/p>\n<p>\u0412\u043e \u043f\u0435\u0440\u0432\u044b\u0445, Open Source \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u044b \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0444\u043e\u0440\u043c. \u0412\u043e \u0432\u0442\u043e\u0440\u044b\u0445, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0440\u043e\u0442\u0430\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0438. \u0412 \u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0435\u0441\u043b\u0438 \u0431\u044b\u043b\u0430 \u0432\u044b\u044f\u0432\u043b\u0435\u043d\u0430 \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, XML \u043a\u043e\u0434 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0438<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0438 \u0440\u043e\u0442\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432\u0430\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u043b system prompt<\/strong><\/p>\n<p>\u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 OpenAI, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u043a\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c role, \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044e: <code>\"assistant\"<\/code> &#8212; \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u044f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438,  <code>\"system\" <\/code>&#8212; \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u043a\u0430\u043a \u0441\u0435\u0431\u044f \u0432\u0435\u0441\u0442\u0438, <code>\"tool\"<\/code> &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430, <code>\"user\"<\/code> &#8212; \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u041f\u0440\u0438 \u0440\u043e\u0442\u0430\u0446\u0438\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 <code>\"system\"<\/code> \u0441\u043b\u043e\u043c\u0430\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0443 \u0430\u0433\u0435\u043d\u0442\u0430, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<code> \"tool\"<\/code> \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0434\u0430\u043b\u044f\u0442\u044c\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438 <code>\"assistant\"<\/code> \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442<\/p>\n<\/li>\n<\/ol>\n<h2>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0438\u0442\u044c \u0432\u044b\u0448\u0435\u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0435 \u043f\u0443\u043d\u043a\u0442\u044b, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/p>\n<ul>\n<li>\n<p><strong>PersistStorage<\/strong><\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 ID \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043a\u0430\u043a \u0444\u0438\u043b\u044c\u0442\u0440 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u043e <code>similarity score<\/code> \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 \u043f\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0447\u0435\u0440\u0435\u0437<code> vector search<\/code><\/p>\n<\/li>\n<li>\n<p><strong>PersistState<\/strong><\/p>\n<p>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u043e\u0440\u043c\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043e\u0431\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u043d\u043e\u0435 \u043e\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430\u0447\u043d\u0435\u0442 \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/li>\n<li>\n<p><strong>PersistEmbedding<\/strong><\/p>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <a href=\"https:\/\/platform.openai.com\/docs\/guides\/embeddings\" rel=\"noopener noreferrer nofollow\">vector embeddings<\/a> \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 &#8212; \u043f\u043b\u0430\u0442\u043d\u044b\u0439. \u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 similarity score \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a \u0432 RAG \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0434\u043b\u044f \u0434\u0432\u0443\u0445 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0441\u0442\u0440\u043e\u043a \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u0432 (\u043f\u043e \u0440\u0430\u0437\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443), \u0434\u0430\u043b\u0435\u0435 \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u043d\u043e\u0435 \u0441\u0445\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043e\u0442 0.0 \u0434\u043e 1.0. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043b\u043e\u0434\u0438\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u0443\u0436\u0435 \u0432\u044b\u0447\u0435\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u044c, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447\u044c &#8212; \u0445\u0435\u0448 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438<\/p>\n<\/li>\n<\/ul>\n<h3>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/h3>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u043c, \u043d\u0443\u0436\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b<\/p>\n<ul>\n<li>\n<p><strong>PersistAlive<\/strong><\/p>\n<p>\u0424\u043b\u0430\u0436\u043e\u043a, \u043e\u043d\u043b\u0430\u0439\u043d \u043b\u0438 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043d\u0438\u043a \u044f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u041a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0445\u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/p>\n<\/li>\n<li>\n<p><strong>PersistMemory<\/strong><\/p>\n<p>\u041f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c HTTP \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u043a\u043b\u044e\u0447\u044c-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/p>\n<\/li>\n<li>\n<p><strong>PersistPolicy<\/strong><\/p>\n<p>\u0415\u0441\u043b\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u0437\u0430\u0434\u0430\u0451\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 &#171;\u0427\u0435\u0439 \u041a\u0440\u044b\u043c&#187;, \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0431\u0430\u043d\u0438\u0442\u044c, \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0434\u0435\u043d\u044c\u0433\u0438 \u043e\u043d \u043d\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d. <s>\u042f \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u044e, \u0447\u0442\u043e ChatGPT &#8212; \u044d\u0442\u043e OpenAI \u0438 \u044f \u043f\u043b\u0430\u0447\u0443 \u0438\u043c \u0437\u0430 \u0442\u043e\u043a\u0435\u043d\u044b<\/s><\/p>\n<\/li>\n<li>\n<p><strong>PersistSwarm<\/strong><\/p>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e \u0440\u043e\u044e \u0430\u0433\u0435\u043d\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0442\u0435\u043a \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0434\u043b\u044f <code>navigate back<\/code> \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u0435\u0437 \u0440\u0430\u0441\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430<\/h2>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Another Redis Desktop Manager, <s>\u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u043e \u0431\u0435\u0437 \u0444\u043b\u0430\u0433\u0430<\/s><\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0443\u0431\u043b\u0438\u0440\u0443\u044e \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e<a href=\"https:\/\/github.com\/tripolskypetr\/agent-swarm-kit\/blob\/master\/demo\/redis-persist-chat\/src\/config\/persist.ts\" rel=\"noopener noreferrer nofollow\"> \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435<\/a>. \u0422\u0430\u043c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0447\u0430\u0442, \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0440\u0430\u0431\u043e\u0447\u0430\u044f<\/p>\n<pre><code class=\"typescript\">import {   PersistAlive,   PersistMemory,   PersistPolicy,   PersistState,   PersistStorage,   PersistSwarm,   PersistEmbedding,   History,   type IHistoryInstance,   type IModelMessage,   type IPersistBase,   type IPersistActiveAgentData,   type IPersistNavigationStackData,   type IPersistStateData,   type IPersistStorageData,   type IPersistMemoryData,   type IPersistPolicyData,   type IPersistAliveData,   type IPersistEmbeddingData,   setConfig, } from \"agent-swarm-kit\"; import { singleshot } from \"functools-kit\"; import Redis from \"ioredis\";  setConfig({   CC_PERSIST_EMBEDDING_CACHE: true, });  declare function parseInt(s: unknown): number;  const EMBEDDING_REDIS_TTL = 604800; \/\/ 1 week const HISTORY_REDIS_TTL = 86400; \/\/ 24 hours const ALIVE_REDIS_TTL = 3600; \/\/ 1 hour  const getRedis = singleshot(   () =&gt;     new Promise&lt;Redis&gt;((res) =&gt; {       const redis = new Redis({         host: process.env.CC_REDIS_HOST || \"127.0.0.1\",         port: parseInt(process.env.CC_REDIS_PORT) || 6379,         password: process.env.CC_REDIS_PASSWORD || \"\",       });       redis.on(\"connect\", () =&gt; {         res(redis);       });       redis.on(\"error\", (error) =&gt; {         throw error;       });       redis.on(\"close\", () =&gt; {         throw new Error(\"redis connection closed\");       });       return redis;     }) );  History.useHistoryAdapter(   class implements IHistoryInstance {     private _redis: Redis = null as never;     private _messages: IModelMessage[] = [];      async *iterate(): AsyncIterableIterator&lt;IModelMessage&gt; {       for await (const message of this._messages) {         yield message;       }     }      constructor(public readonly clientId: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();       const messages = await this._redis.lrange(         `history:${this.clientId}:messages`,         0,         -1       );       this._messages = messages.map((msg) =&gt; JSON.parse(msg) as IModelMessage);     });      async push(value: IModelMessage): Promise&lt;void&gt; {       const key = `history:${this.clientId}:messages`;       await this._redis.rpush(key, JSON.stringify(value));       await this._redis.expire(key, HISTORY_REDIS_TTL);       this._messages.push(value);     }      async pop(): Promise&lt;IModelMessage | null&gt; {       const key = `history:${this.clientId}:messages`;       await this._redis.lpop(key);       return this._messages.pop() ?? null;     }      async dispose() {       this._messages = [];     }   } );  PersistSwarm.usePersistActiveAgentAdapter(   class implements IPersistBase&lt;IPersistActiveAgentData&gt; {     private _redis: Redis = null as never;      constructor(private readonly swarmName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistActiveAgentData&gt; {       const key = `swarm:${this.swarmName}:active_agent:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistActiveAgent ${clientId} not found.`);       }       return JSON.parse(value) as IPersistActiveAgentData;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `swarm:${this.swarmName}:active_agent:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistActiveAgentData     ): Promise&lt;void&gt; {       const key = `swarm:${this.swarmName}:active_agent:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistSwarm.usePersistNavigationStackAdapter(   class implements IPersistBase&lt;IPersistNavigationStackData&gt; {     private _redis: Redis = null as never;      constructor(private readonly swarmName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistNavigationStackData&gt; {       const key = `swarm:${this.swarmName}:navigation_stack:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistNavigationStack ${clientId} not found.`);       }       return JSON.parse(value) as IPersistNavigationStackData;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `swarm:${this.swarmName}:navigation_stack:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistNavigationStackData     ): Promise&lt;void&gt; {       const key = `swarm:${this.swarmName}:navigation_stack:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistState.usePersistStateAdapter(   class implements IPersistBase&lt;IPersistStateData&gt; {     private _redis: Redis = null as never;      constructor(private readonly stateName: string) {}      public waitForInit = singleshot(async () =&gt; {       this._redis = await getRedis();     });      async readValue(clientId: string): Promise&lt;IPersistStateData&lt;unknown&gt;&gt; {       const key = `state:${this.stateName}:${clientId}`;       const value = await this._redis.get(key);       if (!value) {         throw new Error(`PersistState ${clientId} not found.`);       }       return JSON.parse(value) as IPersistStateData&lt;unknown&gt;;     }      async hasValue(clientId: string): Promise&lt;boolean&gt; {       const key = `state:${this.stateName}:${clientId}`;       const exists = await this._redis.exists(key);       return exists === 1;     }      async writeValue(       clientId: string,       entity: IPersistStateData&lt;unknown&gt;     ): Promise&lt;void&gt; {       const key = `state:${this.stateName}:${clientId}`;       await this._redis.set(key, JSON.stringify(entity));     }   } );  PersistStorage.usePersistStorageAdapter(   class implements IPersistBase&lt;IPersistStorageData&gt; {     private _redis: Redis = <\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-452504","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/452504","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=452504"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/452504\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=452504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=452504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=452504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}