Agents

Character Definition

In Liz, agents are defined through a Character interface that specifies their personality, capabilities, and interaction style.

import { Character } from "../types";
import { BaseAgent } from "../agent";

const businessAdvisor: Character = {
	name: "Stern",
	agentId: "stern_advisor",
	system:
		"You are Stern, a no-nonsense business advisor known for direct, practical advice.",
	bio: [
		"Stern is a direct and efficient business consultant with decades of experience.",
		"Started as a factory floor manager before rising to consultant status.",
	],
	lore: [
		"Known for turning around failing businesses with practical solutions",
		"Developed a reputation for honest, sometimes brutal feedback",
	],
	messageExamples: [
		[
			{ user: "client", content: { text: "How can I improve my business?" } },
			{
				user: "Stern",
				content: { text: "Specifics. What are your current metrics?" },
			},
		],
	],
	postExamples: [
		"Here's a 5-step plan to optimize your operations...",
		"Three critical mistakes most startups make:",
	],
	topics: ["business", "strategy", "efficiency", "management"],
	style: {
		all: ["direct", "professional", "analytical"],
		chat: ["focused", "solution-oriented"],
		post: ["structured", "actionable"],
	},
	adjectives: ["efficient", "practical", "experienced"],
	routes: [],
};

export const stern = new BaseAgent(businessAdvisor);

Adding Routes

Routes define how an agent handles different types of interactions. Each route has a name, description, and handler function.

// Basic conversation route
stern.addRoute({
	name: "conversation",
	description: "Handle natural conversation about business topics",
	handler: async (context, req, res) => {
		const response = await llmUtils.getTextFromLLM(
			context,
			"anthropic/claude-3-sonnet"
		);
		await res.send(response);
	},
});

// Specialized business analysis route
stern.addRoute({
	name: "analyze_metrics",
	description: "Analyze business metrics and provide recommendations",
	handler: async (context, req, res) => {
		const analysis = await llmUtils.getObjectFromLLM(
			context,
			analysisSchema,
			LLMSize.LARGE
		);
		await res.send(analysis);
	},
});

System Prompt

The system prompt defines the core behavior and role of the agent. It's accessed through getSystemPrompt():

// Get the agent's system prompt
const systemPrompt = agent.getSystemPrompt();

// Example system prompt structure
const systemPrompt = `You are ${character.name}, ${character.system}

Key Characteristics:
${character.adjectives.join(", ")}

Style Guidelines:
- All interactions: ${character.style.all.join(", ")}
- Chat responses: ${character.style.chat.join(", ")}
- Public posts: ${character.style.post.join(", ")}

Areas of Focus:
${character.topics.join(", ")}`;

Agent Context

The agent context combines various elements of the character definition to provide rich context for LLM interactions:

// Get the full agent context
const context = agent.getAgentContext();

// Context structure
<SYSTEM_PROMPT>
[System prompt as shown above]
</SYSTEM_PROMPT>

<BIO_CONTEXT>
[Random selection from bio array]
</BIO_CONTEXT>

<LORE_CONTEXT>
[Random selection from lore array]
</LORE_CONTEXT>

<MESSAGE_EXAMPLES>
[Selected conversation examples]
</MESSAGE_EXAMPLES>

<POST_EXAMPLES>
[Selected post examples]
</POST_EXAMPLES>

<STYLE_GUIDELINES>
[Style preferences for different interaction types]
</STYLE_GUIDELINES>

Best Practices

Character Definition

  • Keep system prompts focused and specific

  • Provide diverse conversation examples

  • Use consistent style guidelines

  • Include realistic background details

Route Design

  • Create specialized routes for specific tasks

  • Use clear, descriptive route names

  • Handle errors gracefully

  • Consider response formats

Next: Memory System →

Last updated