Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@

Generazione di URL Kibana per interrogazione database ElasticSearch e filtraggio di log in linguaggio naturale con correzione errori e validazione, tramite LLM ma nel modo più deterministico possibile.</br>

```mermaid
graph LR

UTENTE[UTENTE] <--> CHESHIRE_CAT["CHESHIRE<br>CAT"]
CHESHIRE_CAT <--> LLM[LLM]

subgraph EXT[Servizi Esterni]
style EXT fill:#f,stroke-width:2px
direction TB
KIBANA[KIBANA] <--> ELASTIC[ELASTIC]
end

CHESHIRE_CAT --> ELASTIC
CHESHIRE_CAT --> KIBANA

```

Abbiamo sviluppato due plugin per Cheshire Cat:
- **[KibCat](https://github.com/shini161/kibcat/tree/main/cat/plugins/kibcat)**: Plugin per la generazione di URL Kibana con linguaggio naturale - Il progetto principale.
- **[Token Counter](https://github.com/shini161/kibcat/tree/main/cat/plugins/token_counter)**: Plugin per contare i token utilizzati in Input/Output dall'LLM.
Expand Down
98 changes: 96 additions & 2 deletions wiki/DIARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -1054,5 +1054,99 @@ def get_token_usage(input, cat):
input_tokens = cat.working_memory.model_interactions[1].input_tokens
return f"Input tokens: {input_tokens}"
```
Il grosso problema che abbiamo riscontrato, però, è che gli `output_tokens` non vengono aggiornati correttamente, e rimangono fissi a 22. Gli `input_tokens`, invece, vengono aggiornati correttamente, ma un tool che restituisce solamente i token di input non è molto utile.
Nelle successive modifiche al codice lo abbiamo quindi rimosso, in quanto non pienamente funzionante.
Il grosso problema che abbiamo riscontrato, però, è che gli `output_tokens` non vengono aggiornati correttamente, e rimangono fissi a 22.
Gli `input_tokens`, invece, vengono aggiornati correttamente, ma un tool che restituisce solamente i token di input non è molto utile.
Nelle successive modifiche al codice lo abbiamo quindi rimosso, in quanto non pienamente funzionante.

# 07/06/2025

Per migliorare la leggibilità del codice e per rispettare le convenzioni dei plugin per il Cheshire Cat, abbiamo deciso di utilizzare la funzione `parse_json` per il parsing del JSON restituito da LLM, invece di utilizzare `json.loads` insieme a varie funzioni per la manipolazione di stringhe.

```python
# PRIMA
json_str = self.cat.llm(
prompt
).replace("```json", "").replace("`", "")
response = json.loads(json_str)
```
```python
# DOPO
response = parse_json(
self.cat.llm(prompt)
)
```

Il codice della funzione `parse_json` implementata nel core del CC è il seguente:
[cheshire-cat-ai\core\core\cat\utils.py](https://github.com/cheshire-cat-ai/core/blob/abafac5cf0aba5dcb7bc3ce7b4d5ae981da15ed7/core/cat/utils.py#L168)
```python
def parse_json(json_string: str, pydantic_model: BaseModel = None) -> dict:
# instantiate parser
parser = JsonOutputParser(pydantic_object=pydantic_model)

# clean to help small LLMs
replaces = {
"\_": "_",
"\-": "-",
"None": "null",
"{{": "{",
"}}": "}",
}
for k, v in replaces.items():
json_string = json_string.replace(k, v)

# first "{" occurrence (required by parser)
start_index = json_string.index("{")

# parse
parsed = parser.parse(json_string[start_index:])

if pydantic_model:
return pydantic_model(**parsed)
return parsed
```
Da notare che questa introduce vari miglioramenti rispetto alla precedente implementazione:
- Utilizza [`JsonOutputParser` di Langchain](https://python.langchain.com/api_reference/core/output_parsers/langchain_core.output_parsers.json.JsonOutputParser.html#langchain_core.output_parsers.json.JsonOutputParser) per il parsing del JSON, che è progettato per gestire in modo più robusto le risposte JSON.
- Rimuove automaticamente i caratteri di escape e altri caratteri non necessari, che alcuni LLM più piccoli potrebbero includere nelle loro risposte.

# 10/06/2025

Abbiamo riscritto il codice per rilevare quando l'utente vuole uscire dal form, in modo da poterlo rendere più robusto e meno soggetto a errori di interpretazione (che ha causato varie volte la chiusura del form quando l'utente chiede di modificare i dati inseriti).

[plugin.py](https://github.com/shini161/kibcat/blob/4e2dc220288cf29590bdf9261e083d0a77cfb100/cat/plugins/kibcat/plugin.py#L456-L467)
```python
def check_exit_intent(self) -> bool:
# Get user message
last_message = self.cat.working_memory.user_message_json.text

# Queries the LLM and check if user is agree or not
response = self.cat.llm(
build_form_check_exit_intent(
last_message=last_message,
logger=KibCatLogger,
)
)
return "true" in response.lower()
```
[form_check_exit_intent.jinja2](https://github.com/shini161/kibcat/blob/4e2dc220288cf29590bdf9261e083d0a77cfb100/cat/plugins/kibcat/prompts/templates/form_check_exit_intent.jinja2)
````jinja2
{% raw %}Your task is return a JSON that indicates whether the user wants to exit the form or not. The JSON should be structured as follows:
```json
{
"exit": // type boolean, must be `true` or `false`
}
```

Exit ONLY if the user *explicitly states* they want to exit the form.
Example phrases that indicate the user wants to exit include:
- "I want to exit the form"
- "Stop this conversation"
- "End this chat"
If the user does not mention exiting, return `false`.

User said "{% endraw %}{{ last_message }}{% raw %}"

Now return a JSON response:{% endraw %}
````
> [!NOTE]
> Nel commit inserito in questa riga c'è un errore di battitura nel prompt, che è stato corretto in seguito.
> `{user_message}` dovrebbe essere `{{ last_message }}`.