Best Practices for Prompt Engineering and Agent Configuration in LMForge
LMForge structures every agent as three configurable layers—system prompt, preset prompt, and contextual prompt—while enforcing strict validation on token limits, iteration counts, and tool whitelisting to ensure deterministic, safe AI behavior.
Effective prompt engineering and agent configuration in LMForge require understanding how the platform separates static instructions from dynamic context. The repository haohao-end/lmforge-end-to-end-llmops-platform-for-multi-model-agents implements this architecture in api/internal/core/agent/entities/agent_entity.py, allowing developers to tune global behavior, application personality, and conversation history independently. Mastering these layers ensures your agents remain within token budgets while maximizing tool-use accuracy.
Understanding the Three-Layer Prompt Architecture
LMForge agents combine three distinct prompt layers that are merged at runtime. This separation allows you to update application personality without touching system logic, or adjust memory settings without rewriting prompts.
System Prompt Layer
The system prompt defines global behavior, tool-use policies, and response formats. In agent_entity.py (lines 10-38), LMForge provides two base templates: AGENT_SYSTEM_PROMPT_TEMPLATE for standard agents and REACT_AGENT_SYSTEM_PROMPT_TEMPLATE for ReACT-style tool use. These templates contain explicit placeholders such as {preset_prompt}, {long_term_memory}, and {tool_description} that the platform injects at runtime.
Preset Prompt Layer
The preset prompt stores customer-specific instructions that define an application's "personality." Stored in the App config via app_service.py (lines 97-106), this field is validated to ensure it does not exceed 2000 characters (lines 795-796). Keeping preset prompts concise prevents token-budget overflow while allowing product teams to customize tone and domain focus without engineering changes.
Contextual Prompt Layer
The contextual prompt comprises short-term conversation history, long-term memory summaries, and retrieved knowledge. The TokenBufferMemory.get_history_prompt_messages method in token_buffer_memory.py (lines 24-63) handles token-aware trimming, ensuring the LLM receives only the most recent relevant dialogue while staying within the model's context window.
Prompt Engineering Best Practices for LMForge Agents
Following these ten practices ensures your agents operate reliably within LMForge's guardrails.
-
Use a clear system-prompt template. Keep language concise, enumerate rules explicitly, and include placeholders for
{preset_prompt}and{long_term_memory}. This guarantees the LLM receives a deterministic frame each turn. -
Validate preset-prompt length. Enforce the 2000-character maximum in
app_service.pyto prevent token-budget overflow and maintain model performance. -
Trim historic messages by token count. Configure
TokenBufferMemorywith amax_token_limit(default 2000) to ensure the LLM sees only recent, relevant dialogue. -
Inject long-term memory conditionally. Enable this only via
AgentConfig.enable_long_term_memoryto avoid unnecessary prompt bloat for stateless agents. -
Leverage tool-call features. Pass
ModelFeature.TOOL_CALLandModelFeature.AGENT_THOUGHTwhen constructing the LLM instance to enable JSON-structured tool execution. -
Separate optimization from generation. Use
AIService.optimize_promptwith its dedicatedOPTIMIZE_PROMPT_TEMPLATE(defined inai_entity.py) to polish user prompts without affecting the main agent flow. -
Define tools declaratively. Populate
AgentConfig.toolswithBaseToolsubclasses to ensure only whitelisted tools are reachable during a session. -
Set a safe max-iteration count. Configure
AgentConfig.max_iteration_count(default 5) to prevent runaway loops during tool-call chains. -
Version-control all templates. Keep prompt templates as constants in source files (e.g.,
agent_entity.py) rather than database records to ensure reproducibility and auditability.
Configuring Agent Runtime Parameters
The AgentConfig class in agent_entity.py (lines 91-108) serves as the central configuration object. Instantiate it with validated parameters to ensure safe execution.
from uuid import UUID
from langchain_core.tools import BaseTool
from internal.core.agent.entities.agent_entity import AgentConfig, AGENT_SYSTEM_PROMPT_TEMPLATE
# 1️⃣ Identify the user & source
user_id: UUID = ... # from authentication
invoke_source = "WEB_APP" # or other enum value
# 2️⃣ Prepare a concise preset prompt (<2k chars)
preset = """You are a travel‑assistant that only recommends eco‑friendly destinations. \
Only reply in English and list up to three options with short (≤50 words) descriptions."""
# 3️⃣ Choose enabled features
enable_memory = True # long‑term memory flag
tools: list[BaseTool] = [...] # e.g. dataset_retrieval, google_search
# 4️⃣ Build the AgentConfig
config = AgentConfig(
user_id=user_id,
invoke_from=invoke_source,
max_iteration_count=5,
system_prompt=AGENT_SYSTEM_PROMPT_TEMPLATE, # default system frame
preset_prompt=preset,
enable_long_term_memory=enable_memory,
tools=tools,
review_config={"review_required": False},
)
All fields are validated by Pydantic; the platform automatically inserts preset_prompt into the system template before the LLM call.
Implementing Tool-Call Agents
For agents requiring tool use, LMForge provides ReactAgent in react_agent.py. This class automatically injects ModelFeature.TOOL_CALL and uses REACT_AGENT_SYSTEM_PROMPT_TEMPLATE to instruct the model on JSON tool-call formatting.
from internal.core.agent.agents.react_agent import ReactAgent
from internal.core.agent.entities.agent_entity import AgentConfig
from internal.core.tools.builtin_tools.providers.google_search import GoogleSearchTool
# 1️⃣ Define tools
search_tool = GoogleSearchTool() # implements BaseTool, safe‑sandboxed wrapper
# 2️⃣ Build config
cfg = AgentConfig(
user_id=current_user.id,
invoke_from="WEB_APP",
preset_prompt="You are a finance‑assistant focused on personal budgeting.",
tools=[search_tool],
enable_long_term_memory=False,
)
# 3️⃣ Instantiate the agent
agent = ReactAgent(cfg, db=db, conversation=conv)
# 4️⃣ Run a single step (the platform loops internally)
output = agent.run_step(user_input="How can I save on groceries this month?")
print(output)
The ReactAgent automatically handles the ReACT loop, parsing JSON tool calls and executing them against the whitelisted tools defined in AgentConfig.tools.
Summary
- Separate prompt concerns into system, preset, and contextual layers to enable independent updates without breaking agent workflows.
- Enforce length limits on preset prompts (2000 characters) and conversation history (token-based trimming via
TokenBufferMemory) to prevent context window overflow. - Configure runtime safety via
AgentConfigparameters includingmax_iteration_count(default 5) and explicit tool whitelisting. - Leverage built-in optimization through
AIService.optimize_promptfor polishing user prompts without affecting production agent flows. - Version-control templates by keeping system prompts as code constants in
agent_entity.pyrather than database records.
Frequently Asked Questions
What is the maximum length for preset prompts in LMForge?
LMForge enforces a 2000-character limit on preset prompts. This validation occurs in app_service.py (lines 795-796) during app configuration. Exceeding this limit raises a validation error to prevent token-budget overflow and ensure the combined system and preset prompts fit within the model's context window.
How does LMForge prevent token overflow in conversation history?
The platform uses TokenBufferMemory.get_history_prompt_messages in token_buffer_memory.py (lines 24-63) to trim historic messages. This method calculates token counts for each message and removes oldest entries once the max_token_limit (default 2000) is reached. This ensures the LLM receives only the most recent, relevant dialogue while staying within context limits.
What is the default maximum iteration count for agents?
LMForge sets a default max_iteration_count of 5 in AgentConfig (agent_entity.py, lines 91-108). This safety bound prevents runaway loops when agents repeatedly invoke tools or self-refine. When this limit is reached, the platform returns MAX_ITERATION_RESPONSE to signal the front-end that the agent has stopped to prevent infinite recursion.
How do I enable long-term memory for an agent?
Enable long-term memory by setting enable_long_term_memory=True in AgentConfig. When enabled, the platform injects memory content into the {long_term_memory} placeholder in the system prompt template. This feature should only be activated for agents requiring stateful context, as it increases prompt size. Stateless agents should leave this disabled to minimize token consumption.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →