Skip to main content
Based on a simplified mapping of human cognitive patterns and engineering considerations, OpenViking abstracts context into three basic types: Resource, Memory, and Skill, each serving different purposes in Agent applications.

Overview

Resource

External knowledge and rules
  • Long-term, static
  • User adds

Memory

Agent’s cognition
  • Long-term, dynamic
  • Agent records

Skill

Callable capabilities
  • Long-term, static
  • Agent invokes
TypePurposeLifecycleInitiative
ResourceKnowledge and rulesLong-term, relatively staticUser adds
MemoryAgent’s cognitionLong-term, dynamically updatedAgent records
SkillCallable capabilitiesLong-term, staticAgent invokes

Resource

Resources are external knowledge that Agents can reference - such as documentation, code repositories, research papers, and product manuals.

Characteristics

Resource information actively added by users to supplement LLM knowledge, such as product manuals and code repositories.
Content rarely changes after addition, usually modified by users rather than Agents.
Organized by project or topic in directory hierarchy, with multi-layer information extraction (L0/L1/L2).

Examples

  • API documentation and product manuals
  • FAQ databases and code repositories
  • Research papers and technical specifications
  • Web pages and articles

Usage

from openviking import OpenViking

client = OpenViking()

# Add resource from URL
await client.add_resource(
    "https://docs.example.com/api.pdf",
    reason="API documentation"
)

# Add resource from local file
await client.add_resource(
    "/path/to/project/",
    reason="Project codebase"
)

# Search resources only
results = await client.find(
    "authentication methods",
    target_uri="viking://resources/"
)

for ctx in results.resources:
    print(f"URI: {ctx.uri}")
    print(f"Abstract: {ctx.abstract}")

Storage Structure

viking://resources/
├── my_project/
│   ├── .abstract.md          # L0: Project summary
│   ├── .overview.md          # L1: Project overview
│   ├── docs/
│   │   ├── .abstract.md
│   │   ├── .overview.md
│   │   ├── api/
│   │   │   ├── auth.md       # L2: Full documentation
│   │   │   └── endpoints.md
│   │   └── tutorials/
│   └── src/
│       ├── .abstract.md
│       ├── .overview.md
│       └── main.py
└── another_project/

Memory

Memories are divided into user memories and Agent memories, representing learned knowledge about users and the world.

Characteristics

Memory information actively extracted and recorded by Agent from interactions.
Continuously updated from interactions by Agent, reflecting learning and adaptation.
Learned for specific users or specific Agents, creating personalized experiences.

6 Memory Categories

OpenViking extracts memories into 6 categories, each with different update strategies:
CategoryLocationDescriptionUpdate Strategy
profileuser/memories/.overview.mdUser basic info and identity✅ Appendable
preferencesuser/memories/preferences/User preferences by topic✅ Appendable
entitiesuser/memories/entities/Entity memories (people, projects)✅ Appendable
eventsuser/memories/events/Event records (decisions, milestones)❌ No update
casesagent/memories/cases/Learned cases from interactions❌ No update
patternsagent/memories/patterns/Reusable patterns and best practices❌ No update

User Memories

User basic information and identityStored in viking://user/{user_id}/.overview.mdExamples:
  • Name, role, occupation
  • Technical background
  • Communication style
Update: Appendable (can add new information)

Agent Memories

Specific problems and solutionsStored in viking://agent/{agent_id}/memories/cases/Examples:
  • How to debug a specific error
  • Solution to a particular API integration issue
  • Workaround for a known limitation
Update: Immutable (each case is independent)

Usage

# Memories are auto-extracted from sessions
session = client.session(session_id="chat_001")

await session.add_message(
    "user",
    [{"type": "text", "text": "I prefer dark mode in all UIs"}]
)

await session.add_message(
    "assistant",
    [{"type": "text", "text": "I'll remember your preference for dark mode."}]
)

# Commit extracts and stores preference memory
result = await session.commit()
print(f"Extracted {result['memories_extracted']} memories")

# Search user memories
results = await client.find(
    "UI preferences",
    target_uri="viking://user/memories/"
)

for ctx in results.memories:
    print(f"Memory: {ctx.uri}")
    print(f"Content: {ctx.abstract}")

Skill

Skills are capabilities that Agents can invoke, defined using the Claude Skills protocol format.

Characteristics

Tool definitions for completing specific tasks, with clear input/output specifications.
Skill definitions don’t change at runtime, but usage memories related to tools are updated in memory.
Agent decides when to use which skill based on task requirements.

Storage Location

viking://agent/{agent_id}/skills/{skill-name}/
├── .abstract.md          # L0: Short description
├── SKILL.md              # L1: Detailed overview
└── scripts/              # L2: Full definition and scripts

Usage

# Add skill
await client.add_skill({
    "name": "search-web",
    "description": "Search the web for information",
    "content": """# search-web

## Description
Search the web using a search engine API.

## Parameters
- query: Search query string
- max_results: Maximum number of results (default: 10)

## Returns
List of search results with title, URL, and snippet.
"""
})

# Search skills
results = await client.find(
    "web search",
    target_uri="viking://agent/skills/"
)

for ctx in results.skills:
    print(f"Skill: {ctx.uri}")
    print(f"Description: {ctx.abstract}")
    
    # Get full skill definition
    overview = await client.overview(ctx.uri)
    print(f"Full definition:\n{overview}")
OpenViking supports unified search across all three context types, providing comprehensive information based on Agent’s needs.
# Search across all context types
results = await client.find("user authentication")

print(f"Found {len(results.memories)} memories")
for ctx in results.memories:
    print(f"  Memory: {ctx.uri}")

print(f"Found {len(results.resources)} resources")
for ctx in results.resources:
    print(f"  Resource: {ctx.uri}")

print(f"Found {len(results.skills)} skills")
for ctx in results.skills:
    print(f"  Skill: {ctx.uri}")

Context Type Implementation

class ContextType(str, Enum):
    """Context type"""
    
    SKILL = "skill"
    MEMORY = "memory"
    RESOURCE = "resource"

class Context:
    def __init__(self, uri: str, ...):
        self.uri = uri
        self.context_type = context_type or self._derive_context_type()
    
    def _derive_context_type(self) -> str:
        """Derive context type from URI using substring matching."""
        if "/skills" in self.uri:
            return "skill"
        elif "/memories" in self.uri:
            return "memory"
        else:
            return "resource"

Architecture

System architecture and data flow

Context Layers

L0/L1/L2 progressive loading model

Viking URI

URI specification and structure

Session Management

Memory extraction mechanism