Updated working principles
This commit is contained in:
75
diagrams/SIA_Class_Diagram.puml
Normal file
75
diagrams/SIA_Class_Diagram.puml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
@startuml
|
||||||
|
skinparam classAttributeIconSize 0
|
||||||
|
|
||||||
|
class AgentCore {
|
||||||
|
- LLMEngine llmEngine
|
||||||
|
- List<CoreAction> actions
|
||||||
|
+ run()
|
||||||
|
+ templateActions(): List[Element]
|
||||||
|
+ systemInfo(): Element
|
||||||
|
+ buildContext(systemInfo: Element, actions: List[Element]): str
|
||||||
|
+ parseResponse(response: str): List[CoreAction], List[int]
|
||||||
|
+ deleteActions(List[int])
|
||||||
|
+ deleteAction(id: int)
|
||||||
|
+ stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServerCore {
|
||||||
|
- WebSystem webSystem
|
||||||
|
+ run()
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebSystem {
|
||||||
|
+ updateContext(context: str)
|
||||||
|
+ getUpdatedContext(): str
|
||||||
|
+ updateActions(actions: List[CoreAction])
|
||||||
|
+ getUpdatedActions(): List[CoreAction]
|
||||||
|
}
|
||||||
|
|
||||||
|
class LLMEngine {
|
||||||
|
+ infer(context: str): Iterator[str]
|
||||||
|
}
|
||||||
|
|
||||||
|
class CoreAction {
|
||||||
|
+ id: str
|
||||||
|
+ template(id: str): Element
|
||||||
|
+ execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
class SingleShotAction extends CoreAction {
|
||||||
|
}
|
||||||
|
|
||||||
|
class RepeatAction extends CoreAction {
|
||||||
|
}
|
||||||
|
|
||||||
|
class BackgroundAction extends CoreAction {
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeleteAction {
|
||||||
|
+ execute(context: Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
class InferenceResult {
|
||||||
|
+ reasoning: str
|
||||||
|
+ actions: List[CoreAction]
|
||||||
|
+ {static} parse(llmOutput: str): InferenceResult
|
||||||
|
}
|
||||||
|
|
||||||
|
Agent o-- LLMEngine
|
||||||
|
Agent o-- AgentCore
|
||||||
|
Agent o-- ServerCore
|
||||||
|
Agent o-- CoreAction
|
||||||
|
|
||||||
|
AgentCore o-- Context
|
||||||
|
AgentCore o-- InferenceResult
|
||||||
|
AgentCore o-- CoreAction
|
||||||
|
|
||||||
|
ServerCore o-- WebSystem
|
||||||
|
ServerCore o-- InferenceResult
|
||||||
|
ServerCore o-- CoreAction
|
||||||
|
|
||||||
|
CoreAction <|-- SingleShotAction
|
||||||
|
CoreAction <|-- RepeatAction
|
||||||
|
CoreAction <|-- BackgroundAction
|
||||||
|
CoreAction o-- DeleteAction
|
||||||
|
@enduml
|
||||||
44
old_architecture.md
Normal file
44
old_architecture.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
## Architecture
|
||||||
|
|
||||||
|
An overview of the key components and their interactions.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Core Actions
|
||||||
|
|
||||||
|
Core actions are implemented each in a separate class.
|
||||||
|
Each action in the context is an instance of the corresponding class.
|
||||||
|
The `delete` and `stop` actions are exceptions to this.
|
||||||
|
They are implemented as functions in the `AgentCore`.
|
||||||
|
|
||||||
|
Actions have a `template(id)` method that returns an XML Element.
|
||||||
|
If they require updating in each iteration, they do so at the start of the `template` method.
|
||||||
|
|
||||||
|
### Agent Core
|
||||||
|
|
||||||
|
The `AgentCore` manages the state of the agent.
|
||||||
|
|
||||||
|
It can also run a basic main loop consisting of:
|
||||||
|
- Running template on all actions
|
||||||
|
- Collecting system information
|
||||||
|
- Building the context
|
||||||
|
- Running the LLM
|
||||||
|
- Splitting the LLM output in reasoning and actions
|
||||||
|
- Instantiating the new actions and listing id's to delete
|
||||||
|
- Deleting the old actions
|
||||||
|
|
||||||
|
### Web System
|
||||||
|
|
||||||
|
The `WebSystem` uses an `AgentCore` but doesn't run the main loop.
|
||||||
|
It runs a modified main loop and interacts with the WebSystem.
|
||||||
|
It also instantiates alternative actions for stdio to interact with the WebSystem.
|
||||||
|
|
||||||
|
### LLM Engine
|
||||||
|
|
||||||
|
The `LLMEngine` does the LLM inference.
|
||||||
|
It takes a context as string and returns an iterator of tokens.
|
||||||
|
|
||||||
|
### Inference Result
|
||||||
|
|
||||||
|
An `InferenceResult` object contains the resoning and parsed actions.
|
||||||
|
Parsing is part of the Inference Result constructor.
|
||||||
279
readme.md
279
readme.md
@@ -1,16 +1,114 @@
|
|||||||
# SIA - The Self Improving Agent
|
# SIA - The Self Improving Agent
|
||||||
|
|
||||||
SIA is an agentic artificial intelligence system that autonomously completes complex tasks by writing and executing scripts.
|
SIA is an agentic artificial intelligence system that autonomously completes complex tasks by writing and executing scripts.
|
||||||
It uses a Large Language Model (LLM) which operates in a loop, generating reasoning and actions based on an updating context.
|
It uses a Large Language Model (LLM) which operates in a loop.
|
||||||
|
Each iteration a context is updated with system info and a list of previous reasoning and actions.
|
||||||
|
The agent responds with a new reasoning or an action.
|
||||||
Context, reasoning and actions are stored in a file for each iteration.
|
Context, reasoning and actions are stored in a file for each iteration.
|
||||||
SIA can read past iterations to improve its reasoning and actions.
|
SIA can read past iterations to improve its reasoning and actions.
|
||||||
It can improve in two ways:
|
It can improve in two ways:
|
||||||
- By providing better reasoning or actions for a given context and update the LLM.
|
- By finetuning the LLM with a better reasoning or action for a given context
|
||||||
- By modifying its own source code.
|
- By modifying its own source code
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
This example shows a typical context with some monitored items and previous actions.
|
||||||
|
Between each of the responses, the context would be updated.
|
||||||
|
|
||||||
|
### Context
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<context
|
||||||
|
time="2024-10-18T12:00:00Z"
|
||||||
|
cpu="12"
|
||||||
|
gpu="26"
|
||||||
|
memory_used="9556302234"
|
||||||
|
memory_total="17179869184"
|
||||||
|
disk_used="244434939904"
|
||||||
|
disk_total="273145991168"
|
||||||
|
context="3"
|
||||||
|
stdin="0"
|
||||||
|
/>
|
||||||
|
<repeat id="a3d89ee5-28ec-4c5a-b9e9-a30af53d43a0" exit_code="0">
|
||||||
|
<![CDATA[ls -lah /]]>
|
||||||
|
<stdout><![CDATA[total 16K
|
||||||
|
drwxr-xr-x 1 sia 1049089 0 Oct 28 13:40 ./
|
||||||
|
drwxr-xr-x 1 sia 1049089 0 Oct 28 13:40 ../
|
||||||
|
drwxr-xr-x 1 sia 1049089 0 Oct 28 13:40 tasks/
|
||||||
|
drwxr-xr-x 1 sia 1049089 0 Oct 28 13:40 user/
|
||||||
|
]]></stdout>
|
||||||
|
<stderr/>
|
||||||
|
</repeat>
|
||||||
|
<repeat id="be8070f8-dbd2-47ee-a208-defe6fd49ae0" exit_code="0">
|
||||||
|
<![CDATA[ls -lah /tasks]]>
|
||||||
|
<stdout><![CDATA[total 0
|
||||||
|
drwxr-xr-x 1 ngeens 1049089 0 Oct 28 13:40 ./
|
||||||
|
drwxr-xr-x 1 ngeens 1049089 0 Oct 28 13:40 ../
|
||||||
|
]]></stdout>
|
||||||
|
<stderr/>
|
||||||
|
</repeat>
|
||||||
|
<repeat id="375e1657-8140-456b-bda4-a8690bc4b3fb" exit_code="0">
|
||||||
|
<![CDATA[cat /user/general_info.txt]]>
|
||||||
|
<stdout><![CDATA[Name: John (I don't know his last name)
|
||||||
|
Location: Somewhere in Belgium
|
||||||
|
]]></stdout>
|
||||||
|
<stderr/>
|
||||||
|
</repeat>
|
||||||
|
<reasoning id="c92d1594-4487-4a42-a153-f0a99da1762f"><![CDATA[There is data available on the standard input channel. I have no other running tasks to tend to and there is room in the context. I should read the standard input.]]></reasoning>
|
||||||
|
<read_stdin id="5361ad0d-3ed1-4567-9f5a-70f3b462fd8d"><![CDATA[Remind me to feed the cat tomorrow morning]]></read_stdin>
|
||||||
|
</context>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Responses
|
||||||
|
|
||||||
|
Start by reasoning about the task.
|
||||||
|
```xml
|
||||||
|
<reasoning>
|
||||||
|
John did not specify an exact time.
|
||||||
|
I'll suggest 9am.
|
||||||
|
He also did not specify how to be reminded.
|
||||||
|
I'll ask but if he doesn't respond I'll assume a text message on standard output is fine.
|
||||||
|
I'll write down this task in a file so I remember it even on a power failure.
|
||||||
|
</reasoning>
|
||||||
|
```
|
||||||
|
|
||||||
|
Store important information on disk.
|
||||||
|
```xml
|
||||||
|
<single_shot><![CDATA[echo 'Remind John to feed the cat on 2024-10-18T09:00:00+02:00. Use standard output.' > /tasks/reminder_to_feed_cat.txt]]></single_shot>
|
||||||
|
```
|
||||||
|
|
||||||
|
Respond to the user.
|
||||||
|
```xml
|
||||||
|
<write_stdout>I'll remind you to feed the cat tomorrow morning at 9am. Is a message on the standard output ok?</write_stdout>
|
||||||
|
```
|
||||||
|
|
||||||
|
Clear initial reasoning.
|
||||||
|
```xml
|
||||||
|
<delete id="c92d1594-4487-4a42-a153-f0a99da1762f"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
The conversation is kept in context to understand the user's expected response.
|
||||||
|
If the context was near full, it would be summarized and cleaned up.
|
||||||
|
|
||||||
|
The single shot is also kept in context.
|
||||||
|
If the file was updated often, it could be replaced by a repeated `cat`, like the general info.
|
||||||
|
|
||||||
## Working principles
|
## Working principles
|
||||||
|
|
||||||
High-level overview of the main components of SIA and how they work together.
|
The main context is regenerated for each iteration.
|
||||||
|
It contains info about the system and previous actions that have not been deleted.
|
||||||
|
Together with the system prompt and available core actions it forms the prompt for the LLM.
|
||||||
|
The LLM responds with one core action.
|
||||||
|
|
||||||
|
### Core Actions
|
||||||
|
|
||||||
|
There are only a few core actions:
|
||||||
|
- Starting a script
|
||||||
|
- Deleting data from context
|
||||||
|
- Stopping SIA
|
||||||
|
- Reading standard input
|
||||||
|
- Writing to standard output
|
||||||
|
- Reasoning
|
||||||
|
|
||||||
### Scripts
|
### Scripts
|
||||||
|
|
||||||
@@ -34,38 +132,10 @@ Similar to single-shot scripts, the next iteration starts after all repeat scrip
|
|||||||
#### Background
|
#### Background
|
||||||
|
|
||||||
The script is started and keeps running.
|
The script is started and keeps running.
|
||||||
This is useful for long-running processes e.g. a web server or a communication channel.
|
This is useful for waiting for events, a communication channels or a process that requires attention.
|
||||||
Because output of a background script can grow long, it is often redirected to a file.
|
|
||||||
|
|
||||||
### LLM prompt
|
Long-running processes e.g. a web server can be run as a service or detached process to keep the context small.
|
||||||
|
The output can be redirected to a file and monitored with a repeat script.
|
||||||
The main context is regenerated for each iteration.
|
|
||||||
It contains info about the system, the scripts and what happended in the previous iteration.
|
|
||||||
Together with the system prompt and available core actions it forms the prompt for the LLM.
|
|
||||||
|
|
||||||
The LLM generates reasoning and an XML structure with core actions.
|
|
||||||
If the structure cannot be parsed, the error is described and the LLM is asked to try again.
|
|
||||||
This can continue until the context overflows.
|
|
||||||
Only the first reasoning, last reasoning and last actions are shown in the new context.
|
|
||||||
All is stored on the file system.
|
|
||||||
|
|
||||||
### Core Actions
|
|
||||||
|
|
||||||
There are only a few core actions:
|
|
||||||
- Starting a script
|
|
||||||
- Stopping a script
|
|
||||||
- Stopping SIA
|
|
||||||
- Reading standard input
|
|
||||||
- Writing to standard output
|
|
||||||
|
|
||||||
Standard error is used by the core for debugging.
|
|
||||||
|
|
||||||
SIA typically runs in a Docker container.
|
|
||||||
When stopped, the latest container version is pulled.
|
|
||||||
This is how SIA can be updated.
|
|
||||||
|
|
||||||
SIA can also run SIA processes as script.
|
|
||||||
This can be used for testing updates to the LLM or core functionality.
|
|
||||||
|
|
||||||
### Use of XML
|
### Use of XML
|
||||||
|
|
||||||
@@ -73,11 +143,21 @@ The context and actions are formatted as XML.
|
|||||||
For the context this adds clear rules for escaping.
|
For the context this adds clear rules for escaping.
|
||||||
This is usefull in case a previous context is embedded.
|
This is usefull in case a previous context is embedded.
|
||||||
|
|
||||||
The response starts with freeform reasoning followed by XML formatted actions.
|
The LLM is free to escape data any way it wants,
|
||||||
In case the LLM makes a mistake it can start over.
|
as long as it results in valid XML.
|
||||||
Only the last XML block is evaluated.
|
The Context is escaped using CDATA blocks.
|
||||||
|
Except when the data contains CDATA closing sequences.
|
||||||
|
Then the whole block is escaped using standard XML escaping.
|
||||||
|
|
||||||
Action results are added in the context in the previous_iteration section.
|
### The SIA process
|
||||||
|
|
||||||
|
SIA is typically runs with the `restart.sh` script.
|
||||||
|
This is a simple shell script that runs SIA in a loop.
|
||||||
|
When stopped, SIA restarts and reloads the Python files.
|
||||||
|
This is how SIA can self-update.
|
||||||
|
|
||||||
|
SIA can also run SIA processes as script.
|
||||||
|
This can be used for testing updates to the LLM or core functionality.
|
||||||
|
|
||||||
### Server for debuggin and human input
|
### Server for debuggin and human input
|
||||||
|
|
||||||
@@ -88,123 +168,4 @@ The web interface takes over standard input and output.
|
|||||||
It will display the context for editing before handing it to the LLM.
|
It will display the context for editing before handing it to the LLM.
|
||||||
After each run of the LLM, before parsing, it will display the reasoning and actions.
|
After each run of the LLM, before parsing, it will display the reasoning and actions.
|
||||||
It interactively displays if the actions can be parsed.
|
It interactively displays if the actions can be parsed.
|
||||||
At any time, the user can write to the standard input of SIA.
|
At any time, the user can write to the standard input of SIA.
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
An overview of the key components and their interactions.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### Modules
|
|
||||||
|
|
||||||
Modules execute core commands and provide data for the context template.
|
|
||||||
|
|
||||||
- System Module
|
|
||||||
- System information
|
|
||||||
- SIA stdio operations
|
|
||||||
- Stopping SIA (possibly triggering an update)
|
|
||||||
- Process Module
|
|
||||||
- Starting scripts
|
|
||||||
- Stopping scripts
|
|
||||||
- Managing process stdio and status
|
|
||||||
|
|
||||||
### Agent Core
|
|
||||||
|
|
||||||
The Agent Core runs the SIA main loop.
|
|
||||||
This loop consists of:
|
|
||||||
- Templating the context
|
|
||||||
- Running the LLM
|
|
||||||
- Parsing the LLM output
|
|
||||||
- Rerunning the LLM if the output cannot be parsed
|
|
||||||
- Executing the appropriate actions
|
|
||||||
|
|
||||||
### Server Core
|
|
||||||
|
|
||||||
The Server Core is an alternative for the Agent Core.
|
|
||||||
It runs a modified main loop and ues the WebSystem Module.
|
|
||||||
This is an extension of the System Module redirecting stdio to the web interface.
|
|
||||||
|
|
||||||
### LLM Engine
|
|
||||||
|
|
||||||
The LLM Engine does the LLM inference.
|
|
||||||
It takes a context and returns an iterator of tokens.
|
|
||||||
|
|
||||||
### Inference Result
|
|
||||||
|
|
||||||
An Inference Result object contains the resoning and parsed actions.
|
|
||||||
Parsing is part of the Inference Result constructor.
|
|
||||||
|
|
||||||
## Example iterations
|
|
||||||
|
|
||||||
### Clarifying a task
|
|
||||||
|
|
||||||
This example shows how to work with standard IO, run simple scripts and monitor files.
|
|
||||||
|
|
||||||
#### Context
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<context>
|
|
||||||
<system
|
|
||||||
time="2024-10-18T12:00:00Z"
|
|
||||||
cpu="12"
|
|
||||||
gpu="26"
|
|
||||||
memory_used="9556302234"
|
|
||||||
memory_total="17179869184"
|
|
||||||
disk_used="244434939904"
|
|
||||||
disk_total="273145991168"
|
|
||||||
context="3"
|
|
||||||
stdin="0"
|
|
||||||
/>
|
|
||||||
<containers/>
|
|
||||||
<previous>
|
|
||||||
<reasoning>
|
|
||||||
There is data available on the standard input channel. I should read it. I have no other running tasks to tend to.
|
|
||||||
</reasoning>
|
|
||||||
<actions>
|
|
||||||
<read_stdin>
|
|
||||||
<![CDATA[Remind me to feed the cat tomorrow morning]]>
|
|
||||||
</read_stdin>
|
|
||||||
</actions>
|
|
||||||
</previous>
|
|
||||||
<files>
|
|
||||||
<file name="/" type="dir" index="0">
|
|
||||||
<![CDATA[
|
|
||||||
drwxr-xr-x 1 sia 197121 0 2024-10-16 23:02:16.486152500 +0200 tasks/
|
|
||||||
drwxr-xr-x 1 sia 197121 0 2024-10-16 22:35:31.806079500 +0200 user/
|
|
||||||
]]>
|
|
||||||
</file>
|
|
||||||
<file name="/tasks" type="dir" index="1">
|
|
||||||
</file>
|
|
||||||
<file name="/user" type="dir">
|
|
||||||
<![CDATA[
|
|
||||||
-rw-r--r-- 1 sia 197121 71 2024-10-16 22:41:23.223580300 +0200 general_info.txt
|
|
||||||
]]>
|
|
||||||
</file>
|
|
||||||
<file name="/user/general_info.txt" type="file" index="2">
|
|
||||||
<![CDATA[
|
|
||||||
Name: John (I don't know his last name)
|
|
||||||
Location: Somewhere in Belgium
|
|
||||||
]]>
|
|
||||||
</file>
|
|
||||||
</files>
|
|
||||||
</context>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### LLM response
|
|
||||||
|
|
||||||
```xml
|
|
||||||
John did not specify an exact time. I'll suggest 9am. He also did not specify how to be reminded. I'll ask but if he doesn't respond I'll assume a text message on standard output is fine. I'll write down this task in a file so I can keep it in context. I can write simple files with busybox:latest and echo but I will need to use sh -c to do the redirect.
|
|
||||||
<actions>
|
|
||||||
<write_stdout message="I'll remind you to feed the cat tomorrow morning at 9am. Is a message on the standard output ok?"/>
|
|
||||||
<start_container image="busybox:latest" timeout="1000">
|
|
||||||
<command>sh</command>
|
|
||||||
<argtument>-c</argument>
|
|
||||||
<argument><![CDATA[echo 'Remind John to feed the cat on 2024-10-18T09:00:00+02:00. Use standard output.' > /tasks/reminder.txt]]></argument>
|
|
||||||
<volumes>
|
|
||||||
<volume>/tasks:/tasks</volume>
|
|
||||||
</volumes>
|
|
||||||
</start_container>
|
|
||||||
<monitor_file path="/tasks/reminder.txt"/>
|
|
||||||
</actions>
|
|
||||||
```
|
|
||||||
Reference in New Issue
Block a user