mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-25 08:26:21 +02:00
480 lines
17 KiB
Markdown
480 lines
17 KiB
Markdown
|
|
---
|
||
|
|
layout: default
|
||
|
|
title: "Serviços de Ferramentas: Ferramentas de Agente Dinamicamente Plugáveis"
|
||
|
|
parent: "Portuguese (Beta)"
|
||
|
|
---
|
||
|
|
|
||
|
|
# Serviços de Ferramentas: Ferramentas de Agente Dinamicamente Plugáveis
|
||
|
|
|
||
|
|
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
|
||
|
|
|
||
|
|
## Status
|
||
|
|
|
||
|
|
Implementado
|
||
|
|
|
||
|
|
## Visão Geral
|
||
|
|
|
||
|
|
Esta especificação define um mecanismo para ferramentas de agente dinamicamente plugáveis, chamadas "serviços de ferramentas". Ao contrário dos tipos de ferramentas integradas existentes (`KnowledgeQueryImpl`, `McpToolImpl`, etc.), os serviços de ferramentas permitem que novas ferramentas sejam introduzidas por:
|
||
|
|
|
||
|
|
1. Implantando um novo serviço baseado em Pulsar
|
||
|
|
2. Adicionando um descritor de configuração que informa ao agente como invocá-lo
|
||
|
|
|
||
|
|
Isso permite a extensibilidade sem modificar o framework de resposta do agente principal.
|
||
|
|
|
||
|
|
## Terminologia
|
||
|
|
|
||
|
|
| Termo | Definição |
|
||
|
|
|------|------------|
|
||
|
|
| **Ferramenta Integrada** | Tipos de ferramentas existentes com implementações codificadas em `tools.py` |
|
||
|
|
| **Serviço de Ferramenta** | Um serviço Pulsar que pode ser invocado como uma ferramenta de agente, definido por um descritor de serviço |
|
||
|
|
| **Ferramenta** | Uma instância configurada que referencia um serviço de ferramenta, exposta ao agente/LLM |
|
||
|
|
|
||
|
|
Este é um modelo de duas camadas, análogo às ferramentas MCP:
|
||
|
|
MCP: O servidor MCP define a interface da ferramenta → A configuração da ferramenta a referencia
|
||
|
|
Serviços de Ferramenta: O serviço de ferramenta define a interface Pulsar → A configuração da ferramenta a referencia
|
||
|
|
|
||
|
|
## Contexto: Ferramentas Existentes
|
||
|
|
|
||
|
|
### Implementação de Ferramenta Integrada
|
||
|
|
|
||
|
|
As ferramentas são atualmente definidas em `trustgraph-flow/trustgraph/agent/react/tools.py` com implementações tipadas:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class KnowledgeQueryImpl:
|
||
|
|
async def invoke(self, question):
|
||
|
|
client = self.context("graph-rag-request")
|
||
|
|
return await client.rag(question, self.collection)
|
||
|
|
```
|
||
|
|
|
||
|
|
Cada tipo de ferramenta:
|
||
|
|
Possui um serviço Pulsar pré-definido que ele chama (por exemplo, `graph-rag-request`)
|
||
|
|
Conhece o método exato a ser chamado no cliente (por exemplo, `client.rag()`)
|
||
|
|
Possui argumentos tipados definidos na implementação
|
||
|
|
|
||
|
|
### Registro de Ferramentas (service.py:105-214)
|
||
|
|
|
||
|
|
As ferramentas são carregadas da configuração com um campo `type` que mapeia para uma implementação:
|
||
|
|
|
||
|
|
```python
|
||
|
|
if impl_id == "knowledge-query":
|
||
|
|
impl = functools.partial(KnowledgeQueryImpl, collection=data.get("collection"))
|
||
|
|
elif impl_id == "text-completion":
|
||
|
|
impl = TextCompletionImpl
|
||
|
|
# ... etc
|
||
|
|
```
|
||
|
|
|
||
|
|
## Arquitetura
|
||
|
|
|
||
|
|
### Modelo de Duas Camadas
|
||
|
|
|
||
|
|
#### Camada 1: Descritor do Serviço de Ferramenta
|
||
|
|
|
||
|
|
Um serviço de ferramenta define uma interface de serviço Pulsar. Ele declara:
|
||
|
|
As filas Pulsar para solicitação/resposta
|
||
|
|
Os parâmetros de configuração que ele requer das ferramentas que o utilizam
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "custom-rag",
|
||
|
|
"request-queue": "non-persistent://tg/request/custom-rag",
|
||
|
|
"response-queue": "non-persistent://tg/response/custom-rag",
|
||
|
|
"config-params": [
|
||
|
|
{"name": "collection", "required": true}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Um serviço de ferramenta que não requer parâmetros de configuração:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "calculator",
|
||
|
|
"request-queue": "non-persistent://tg/request/calc",
|
||
|
|
"response-queue": "non-persistent://tg/response/calc",
|
||
|
|
"config-params": []
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Nível 2: Descritor de Ferramenta
|
||
|
|
|
||
|
|
Uma ferramenta referencia um serviço de ferramenta e fornece:
|
||
|
|
Valores de parâmetros de configuração (que satisfazem os requisitos do serviço)
|
||
|
|
Metadados da ferramenta para o agente (nome, descrição)
|
||
|
|
Definições de argumentos para o LLM
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "tool-service",
|
||
|
|
"name": "query-customers",
|
||
|
|
"description": "Query the customer knowledge base",
|
||
|
|
"service": "custom-rag",
|
||
|
|
"collection": "customers",
|
||
|
|
"arguments": [
|
||
|
|
{
|
||
|
|
"name": "question",
|
||
|
|
"type": "string",
|
||
|
|
"description": "The question to ask about customers"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Múltiplas ferramentas podem referenciar o mesmo serviço com diferentes configurações:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "tool-service",
|
||
|
|
"name": "query-products",
|
||
|
|
"description": "Query the product knowledge base",
|
||
|
|
"service": "custom-rag",
|
||
|
|
"collection": "products",
|
||
|
|
"arguments": [
|
||
|
|
{
|
||
|
|
"name": "question",
|
||
|
|
"type": "string",
|
||
|
|
"description": "The question to ask about products"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Formato da Requisição
|
||
|
|
|
||
|
|
Quando uma ferramenta é invocada, a requisição ao serviço da ferramenta inclui:
|
||
|
|
`user`: Do pedido do agente (multi-tenência)
|
||
|
|
`config`: Valores de configuração codificados em JSON, provenientes da descrição da ferramenta
|
||
|
|
`arguments`: Argumentos codificados em JSON, provenientes do LLM
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"user": "alice",
|
||
|
|
"config": "{\"collection\": \"customers\"}",
|
||
|
|
"arguments": "{\"question\": \"What are the top customer complaints?\"}"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
O serviço de ferramenta recebe estes como dicionários analisados no método `invoke`.
|
||
|
|
|
||
|
|
### Implementação Genérica do Serviço de Ferramenta
|
||
|
|
|
||
|
|
Uma classe `ToolServiceImpl` invoca serviços de ferramenta com base na configuração:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class ToolServiceImpl:
|
||
|
|
def __init__(self, context, request_queue, response_queue, config_values, arguments, processor):
|
||
|
|
self.request_queue = request_queue
|
||
|
|
self.response_queue = response_queue
|
||
|
|
self.config_values = config_values # e.g., {"collection": "customers"}
|
||
|
|
# ...
|
||
|
|
|
||
|
|
async def invoke(self, **arguments):
|
||
|
|
client = await self._get_or_create_client()
|
||
|
|
response = await client.call(user, self.config_values, arguments)
|
||
|
|
if isinstance(response, str):
|
||
|
|
return response
|
||
|
|
else:
|
||
|
|
return json.dumps(response)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Decisões de Design
|
||
|
|
|
||
|
|
### Modelo de Configuração de Duas Camadas
|
||
|
|
|
||
|
|
Os serviços de ferramentas seguem um modelo de duas camadas semelhante às ferramentas MCP:
|
||
|
|
|
||
|
|
1. **Serviço de Ferramenta**: Define a interface do serviço Pulsar (tópico, parâmetros de configuração necessários)
|
||
|
|
2. **Ferramenta**: Referencia um serviço de ferramenta, fornece valores de configuração, define argumentos do LLM
|
||
|
|
|
||
|
|
Essa separação permite:
|
||
|
|
Que um único serviço de ferramenta seja usado por várias ferramentas com diferentes configurações
|
||
|
|
Uma distinção clara entre a interface do serviço e a configuração da ferramenta
|
||
|
|
A reutilização das definições de serviço
|
||
|
|
|
||
|
|
### Mapeamento de Solicitações: Transmissão com Envelope
|
||
|
|
|
||
|
|
A solicitação a um serviço de ferramenta é um envelope estruturado contendo:
|
||
|
|
`user`: Propagado do pedido do agente para multi-inquilinato
|
||
|
|
Valores de configuração: Do descritor da ferramenta (por exemplo, `collection`)
|
||
|
|
`arguments`: Argumentos fornecidos pelo LLM, transmitidos como um dicionário
|
||
|
|
|
||
|
|
O gerenciador de agente analisa a resposta do LLM em `act.arguments` como um dicionário (`agent_manager.py:117-154`). Este dicionário é incluído no envelope da solicitação.
|
||
|
|
|
||
|
|
### Tratamento de Esquemas: Não Tipados
|
||
|
|
|
||
|
|
As solicitações e respostas usam dicionários não tipados. Não há validação de esquema no nível do agente - o serviço de ferramenta é responsável por validar suas entradas. Isso fornece o máximo de flexibilidade para definir novos serviços.
|
||
|
|
|
||
|
|
### Interface do Cliente: Tópicos Pulsar Diretos
|
||
|
|
|
||
|
|
Os serviços de ferramentas usam tópicos Pulsar diretos, sem a necessidade de configuração de fluxo. O descritor do serviço de ferramenta especifica os nomes completos das filas:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "joke-service",
|
||
|
|
"request-queue": "non-persistent://tg/request/joke",
|
||
|
|
"response-queue": "non-persistent://tg/response/joke",
|
||
|
|
"config-params": [...]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Isso permite que os serviços sejam hospedados em qualquer namespace.
|
||
|
|
|
||
|
|
### Tratamento de Erros: Convenção de Erro Padrão
|
||
|
|
|
||
|
|
As respostas do serviço de ferramenta seguem a convenção de esquema existente com um campo `error`:
|
||
|
|
|
||
|
|
```python
|
||
|
|
@dataclass
|
||
|
|
class Error:
|
||
|
|
type: str = ""
|
||
|
|
message: str = ""
|
||
|
|
```
|
||
|
|
|
||
|
|
Estrutura da resposta:
|
||
|
|
Sucesso: `error` é `None`, a resposta contém o resultado
|
||
|
|
Erro: `error` é preenchido com `type` e `message`
|
||
|
|
|
||
|
|
Isso corresponde ao padrão usado em todo o serviço existente (por exemplo, `PromptResponse`, `QueryResponse`, `AgentResponse`).
|
||
|
|
|
||
|
|
### Correlação de Requisições/Respostas
|
||
|
|
|
||
|
|
As requisições e respostas são correlacionadas usando um `id` nas propriedades da mensagem Pulsar:
|
||
|
|
|
||
|
|
A requisição inclui `id` nas propriedades: `properties={"id": id}`
|
||
|
|
A(s) resposta(s) incluem o mesmo `id`: `properties={"id": id}`
|
||
|
|
|
||
|
|
Isso segue o padrão existente usado em todo o código-fonte (por exemplo, `agent_service.py`, `llm_service.py`).
|
||
|
|
|
||
|
|
### Suporte a Streaming
|
||
|
|
|
||
|
|
Os serviços de ferramenta podem retornar respostas em streaming:
|
||
|
|
|
||
|
|
Múltiplas mensagens de resposta com o mesmo `id` nas propriedades
|
||
|
|
Cada resposta inclui o campo `end_of_stream: bool`
|
||
|
|
A resposta final tem `end_of_stream: True`
|
||
|
|
|
||
|
|
Isso corresponde ao padrão usado em `AgentResponse` e outros serviços de streaming.
|
||
|
|
|
||
|
|
### Tratamento da Resposta: Retorno de String
|
||
|
|
|
||
|
|
Todas as ferramentas existentes seguem o mesmo padrão: **receber argumentos como um dicionário, retornar a observação como uma string**.
|
||
|
|
|
||
|
|
| Ferramenta | Tratamento da Resposta |
|
||
|
|
|------|------------------|
|
||
|
|
| `KnowledgeQueryImpl` | Retorna `client.rag()` diretamente (string) |
|
||
|
|
| `TextCompletionImpl` | Retorna `client.question()` diretamente (string) |
|
||
|
|
| `McpToolImpl` | Retorna uma string, ou `json.dumps(output)` se não for uma string |
|
||
|
|
| `StructuredQueryImpl` | Formata o resultado para uma string |
|
||
|
|
| `PromptImpl` | Retorna `client.prompt()` diretamente (string) |
|
||
|
|
|
||
|
|
Os serviços de ferramenta seguem o mesmo contrato:
|
||
|
|
O serviço retorna uma resposta em string (a observação)
|
||
|
|
Se a resposta não for uma string, ela é convertida via `json.dumps()`
|
||
|
|
Nenhuma configuração de extração é necessária no descritor
|
||
|
|
|
||
|
|
Isso mantém o descritor simples e coloca a responsabilidade de retornar uma resposta de texto apropriada para o agente no serviço.
|
||
|
|
|
||
|
|
## Guia de Configuração
|
||
|
|
|
||
|
|
Para adicionar um novo serviço de ferramenta, são necessários dois itens de configuração:
|
||
|
|
|
||
|
|
### 1. Configuração do Serviço de Ferramenta
|
||
|
|
|
||
|
|
Armazenado sob a chave de configuração `tool-service`. Define as filas Pulsar e os parâmetros de configuração disponíveis.
|
||
|
|
|
||
|
|
| Campo | Obrigatório | Descrição |
|
||
|
|
|-------|----------|-------------|
|
||
|
|
| `id` | Sim | Identificador único para o serviço de ferramenta |
|
||
|
|
| `request-queue` | Sim | Tópico Pulsar completo para requisições (por exemplo, `non-persistent://tg/request/joke`) |
|
||
|
|
| `response-queue` | Sim | Tópico Pulsar completo para respostas (por exemplo, `non-persistent://tg/response/joke`) |
|
||
|
|
| `config-params` | Não | Array de parâmetros de configuração que o serviço aceita |
|
||
|
|
|
||
|
|
Cada parâmetro de configuração pode especificar:
|
||
|
|
`name`: Nome do parâmetro (obrigatório)
|
||
|
|
`required`: Se o parâmetro deve ser fornecido pelas ferramentas (padrão: falso)
|
||
|
|
|
||
|
|
Exemplo:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "joke-service",
|
||
|
|
"request-queue": "non-persistent://tg/request/joke",
|
||
|
|
"response-queue": "non-persistent://tg/response/joke",
|
||
|
|
"config-params": [
|
||
|
|
{"name": "style", "required": false}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Configuração da Ferramenta
|
||
|
|
|
||
|
|
Armazenado sob a chave de configuração `tool`. Define uma ferramenta que o agente pode usar.
|
||
|
|
|
||
|
|
| Campo | Obrigatório | Descrição |
|
||
|
|
|-------|----------|-------------|
|
||
|
|
| `type` | Sim | Deve ser `"tool-service"` |
|
||
|
|
| `name` | Sim | Nome da ferramenta exposto para o LLM |
|
||
|
|
| `description` | Sim | Descrição do que a ferramenta faz (mostrada para o LLM) |
|
||
|
|
| `service` | Sim | ID do serviço de ferramenta a ser invocado |
|
||
|
|
| `arguments` | Não | Array de definições de argumentos para o LLM |
|
||
|
|
| *(parâmetros de configuração)* | Varia | Quaisquer parâmetros de configuração definidos pelo serviço |
|
||
|
|
|
||
|
|
Cada argumento pode especificar:
|
||
|
|
`name`: Nome do argumento (obrigatório)
|
||
|
|
`type`: Tipo de dados, por exemplo, `"string"` (obrigatório)
|
||
|
|
`description`: Descrição mostrada para o LLM (obrigatório)
|
||
|
|
|
||
|
|
Exemplo:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "tool-service",
|
||
|
|
"name": "tell-joke",
|
||
|
|
"description": "Tell a joke on a given topic",
|
||
|
|
"service": "joke-service",
|
||
|
|
"style": "pun",
|
||
|
|
"arguments": [
|
||
|
|
{
|
||
|
|
"name": "topic",
|
||
|
|
"type": "string",
|
||
|
|
"description": "The topic for the joke (e.g., programming, animals, food)"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Carregando a Configuração
|
||
|
|
|
||
|
|
Use `tg-put-config-item` para carregar as configurações:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Load tool-service config
|
||
|
|
tg-put-config-item tool-service/joke-service < joke-service.json
|
||
|
|
|
||
|
|
# Load tool config
|
||
|
|
tg-put-config-item tool/tell-joke < tell-joke.json
|
||
|
|
```
|
||
|
|
|
||
|
|
O agente-gerenciador deve ser reiniciado para aplicar novas configurações.
|
||
|
|
|
||
|
|
## Detalhes da Implementação
|
||
|
|
|
||
|
|
### Esquema
|
||
|
|
|
||
|
|
Tipos de requisição e resposta em `trustgraph-base/trustgraph/schema/services/tool_service.py`:
|
||
|
|
|
||
|
|
```python
|
||
|
|
@dataclass
|
||
|
|
class ToolServiceRequest:
|
||
|
|
user: str = "" # User context for multi-tenancy
|
||
|
|
config: str = "" # JSON-encoded config values from tool descriptor
|
||
|
|
arguments: str = "" # JSON-encoded arguments from LLM
|
||
|
|
|
||
|
|
@dataclass
|
||
|
|
class ToolServiceResponse:
|
||
|
|
error: Error | None = None
|
||
|
|
response: str = "" # String response (the observation)
|
||
|
|
end_of_stream: bool = False
|
||
|
|
```
|
||
|
|
|
||
|
|
### Servidor: DynamicToolService
|
||
|
|
|
||
|
|
Classe base em `trustgraph-base/trustgraph/base/dynamic_tool_service.py`:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class DynamicToolService(AsyncProcessor):
|
||
|
|
"""Base class for implementing tool services."""
|
||
|
|
|
||
|
|
def __init__(self, **params):
|
||
|
|
topic = params.get("topic", default_topic)
|
||
|
|
# Constructs topics: non-persistent://tg/request/{topic}, non-persistent://tg/response/{topic}
|
||
|
|
# Sets up Consumer and Producer
|
||
|
|
|
||
|
|
async def invoke(self, user, config, arguments):
|
||
|
|
"""Override this method to implement the tool's logic."""
|
||
|
|
raise NotImplementedError()
|
||
|
|
```
|
||
|
|
|
||
|
|
### Cliente: ToolServiceImpl
|
||
|
|
|
||
|
|
Implementação em `trustgraph-flow/trustgraph/agent/react/tools.py`:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class ToolServiceImpl:
|
||
|
|
def __init__(self, context, request_queue, response_queue, config_values, arguments, processor):
|
||
|
|
# Uses the provided queue paths directly
|
||
|
|
# Creates ToolServiceClient on first use
|
||
|
|
|
||
|
|
async def invoke(self, **arguments):
|
||
|
|
client = await self._get_or_create_client()
|
||
|
|
response = await client.call(user, config_values, arguments)
|
||
|
|
return response if isinstance(response, str) else json.dumps(response)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Arquivos
|
||
|
|
|
||
|
|
| Arquivo | Propósito |
|
||
|
|
|------|---------|
|
||
|
|
| `trustgraph-base/trustgraph/schema/services/tool_service.py` | Esquemas de requisição/resposta |
|
||
|
|
| `trustgraph-base/trustgraph/base/tool_service_client.py` | Cliente para invocar serviços |
|
||
|
|
| `trustgraph-base/trustgraph/base/dynamic_tool_service.py` | Classe base para implementação de serviço |
|
||
|
|
| `trustgraph-flow/trustgraph/agent/react/tools.py` | Classe `ToolServiceImpl` |
|
||
|
|
| `trustgraph-flow/trustgraph/agent/react/service.py` | Carregamento de configuração |
|
||
|
|
|
||
|
|
### Exemplo: Serviço de Piadas
|
||
|
|
|
||
|
|
Um exemplo de serviço em `trustgraph-flow/trustgraph/tool_service/joke/`:
|
||
|
|
|
||
|
|
```python
|
||
|
|
class Processor(DynamicToolService):
|
||
|
|
async def invoke(self, user, config, arguments):
|
||
|
|
style = config.get("style", "pun")
|
||
|
|
topic = arguments.get("topic", "")
|
||
|
|
joke = pick_joke(topic, style)
|
||
|
|
return f"Hey {user}! Here's a {style} for you:\n\n{joke}"
|
||
|
|
```
|
||
|
|
|
||
|
|
Configuração do serviço de ferramenta:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": "joke-service",
|
||
|
|
"request-queue": "non-persistent://tg/request/joke",
|
||
|
|
"response-queue": "non-persistent://tg/response/joke",
|
||
|
|
"config-params": [{"name": "style", "required": false}]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Configuração da ferramenta:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"type": "tool-service",
|
||
|
|
"name": "tell-joke",
|
||
|
|
"description": "Tell a joke on a given topic",
|
||
|
|
"service": "joke-service",
|
||
|
|
"style": "pun",
|
||
|
|
"arguments": [
|
||
|
|
{"name": "topic", "type": "string", "description": "The topic for the joke"}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Compatibilidade com versões anteriores
|
||
|
|
|
||
|
|
Os tipos de ferramentas integradas existentes continuam a funcionar sem alterações.
|
||
|
|
`tool-service` é um novo tipo de ferramenta, juntamente com os tipos existentes (`knowledge-query`, `mcp-tool`, etc.).
|
||
|
|
|
||
|
|
## Considerações futuras
|
||
|
|
|
||
|
|
### Serviços de autoanúncio
|
||
|
|
|
||
|
|
Uma melhoria futura poderia permitir que os serviços publicassem seus próprios descritores:
|
||
|
|
|
||
|
|
Os serviços publicam em um tópico `tool-descriptors` conhecido na inicialização.
|
||
|
|
O agente se inscreve e registra dinamicamente as ferramentas.
|
||
|
|
Permite um verdadeiro sistema de plug-and-play sem alterações de configuração.
|
||
|
|
|
||
|
|
Isso está fora do escopo da implementação inicial.
|
||
|
|
|
||
|
|
## Referências
|
||
|
|
|
||
|
|
Implementação atual da ferramenta: `trustgraph-flow/trustgraph/agent/react/tools.py`
|
||
|
|
Registro de ferramentas: `trustgraph-flow/trustgraph/agent/react/service.py:105-214`
|
||
|
|
Esquemas do agente: `trustgraph-base/trustgraph/schema/services/agent.py`
|