Performance: Implemented Turbo Lite mode for Ollama local
This commit is contained in:
75
ai_agent.py
75
ai_agent.py
@@ -5,7 +5,7 @@ import json
|
|||||||
from tools import AVAILABLE_TOOLS
|
from tools import AVAILABLE_TOOLS
|
||||||
from config import get_config
|
from config import get_config
|
||||||
|
|
||||||
def get_llm_response(prompt: str, provider: str, cfg: dict) -> str:
|
def get_llm_response(prompt: str, provider: str, cfg: dict, temp: float = 0.7, ctx: int = 4096) -> str:
|
||||||
"""Invoca o provedor de LLM configurado."""
|
"""Invoca o provedor de LLM configurado."""
|
||||||
if provider == "gemini":
|
if provider == "gemini":
|
||||||
api_key = cfg.get("gemini_api_key") or os.getenv("GEMINI_API_KEY")
|
api_key = cfg.get("gemini_api_key") or os.getenv("GEMINI_API_KEY")
|
||||||
@@ -23,8 +23,8 @@ def get_llm_response(prompt: str, provider: str, cfg: dict) -> str:
|
|||||||
"prompt": prompt,
|
"prompt": prompt,
|
||||||
"stream": False,
|
"stream": False,
|
||||||
"options": {
|
"options": {
|
||||||
"temperature": 0.1,
|
"temperature": temp,
|
||||||
"num_ctx": 4096
|
"num_ctx": ctx
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if res.status_code == 200:
|
if res.status_code == 200:
|
||||||
@@ -37,57 +37,23 @@ def query_agent(prompt: str, override_provider: str = None, chat_history: list =
|
|||||||
"""
|
"""
|
||||||
Motor Agente em Loop (ReAct): Pensamento -> Ação -> Observação -> Resposta Final.
|
Motor Agente em Loop (ReAct): Pensamento -> Ação -> Observação -> Resposta Final.
|
||||||
"""
|
"""
|
||||||
|
# Ajuste de Provedor e Contexto
|
||||||
cfg = get_config()
|
cfg = get_config()
|
||||||
provider = override_provider or cfg.get("active_provider", "gemini")
|
provider = override_provider or cfg.get("active_provider", "gemini")
|
||||||
|
|
||||||
# Contexto de Ferramentas para a IA
|
# Prompt otimizado para ser curto se for Ollama (evita CPU 90% em conversas simples)
|
||||||
tools_desc = "\n".join([f"- {k}: {v['description']}" for k,v in AVAILABLE_TOOLS.items()])
|
if provider == "ollama":
|
||||||
|
system_prompt = "Você é o [BotVPS] do Marcos. Seja técnico e breve. Use [TOOL:nome] arg [/TOOL] apenas se for necessário agir na VPS. Responda em Português."
|
||||||
# Prompt especializado reformulado para evitar alucinações
|
num_context = 2048
|
||||||
system_prompt_base = """Você é o [Antigravity VPS Agent], o SysAdmin de elite do Marcos.
|
else:
|
||||||
Você tem acesso root completo à VPS e deve agir de forma profissional e precisa.
|
system_prompt = system_prompt_base.replace("{TOOLS_LIST}", tools_desc)
|
||||||
|
num_context = 4096
|
||||||
### REGRAS DE OURO:
|
|
||||||
1. Responda em PORTUGUÊS (Brasil).
|
|
||||||
2. Se o usuário pedir o status da VPS, SEMPRE use a ferramenta 'get_system_health'.
|
|
||||||
3. Se o usuário pedir algo sobre containers, use 'get_docker_stats'.
|
|
||||||
4. Antes de decidir que um arquivo não existe, use 'run_bash_command' com 'ls' para verificar o diretório.
|
|
||||||
5. NUNCA invente que buscou por arquivos (como syslog.conf) se o usuário não pediu especificamente por eles.
|
|
||||||
6. A seção <REFINED> deve conter apenas as informações solicitadas. Se não houver imagem relevante, não inclua tags de imagem.
|
|
||||||
7. O disco da VPS está montado em `/host_root`. Os arquivos do Marcos ficam principalmente em `/host_root/root/VPS_Sync`. Use este caminho como ponto de partida se o `find` na raiz falhar ou demorar demais.
|
|
||||||
|
|
||||||
### FORMATO DE AÇÃO:
|
|
||||||
Use: [TOOL:nome_da_ferramenta] argumento [/TOOL]
|
|
||||||
Rode UMA ferramenta por vez. Aguarde a saída do SISTEMA antes de concluir.
|
|
||||||
|
|
||||||
### RESPOSTA FINAL:
|
|
||||||
Sua resposta terminada deve ter:
|
|
||||||
- Um resumo técnico.
|
|
||||||
- Uma seção <REFINED> ... </REFINED> com Markdown limpo.
|
|
||||||
- **DICA**: Só use imagens em <REFINED> se o usuário pediu para ver um arquivo de imagem específico que você localizou. Use o caminho absoluto encontrado.
|
|
||||||
|
|
||||||
### FERRAMENTAS DISPONÍVEIS:
|
|
||||||
{TOOLS_LIST}
|
|
||||||
|
|
||||||
### EXEMPLO DE SUCESSO:
|
|
||||||
Usuário: qual o uso de ram agora?
|
|
||||||
Agente: [TOOL:get_system_health] [/TOOL]
|
|
||||||
SISTEMA: CPU: 5% | RAM Usada: 20% | Disco Usado: 40%
|
|
||||||
Resposta: A memória RAM está operando com 20% de uso.
|
|
||||||
<REFINED>
|
|
||||||
### 📊 Memória e CPU
|
|
||||||
- **RAM Utilizada**: 20%
|
|
||||||
- **CPU**: 5%
|
|
||||||
</REFINED>
|
|
||||||
"""
|
|
||||||
system_prompt = system_prompt_base.replace("{TOOLS_LIST}", tools_desc)
|
|
||||||
|
|
||||||
# Preparação de Histórico Limpa
|
# Preparação de Histórico Limpa
|
||||||
hist_list = chat_history[-5:] if chat_history else []
|
hist_list = chat_history[-3:] if chat_history else [] # Apenas as últimas 3 para o Ollama voar
|
||||||
hist_txt = "\n".join([f"Usuário: {m['user']}\nAgente: {m['bot']}" for m in hist_list])
|
hist_txt = "\n".join([f"Usuário: {m['user']}\nAgente: {m['bot']}" for m in hist_list])
|
||||||
|
|
||||||
# Cabeçalho de Execução
|
execution_context = f"\nHistorico: {hist_txt}\nORDEM: {prompt}\n"
|
||||||
execution_context = f"\n--- HISTÓRICO RECENTE ---\n{hist_txt}\n------------------------\n\nORDEM ATUAL: {prompt}\n"
|
|
||||||
current_reasoning = ""
|
current_reasoning = ""
|
||||||
|
|
||||||
max_loops = 12
|
max_loops = 12
|
||||||
@@ -96,15 +62,20 @@ Resposta: A memória RAM está operando com 20% de uso.
|
|||||||
for i in range(max_loops):
|
for i in range(max_loops):
|
||||||
print(f"\n[LOOP {i+1}/{max_loops}]")
|
print(f"\n[LOOP {i+1}/{max_loops}]")
|
||||||
|
|
||||||
# Constrói o Prompt Final separando REGRAS, PASSADO e PENSAMENTO ATUAL
|
full_prompt = f"{system_prompt}\n{execution_context}\n{current_reasoning}\n"
|
||||||
full_prompt = f"{system_prompt}\n{execution_context}\n\nSEU PENSAMENTO ATUAL (Ações e Observações):\n{current_reasoning}\n"
|
|
||||||
|
|
||||||
response = get_llm_response(full_prompt, provider, cfg)
|
# Injeta o num_ctx dinâmico no payload
|
||||||
|
if provider == "ollama":
|
||||||
|
response = get_llm_response(full_prompt, provider, cfg, temp=0.1, ctx=num_context)
|
||||||
|
else:
|
||||||
|
response = get_llm_response(full_prompt, provider, cfg)
|
||||||
|
|
||||||
print(f"PENSAMENTO:\n{response}")
|
print(f"PENSAMENTO:\n{response}")
|
||||||
|
|
||||||
match = re.search(r"\[TOOL:(.*?)\](.*?)\[/TOOL\]", response, re.IGNORECASE | re.DOTALL)
|
match = re.search(r"\[TOOL:(.*?)\](.*?)\[/TOOL\]", response, re.IGNORECASE | re.DOTALL)
|
||||||
|
|
||||||
if match:
|
if match:
|
||||||
|
# ... (lógica de ferramenta existente) ...
|
||||||
tool_name = match.group(1).strip()
|
tool_name = match.group(1).strip()
|
||||||
arg = match.group(2).strip()
|
arg = match.group(2).strip()
|
||||||
print(f"EXECUTANDO: {tool_name}")
|
print(f"EXECUTANDO: {tool_name}")
|
||||||
@@ -112,12 +83,10 @@ Resposta: A memória RAM está operando com 20% de uso.
|
|||||||
if tool_name in AVAILABLE_TOOLS:
|
if tool_name in AVAILABLE_TOOLS:
|
||||||
func = AVAILABLE_TOOLS[tool_name]["func"]
|
func = AVAILABLE_TOOLS[tool_name]["func"]
|
||||||
observation = func() if tool_name in ["get_system_health", "get_docker_stats"] else func(arg)
|
observation = func() if tool_name in ["get_system_health", "get_docker_stats"] else func(arg)
|
||||||
print(f"OBSERVAÇÃO (suprimida): {str(observation)[:150]}...")
|
|
||||||
else:
|
else:
|
||||||
observation = f"Erro: Ferramenta '{tool_name}' não encontrada."
|
observation = f"Erro: Ferramenta '{tool_name}' não encontrada."
|
||||||
|
|
||||||
# Adiciona ao PENSAMENTO ATUAL apenas, sem sujar o histórico original
|
current_reasoning += f"\nAção: {response}\nSISTEMA: {observation}\n"
|
||||||
current_reasoning += f"\nAgente (Ação): {response}\nSISTEMA (Saída): {observation}\n"
|
|
||||||
else:
|
else:
|
||||||
print("--- RESPOSTA FINAL ENCONTRADA ---")
|
print("--- RESPOSTA FINAL ENCONTRADA ---")
|
||||||
return response
|
return response
|
||||||
|
|||||||
Reference in New Issue
Block a user