luci-memory
Setup
Requires an MEMORIES_AI_KEY. On first use, if no key is found, the script will error and ask for one.
When the user provides their key, save it to {baseDir}/.env:
CODEBLOCK0
After that, everything just works — the key is loaded automatically from .env on every run.
Timezone
All timestamps in Luci-memory are stored and returned in UTC. Skill output labels them with " UTC" so this is unambiguous. The user's local timezone is in USER.md (e.g. Asia/Shanghai). You are responsible for converting in both directions:
- 1. Reading results. When presenting
captured_time to the user, convert from UTC to the user's local timezone. Never show raw UTC labels to the user.
- 2. Writing filters.
--after and --before are interpreted as UTC. If the user says relative dates like "yesterday" or "this morning", convert their local-time intent to a UTC range before passing the dates.
Example (user in Asia/Shanghai, UTC+8, asks "what did I do yesterday" on 2026-04-08):
- - Local intent: 2026-04-07 00:00 → 2026-04-08 00:00 (Asia/Shanghai)
- UTC range to pass: INLINECODE9
If USER.md has no timezone and the user uses relative dates, ask them first.
Unified search across personal media and portrait data from the Luci-memory API.
The user's videos go through two processing pipelines that produce different data:
- - Media content (personal): video summaries, audio transcripts, visual transcripts, keyframes, images
- People & knowledge (portrait): traits, events with participants, relationships, speeches attributed to speakers
When to use
- - User asks to find or search videos, images, or photos
- User asks what was said or shown in a video
- User asks to list recent videos or images
- User asks about media at a specific location or time
- User asks about traits, personality, hobbies, interests
- User asks what events happened, or events involving specific people
- User asks about relationships between people
- User asks about what someone said
- User mentions "luci memory" or wants to use their video memory
Choosing the right type
- - About content (what happened, what was said/shown, find media) → use media types (
search_video, query_audio, etc.) - About people (who, traits, relationships, named individuals) → use portrait types (
traits, events, speeches, etc.) - Ambiguous questions like "What happened with Alice last week?" → use both: portrait types to identify the person and events, media types to get detailed video content and transcripts.
- Person name fallback: Portrait data only exists for people who have appeared in at least 5 videos AND been named by the user in the app. If a portrait query by person name returns no results, fall back to media types — search video summaries, audio transcripts, or visual transcripts for mentions of that name instead.
Relevance guidelines
- - There is no rerank process — retrieved results may contain items irrelevant to the user's actual intent.
- Always verify relevance: after receiving results, check each item against the user's original query. Only present results that are relevant. Discard anything that doesn't match.
- Refine and retry: if results seem off or too broad, retry with a more specific query, narrower date range, or additional filters. Do not just dump low-quality results to the user.
- Ask the user: if the query is ambiguous or too vague to produce good results, ask the user for more specific conditions before searching. It is better to clarify than to return noise. Do this no more than 1 time.
No hallucination — ground every claim in retrieved data
- - Never fabricate what the user did, said, or experienced. Every detail in your answer must come from actual search results.
- Multi-step retrieval: for questions like "what did I do and say at XXX", do NOT answer from a single broad search. Follow this pattern:
1.
Locate: search broadly (search
video, searchevents) to find relevant video
ids or eventids.
2.
Retrieve: once you have IDs, prefer
queryaudio / queryvisual with
--video-ids to get complete transcripts. You can also use
searchaudio / searchvisual scoped to those video IDs to find specific moments — use both flexibly as needed.
- - Do not stuff keywords into search queries. Each semantic search query should be a short, coherent natural-language query, rather than stacking multiple possible words. You are encouraged to try different ones and query various times though.
- If data is missing, say so. Do not fill gaps with plausible-sounding guesses. "I couldn't find transcript data for that video" is always better than making something up.
How to invoke
Note: --after / --before are UTC. Convert from the user's local timezone first (see Timezone section above).
CODEBLOCK1
Parameters
| Flag | Short | Description |
|---|
| INLINECODE19 | INLINECODE20 | Search term (required for search_* types) |
| INLINECODE22 |
-t | Operation type (default:
search_video) |
|
--top-k |
-k | Max results (default: 10) |
|
--location |
-l | Filter by location name, geocoded via Google Maps (e.g. "Suzhou") |
|
--after | | Only results after this date (
YYYY-MM-DD or
YYYY-MM-DDTHH:MM:SS) |
|
--before | | Only results before this date |
|
--video-ids | | Comma-separated video IDs (media types) |
|
--person |
-p | Filter by person name(s), comma-separated (portrait types). Use
user for self. |
|
--event-ids | | Comma-separated event IDs (portrait types) |
Signed URLs
Image and keyframe results include a signed_url field — a temporary (1-hour) direct link to view/download from Google Cloud Storage. No authentication needed, but they expire after 1 hour.
Types reference
Media search types (require --query)
| Type | What it searches | Supports |
|---|
| INLINECODE40 | Video summaries by meaning | INLINECODE41 , INLINECODE42 |
| INLINECODE43 |
Image descriptions by meaning |
--location,
--after/before |
|
search_audio | Audio transcripts by meaning |
--video-ids,
--after/before |
|
search_visual | Visual transcripts by meaning |
--video-ids,
--after/before |
|
search_keyframe | Keyframe images by meaning |
--video-ids,
--after/before |
Media query types (list/filter)
| Type | What it returns | Requires | Supports |
|---|
| INLINECODE55 | Recent videos | — | INLINECODE56 , INLINECODE57 |
| INLINECODE58 |
Recent images | — |
--location,
--after/before |
|
query_audio | Audio transcripts for videos |
--video-ids |
--after/before |
|
query_visual | Visual transcripts for videos |
--video-ids |
--after/before |
|
query_keyframe | Keyframes for videos |
--video-ids |
--after/before |
Portrait query types (list/filter)
| Type | What it returns | Supports |
|---|
| INLINECODE70 | Personality traits, hobbies, interests | INLINECODE71 |
| INLINECODE72 |
Events with participants |
--person,
--after/before,
--event-ids |
|
relationships | How user relates to people |
--person |
|
speeches | What people said |
--person,
--event-ids |
Portrait search types (semantic, require --query)
| Type | What it searches | Supports |
|---|
| INLINECODE82 | Events by meaning | INLINECODE83 , INLINECODE84 |
| INLINECODE85 |
Traits by meaning | — |
luci-memory
设置
需要MEMORIESAIKEY。首次使用时,如果未找到密钥,脚本将报错并要求提供密钥。
当用户提供密钥后,将其保存到{baseDir}/.env文件中:
MEMORIESAIKEY=sk-their-key-here
之后一切正常运作——每次运行时密钥都会自动从.env文件加载。
时区
Luci-memory中的所有时间戳均以UTC格式存储和返回。 技能输出会标注 UTC以确保明确无误。用户的本地时区记录在USER.md文件中(例如Asia/Shanghai)。您负责双向转换:
- 1. 读取结果。 在向用户展示captured_time时,从UTC转换为用户的本地时区。切勿向用户显示原始的UTC标签。
- 2. 写入筛选条件。 --after和--before参数按UTC解释。如果用户提到相对日期如昨天或今早,在传递日期前将用户的本地时间意图转换为UTC范围。
示例(用户位于Asia/Shanghai,UTC+8,在2026-04-08询问我昨天做了什么):
- - 本地意图:2026-04-07 00:00 → 2026-04-08 00:00(Asia/Shanghai)
- 传递的UTC范围:--after 2026-04-06T16:00:00 --before 2026-04-07T16:00:00
如果USER.md中没有时区信息且用户使用了相对日期,请先询问用户。
通过Luci-memory API对个人媒体和肖像数据进行统一搜索。
用户的视频经过两条处理流水线,产生不同的数据:
- - 媒体内容(个人):视频摘要、音频转录、视觉转录、关键帧、图像
- 人物与知识(肖像):特质、包含参与者的事件、关系、归属于说话者的言论
何时使用
- - 用户要求查找或搜索视频、图像或照片
- 用户询问视频中说了什么或展示了什么
- 用户要求列出最近的视频或图像
- 用户询问特定地点或时间的媒体
- 用户询问特质、个性、爱好、兴趣
- 用户询问发生了什么事件,或涉及特定人物的事件
- 用户询问人物之间的关系
- 用户询问某人说了什么
- 用户提到luci memory或想使用他们的视频记忆
选择正确的类型
- - 关于内容(发生了什么、说了/展示了什么、查找媒体)→ 使用媒体类型(searchvideo、queryaudio等)
- 关于人物(谁、特质、关系、具名个体)→ 使用肖像类型(traits、events、speeches等)
- 模糊问题如上周Alice发生了什么?→ 同时使用两者:肖像类型用于识别人员和事件,媒体类型用于获取详细的视频内容和转录。
- 人名回退: 肖像数据仅存在于至少在5个视频中出现过且在应用中由用户命名的人员。如果按人名查询肖像未返回结果,则回退到媒体类型——搜索视频摘要、音频转录或视觉转录中对该名字的提及。
相关性指南
- - 没有重排序过程——检索结果可能包含与用户实际意图无关的项目。
- 始终验证相关性: 收到结果后,对照用户的原始查询检查每个项目。仅呈现相关的结果。丢弃任何不匹配的内容。
- 优化并重试: 如果结果看起来不准确或过于宽泛,使用更具体的查询、更窄的日期范围或额外筛选条件重试。不要直接将低质量结果抛给用户。
- 询问用户: 如果查询模糊或过于笼统而无法产生良好结果,在搜索前询问用户更具体的条件。澄清优于返回噪音。此操作不超过1次。
禁止幻觉——每项声明都必须基于检索数据
- - 切勿编造用户做过、说过或经历过的事情。回答中的每个细节必须来自实际的搜索结果。
- 多步检索: 对于我在XXX做了什么和说了什么这类问题,不要通过一次宽泛搜索来回答。遵循以下模式:
1.
定位: 宽泛搜索(search
video、searchevents)以找到相关的video
id或eventid。
2.
检索: 一旦获得ID,优先使用带--video-ids参数的
queryaudio / queryvisual获取完整转录。也可以使用限定在这些视频ID范围内的
searchaudio / searchvisual来查找特定时刻——根据需要灵活使用两者。
- - 不要将关键词塞入搜索查询。 每个语义搜索查询应是一个简短、连贯的自然语言查询,而不是堆叠多个可能的词语。不过鼓励尝试不同的查询并多次查询。
- 如果数据缺失,请如实说明。 不要用听起来合理的猜测填补空白。我找不到该视频的转录数据总是比编造内容要好。
如何调用
注意:--after / --before 为UTC时间。请先转换用户的本地时区(参见上方时区部分)。
bash
============ 媒体内容(个人) ============
--- 视频 ---
bash {baseDir}/run.sh --query 在厨房做饭 --type search_video
bash {baseDir}/run.sh --query 我做了什么 --type search_video --location 菏泽
bash {baseDir}/run.sh --query 会议 --type search_video --after 2025-12-01 --before 2026-01-01
bash {baseDir}/run.sh --type query_video
bash {baseDir}/run.sh --type query_video --location 苏州 --after 2025-12-01
--- 图像 ---
bash {baseDir}/run.sh --query 日落 --type search_image
bash {baseDir}/run.sh --query 食物 --type search_image --location 北京
bash {baseDir}/run.sh --type query_image
--- 音频转录(说了什么) ---
bash {baseDir}/run.sh --query 谈论工作 --type search_audio
bash {baseDir}/run.sh --query 预算 --type search_audio --video-ids VI123,VI456
bash {baseDir}/run.sh --type query_audio --video-ids VI123,VI456
--- 视觉转录(展示了什么) ---
bash {baseDir}/run.sh --query 在公园散步 --type search_visual
bash {baseDir}/run.sh --type query_visual --video-ids VI123,VI456
--- 关键帧 ---
bash {baseDir}/run.sh --query 挥手的人 --type search_keyframe
bash {baseDir}/run.sh --type query_keyframe --video-ids VI123,VI456
============ 人物与知识(肖像) ============
--- 特质 ---
bash {baseDir}/run.sh --type traits
bash {baseDir}/run.sh --type traits --person Alice
bash {baseDir}/run.sh --query 户外活动 --type search_traits
--- 事件 ---
bash {baseDir}/run.sh --type events
bash {baseDir}/run.sh --type events --person Alice
bash {baseDir}/run.sh --type events --person Alice,Bob
bash {baseDir}/run.sh --type events --after 2025-12-01 --before 2026-01-01
bash {baseDir}/run.sh --query 在厨房做饭 --type search_events
bash {baseDir}/run.sh --query 会议 --type search_events --person Bob --after 2025-12-01
--- 关系 ---
bash {baseDir}/run.sh --type relationships
bash {baseDir}/run.sh --type relationships --person Alice
--- 言论 ---
bash {baseDir}/run.sh --type speeches
bash {baseDir}/run.sh --type speeches --person Alice
bash {baseDir}/run.sh --type speeches --event-ids EVT123,EVT456
bash {baseDir}/run.sh --type speeches --person Alice --event-ids EVT123
参数
| 标志 | 缩写 | 描述 |
|---|
| --query | -q | 搜索词(search*类型必填) |
| --type |
-t | 操作类型(默认:searchvideo) |
| --top-k | -k | 最大结果数(默认:10) |
| --location | -l | 按地点名称筛选,通过Google Maps进行地理编码(例如苏州) |
| --after | | 仅返回此日期之后的结果(YYYY-MM-DD或YYYY-MM-DDTHH:MM:SS) |
| --before | | 仅返回此日期之前的结果 |
| --video-ids | | 逗号分隔的视频ID(媒体类型) |
| --person | -p |