Skip to content

Memory extraction is unreliable with local Ollama models (non-dict parser output / empty extract results) #605

@a1461750564

Description

@a1461750564

Summary

When using OpenViking with local Ollama models, the memory pipeline is not reliably usable out of the box:

  1. session -> extract may fail internally because the LLM response parser assumes a dict-like payload.
  2. Even when the server stays up, extraction can return [], so memory write/search is not actually usable without a fallback path.

In my environment, I had to patch the extractor to tolerate list-shaped payloads and add a fallback resource-based memory capture path on the OpenClaw side to make the system practically usable.

Environment

  • Host: macOS (Apple Silicon)
  • OpenViking: latest pip package as of 2026-03-15
  • Runtime: openviking-server --config ~/.openviking/ov.conf
  • Embedding model via Ollama OpenAI-compatible API: bge-m3:latest
  • Chat/VLM model via Ollama OpenAI-compatible API: llama3.1:latest
  • OpenClaw plugin integration on top, but the core issue reproduces at the OpenViking server / extractor layer

Config used

{
  "storage": {
    "workspace": "~/.openviking/workspace"
  },
  "embedding": {
    "dense": {
      "provider": "openai",
      "api_base": "http://127.0.0.1:11434/v1",
      "api_key": "ollama-local",
      "dimension": 1024,
      "model": "bge-m3:latest"
    }
  },
  "vlm": {
    "provider": "openai",
    "api_base": "http://127.0.0.1:11434/v1",
    "api_key": "ollama-local",
    "model": "llama3.1:latest"
  },
  "log": {
    "level": "INFO",
    "output": "stdout"
  }
}

Reproduction

  1. Start server:
openviking-server --config ~/.openviking/ov.conf
  1. Create a session:
curl -X POST http://127.0.0.1:1933/api/v1/sessions
  1. Add a user message:
curl -X POST http://127.0.0.1:1933/api/v1/sessions/<session_id>/messages \
  -H 'Content-Type: application/json' \
  -d '{"role":"user","content":"用户偏好:回答要专业、简洁、高执行力,少废话。"}'
  1. Extract:
curl -X POST http://127.0.0.1:1933/api/v1/sessions/<session_id>/extract \
  -H 'Content-Type: application/json' \
  -d '{}'

Actual behavior

Observed one or both of the following:

A. Internal parser failure

Server log included errors like:

Memory extraction failed: 'list' object has no attribute 'get'

and later also:

Memory extraction failed: 'str' object has no attribute 'get'

This suggests the extractor path assumes parse_json_from_response(...) always returns a dict with a memories key, but local-model outputs may parse into a list or other JSON shapes.

B. Extract succeeds but returns empty result

The HTTP API returns 200, but with:

{"status":"ok","result":[]}

and then semantic search over viking://user/memories returns no memories.

So from an operator perspective, the pipeline looks healthy but memory extraction is not practically working.

Expected behavior

  • Extractor should robustly accept common structured-output variants from local models (at minimum dict/list normalization, plus safe rejection of malformed scalars).
  • If extraction produces no valid memory candidates, there should be clearer diagnostics and ideally an official fallback or degraded-mode path.
  • It would help if the docs explicitly stated which local models / output formats are currently reliable for memory extraction.

Local patch that improved behavior

A minimal local change that fixed one of the crashes was normalizing list output before iterating memories:

data = parse_json_from_response(response) or {}
if isinstance(data, list):
    data = {"memories": data}
elif not isinstance(data, dict):
    logger.error("Memory extraction parse failed: non-dict payload: %r", data)
    data = {}

This avoided at least the 'list' object has no attribute 'get' crash.

Why this matters

For local/self-hosted users, the main value proposition is exactly this setup: Ollama + OpenViking + local agent memory. Right now, the server can appear healthy while the memory extraction path is effectively unusable unless the operator patches around it.

If useful, I can also provide the fallback resource-memory workaround I implemented on the client side, but I think the main upstream issue is the extractor robustness and the lack of clear degraded-mode behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions