diff --git a/examples/giga_chain_api_plus/README.md b/examples/giga_chain_api_plus/README.md new file mode 100644 index 00000000..91f92ec9 --- /dev/null +++ b/examples/giga_chain_api_plus/README.md @@ -0,0 +1,28 @@ +# Пример работы с GigaChat + +## Описание + +Цепочка для суммаризации документов с помощью GigaChat. + +## Установка + +Добавьте данные авторизации и настройки GigaChat в переменные окружения, например: +``` + "GIGACHAT_USER": "...", + "GIGACHAT_PASSWORD": "...", + "GIGACHAT_VERIFY_SSL_CERTS": "...", + "GIGACHAT_BASE_URL": "...", + "GIGACHAT_MODEL": "GigaChat:latest", +``` + +## Использование + +Запустите сервер с помощью команды: +``` + python examples/giga_chain_api_plus/server.py +``` + +Запустите пример клиента с помощью команды: +``` + python examples/giga_chain_api_plus/client.py +``` \ No newline at end of file diff --git a/examples/giga_chain_api_plus/access_token.txt b/examples/giga_chain_api_plus/access_token.txt new file mode 100644 index 00000000..a9dc5eae --- /dev/null +++ b/examples/giga_chain_api_plus/access_token.txt @@ -0,0 +1 @@ +access_token \ No newline at end of file diff --git a/examples/giga_chain_api_plus/attractor.txt b/examples/giga_chain_api_plus/attractor.txt new file mode 100644 index 00000000..522ae5a8 --- /dev/null +++ b/examples/giga_chain_api_plus/attractor.txt @@ -0,0 +1,34 @@ +Вели́кий аттра́ктор (Великий центр притяжения, от англ. attract — «привлекать, притягивать, пленять») — гравитационная аномалия, расположенная в межгалактическом пространстве на расстоянии примерно 75 Мпк, или около 250 млн световых лет от Земли в созвездии Наугольник. Этот объект, имеющий массу порядка 5⋅1016 M☉ (или 105 масс Млечного Пути), является, скорее всего, огромным сверхскоплением галактик. Средняя плотность вещества в районе Великого аттрактора ненамного больше средней плотности Вселенной, но за счёт гигантских размеров его масса оказывается настолько велика, что не только наша звёздная система, но и другие галактики и их скопления поблизости (в том числе скопление Девы и ряд близких сверхскоплений) имеют пекулярные скорости, направленные на него, формируя огромный поток галактик. Существование Великого аттрактора подтверждается эффектом, который он оказывает на движение наблюдаемых нами галактик и их скоплений на участке пространства протяжённостью в несколько сотен миллионов световых лет. +Центр Великого аттрактора — скопление Норма (ACO 3627, или Наугольник) в созвездии Наугольника — лежит на пересечении двух крупнейших структур, а именно стены Центавра, включающей сверхскопление Девы, скопление Центавра (Abell 3526) и собственно скопление Норма, и другой, простирающейся от скопления Павлина до сверхскопления Парусов. Иногда Великим аттрактором называют всю эту стену с центром в кластере ACO 3627, сам же он образует центр тяжести крупнейшей структуры Ланиакеа, в которую входит содержащее нашу галактику сверхскопление Девы. + + +== Экспериментальные данные == +Необходимость существования некоего центра притяжения следовала из расхождения предсказанной в 1960-х годах и выявленной в 1970-х годах дипольной анизотропии реликтового излучения и известных на тот момент её источников — вращения Земли вместе с Солнцем вокруг центра Галактики в направлении созвездия Лебедя, а также движения в сторону созвездия Льва. Данные свидетельствовали о том, что наша галактика и её соседи, составляющие так называемую Местную Группу, а также скопление Девы, кроме взаимного движения, движутся со скоростью около 600 км/с в направлении созвездия Гидра. Суперпозиция скоростей движения к скоплению галактик в созвездии Девы и к Великому аттрактору и даёт наблюдаемую скорость движения Млечного Пути относительно космической системы отсчёта, измеряемую по величине дипольной анизотропии реликтового излучения. +Таким образом учёные пришли к заключению о существовании Великого аттрактора, находящегося на расстоянии около 60 Мпк, из столь огромного скопления материи, что его притяжение достаточно однородно, чтобы не разрывать гравитационную связь галактических скоплений между собой. Впервые гипотеза была высказана Аланом Дресслером в 1986 году. Прямое наблюдение Великого аттрактора, однако, затруднено тем, что он находится в так называемой «зоне избегания», закрытой от наблюдения плоскостью Млечного пути с большим количеством звёзд и межзвёздной пыли; скопление вещества отчётливо прослеживается только путём радионаблюдений рентгеновских источников. В 1980-е годы с помощью радиотелескопов было открыто (первым в «зоне избегания») новое скопление на расстоянии 20 Мпк в созвездии Корма; учёт его влияния давал несколько лучшее согласие с положением космического фонового диполя. Хотя в этом предполагаемом направлении на Великий аттрактор плотность видимых галактик и увеличивалась, скопление включало только 50 галактик, что не могло составлять достаточную массу для аттрактора. Лишь к концу 1990-х годов дальний обзор в оптическом диапазоне на различных телескопах, находящихся в южном полушарии, позволил учёным из Европейской южной обсерватории обнаружить ещё 600 галактик в этом скоплении. Это исследование показало, что центр Великого аттрактора находится в скоплении Наугольника. Оно напоминает скопление Волос Вероники, в частности, имеет массу порядка 1015 M☉, или около 1000 масс нашей Галактики. Учёт его влияния уже позволил практически полностью объяснить наблюдаемые движения галактик в ближайшей Вселенной. +В прилегающих к Аттрактору областях Вселенной галактики обнаруживают крупномасштабное течение в его сторону. Многие галактики в составе самого кластера Наугольника движутся по направлению друг к другу, весь же он в целом находится, судя по всему, в покое относительно реликтового излучения. Однако потоки галактик, аналогичные падению нашей и других расположенных рядом систем на Великий аттрактор, — это местные явления, существование которых не противоречит справедливости космологического принципа в больших масштабах, где отклонения от закона Хаббла сравнительно невелики. +Возможно, помимо Великого аттрактора, свой вклад в наличие пекулярной скорости Местного сверхскопления вносит притяжение и других систем галактик: Местная группа находится также и в зоне притяжения сверхскопления Персея — Рыб, а также сверхскопления Шепли в созвездии Центавра (с центром в Abell 3558) в 400 миллионах световых лет от Земли. Существуют и данные, указывающие на присутствие других источников притяжения, скрытых за плоскостью Млечного Пути. Поскольку все зарегистрированные сверхскопления всё ещё не могут полностью объяснить движение Млечного пути, вероятно, что эти данные не полны. Большую роль также играет не до конца изученное распределение тёмной материи (центр тяжести её скоплений может не совпадать с центром тяжести местного сверхскопления), определяющее крупномасштабную структуру Вселенной. + + +== См. также == +Тёмный поток +Крупномасштабная структура Вселенной +Дипольный отталкиватель + + +== Примечания == +Комментарии + +Источники + + +== Литература == +Drake, Nadia. New map locates Milky Way in neighborhood of 100,000 galaxies, National Geographic (3 сентября 2014). +Dressler, Alan. Voyage to the Great Attractor: Exploring Intergalactic Space. — New York, NY : Alfred A. Knopf, 1994. — P. 355. — ISBN 978-0-394-58899-5. + + +== Ссылки == +Методика проведения 2 урока «Галактики» // astronet.ru +Mathewson, D.S.; Ford, V.L.; Buchhorn, M. (1992). “No back-side infall into the Great Attractor”. The Astrophysical Journal. 389: L5. Bibcode:1992ApJ...389L...5M. DOI:10.1086/186335. +Dressler, Alan (1988). “The Supergalactic Plane Redshift Survey: A candidate for the Great Attractor”. The Astrophysical Journal. 329: 519. Bibcode:1988ApJ...329..519D. DOI:10.1086/166398. +Raychaudhury, Somak (1989). “The distribution of galaxies in the direction of the 'Great Attractor'”. Nature. 342 (6247): 251—255. Bibcode:1989Natur.342..251R. DOI:10.1038/342251a0. +Bertschinger, Edmund; Juszkiewicz, Roman (1988). “Searching for the Great Attractor”. The Astrophysical Journal. 334: L59. Bibcode:1988ApJ...334L..59B. DOI:10.1086/185312. \ No newline at end of file diff --git a/examples/giga_chain_api_plus/chain.py b/examples/giga_chain_api_plus/chain.py new file mode 100644 index 00000000..af70a28a --- /dev/null +++ b/examples/giga_chain_api_plus/chain.py @@ -0,0 +1,21 @@ +from langchain.chains import AnalyzeDocumentChain +from langchain.chains.summarize import load_summarize_chain +from langchain.chat_models.gigachat import GigaChat +from langchain.prompts import load_prompt +from langchain.text_splitter import RecursiveCharacterTextSplitter + +giga = GigaChat(profanity=False, verbose=True, timeout=30, verify_ssl_certs=False) + +map_prompt = load_prompt("lc://prompts/summarize/map_reduce/map.yaml") +combine_prompt = load_prompt("lc://prompts/summarize/map_reduce/combine.yaml") + +splitter = RecursiveCharacterTextSplitter(chunk_size=4000, chunk_overlap=0) +combine_chain = load_summarize_chain( + giga, + chain_type="map_reduce", + map_prompt=map_prompt, + combine_prompt=combine_prompt, +) + +chain = AnalyzeDocumentChain(combine_docs_chain=combine_chain, text_splitter=splitter) +chain.save("chain.yaml") diff --git a/examples/giga_chain_api_plus/chain.yaml b/examples/giga_chain_api_plus/chain.yaml new file mode 100644 index 00000000..6553a0be --- /dev/null +++ b/examples/giga_chain_api_plus/chain.yaml @@ -0,0 +1,139 @@ +_type: analyze_document_chain +combine_docs_chain: + _type: map_reduce_documents_chain + document_variable_name: text + input_key: input_documents + llm_chain: + _type: llm_chain + llm: + _type: giga-chat-model + max_tokens: null + model: null + profanity: false + streaming: false + temperature: null + llm_kwargs: {} + memory: null + metadata: null + output_key: text + output_parser: + _type: default + prompt: + _type: prompt + input_types: {} + input_variables: + - text + output_parser: null + partial_variables: {} + template: "\u0412\u044B\u0434\u0435\u043B\u0438 5 \u0433\u043B\u0430\u0432\u043D\ + \u044B\u0445 \u0444\u0430\u043A\u0442\u043E\u0432 \u0438 \u043C\u044B\u0441\ + \u043B\u0435\u0439 \u0438\u0437 \u044D\u0442\u043E\u0433\u043E \u0442\u0435\ + \u043A\u0441\u0442\u0430. \u0421\u0444\u043E\u0440\u043C\u0443\u043B\u0438\ + \u0440\u0443\u0439 \u043A\u0430\u0436\u0434\u044B \u0444\u0430\u043A\u0442\ + \ \u0432 \u0432\u0438\u0434\u0435 \u043E\u0434\u043D\u043E\u0439 \u0441\u0442\ + \u0440\u043E\u043A\u0438.\n\n\"{text}\"\n\n\u041E\u0441\u043D\u043E\u0432\u043D\ + \u044B\u0435 5 \u0444\u0430\u043A\u0442\u043E\u0432:" + template_format: f-string + validate_template: false + return_final_only: true + tags: null + verbose: false + memory: null + metadata: null + output_key: output_text + reduce_documents_chain: + _type: reduce_documents_chain + collapse_documents_chain: null + combine_documents_chain: + _type: stuff_documents_chain + document_prompt: + _type: prompt + input_types: {} + input_variables: + - page_content + output_parser: null + partial_variables: {} + template: '{page_content}' + template_format: f-string + validate_template: false + document_separator: ' + + + ' + document_variable_name: text + input_key: input_documents + llm_chain: + _type: llm_chain + llm: + _type: giga-chat-model + max_tokens: null + model: null + profanity: false + streaming: false + temperature: null + llm_kwargs: {} + memory: null + metadata: null + output_key: text + output_parser: + _type: default + prompt: + _type: prompt + input_types: {} + input_variables: + - text + output_parser: null + partial_variables: {} + template: "\u041D\u0438\u0436\u0435 \u043F\u0440\u0438\u0432\u0435\u0434\ + \u0435\u043D \u043D\u0430\u0431\u043E\u0440 \u0444\u0430\u043A\u0442\u043E\ + \u0432 \u0438 \u043C\u044B\u0441\u043B\u0435\u0439. \u0412\u044B\u0434\ + \u0435\u043B\u0438 \u0438\u0437 \u043D\u0438\u0445 7 \u0441\u0430\u043C\ + \u044B\u0445 \u0432\u0430\u0436\u043D\u044B\u0445.\n\n\"{text}\"\n\n\u041E\ + \u0441\u043D\u043E\u0432\u043D\u044B\u0435 7 \u0444\u0430\u043A\u0442\u043E\ + \u0432 \u0438\u0437 \u0442\u0435\u043A\u0441\u0442\u0430:" + template_format: f-string + validate_template: false + return_final_only: true + tags: null + verbose: false + memory: null + metadata: null + output_key: output_text + tags: null + verbose: false + input_key: input_documents + memory: null + metadata: null + output_key: output_text + tags: null + token_max: 3000 + verbose: false + return_intermediate_steps: false + tags: null + verbose: false +input_key: input_document +memory: null +metadata: null +tags: null +text_splitter: + _type: RecursiveCharacterTextSplitter + add_start_index: false + chunk_overlap: 0 + chunk_size: 4000 + is_separator_regex: false + keep_separator: true + length_function: + module: builtins + name: len + separators: + - ' + + + ' + - ' + + ' + - ' ' + - '' + strip_whitespace: true +verbose: false diff --git a/examples/giga_chain_api_plus/client.py b/examples/giga_chain_api_plus/client.py new file mode 100644 index 00000000..d628c41c --- /dev/null +++ b/examples/giga_chain_api_plus/client.py @@ -0,0 +1,30 @@ +"""Пример вызова суммаризации статьи "Великий аттрактор" из Википедии""" +import requests +import yaml + +with open("chain.yaml", "r", encoding="utf-8") as f: + CHAIN_CONFIG = yaml.safe_load(f) + +with open("attractor.txt", "r", encoding="utf-8") as f: + TEXT = f.read() + +with open("access_token.txt", "r", encoding="utf-8") as f: + ACCESS_TOKEN = f.read().strip() + +# Пример обращения с помощью requests +response = requests.post( + "http://localhost:8000/chain_invoke", + json={"chain_config": CHAIN_CONFIG, "input": {"input_document": TEXT}}, + timeout=600, + headers={ + "Authorization": f"Bearer {ACCESS_TOKEN}", + # for logging + "X-Client-ID": "8324244b-7133-4d30-a328-31d8466e5502", + "X-Session-ID": "8324244b-7133-4d30-a328-31d8466e5502", + "X-Request-ID": "8324244b-7133-4d30-a328-31d8466e5502", + }, +) + +print(response.status_code) +resp = response.json() +print(resp) diff --git a/examples/giga_chain_api_plus/server.py b/examples/giga_chain_api_plus/server.py new file mode 100644 index 00000000..937f06d8 --- /dev/null +++ b/examples/giga_chain_api_plus/server.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +"""Example LangChain server API+.""" +import asyncio +import logging +from contextlib import asynccontextmanager +from typing import Any + +import fastapi +from gigachat.exceptions import AuthenticationError +from langchain.pydantic_v1 import BaseModel +from langchain.chains.loading import load_chain_from_config +from contextvars_executor import ContextVarExecutor +from gigachat.context import ( + authorization_cvar, + client_id_cvar, + request_id_cvar, + session_id_cvar, +) + +logging.basicConfig(level=logging.INFO) + + +@asynccontextmanager +async def lifespan(app): + loop = asyncio.get_running_loop() + loop.set_default_executor(ContextVarExecutor()) + yield + + +app = fastapi.FastAPI(lifespan=lifespan) + + +@app.middleware("http") +async def middleware(request, call_next): + # forwarding headers to gigachat + authorization_cvar.set(request.headers.get("Authorization")) + client_id_cvar.set(request.headers.get("X-Client-ID")) + session_id_cvar.set(request.headers.get("X-Session-ID")) + request_id_cvar.set(request.headers.get("X-Request-ID")) + + return await call_next(request) + + +class Payload(BaseModel): + chain_config: dict[str, Any] + input: dict[str, Any] + + +class Result(BaseModel): + output: dict[str, Any] + + +@app.post("/chain_invoke") +def chain_invoke(payload: Payload) -> Result: + chain = load_chain_from_config(payload.chain_config) + try: + output = chain.invoke(input=payload.input) + return Result(output=output) + except AuthenticationError: + raise fastapi.HTTPException( + status_code=fastapi.status.HTTP_401_UNAUTHORIZED, detail="Wrong token" + ) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="localhost", port=8000)