How Anchor-Based Landing Ensures Precise Injection into System Prompts

Anchor-based landing resolves semantic slots against an AgentProfile to rebuild system messages at exact structural locations, falling back to point-based injection when anchors cannot be resolved.

The Memory Proxy component in TencentCloud/TencentDB-Agent-Memory manages the dynamic assembly of LLM system prompts by injecting skills, Wiki pages, and custom tools. Through anchor-based landing, the system achieves surgical precision in content placement, ensuring that injected blocks land exactly where the agent’s prompt structure expects them—such as inside a specific "Memory" or "Skills" section.

The Architecture of Anchor-Based Injection

The injection pipeline in MemoryProxy/src/injection/pipeline.ts implements a two-step resolution process that bridges portable semantic tags with concrete prompt structures.

Defining Anchor Targets

Each InjectionHook may declare an optional anchor property that specifies exactly where content should land. The AnchorTarget interface, defined in MemoryProxy/src/injection/types.ts, supports both portable semantic slots and concrete structural keys:

export interface AnchorTarget {
  slot?: SemanticSlot;      // portable tag such as "memory", "skills", …
  rawKey?: string;          // concrete heading/key used as an escape hatch
  relation: AnchorRelation; // before / after / inside_prepend / inside_append
}

This dual-key design allows developers to reference abstract content categories (like "skills") that resolve differently per agent, or pin injections to literal headings (like "## Memory") when portability is not required.

The Resolution Pipeline

When applyInjection processes a hook, it first attempts to resolve the anchor against the current request’s AgentProfile. According to the source code at lines 56–58 in MemoryProxy/src/injection/pipeline.ts:

const key = hook.anchor.rawKey
  ?? (hook.anchor.slot ? profile.resolveSlot(hook.anchor.slot) : null);

The profile.resolveSlot method translates portable semantic tags into agent-specific headings. For example, the slot "skills" might resolve to "## Skills" for one agent profile but "### Tooling" for another, enabling the same injector to work across diverse agent configurations.

Segment Validation and Prompt Reconstruction

Once the target key is resolved, the pipeline validates existence within the current system message and performs surgical insertion.

Parsing and Matching Segments

The current system text is parsed into discrete segments using profile.parse(currentText). The pipeline checks whether any segment’s key matches the resolved anchor key. If found, the injection proceeds using the specified AnchorRelation (before, after, inside_prepend, or inside_append).

As implemented in applyInjection at lines 60–68:

const newSegments = profile.applyAnchor(
  segments,
  { key, relation: hook.anchor.relation },
  text,
);
sysMsg.blocks = [{ type: "text", content: profile.rebuild(newSegments) }];

The profile.applyAnchor method inserts the new content at the specified relation, and profile.rebuild reconstructs the system prompt with the injected block preserving all surrounding context and formatting.

Fallback Strategy for Missing Anchors

When anchor resolution fails—due to missing profiles, undefined slots, or absent raw keys—the system degrades gracefully to maintain functionality.

Point-Based Fallback

If the anchor cannot be resolved, the pipeline emits a diagnostic warning and delegates to applyByPoint, which inserts the block at coarse-grained locations such as system.prefix, system.suffix, or system.before_tools. From lines 71–76 in MemoryProxy/src/injection/pipeline.ts:

console.warn(`[injection] anchor slot "${hook.anchor.slot ?? hook.anchor.rawKey}" unresolved …`);
this.applyByPoint(ctx, point, blocks);

This fallback mechanism ensures that injectors remain functional across agents that may not implement the expected profile structure, preserving backward compatibility while encouraging migration to structured profiles.

Practical Implementation Examples

Example 1: Semantic Slot Injection

The following hook uses a portable slot to inject skill documentation before the skills section:

export const skillInjector: InjectionHook = {
  id: "skill-injector",
  point: "system.suffix",          // fallback point
  anchor: { slot: "skills", relation: "before" },
  priority: HOOK_PRIORITY.SKILL,
  description: "Inject custom skill blocks",
  async execute(ctx) {
    return [{ type: "text", content: "## CustomSkill\nUse this whenever …" }];

  },
};

hookRegistry.register(skillInjector);

When the request matches an agent profile containing a "## Skills" heading (or whatever the profile maps the "skills" slot to), the injection appears immediately before that section. If the profile lacks the heading, the block appends to the system prompt suffix.

Example 2: Raw Key Targeting

For non-portable, exact placement requirements, use rawKey to bypass slot resolution:

const rawKeyInjector: InjectionHook = {
  id: "rawkey-injector",
  point: "system.suffix",
  anchor: { rawKey: "## Memory", relation: "inside_append" },

  priority: HOOK_PRIORITY.MEMORY,
  description: "Append extra memory description",
  async execute() {
    return [{ type: "text", content: "Additional context for the Memory section." }];
  },
};

Here rawKey pins the injection to the literal heading "## Memory", appending content inside that section regardless of the agent’s profile slot mappings.

Summary

  • Anchor-based landing uses AnchorTarget declarations to specify exact insertion points within system prompts via semantic slots or raw keys.
  • The resolution pipeline in applyInjection translates portable slots to concrete headings using profile.resolveSlot, then validates and inserts content using profile.applyAnchor.
  • The system rebuilds the complete prompt with profile.rebuild after injection, preserving surrounding context and formatting integrity.
  • When anchors cannot be resolved, the pipeline falls back to point-based injection at system.prefix, system.suffix, or system.before_tools to maintain compatibility.
  • Concrete implementations can be found in MemoryProxy/src/injection/injectors/skill-injector.ts and tdai-profile-memory-injector.ts on the feat/server_team branch.

Frequently Asked Questions

What is the difference between anchor-based and point-based injection in TencentDB-Agent-Memory?

Anchor-based injection targets specific structural locations within the system prompt (like sections or headings) using semantic slots or raw keys, while point-based injection operates at coarse-grained positions such as system.prefix or system.suffix without knowledge of the prompt’s internal structure. Anchor-based landing provides precise control but requires an AgentProfile to resolve slot mappings.

How does the system handle missing anchors or unresolved slots?

When an anchor cannot be resolved—either because the profile is missing, the slot is undefined, or the rawKey is absent—the pipeline logs a warning and automatically falls back to point-based injection using the hook’s declared point property. This ensures that content is still injected into the system prompt even when precise placement is impossible.

What anchor relations are supported for positioning injected content?

The AnchorRelation type supports four positioning strategies: before (insert immediately before the target segment), after (insert immediately after), inside_prepend (insert at the beginning of the target section), and inside_append (insert at the end of the target section). These relations are defined in MemoryProxy/src/injection/types.ts.

Where is the core injection logic implemented in the repository?

The core injection orchestration resides in MemoryProxy/src/injection/pipeline.ts, specifically within the applyInjection method (lines 56–76 on the feat/server_team branch). Type definitions including AnchorTarget, AnchorRelation, and InjectionHook are located in MemoryProxy/src/injection/types.ts.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →