Agent Blackboard
Der Blackboard ist ein gemeinsamer Speicherbereich, der für alle Agenten im UFO-Framework sichtbar ist. Er speichert Informationen, die Agenten benötigen, um auf jeder Stufe mit dem Benutzer und Anwendungen zu interagieren. Der Blackboard ist eine Schlüsselkomponente des UFO-Frameworks, die es Agenten ermöglicht, Informationen zu teilen und zusammenzuarbeiten, um Benutzeranfragen zu erfüllen. Der Blackboard wird als Klasse in der Datei ufo/agents/memory/blackboard.py implementiert.
Komponenten
Der Blackboard besteht aus den folgenden Datenkomponenten
| Komponente |
Beschreibung |
Fragen |
Eine Liste von Fragen, die UFO dem Benutzer stellt, zusammen mit den entsprechenden Antworten. |
Anfragen |
Eine Liste historischer Benutzeranfragen, die in vorherigen Round empfangen wurden. |
Trajektorien |
Eine Liste schrittweiser Trajektorien, die die Aktionen und Entscheidungen des Agenten in jedem Schritt aufzeichnen. |
Screenshots |
Eine Liste von Screenshots, die vom Agenten aufgenommen werden, wenn er glaubt, dass der aktuelle Zustand für zukünftige Referenz wichtig ist. |
Tipp
Die in den trajectories gespeicherten Schlüssel sind in der Datei config_dev.yaml als HISTORY_KEYS konfiguriert. Sie können die Schlüssel basierend auf Ihren Anforderungen und der Logik des Agenten anpassen.
Tipp
Ob die Screenshots gespeichert werden, wird vom AppAgent bestimmt. Sie können die Screenshot-Erfassung aktivieren oder deaktivieren, indem Sie das Flag SCREENSHOT_TO_MEMORY in der Datei config_dev.yaml setzen.
Blackboard zu Prompt
Die Daten im Blackboard basieren auf der Klasse MemoryItem. Sie hat eine Methode blackboard_to_prompt, die die im Blackboard gespeicherten Informationen in einen String-Prompt umwandelt. Agenten rufen diese Methode auf, um den Prompt für die Inferenz der LLM zu konstruieren. Die Methode blackboard_to_prompt ist wie folgt definiert
def blackboard_to_prompt(self) -> List[str]:
"""
Convert the blackboard to a prompt.
:return: The prompt.
"""
prefix = [
{
"type": "text",
"text": "[Blackboard:]",
}
]
blackboard_prompt = (
prefix
+ self.texts_to_prompt(self.questions, "[Questions & Answers:]")
+ self.texts_to_prompt(self.requests, "[Request History:]")
+ self.texts_to_prompt(self.trajectories, "[Step Trajectories Completed Previously:]")
+ self.screenshots_to_prompt()
)
return blackboard_prompt
Referenz
Klasse für den Blackboard, die die Daten und Bilder speichert, die für alle Agenten sichtbar sind.
Initialisiert den Blackboard.
Quellcode in agents/memory/blackboard.py
41
42
43
44
45
46
47
48
49
50
51
52
53 | def __init__(self) -> None:
"""
Initialize the blackboard.
"""
self._questions: Memory = Memory()
self._requests: Memory = Memory()
self._trajectories: Memory = Memory()
self._screenshots: Memory = Memory()
if configs.get("USE_CUSTOMIZATION", False):
self.load_questions(
configs.get("QA_PAIR_FILE", ""), configs.get("QA_PAIR_NUM", -1)
)
|
questions property
Ruft die Daten vom Blackboard ab.
| Rückgabe |
-
Memory –
Die Fragen vom Blackboard.
|
requests property
Ruft die Daten vom Blackboard ab.
| Rückgabe |
-
Memory –
Die Anfragen vom Blackboard.
|
screenshots property
Ruft die Bilder vom Blackboard ab.
| Rückgabe |
-
Memory –
Die Bilder vom Blackboard.
|
trajectories property
Ruft die Daten vom Blackboard ab.
| Rückgabe |
-
Memory –
Die Trajektorien vom Blackboard.
|
add_data(data, memory)
Fügt die Daten zu einem Speicher im Blackboard hinzu.
| Parameter |
-
data (Union[MemoryItem, Dict[str, str], str]) –
Die hinzuzufügenden Daten. Es kann ein Wörterbuch oder ein MemoryItem oder ein String sein.
-
memory (Memory) –
Der Speicher, zu dem die Daten hinzugefügt werden sollen.
|
Quellcode in agents/memory/blackboard.py
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 | def add_data(
self, data: Union[MemoryItem, Dict[str, str], str], memory: Memory
) -> None:
"""
Add the data to the a memory in the blackboard.
:param data: The data to be added. It can be a dictionary or a MemoryItem or a string.
:param memory: The memory to add the data to.
"""
if isinstance(data, dict):
data_memory = MemoryItem()
data_memory.add_values_from_dict(data)
memory.add_memory_item(data_memory)
elif isinstance(data, MemoryItem):
memory.add_memory_item(data)
elif isinstance(data, str):
data_memory = MemoryItem()
data_memory.add_values_from_dict({"text": data})
memory.add_memory_item(data_memory)
else:
print(f"Warning: Unsupported data type: {type(data)} when adding data.")
|
add_image(screenshot_path='', metadata=None)
Fügt das Bild zum Blackboard hinzu.
| Parameter |
-
screenshot_path (str, Standard: '' ) –
-
metadata (Optional[Dict[str, str]], Standard: None ) –
Die Metadaten des Bildes.
|
Quellcode in agents/memory/blackboard.py
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 | def add_image(
self,
screenshot_path: str = "",
metadata: Optional[Dict[str, str]] = None,
) -> None:
"""
Add the image to the blackboard.
:param screenshot_path: The path of the image.
:param metadata: The metadata of the image.
"""
if os.path.exists(screenshot_path):
screenshot_str = PhotographerFacade().encode_image_from_path(
screenshot_path
)
else:
print(f"Screenshot path {screenshot_path} does not exist.")
screenshot_str = ""
image_memory_item = ImageMemoryItem()
image_memory_item.add_values_from_dict(
{
ImageMemoryItemNames.METADATA: metadata.get(
ImageMemoryItemNames.METADATA
),
ImageMemoryItemNames.IMAGE_PATH: screenshot_path,
ImageMemoryItemNames.IMAGE_STR: screenshot_str,
}
)
self.screenshots.add_memory_item(image_memory_item)
|
add_questions(questions)
Fügt die Daten zum Blackboard hinzu.
| Parameter |
-
questions (Union[MemoryItem, Dict[str, str]]) –
Die hinzuzufügenden Daten. Es kann ein Wörterbuch oder ein MemoryItem oder ein String sein.
|
Quellcode in agents/memory/blackboard.py
109
110
111
112
113
114
115 | def add_questions(self, questions: Union[MemoryItem, Dict[str, str]]) -> None:
"""
Add the data to the blackboard.
:param questions: The data to be added. It can be a dictionary or a MemoryItem or a string.
"""
self.add_data(questions, self.questions)
|
add_requests(requests)
Fügt die Daten zum Blackboard hinzu.
| Parameter |
-
requests (Union[MemoryItem, Dict[str, str]]) –
Die hinzuzufügenden Daten. Es kann ein Wörterbuch oder ein MemoryItem oder ein String sein.
|
Quellcode in agents/memory/blackboard.py
117
118
119
120
121
122
123 | def add_requests(self, requests: Union[MemoryItem, Dict[str, str]]) -> None:
"""
Add the data to the blackboard.
:param requests: The data to be added. It can be a dictionary or a MemoryItem or a string.
"""
self.add_data(requests, self.requests)
|
add_trajectories(trajectories)
Fügt die Daten zum Blackboard hinzu.
| Parameter |
-
trajectories (Union[MemoryItem, Dict[str, str]]) –
Die hinzuzufügenden Daten. Es kann ein Wörterbuch oder ein MemoryItem oder ein String sein.
|
Quellcode in agents/memory/blackboard.py
125
126
127
128
129
130
131 | def add_trajectories(self, trajectories: Union[MemoryItem, Dict[str, str]]) -> None:
"""
Add the data to the blackboard.
:param trajectories: The data to be added. It can be a dictionary or a MemoryItem or a string.
"""
self.add_data(trajectories, self.trajectories)
|
blackboard_from_dict(blackboard_dict)
Konvertiert das Wörterbuch in den Blackboard.
| Parameter |
-
blackboard_dict (Dict[str, List[Dict[str, str]]]) –
|
Quellcode in agents/memory/blackboard.py
264
265
266
267
268
269
270
271
272
273
274 | def blackboard_from_dict(
self, blackboard_dict: Dict[str, List[Dict[str, str]]]
) -> None:
"""
Convert the dictionary to the blackboard.
:param blackboard_dict: The dictionary.
"""
self.questions.from_list_of_dicts(blackboard_dict.get("questions", []))
self.requests.from_list_of_dicts(blackboard_dict.get("requests", []))
self.trajectories.from_list_of_dicts(blackboard_dict.get("trajectories", []))
self.screenshots.from_list_of_dicts(blackboard_dict.get("screenshots", []))
|
blackboard_to_dict()
Konvertiert den Blackboard in ein Wörterbuch.
| Rückgabe |
-
Dict[str, List[Dict[str, str]]] –
Der Blackboard im Wörterbuchformat.
|
Quellcode in agents/memory/blackboard.py
243
244
245
246
247
248
249
250
251
252
253
254
255 | def blackboard_to_dict(self) -> Dict[str, List[Dict[str, str]]]:
"""
Convert the blackboard to a dictionary.
:return: The blackboard in the dictionary format.
"""
blackboard_dict = {
"questions": self.questions.to_list_of_dicts(),
"requests": self.requests.to_list_of_dicts(),
"trajectories": self.trajectories.to_list_of_dicts(),
"screenshots": self.screenshots.to_list_of_dicts(),
}
return blackboard_dict
|
blackboard_to_json()
Konvertiert den Blackboard in einen JSON-String.
Quellcode in agents/memory/blackboard.py
| def blackboard_to_json(self) -> str:
"""
Convert the blackboard to a JSON string.
:return: The JSON string.
"""
return json.dumps(self.blackboard_to_dict())
|
blackboard_to_prompt()
Konvertiert den Blackboard in einen Prompt.
Quellcode in agents/memory/blackboard.py
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298 | def blackboard_to_prompt(self) -> List[str]:
"""
Convert the blackboard to a prompt.
:return: The prompt.
"""
prefix = [
{
"type": "text",
"text": "[Blackboard:]",
}
]
blackboard_prompt = (
prefix
+ self.texts_to_prompt(self.questions, "[Questions & Answers:]")
+ self.texts_to_prompt(self.requests, "[Request History:]")
+ self.texts_to_prompt(
self.trajectories, "[Step Trajectories Completed Previously:]"
)
+ self.screenshots_to_prompt()
)
return blackboard_prompt
|
clear()
Löscht den Blackboard.
Quellcode in agents/memory/blackboard.py
312
313
314
315
316
317
318
319 | def clear(self) -> None:
"""
Clear the blackboard.
"""
self.questions.clear()
self.requests.clear()
self.trajectories.clear()
self.screenshots.clear()
|
is_empty()
Prüft, ob der Blackboard leer ist.
| Rückgabe |
-
bool –
True, wenn der Blackboard leer ist, False andernfalls.
|
Quellcode in agents/memory/blackboard.py
300
301
302
303
304
305
306
307
308
309
310 | def is_empty(self) -> bool:
"""
Check if the blackboard is empty.
:return: True if the blackboard is empty, False otherwise.
"""
return (
self.questions.is_empty()
and self.requests.is_empty()
and self.trajectories.is_empty()
and self.screenshots.is_empty()
)
|
load_questions(file_path, last_k=-1)
Lädt die Daten aus einer Datei.
| Parameter |
-
file_path (str) –
-
last_k –
Die Anzahl der Zeilen, die vom Ende der Datei gelesen werden sollen. Wenn -1, werden alle Zeilen gelesen.
|
Quellcode in agents/memory/blackboard.py
194
195
196
197
198
199
200
201
202 | def load_questions(self, file_path: str, last_k=-1) -> None:
"""
Load the data from a file.
:param file_path: The path of the file.
:param last_k: The number of lines to read from the end of the file. If -1, read all lines.
"""
qa_list = self.read_json_file(file_path, last_k)
for qa in qa_list:
self.add_questions(qa)
|
questions_to_json()
Konvertiert die Daten in ein Wörterbuch.
| Rückgabe |
-
str –
Die Daten im Wörterbuchformat.
|
Quellcode in agents/memory/blackboard.py
| def questions_to_json(self) -> str:
"""
Convert the data to a dictionary.
:return: The data in the dictionary format.
"""
return self.questions.to_json()
|
read_json_file(file_path, last_k=-1) staticmethod
Liest die JSON-Datei.
| Parameter |
-
file_path (str) –
-
last_k –
Die Anzahl der Zeilen, die vom Ende der Datei gelesen werden sollen. Wenn -1, werden alle Zeilen gelesen.
|
Quellcode in agents/memory/blackboard.py
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350 | @staticmethod
def read_json_file(file_path: str, last_k=-1) -> Dict[str, str]:
"""
Read the json file.
:param file_path: The path of the file.
:param last_k: The number of lines to read from the end of the file. If -1, read all lines.
:return: The data in the file.
"""
data_list = []
# Check if the file exists
if os.path.exists(file_path):
# Open the file and read the lines
with open(file_path, "r", encoding="utf-8") as file:
lines = file.readlines()
# If last_k is not -1, only read the last k lines
if last_k != -1:
lines = lines[-last_k:]
# Parse the lines as JSON
for line in lines:
try:
data = json.loads(line.strip())
data_list.append(data)
except json.JSONDecodeError:
print(f"Warning: Unable to parse line as JSON: {line}")
return data_list
|
requests_to_json()
Konvertiert die Daten in ein Wörterbuch.
| Rückgabe |
-
str –
Die Daten im Wörterbuchformat.
|
Quellcode in agents/memory/blackboard.py
| def requests_to_json(self) -> str:
"""
Convert the data to a dictionary.
:return: The data in the dictionary format.
"""
return self.requests.to_json()
|
screenshots_to_json()
Konvertiert die Bilder in ein Wörterbuch.
| Rückgabe |
-
str –
Die Bilder im Wörterbuchformat.
|
Quellcode in agents/memory/blackboard.py
| def screenshots_to_json(self) -> str:
"""
Convert the images to a dictionary.
:return: The images in the dictionary format.
"""
return self.screenshots.to_json()
|
screenshots_to_prompt()
Konvertiert die Bilder in einen Prompt.
Quellcode in agents/memory/blackboard.py
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 | def screenshots_to_prompt(self) -> List[str]:
"""
Convert the images to a prompt.
:return: The prompt.
"""
user_content = []
for screenshot_dict in self.screenshots.list_content:
user_content.append(
{
"type": "text",
"text": json.dumps(
screenshot_dict.get(ImageMemoryItemNames.METADATA, "")
),
}
)
user_content.append(
{
"type": "image_url",
"image_url": {
"url": screenshot_dict.get(ImageMemoryItemNames.IMAGE_STR, "")
},
}
)
return user_content
|
texts_to_prompt(memory, prefix)
Konvertiert die Daten in einen Prompt.
Quellcode in agents/memory/blackboard.py
204
205
206
207
208
209
210
211
212
213
214 | def texts_to_prompt(self, memory: Memory, prefix: str) -> List[str]:
"""
Convert the data to a prompt.
:return: The prompt.
"""
user_content = [
{"type": "text", "text": f"{prefix}\n {json.dumps(memory.list_content)}"}
]
return user_content
|
trajectories_to_json()
Konvertiert die Daten in ein Wörterbuch.
| Rückgabe |
-
str –
Die Daten im Wörterbuchformat.
|
Quellcode in agents/memory/blackboard.py
| def trajectories_to_json(self) -> str:
"""
Convert the data to a dictionary.
:return: The data in the dictionary format.
"""
return self.trajectories.to_json()
|
Hinweis
Sie können die Klasse anpassen, um den Blackboard an Ihre Anforderungen anzupassen.