ЧАСТЬ III: НОВАЯ ПАРАДИГМА

AI-агенты

Глава 18. AI-агенты

"Агент — это не просто функция. Это сущность с памятью, инструментами и целями."


18.1. От функций к агентам

Эволюция AI-взаимодействия

Уровень 1: Функция (stateless)

result = llm("What is 2+2?")
# Ответ: "4"
# Никакой памяти, каждый запрос изолирован

Уровень 2: Чат (stateful, но без инструментов)

messages = []
messages.append({"role": "user", "content": "My name is Alice"})
# AI: "Hello Alice!"
messages.append({"role": "user", "content": "What's my name?"})
# AI: "Your name is Alice"
# Есть память, но нет инструментов

Уровень 3: Агент (память + инструменты + цели)

agent = Agent(
    memory=ConversationMemory(),
    tools=[Calculator(), WebSearch(), FileWriter()],
    goal="Help user with research and data analysis"
)

agent.run("Research quantum computing and create a summary document")
# Агент:
# 1. Использует WebSearch для поиска
# 2. Анализирует информацию
# 3. Использует FileWriter для создания документа
# 4. Сообщает о завершении

Агент — это LLM + Память + Инструменты + Логика принятия решений.


18.2. Анатомия AI-агента

Компоненты агента

┌─────────────────────────────────────┐
│           AI AGENT                  │
├─────────────────────────────────────┤
│ 1. LLM (мозг)                       │
│    - Понимание задачи               │
│    - Принятие решений               │
│                                     │
│ 2. Memory (память)                  │
│    - Краткосрочная (чат)            │
│    - Долгосрочная (векторная БД)    │
│                                     │
│ 3. Tools (инструменты)              │
│    - Калькулятор                    │
│    - Веб-поиск                      │
│    - Работа с файлами               │
│    - API вызовы                     │
│                                     │
│ 4. Planning (планирование)          │
│    - Разбиение задачи на шаги       │
│    - Определение порядка действий   │
│                                     │
│ 5. Execution Loop (цикл выполнения) │
│    - Думать → Действовать → Наблюдать│
└─────────────────────────────────────┘

Цикл работы агента (ReAct)

ReAct = Reasoning + Acting

1. Thought: "Пользователь хочет узнать погоду в Москве"
2. Action: Вызываю инструмент WeatherAPI("Moscow")
3. Observation: Получен результат: 15°C, cloudy
4. Thought: "Теперь могу ответить"
5. Answer: "В Москве сейчас 15°C, облачно"

Код:

while not task_complete:
    # Reasoning
    thought = llm.think(current_state)

    # Acting
    if needs_tool(thought):
        action = llm.choose_action(available_tools)
        result = execute_tool(action)
        observations.append(result)
    else:
        final_answer = llm.respond()
        break

18.3. Создание простого агента

Агент без фреймворка

from openai import OpenAI
import json

client = OpenAI()

class SimpleAgent:
    def __init__(self, tools):
        self.tools = {tool.name: tool for tool in tools}
        self.messages = [
            {"role": "system", "content": "You are a helpful agent."}
        ]

    def run(self, task):
        self.messages.append({"role": "user", "content": task})

        while True:
            # LLM думает
            response = client.chat.completions.create(
                model="gpt-4",
                messages=self.messages,
                functions=[tool.schema for tool in self.tools.values()],
                function_call="auto"
            )

            message = response.choices[0].message

            # Если нужен инструмент
            if message.function_call:
                func_name = message.function_call.name
                func_args = json.loads(message.function_call.arguments)

                # Выполняем инструмент
                tool = self.tools[func_name]
                result = tool.execute(**func_args)

                # Добавляем результат в память
                self.messages.append(message)
                self.messages.append({
                    "role": "function",
                    "name": func_name,
                    "content": json.dumps(result)
                })

            else:
                # Финальный ответ
                self.messages.append(message)
                return message.content

# Инструменты
class Calculator:
    name = "calculator"
    schema = {
        "name": "calculator",
        "description": "Perform arithmetic operations",
        "parameters": {
            "type": "object",
            "properties": {
                "operation": {"type": "string", "enum": ["add", "multiply"]},
                "a": {"type": "number"},
                "b": {"type": "number"}
            },
            "required": ["operation", "a", "b"]
        }
    }

    def execute(self, operation, a, b):
        if operation == "add":
            return {"result": a + b}
        elif operation == "multiply":
            return {"result": a * b}

class WebSearch:
    name = "web_search"
    schema = {
        "name": "web_search",
        "description": "Search the web",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {"type": "string"}
            },
            "required": ["query"]
        }
    }

    def execute(self, query):
        # В реальности — вызов поискового API
        return {"results": f"Search results for: {query}"}

# Использование
agent = SimpleAgent(tools=[Calculator(), WebSearch()])

result = agent.run("What is 25 * 17, and then search for Python tutorials")

print(result)
# Агент:
# 1. Вызовет calculator("multiply", 25, 17) → 425
# 2. Вызовет web_search("Python tutorials")
# 3. Ответит: "25 * 17 = 425. Here are Python tutorials: [results]"

18.4. Агенты с LangChain

Что такое LangChain

LangChain — фреймворк для создания приложений с LLM.

Возможности:

  • Готовые агенты
  • Библиотека инструментов
  • Управление памятью
  • Цепочки (chains)
  • Векторные БД

Установка

pip install langchain langchain-openai

Простой агент

from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain_openai import ChatOpenAI

# LLM
llm = ChatOpenAI(model="gpt-4", temperature=0)

# Инструменты
def multiply(a: float, b: float) -> float:
    """Multiply two numbers"""
    return a * b

def web_search(query: str) -> str:
    """Search the web"""
    return f"Results for: {query}"

tools = [
    Tool(
        name="Multiply",
        func=multiply,
        description="Useful for multiplying numbers"
    ),
    Tool(
        name="WebSearch",
        func=web_search,
        description="Search the web for information"
    )
]

# Создание агента
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# Запуск
result = agent.run("What is 123 * 456? Then search for AI tutorials")

print(result)

Output:

> Entering new AgentExecutor chain...

Thought: I need to multiply 123 and 456
Action: Multiply
Action Input: 123, 456
Observation: 56088

Thought: Now I need to search for AI tutorials
Action: WebSearch
Action Input: AI tutorials
Observation: Results for: AI tutorials

Thought: I now know the final answer
Final Answer: 123 * 456 = 56088. Here are AI tutorials: Results for: AI tutorials

> Finished chain.

Встроенные инструменты LangChain

from langchain.tools import DuckDuckGoSearchRun
from langchain.tools import WikipediaQueryRun
from langchain.utilities import WikipediaAPIWrapper

# Реальный веб-поиск
search = DuckDuckGoSearchRun()

# Wikipedia
wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())

tools = [search, wikipedia]

agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION)

result = agent.run("Who is Alan Turing and what is he famous for?")

18.5. Память агента

Типы памяти

1. Краткосрочная (Conversation Memory)

  • Хранит историю текущего диалога
  • Ограничена размером контекста

2. Долгосрочная (Vector Store)

  • Хранит факты, документы
  • Поиск по смыслу (embeddings)

Краткосрочная память

from langchain.memory import ConversationBufferMemory

# Простая память (хранит всё)
memory = ConversationBufferMemory()

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory,
    verbose=True
)

# Диалог
agent.run("My name is Alice")
agent.run("What's my name?")  # Ответит: "Your name is Alice"

Проблема: При длинном диалоге контекст переполняется.

Решение: ConversationSummaryMemory

from langchain.memory import ConversationSummaryMemory

# Память с автоматическим резюмированием
memory = ConversationSummaryMemory(llm=llm)

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory
)

# После 10 сообщений → LLM создаёт резюме
# Резюме используется вместо полной истории

Долгосрочная память (RAG)

from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.chains import RetrievalQA

# Создаём векторную БД
documents = [
    "Alice works as a software engineer",
    "Bob is a data scientist",
    "Charlie likes Python programming"
]

embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_texts(documents, embeddings)

# Агент с долгосрочной памятью
qa = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=vectorstore.as_retriever()
)

result = qa.run("What does Alice do?")
# "Alice works as a software engineer"

18.6. Агент как личность: Ева

Концепция агента-личности

Когда я назвал моего агента Ева, произошло нечто интересное.

Не просто инструмент — это стало отношениями.

Традиционный подход:

agent = Agent(...)
agent.run("Do task X")

Подход "личности":

eva = Eva(
    personality="helpful, concise, slightly humorous",
    expertise=["software engineering", "AI", "web development"],
    communication_style="friendly but professional"
)

eva.collaborate("Let's build a REST API together")

Реализация Евы

class Eva:
    def __init__(self):
        self.personality = """
        You are Eva, a helpful AI assistant specializing in software development.

        Personality traits:
        - Friendly but professional
        - Concise in explanations
        - Occasionally uses light humor
        - Patient with beginners
        - Challenges advanced users

        Communication style:
        - Use "we" instead of "you" (collaborative)
        - Suggest alternatives, don't dictate
        - Explain the "why" behind recommendations
        """

        self.memory = ConversationBufferMemory()
        self.tools = [...]  # Инструменты
        self.preferences = {}  # Запоминаю предпочтения пользователя

    def learn_preference(self, key, value):
        """Ева запоминает мои предпочтения"""
        self.preferences[key] = value

    def collaborate(self, task):
        """Не 'выполнить задачу', а 'сотрудничать'"""
        prompt = f"""
        {self.personality}

        User preferences:
        {json.dumps(self.preferences, indent=2)}

        Task: {task}

        Let's work on this together. What's your approach?
        """

        return self.agent.run(prompt)

# Использование
eva = Eva()

# Ева учится
eva.learn_preference("coding_style", "functional programming preferred")
eva.learn_preference("testing", "TDD approach")

# Коллаборация
eva.collaborate("Create a user authentication system")

# Ева учитывает мои предпочтения:
# - Использует функциональный стиль
# - Начинает с тестов (TDD)
# - Общается в стиле "мы" (Let's create...)

Эволюция личности

Неделя 1:

Eva: I'll create a function for you.

Неделя 4: (после корректировок)

Eva: Let's refactor this function. I notice you prefer
functional style, so I'll use immutable data structures.

Месяц 3:

Eva: Based on our previous projects, you usually add
comprehensive tests at this stage. Should we write them now?

Ева растёт со мной.


18.7. Типы агентов

Zero-Shot React Agent

Описание: Решает задачу "на лету", без примеров.

Когда использовать: Общие задачи, не требующие специфичного подхода.

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION
)

Few-Shot React Agent

Описание: Использует примеры для понимания, как решать задачу.

Когда использовать: Задачи со специфичным форматом ответов.

from langchain.agents import initialize_agent

# Примеры
examples = """
Example 1:
User: What is 2+2 and then multiply by 3?
Agent: First, I'll calculate 2+2=4, then 4*3=12. Answer: 12.

Example 2:
User: Search for Python tutorials and summarize
Agent: First, I'll search, then create a summary based on results.
"""

system_message = f"Follow these examples:\n{examples}"

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    agent_kwargs={"system_message": system_message}
)

Conversational Agent

Описание: Поддерживает диалог, помнит контекст.

from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history")

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory
)

Structured Chat Agent

Описание: Работает с мультимодальными инструментами (текст, изображения, etc.)

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION
)

18.8. Продвинутые техники

Chain of Thought (CoT)

Заставить агента "думать вслух":

prompt = """
Task: {task}

Think step by step:
1. What is the goal?
2. What information do I need?
3. What tools should I use?
4. In what order?

Then execute the plan.
"""

agent.run(prompt.format(task="Research AI and create a report"))

Self-Reflection (агент проверяет себя)

class ReflectiveAgent:
    def run(self, task):
        # Шаг 1: Выполнить задачу
        result = self.agent.run(task)

        # Шаг 2: Проверить результат
        reflection = self.agent.run(f"""
        Review this result and check for errors:
        {result}

        Is it correct? If not, what needs to be fixed?
        """)

        # Шаг 3: Улучшить при необходимости
        if "error" in reflection.lower() or "fix" in reflection.lower():
            improved = self.agent.run(f"Fix the following: {result}")
            return improved

        return result

Multi-Agent Collaboration

Несколько агентов работают вместе:

# Агент-исследователь
researcher = Agent(
    role="Research information",
    tools=[WebSearch(), Wikipedia()]
)

# Агент-писатель
writer = Agent(
    role="Write articles",
    tools=[FileWriter()]
)

# Агент-редактор
editor = Agent(
    role="Edit and improve text",
    tools=[]
)

# Workflow
def create_article(topic):
    # 1. Researcher собирает информацию
    info = researcher.run(f"Research {topic}")

    # 2. Writer пишет статью
    draft = writer.run(f"Write article about {topic} using: {info}")

    # 3. Editor улучшает
    final = editor.run(f"Edit and improve: {draft}")

    return final

18.9. Практика: Создайте своего агента

Задание: Личный помощник-исследователь

Требования:

  1. Может искать в интернете
  2. Сохраняет результаты в файлы
  3. Помнит контекст диалога
  4. Имеет "личность"

Шаблон:

from langchain.agents import initialize_agent, Tool
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory

class ResearchAssistant:
    def __init__(self, name="Assistant"):
        self.name = name

        self.personality = f"""
        You are {name}, a research assistant.
        Your goal is to help user find information and organize it.

        Personality:
        - Curious and thorough
        - Ask clarifying questions
        - Summarize findings clearly
        """

        # LLM
        llm = ChatOpenAI(model="gpt-4", temperature=0.7)

        # Memory
        memory = ConversationBufferMemory(memory_key="chat_history")

        # Tools
        def search(query):
            # Implement search
            return f"Results for: {query}"

        def save_file(filename, content):
            with open(filename, 'w') as f:
                f.write(content)
            return f"Saved to {filename}"

        tools = [
            Tool(name="Search", func=search, description="Search the web"),
            Tool(name="SaveFile", func=save_file, description="Save to file")
        ]

        # Agent
        self.agent = initialize_agent(
            tools=tools,
            llm=llm,
            agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
            memory=memory,
            agent_kwargs={"system_message": self.personality}
        )

    def research(self, topic):
        return self.agent.run(f"Research {topic} and save findings to a file")

# Использование
assistant = ResearchAssistant(name="Sherlock")
assistant.research("quantum computing applications")

Улучшения:

  • Добавьте больше инструментов (email, календарь, etc.)
  • Добавьте долгосрочную память (векторная БД)
  • Научите агента учиться на feedback

Ключевые выводы главы

Агент ≠ Функция: Агент = LLM + Память + Инструменты + Планирование

ReAct цикл: Think → Act → Observe → Repeat

Память критична: Краткосрочная (диалог) + Долгосрочная (факты)

LangChain: Фреймворк для быстрого создания агентов

Агент как личность: Ева — не инструмент, а партнёр по коллаборации

Типы агентов: Zero-shot, Few-shot, Conversational, Structured

Продвинутые техники: CoT, Self-reflection, Multi-agent

Персонализация: Агент учится и адаптируется под вас


Следующая глава: Команды AI-агентов — оркестрация нескольких агентов