Создание интеллектуального интерфейса мультиинструментального ИИ-агента с помощью Streamlit для бесперебойного взаимодействия в реальном времени

В этом руководстве мы создадим мощное и интерактивное приложение Streamlit, объединяющее возможности LangChain, Google Gemini API и набора передовых инструментов для создания умного ИИ-ассистента. Используя интуитивно понятный интерфейс Streamlit, мы создадим систему на основе чата, которая может искать в интернете, получать содержимое Википедии, выполнять вычисления, запоминать ключевые детали и обрабатывать историю разговоров — всё это в режиме реального времени. Независимо от того, являемся ли мы разработчиками, исследователями или просто изучаем ИИ, такая настройка позволяет нам взаимодействовать с мультиагентной системой прямо из браузера с минимальным количеством кода и максимальной гибкостью.

Установка необходимых пакетов

Для начала установим все необходимые пакеты Python и Node.js, требуемые для нашего приложения-ассистента ИИ. Это включает Streamlit для фронтенда, LangChain для логики агентов и такие инструменты, как Wikipedia, DuckDuckGo и ngrok/localtunnel для внешнего поиска и хостинга. После настройки мы импортируем все модули, чтобы начать создание нашего интерактивного мультиинструментального ИИ-агента.

“`python
!pip install -q streamlit langchain langchain-google-genai langchain-community
!pip install -q pyngrok python-dotenv wikipedia duckduckgo-search
!npm install -g localtunnel
“`

“`python
import streamlit as st
import os
from langchaingooglegenai import ChatGoogleGenerativeAI
from langchain.agents import createreactagent, AgentExecutor
from langchain.tools import Tool, WikipediaQueryRun, DuckDuckGoSearchRun
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts import PromptTemplate
from langchain.callbacks.streamlit import StreamlitCallbackHandler
from langchain_community.utilities import WikipediaAPIWrapper, DuckDuckGoSearchAPIWrapper
import asyncio
import threading
import time
from datetime import datetime
import json
“`

Настройка окружения

Далее мы настраиваем нашу среду, задавая ключ API Google Gemini и аутентификационный токен ngrok. Мы присваиваем этим учётным данным переменные и устанавливаем GOOGLEAPIKEY, чтобы агент LangChain мог безопасно получить доступ к модели Gemini во время выполнения.

“`python
GOOGLEAPIKEY = “Use Your API Key Here”
NGROKAUTHTOKEN = “Use Your Auth Token Here”
os.environ[“GOOGLEAPIKEY”] = GOOGLEAPIKEY
“`

Определение инструментов для инновационного агента

Здесь мы определяем класс InnovativeAgentTools для оснащения нашего ИИ-агента специализированными возможностями. Мы реализуем такие инструменты, как Калькулятор для безопасной оценки выражений, инструменты памяти для сохранения и вызова информации в разных ходах, а также инструмент даты и времени для получения текущей даты и времени. Эти инструменты позволяют нашему агенту Streamlit ИИ рассуждать, запоминать и отвечать контекстуально, как настоящий помощник.

“`python
class InnovativeAgentTools:
“””Advanced tool collection for the multi-agent system”””

@staticmethod
def getcalculatortool():
def calculate(expression: str) -> str:
“””Calculate mathematical expressions safely”””
try:
allowed_chars = set(‘0123456789+-*/.() ‘)
if all(c in allowed_chars for c in expression):
result = eval(expression)
return f”Result: {result}”
else:
return “Error: Invalid mathematical expression”
except Exception as e:
return f”Calculation error: {str(e)}”

return Tool(
name=”Calculator”,
func=calculate,
description=”Calculate mathematical expressions. Input should be a valid math expression.”
)

@staticmethod
def getmemorytool(memory_store):
def savememory(keyvalue: str) -> str:
“””Save information to memory”””
try:
key, value = key_value.split(“:”, 1)
memory_store[key.strip()] = value.strip()
return f”Saved ‘{key.strip()}’ to memory”
except:
return “Error: Use format ‘key: value'”

def recall_memory(key: str) -> str:
“””Recall information from memory”””
return memory_store.get(key.strip(), f”No memory found for ‘{key}'”)

return [
Tool(name=”SaveMemory”, func=save_memory,
description=”Save information to memory. Format: ‘key: value'”),
Tool(name=”RecallMemory”, func=recall_memory,
description=”Recall saved information. Input: key to recall”)
]

@staticmethod
def getdatetimetool():
def getcurrentdatetime(format_type: str = “full”) -> str:
“””Get current date and time”””
now = datetime.now()
if format_type == “date”:
return now.strftime(“%Y-%m-%d”)
elif format_type == “time”:
return now.strftime(“%H:%M:%S”)
else:
return now.strftime(“%Y-%m-%d %H:%M:%S”)

return Tool(
name=”DateTime”,
func=getcurrentdatetime,
description=”Get current date/time. Options: ‘date’, ‘time’, or ‘full'”
)
“`

Создание мультиагентной системы

В этом разделе мы создаём ядро нашего приложения — класс MultiAgentSystem. Здесь мы интегрируем модель Gemini Pro с помощью LangChain и инициализируем все необходимые инструменты, включая веб-поиск, память и функции калькулятора. Мы настраиваем агента ReAct с помощью специального приглашения, которое направляет использование инструментов и обработку памяти. Наконец, мы определяем метод чата, который позволяет агенту обрабатывать ввод пользователя, вызывать инструменты при необходимости и генерировать интеллектуальные, контекстуально осведомлённые ответы.

“`python
class MultiAgentSystem:
“””Innovative multi-agent system with specialized capabilities”””

def init(self, api_key: str):
self.llm = ChatGoogleGenerativeAI(
model=”gemini-pro”,
googleapikey=api_key,
temperature=0.7,
convertsystemmessagetohuman=True
)
self.memory_store = {}
self.conversation_memory = ConversationBufferWindowMemory(
memorykey=”chathistory”,
k=10,
return_messages=True
)
self.tools = self.initializetools()
self.agent = self.createagent()

def initializetools(self):
“””Initialize all available tools”””
tools = []

tools.extend([
DuckDuckGoSearchRun(api_wrapper=DuckDuckGoSearchAPIWrapper()),
WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
])

tools.append(InnovativeAgentTools.getcalculatortool())
tools.append(InnovativeAgentTools.getdatetimetool())
tools.extend(InnovativeAgentTools.getmemorytool(self.memory_store))

return tools

def createagent(self):
“””Create the ReAct agent with advanced prompt”””
prompt = PromptTemplate.from_template(“””
You are an advanced AI assistant with access to multiple tools and persistent memory.

AVAILABLE TOOLS:
{tools}

TOOL USAGE FORMAT:
– Think step by step about what you need to do
– Use Action: tool_name
– Use Action Input: your input
– Wait for Observation
– Continue until you have a final answer

CONVERSATION HISTORY:
{chat_history}

CURRENT QUESTION: {input}

REASONING PROCESS:
{agent_scratchpad}

Begin your response with your thought process, then take action if needed.
“””)

agent = createreactagent(self.llm, self.tools, prompt)
return AgentExecutor(
agent=agent,
tools=self.tools,
memory=self.conversation_memory,
verbose=True,
handleparsingerrors=True,
max_iterations=5
)

def chat(self, message: str, callback_handler=None):
“””Process user message and return response”””
try:
if callback_handler:
response = self.agent.invoke(
{“input”: message},
{“callbacks”: [callback_handler]}
)
else:
response = self.agent.invoke({“input”: message})
return response[“output”]
except Exception as e:
return f”Error processing request: {str(e)}”
“`

Создание Streamlit приложения

В этом разделе мы объединяем всё вместе, создавая интерактивный веб-интерфейс с помощью Streamlit. Мы настраиваем макет приложения, определяем пользовательские стили CSS и настраиваем боковую панель для ввода API-ключей и настройки возможностей агента. Мы инициализируем мультиагентную систему, поддерживаем историю сообщений и включаем интерфейс чата, который позволяет пользователям взаимодействовать в режиме реального времени.

“`python
def createstreamlitapp():
“””Create the innovative Streamlit application”””

st.setpageconfig(
page_title=”Advanced LangChain Agent with Gemini”,
page_icon=””,
layout=”wide”,
initialsidebarstate=”expanded”
)

st.markdown(“””

“””, unsafeallowhtml=True)

st.markdown(“””

Advanced Multi-Agent System

Powered by LangChain + Gemini API + Streamlit

“””, unsafeallowhtml=True)

with st.sidebar:
st.header(“Configuration”)

apikey = st.textinput(
“Google AI API Key”,
type=”password”,
value=GOOGLEAPIKEY if GOOGLEAPIKEY != “your-gemini-api-key-here” else “”,
help=”Get your API key from https://ai.google.dev/”
)

if not api_key:
st.error(“Please enter your Google AI API key to continue”)
st.stop()

st.success(“API Key configured”)

st.header(“Agent Capabilities”)
st.markdown(“””
Web Search (DuckDuckGo)
Wikipedia Lookup
Mathematical Calculator
Persistent Memory
Date & Time
Conversation History
“””)

if ‘agentsystem’ in st.sessionstate:
st.header(“Memory Store”)
memory = st.sessionstate.agentsystem.memory_store
if memory:
for key, value in memory.items():
st.markdown(f”””

{key}: {value}

“””, unsafeallowhtml=True)
else:
st.info(“No memories stored yet”)

if ‘agentsystem’ not in st.sessionstate:
with st.spinner(“Initializing Advanced Agent System…”):
st.sessionstate.agentsystem = MultiAgentSystem(api_key)
st.success(“Agent System Ready!”)

st.header(“Interactive Chat”)

if ‘messages’ not in st.session_state:
st.session_state.messages = [{
“role”: “assistant”,
“content”: “”” Hello! I’m your advanced AI assistant powered by Gemini. I can:

• Search the web and Wikipedia for information
• Perform mathematical calculations
• Remember important information across our conversation
• Provide current date and time
• Maintain conversation context

Try asking me something like:
– “Calculate 15 * 8 + 32”
– “Search for recent news about AI”
– “Remember that my favorite color is blue”
– “What’s the current time?”
“””
}]

for message in st.session_state.messages:
with st.chat_message(message[“role”]):
st.markdown(message[“content”])

if prompt := st.chat_input(“Ask me anything…”):
st.session_state.messages.append({“role”: “user”, “content”: prompt})
with st.chat_message(“user”):
st.markdown(prompt)

with st.chat_message(“assistant”):
callback_handler = StreamlitCallbackHandler(st.container())

with st.spinner(“Thinking…”):
response = st.sessionstate.agentsystem.chat(prompt, callback_handler)

st.markdown(f”””

{response}

“””, unsafeallowhtml=True)

st.session_state.messages.append({“role”: “assistant”, “content”: response})

st.header(“Example Queries”)
col1, col2, col3 = st.columns(3)

with col1:
if st.button(“Search Example”):
example = “Search for the latest developments in quantum computing”
st.sessionstate.examplequery = example

with col2:
if st.button(“Math Example”):
example = “Calculate the compound interest on $1000 at 5% for 3 years”
st.sessionstate.examplequery = example

with col3:
if st.button(“Memory Example”):
example = “Remember that I work as a data scientist at TechCorp”
st.sessionstate.examplequery = example

if ‘examplequery’ in st.sessionstate:
st.info(f”Example query: {st.sessionstate.examplequery}”)
“`

Настройка аутентификации ngrok

Здесь мы настраиваем вспомогательную функцию для аутентификации ngrok, которая позволяет нам выставлять наш локальный Streamlit-приложение в интернет. Мы используем библиотеку pyngrok для настройки аутентификационного токена и проверки соединения. Если токен отсутствует или недействителен, мы предоставляем подробные инструкции по его получению и предлагаем альтернативные методы туннелирования, такие как LocalTunnel или Serveo, что упрощает размещение и совместное использование нашего приложения из таких сред, как Google Colab.

“`python
def setupngrokauth(auth_token):
“””Setup ngrok authentication”””
try:
from pyngrok import ngrok, conf

conf.getdefault().authtoken = auth_token

try:
tunnels = ngrok.get_tunnels()
print(“Ngrok authentication successful!”)
return True
except Exception as e:
print(f”Ngrok authentication failed: {e}”)
return False

except ImportError:
print(“pyngrok not installed. Installing…”)
import subprocess
subprocess.run([‘pip’, ‘install’, ‘pyngrok’], check=True)
return setupngrokauth(auth_token)
“`

Основная функция приложения

Эта функция main() действует как точка входа для нашего Streamlit-приложения. Мы просто вызываем createstreamlitapp() для запуска полного интерфейса. Если что-то пойдёт не так, например, отсутствует API-ключ или не удастся инициализировать инструмент, мы перехватываем ошибку и отображаем полезное сообщение, обеспечивая пользователю возможность восстановления и продолжения использования приложения.

“`python
def main():
“””Main function to run the application”””
try:
createstreamlitapp()
except Exception as e:
st.error(f”Application error: {str(e)}”)
st.info(“Please check your API key and try refreshing the page”)
“`

Запуск в Colab

В функции runincolab() мы упрощаем развёртывание Streamlit-приложения непосредственно из среды Google Colab. Мы начинаем с установки всех необходимых пакетов, затем динамически генерируем и записываем полный код Streamlit-приложения в файл streamlit_app.py. Мы проверяем наличие действительного токена ngrok для обеспечения публичного доступа к приложению из Colab, а если он отсутствует или недействителен, мы предлагаем альтернативные методы туннелирования.

“`python
def runincolab():
“””Run the application in Google Colab with proper ngrok setup”””

print(“Starting Advanced LangChain Agent Setup…”)

if NGROKAUTHTOKEN == “your-ngrok-auth-token-here”:
print(“NGROKAUTHTOKEN not configured!”)
print(getngroktoken_instructions())

print(“Attempting alternative tunnel methods…”)
tryalternativetunnels()
return

print(“Installing required packages…”)
import subprocess

packages = [
‘streamlit’,
‘langchain’,
‘langchain-google-genai’,
‘langchain-community’,
‘wikipedia’,
‘duckduckgo-search’,
‘pyngrok’
]

for package in packages:
try:
subprocess.run([‘pip’, ‘install’, package], check=True, capture_output=True)
print(f”{package} installed”)
except subprocess.CalledProcessError:
print(f”Failed to install {package}”)

app_content = ”’
import streamlit as st
import os
from langchaingooglegenai import ChatGoogleGenerativeAI
from langchain.agents import createreactagent, AgentExecutor
from langchain.tools import Tool, WikipediaQueryRun, DuckDuckGoSearchRun
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts import PromptTemplate
from langchain.callbacks.streamlit import StreamlitCallbackHandler
from langchain_community.utilities import WikipediaAPIWrapper, DuckDuckGoSearchAPIWrapper
from datetime import datetime

# Configuration – Replace with your actual keys
GOOGLEAPIKEY = “{GOOGLEAPIKEY}”
os.environ[“GOOGLEAPIKEY”] = GOOGLEAPIKEY

class InnovativeAgentTools:
@staticmethod
def getcalculatortool():
def calculate(expression: str) -> str:
try:
allowed_chars = set(‘0123456789+-*/.() ‘)
if all(c in allowed_chars for c in expression):
result = eval(expression)
return f”Result: {result}”
else:
return “Error: Invalid mathematical expression”
except Exception as e:
return f”Calculation error: {str(e)}”

return Tool(name=”Calculator”, func=calculate,
description=”Calculate mathematical expressions. Input should be a valid math expression.”)

@staticmethod
def getmemorytool(memory_store):
def savememory(keyvalue: str) -> str:
try:
key, value = key_value.split(“:”, 1)
memory_store[key.strip()] = value.strip()
return f”Saved ‘{key.strip()}’ to memory”
except:
return “Error: Use format ‘key: value'”

def recall_memory(key: str) -> str:
return memory_store.get(key.strip(), f”No memory found for ‘{key}'”)

return [
Tool(name=”SaveMemory”, func=save_memory, description=”Save information to memory. Format: ‘key: value'”),
Tool(name=”RecallMemory”, func=recall_memory, description=”Recall saved information. Input: key to recall”)
]

@staticmethod
def getdatetimetool():
def getcurrentdatetime(format_type: str = “full”) -> str:
now = datetime.now()
if format_type == “date”:
return now.strftime(“%Y-%m-%d”)
elif format_type == “time”:
return now.strftime(“%H:%M:%S”)
else:
return now.strftime(“%Y-%m-%d %H:%M:%S”)

return Tool(name=”DateTime”, func=getcurrentdatetime,
description=”Get current date/time. Options: ‘date’, ‘time’, or ‘full'”)

class MultiAgentSystem:
def init(self, api_key: str):
self.llm = ChatGoogleGenerativeAI(
model=”gemini-pro”,
googleapikey=api_key,
temperature=0.7,
convertsystemmessagetohuman=True
)
self.memory_store = {}
self.conversation_memory = ConversationBufferWindowMemory(
memorykey=”chathistory”, k=10, return_messages=True
)
self.tools = self.initializetools()
self.agent = self.createagent()

def initializetools(self):
tools = []
try:
tools.extend([
DuckDuckGoSearchRun(api_wrapper=DuckDuckGoSearchAPIWrapper()),
WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
])
except Exception as e:
st.warning(f”Search tools may have limited functionality: {e}”)

tools.append(InnovativeAgentTools.getcalculatortool())
tools.append(InnovativeAgentTools.getdatetimetool())
tools.extend(InnovativeAgentTools.getmemorytool(self.memory_store))
return tools

def createagent(self):
prompt = PromptTemplate.from_template(“””
You are an advanced AI assistant with access to multiple tools and persistent memory.

AVAILABLE TOOLS:
{tools}

TOOL USAGE FORMAT:
– Think step by step about what you need to do
– Use Action: tool_name
– Use Action Input: your input
– Wait for Observation
– Continue until you have a final answer

CONVERSATION HISTORY:
{chat_history}

CURRENT QUESTION: {input}

REASONING PROCESS:
{agent_scratchpad}

Begin your response with your thought process, then take action if needed.
“””)

agent = createreactagent(self.llm, self.tools, prompt)
return AgentExecutor(agent=agent, tools=self.tools, memory=self.conversation_memory,
verbose=True, handleparsingerrors=True, max_iterations=5)

def chat(self, message: str, callback_handler=None):
try:
if callback_handler:
response = self.agent.invoke({“input”: message}, {“callbacks”: [callback_handler]})
else:
response = self.agent.invoke({“input”: message})
return response[“output”]
except Exception as e:
return f”Error processing request: {str(e)}”

# Streamlit App
st.setpageconfig(pagetitle=”Advanced LangChain Agent”, pageicon=””, layout=”wide”)

st.markdown(“””

“””, unsafeallowhtml=True)

st.markdown(‘

Advanced Multi-Agent System

Powered by LangChain + Gemini API

‘, unsafeallowhtml=True)

with st.sidebar:
st.header(“Configuration”)
apikey = st.textinput(“Google AI API Key”, type=”password”, value=GOOGLEAPIKEY)

if not api_key:
st.error(“Please enter your Google AI API key”)
st.stop()

st.success(“API Key configured”)

st.header(“Agent Capabilities”)
st.markdown(“- Web Search\n- Wikipedia\n- Calculator\n- Memory\n- Date/Time”)

if ‘agentsystem’ in st.sessionstate and st.sessionstate.agentsystem.memory_store:
st.header(“Memory Store”)
for key, value in st.sessionstate.agentsystem.memory_

Источник

Оставьте комментарий