Developing Agents
Learn how to implement custom Agent logic for your Genbase Kits by extending the BaseAgent class.
While Genbase provides built-in agents like TaskerAgent
, you can create custom Agents within your Kit to implement specialized logic, control conversation flow more precisely, or manage unique internal states for your Profiles.
When to Create a Custom Agent
Consider creating a custom agent when:
- You need fine-grained control over the interaction flow beyond what built-in agents offer.
- The agent needs to maintain specific internal state or memory across multiple turns within a Profile session.
- You require complex decision-making logic about when to call LLMs versus Tools.
- You want to implement custom parsing of user input or formatting of outputs.
- You need specialized Internal Tools specific to the agent's logic.
If your Profile primarily involves straightforward task execution based on user requests (like running a sequence of predefined Tools), a built-in agent like TaskerAgent
might be sufficient.
Implementation Basics
- Location: Place your custom agent Python code within the
agents/
directory of your Kit. - Inheritance: Your custom agent class must inherit from
engine.services.agents.base_agent.BaseAgent
. - Core Methods:
- Implement the
@property def agent_type(self) -> str:
method. This must return the uniquename
you assign to this agent definition in yourkit.yaml
'sagents:
section. - Implement the
async def process_request(self, context: AgentContext, profile_data: ProfileMetadataResult) -> Dict[str, Any]:
method. This is the main entry point where your agent receives user input and orchestrates the response.
- Implement the
- Registration: Declare your custom agent in the
agents:
section of yourkit.yaml
file, providing a uniquename
and theclass
name. Link it to one or more Profiles using theagent:
field within theprofiles:
section. (See kit.yaml Reference).
Example (agents/my_custom_agent.py
):
Corresponding kit.yaml
Snippet:
Using BaseAgent
Capabilities
Your custom agent inherits useful methods and properties from BaseAgent
:
self.set_context(...)
: Define the system prompt and which tools (Kit-defined, Provided, Internal) are available as tools for the LLM. UseIncludeOptions
for fine-grained control.self.create(...)
: Make calls to the configured LLM. Handles message history automatically. Can execute tool calls requested by the LLM ifrun_tools=True
.self.create_structured(...)
: Call the LLM expecting a Pydantic model as output.self.run_tool(name, params)
: Manually execute a specific Kit Tool or Provided Tool.self.add_message(...)
: Manually add messages (user, assistant, tool) to the chat history for the current session.self.get_messages()
: Retrieve the current chat history list.self.utils
: AccessAgentUtils
for file operations within the Module's workspace (read_file
,write_file
,list_files
, etc.).self.get_store(collection_name)
: Get aProfileStoreService
instance to store/retrieve key-value data specific to this module, profile, and a named collection.self.tool_manager
: (Advanced) Interact with the manager for Internal Tools defined on the agent class itself.
State Management
For simple state within a single process_request
call, use local variables. For state that needs to persist across multiple turns within the same chat session, use agent instance variables (self.my_state
). For state that needs to persist across different sessions or different profiles within the same Module, use the ProfileStoreService
(self.get_store(...)
).
Developing custom agents gives you maximum flexibility in defining how users interact with your Kit's capabilities. Remember to clearly define the agent's purpose and link it correctly in your kit.yaml
.