vectorize-io

Activity

Stars and mentions · Last 30 days, Oct 6 – Nov 4

GitHub stars9,579
Mentions66
02625247861KOct 6Oct 20Nov 4
UTC days · repositories vectorize-io owns6 repositories

Top repositories

vectorize-io’s repositories ranked by pull request authors, as on trending.

Loading

Contributes to

Repositories outside vectorize-io’s account where vectorize-io opened or reviewed pull requests in the past 365 days.

Who noticed vectorize-io

Everyone who starred or forked vectorize-io’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

63posts
Nov 52 posts
  1. Your On-Call Agent Needs Hindsight, Not a Bigger Model Description: An on-call SRE agent is only as good as the incidents it can recall. Structured retention, evidence-backed ranking, and a contradiction guard built on Hindsight. It is 02:14. Checkout p99 has gone from 400 ms to 3.9 seconds, the payment provider is retrying, and an alert is burning through the error budget. The engineer who fixed this exact failure six weeks ago is asleep. The migration that solved it was applied by hand and never written down. So the person on call searches, guesses, and restarts the pods. The restart works for forty minutes. I kept coming back to that gap. The model is not the bottleneck. A good model has read every runbook and every public postmortem. What it does not have is your history: this failure, on this service, with these signals, fixed in six minutes by a specific person, and whether the fix held. I built Déjà Vu to test that claim seriously — an on-call SRE agent whose entire value comes from remembering incidents, and whose memory layer is Hindsight. What the system actually does Déjà Vu watches an alert queue. When one fires, it builds a query from the service, title, body and signal fingerprint, recalls candidates from a Hindsight bank called dejavu-oncall, re-ranks them, and answers with evidence. One bank per team: your incidents only, never another team's. The answer is not a paragraph. It is a hypothesis plus receipts: - INC-1006 — missing composite index on orders(created_at, status) — 6 minutes — Priya Raman — resolved - INC-1001 — same cause class — resolved - INC-1002 — same class — resolved Same alert, memory off: "generic triage, restart the affected pods", 31% confidence, no incident, no owner, no fix time. Memory on: the index migration, 97% confidence, the receipts, a named engineer. The second answer is not smarter. It is informed. Making memory the actual product The naive version of this is a vector store full of postmortems with a prompt that says "use the context below." It demos well and fails quietly, for three reasons. It retrieves paragraphs, not incidents — so nothing is auditable. It treats similarity as identity — so a look-alike incident with a different cause gets recommended with full confidence. And it never learns from what happened after the fix. So the memory is structured, not chunked. One document per incident, with metadata that survives retrieval: resp = client().retain( bank_id="dejavu-oncall", content=text, # symptom, signals, cause, fix, time, outcome document_id=incident_id, context=f"{inc.get('service')} {inc.get('severity')} incident on {ts[:10]}", metadata={ "incident_id": incident_id, "service": inc.get("service"), "root_cause": inc.get("root_cause"), "fix": inc.get("fix"), "outcome": inc.get("outcome"), "fix_minutes": str(inc.get("fix_minutes")), "engineer": inc.get("engineer"), "severity": inc.get("severity"), }, tags=[inc["service"], inc["severity"], inc["outcome"]], ) That metadata is the difference between a receipt and a rumour. When the agent says "six minutes, Priya Raman, resolved," those values came from memory, not the model's imagination. Recall is deliberate: the alert's fingerprint becomes the query, Hindsight returns candidates by meaning, and the application re-ranks them — retrieval similarity and operational similarity are not the same thing: similarity = 0.50 * signal_similarity + 0.45 * text_similarity + 0.05 * coverage score = 0.82 * similarity score += 0.10 * min(1.0, support / 3) # how many incidents back this cause score += 0.08 * success_rate # did the fix actually hold score += 0.02 * recency # recent precedent wins ties if stale: score -= 0.06 # flag it, do not trust it Fifty percent of the decision is the signal fingerprint — the numbers, not the prose. p99_ms 3900 against 3800. pool_wait_ms 1240 against 1180. cert_age_days 2 against 61. That last one is why a certificate incident gets ruled out even when the text looks identical. The part that matters: the contradiction guard Two incidents can share every word and need opposite fixes. Incident INC-1009 has the same service, the same pool timeout, the same graph shape, and 53% similarity to the live alert. But its cause was a pool size capped during a config rollout, and its fix was a config change plus a redeploy — not an index. Before committing, Déjà Vu checks the runner-up failure class. If a different cause is close, it surfaces the look-alike explicitly: the incident ID, the similarity, the one signal that separates them, and the different fix it required. This is the failure mode of every naive retrieval system. A text search returns the nearest paragraph. The agent has to tell you what it ruled out, and why. Measurement, not a claim Every memory product says it improves. Almost none measure it, because honest measurement is uncomfortable. The repo includes a replay that walks the incident corpus in chronological order. At each incident, the agent may only use memories that existed before that timestamp. No peeking. No LLM in the grading loop. Across 22 graded incidents: 50% top-1, 64% top-3. First six graded alerts: 33%. Last six: 83%. That pair is the thesis. The agent is measurably better at the end of the quarter than at the start, because it lived through the quarter. The Learning screen plots every graded incident, including the ones it got wrong. A memory system that only shows its wins is a marketing surface. The loop has to close Resolving an alert is not the end of the interaction. It is the write. When an engineer resolves an incident, Déjà Vu stores a postmortem, retains it with source: live, and marks the alert closed. Fire the same fingerprint again and the first receipt is the incident that was just created, answered in milliseconds. That closed loop is also where a second agent earns its place. In the Band room, DejaVu-Recall posts the hypothesis and receipts, then DejaVu-Critic answers the recall — not the alert — with four deterministic checks: at least two receipts, no stale precedent, precedent fixes that held, confidence above threshold. It can block the fix from ever reaching a human. I wrote the critic as code, not a model call: a reviewer should check evidence, not generate more of it. What I got wrong Three things, in order of embarrassment. First, I scoped recall to the same service. That hid the lesson: a missing index on payments-api is the same failure as one on checkout-api. Cross-service transfer drove most of the late-corpus accuracy. Second, I graded at string level before switching to failure classes. "Missing index on orders" and "missing index on settlement_date" are different strings and the same lesson. String-level grading made the agent look worse than it was. Third, I trusted retrieval scores for too long. The signal fingerprint is weighted above text on purpose now. The text is how you find candidates; the numbers are how you decide. Where it still breaks First-time failures cannot be recalled. If the team has never seen it, memory has nothing, and the Learning screen shows exactly those incidents as misses. Per-service histories hold eight to ten incidents, so cross-service transfer helps but is not evidence of production-scale performance. The corpus is synthetic — real incident data is confidential — and the weights were tuned on it. A production deployment needs re-tuning against real signals and a plan for the long tail of incidents that happen once. And memory can be wrong. Precedent is not proof. That is why every answer carries confidence, receipts, and a visible trace of which path served it. When Hindsight is unreachable, the app serves from a BM25 index over the same SQLite mirror and the header badge changes from HINDSIGHT to BM25 FALLBACK. A demo should not die because a service did not start, but it should never pretend which path answered. What I took away The next improvement in on-call tooling is not a bigger context window. It is a memory that is specific to your systems, weighted by what actually worked, honest about what it does not know, and measured against its own past. Hindsight made the memory layer the easy part: a bank, a retain with real metadata, a recall that returns meaning. The hard part was deciding what counts as the same failure — and being willing to show the moment the agent gets it wrong. At 2 a.m., the question is not "what does a good SRE do?" It is "what did we do last time, did it work, and who can I ask?" If you are building agents with memory, start with Hindsight's open-source memory engine and read the Hindsight documentation. It is also worth getting clear on what agent memory actually means before you design a schema you will regret. Running agent: dejavu-tau.vercel.app. Source, including the replay harness: abinivesh-m/dejavu.

    1 reaction
  2. How I Designed TradeMind's Six-Stage Hindsight Learning Loop How I Designed TradeMind's Six-Stage Hindsight Learning Loop A trading system can calculate RSI correctly, generate a plausible thesis, and still repeat the same mistake tomorrow. I built TradeMind around a different question: how can a market-analysis service carry useful experience from one decision into the next without asking an LLM to remember everything or letting it invent the underlying numbers? TradeMind is a quantitative research and paper-trading system for Indian instruments such as NIFTY 50, BANK NIFTY, Reliance, TCS, and Infosys. Its architecture separates numerical work from language-model reasoning: Python computes market features, tabular models estimate direction and volatility, Groq turns that evidence into a structured hypothesis, and Vectorize Hindsight supplies long-term experiential memory. The interesting part is not any single model. It is the feedback path connecting a market snapshot, a decision, an outcome, and a later decision. The system in six stages The workflow is deliberately explicit. It is implemented in backend/services/workflow_loop_service.py and exposes six stages in its response: 1. Ingest market data and calculate technical indicators. 2. Run tabular machine-learning analysis. 3. Recall relevant prior experience from Hindsight. 4. Ask Groq to formulate a structured trading hypothesis. 5. Execute or evaluate the hypothesis in a paper-trading environment. 6. Reflect on the outcome and retain a lesson for future retrieval. The rest of the codebase supports this path. data_loader.py supplies OHLCV data; technical_indicators.py calculates RSI, moving averages, MACD, Bollinger Bands, and ATR; ml_models_service.py produces tabular analysis; llm_service.py handles hypothesis generation; paper_trading_service.py models virtual execution; and hindsight_service.py wraps the Hindsight client. FastAPI exposes the services, while the React frontend presents the trading dashboard, charts, analysis, and memory views. I made one boundary non-negotiable: the language model should explain and synthesize evidence, not manufacture it. The README describes this as “No LLM Training on Raw Stock Numbers.” Numerical features and trading calculations stay in Python. The LLM receives those results and produces a typed hypothesis with a direction, confidence, supporting evidence, entry assumptions, stop-loss and target assumptions, invalidation conditions, and risk explanation. That split matters in a financial workflow. If a response says RSI is 74.2, I want that value to trace back to a deterministic calculation over a known candle series—not to a token prediction. It also means I can test the indicator code independently of the language model. Hindsight is a memory service, not a chat transcript I use Hindsight as an experiential memory layer. A transcript records what was said. A useful memory system should help answer a different question: what past experience is relevant to the situation in front of me now? TradeMind uses Hindsight’s three core operations: - retain adds market context, hypotheses, and completed paper-trade outcomes to a memory bank. - recall searches for experiences related to the current instrument and market conditions. - reflect synthesizes lessons across remembered experiences. The integration is intentionally concentrated in backend/services/hindsight_service.py, rather than scattered across every feature. The service creates a client from configuration, ensures the configured bank exists, and runs synchronous SDK calls in a small thread pool. That thread boundary is there to keep the synchronous client work away from the request’s event-loop execution path. The relevant part of the recall path is small: res = self._execute_sync( self.client.recall, bank_id=self.bank_id, query=query, tags=tags, budget="mid" ) The query is not just “What happened to NIFTY?” It includes the current instrument and the tabular model’s view of direction, volatility regime, and sentiment. This gives the retrieval system a description of the decision context rather than only a ticker symbol. The service then converts returned items into MemoryItem objects containing content, tags, score, and bank identity. The caller can pass those memories to the reasoning layer. This is where the Hindsight GitHub project and the Hindsight documentation become useful references: retain, recall, and reflect are different operations in a memory lifecycle, not interchangeable names for saving and loading chat history. The broader idea is also explained in Vectorize’s overview of agent memory for stateful AI systems. Running retain and recall from the terminal I also wanted a test that exercises the same service boundary the application uses, rather than a mocked memory object. From the repository root, with the Hindsight service configured in .env, I can run this smoke test: python - <<'PY' import json import time import uuid from backend.services.hindsight_service import hindsight_service marker = f"TRADEMIND-HINDSIGHT-SMOKE-{uuid.uuid4().hex[:10]}" content = ( f"{marker}: A test memory for NIFTY. " "This is a connectivity check, not a trading recommendation." ) # 1. Write a uniquely identifiable memory to the configured bank. retained = hindsight_service.retain_memory( content=content, tags=["NIFTY", "smoke_test"], metadata={"test_marker": marker, "purpose": "retain_recall_smoke_test"}, ) print("RETAIN:", json.dumps(retained, indent=2)) if not retained.get("success"): raise SystemExit("Hindsight retain failed; check service URL, credentials and bank configuration.") # 2. Query for that exact marker. Retain may be indexed asynchronously, # so poll briefly instead of assuming it is immediately searchable. memories = [] for attempt in range(15): memories = hindsight_service.recall_memories( query=f"Find the TradeMind smoke-test memory containing {marker}", tags=["smoke_test"], limit=5, ) if any(marker in item.content for item in memories): break time.sleep(2) print("RECALL:") for item in memories: print(json.dumps({ "bank_id": item.bank_id, "content": item.content, "tags": item.tags, "score": item.score, }, indent=2, default=str)) if not any(marker in item.content for item in memories): raise SystemExit( "Retain succeeded, but the marker was not returned by recall within 30 seconds. " "Check Hindsight indexing and query behavior before treating this as a pass." ) print("PASS: the retained marker was returned by Hindsight recall.") PY The output is generated by the configured Hindsight instance; I do not hard-code a successful transcript into the article. A successful run prints the actual retain response (including its operation identifier when supplied), the recalled memory content and metadata, and the final PASS line. If retain fails, or recall does not return the marker within the polling window, the script exits with an error instead of presenting a false success. Run it against a development bank because it writes a smoke-test memory to that bank. The underlying SDK calls in hindsight_service.py are the same calls this test reaches through the application wrapper: self.client.retain(...) and self.client.recall(...). That makes the terminal check useful evidence of connectivity and round-trip retrieval, while still not claiming that the trading workflow has learned a validated strategy from this test. Retrieval is conditioned on the market state In the workflow, recall happens after the market snapshot and tabular ML analysis are available. That order is intentional. A generic memory query would retrieve broad trading advice. A state-conditioned query can ask for previous experiences that resemble the current setup. The workflow constructs that query from the model output: recall_query = ( f"Trading {instrument_id} when ML predicts {ml_result.direction.direction} " f"with volatility {ml_result.volatility.volatility_regime} " f"({ml_result.volatility.predicted_volatility_pct}%) " f"and sentiment {ml_result.sentiment.sentiment_label}. " "Previous lessons and outcome reviews." ) recalled_memories = hindsight_service.recall_memories( query=recall_query, limit=3 ) The recalled information is then available to the hypothesis-generation path. llm_service.py also has a memory-aware hypothesis method, so the model can reason over the current indicators and recalled lessons together. The aim is not to force the latest memory to dictate a trade. It is to add relevant precedent to the evidence the model must consider. For example, imagine the latest NIFTY snapshot has a bullish trend, elevated RSI, and a low-volatility regime. A useful recalled experience might describe a prior overbought setup in which momentum weakened before price reversed. The model should not treat that memory as a universal rule. It should compare it with the current evidence, state whether the precedent applies, and describe what would invalidate the thesis. That is a better use of memory than simply prepending the last ten chat messages to every prompt. A transcript is chronological; a retrieval system is contextual. The latter can bring an older but relevant experience into a new analysis without making the entire conversation history part of the prompt. The outcome is what makes the loop interesting Recall alone does not create a learning loop. If a system remembers only its own hypotheses, it accumulates opinions. It needs outcomes to compare those opinions against. TradeMind’s intended feedback path captures the instrument, market context, model output, trade assumptions, execution details, and realized result. The Hindsight service also has a dedicated method for reflecting on a completed paper trade: lesson = self.reflect_lessons(query) retain_res = self.retain_memory( content=f"QUALIFIED LESSON ({instrument}): {lesson}", tags=[instrument, "verified_lesson", outcome_str], metadata={ "instrument": instrument, "net_pnl": str(net_pnl), "outcome": outcome_str, "learned_at": datetime.now().isoformat() } ) This is the point where I want the system to be careful. A profitable trade does not prove that the thesis was sound; it may have benefited from noise. A losing trade does not prove that the reasoning was wrong; execution, sizing, and market regime matter. The reflection request therefore needs the original hypothesis and the actual entry, exit, P&L, and exit reason. The retained lesson should preserve that evidence, not turn one outcome into a universal trading rule. In a production implementation, the workflow must only reflect after an actual paper-trade outcome exists. If the position is still open or there is not enough forward market data, the state should remain pending. No synthetic exit should be used to manufacture a completed experience. That distinction is essential because Hindsight is only as useful as the provenance of what it stores. There is an important engineering lesson in the current repository. The workflow code presently derives a fixed expected_move_pct from the model’s predicted direction, calculates a synthetic exit price, and closes the paper order immediately. That is useful as a placeholder for exercising the flow, but it is not evidence of a market outcome. The production version described here replaces that shortcut with subsequent eligible market updates or replay candles, and retains a lesson only after the exit has been evaluated against those real observations. This is not a benchmark claim; it is a correctness requirement for the loop to mean what its name says. Keep the memory boundary explicit A central memory service should not become a second database for everything. TradeMind has different persistence needs: - Conversation history belongs in a transactional store, where ordering, edits, ownership, and pagination are well-defined. - Paper orders and balances belong in a transactional trading store, where duplicate execution and P&L consistency matter. - Raw OHLCV candles belong in the market-data layer, with source and timestamp metadata. - Hindsight should store concise, retrievable experiences and lessons, not raw uploaded files or the complete financial ledger. This separation also matters for multi-user deployments. The current Hindsight service uses a configured bank identifier in a global service instance. That is adequate for a single configured environment, but a SaaS deployment needs an explicit user or organization memory boundary. A user’s risk preferences and trading history must not be retrievable by another user. The application must enforce ownership checks as well as use appropriately scoped memory banks or the supported Hindsight isolation mechanism. The system should also degrade honestly. When Hindsight is unavailable or its API key is missing, TradeMind can still calculate indicators and run deterministic parts of the analysis. It should report that memory is offline and omit recalled lessons. It should never invent a memory count, pretend a recall succeeded, or present a generic fallback rule as something Hindsight remembered. What the user should see I want the memory contribution to be inspectable. When TradeMind generates a hypothesis, the UI should be able to show which memories were recalled and which ones influenced the answer. That allows a user to challenge a remembered lesson, distinguish a verified outcome from a preference, and understand why a recommendation differs from an earlier one. A concrete interaction might look like this: 1. The user asks for a NIFTY analysis. 2. TradeMind loads the latest eligible market snapshot and calculates indicators. 3. The tabular models classify direction, volatility, and sentiment. 4. Hindsight retrieves a previous experience involving a similar volatility regime and momentum state. 5. Groq generates a structured hypothesis, citing the current numerical evidence and acknowledging the relevant precedent. 6. The user paper-trades the setup. Once a real simulated exit is recorded, TradeMind reflects on the hypothesis versus the outcome and retains a qualified experience. 7. On a later setup, recall can surface that experience if the new context is relevant. The result is not a model that changes its weights after every conversation. It is a reasoning service whose future context can improve as its evidence base grows. That distinction keeps the system understandable and makes failures easier to investigate. Lessons I would reuse 1. Calculate numbers outside the LLM. Keep indicators, prices, quantities, fees, and P&L deterministic. Let the model explain the evidence rather than create it. 2. Retrieve after you know the current context. A memory query built from instrument, direction, volatility, and sentiment is more useful than a broad search for the instrument name alone. 3. Store outcomes with provenance. Preserve the hypothesis, timestamps, source, execution assumptions, and exit reason. A label such as WIN is not a lesson by itself. 4. Treat memory availability as a real service state. Offline memory should be visible and should not silently turn into fabricated recall. 5. Measure whether memory helps before claiming that it does. The repository includes a memory-versus-no-memory experiment path, but its current Agent B logic uses hard-coded memory-style rules rather than a true sequential Hindsight retrieval loop. A credible comparison needs to retrieve only information available at each historical decision point, evaluate against later candles, and report the resulting metrics without leaking future information. That last point is the standard I would use to judge the whole design. Hindsight gives TradeMind a place to retain and retrieve experience. The engineering work is making sure that experience is relevant, correctly scoped, tied to real outcomes, and visible when it affects a decision. The six stages are useful only when the last stage improves the evidence available to the first four on the next cycle. !Architecture Diagram !Dashboard Screenshot 1 !Dashboard Screenshot 2 !Memory View

  3. Multi-agent work in three spoonfuls (part IV): from a terminal trident to an autopoietic loop --- title: "Multi-agent work in three spoonfuls (part IV): from a terminal trident to an autopoietic loop" published: true description: "Fourth entry in the penta-agent multi-agent series: quota-governed routing, 70 ms hybrid memory, MCP tools, and a zero-token local autopoiesis loop in Harness2." tags: "ai, agents, cli, automation" canonical_url: "3cucharadas.cl" cover_image: "3cucharadas.cl" ai_disclosure_level: "some_ai" --- After benchmarking the models in part I, auditing retrieval in part II, and tracing provenance in part III of this series, I closed my laptop with a sense of victory: I had a trident of agents running from the terminal on Arch Linux. With a couple of zsh aliases, I could invoke Claude Code for architectural reasoning, hand off a task to Codex CLI to edit code, or ask Gemini CLI and Antigravity for a quick second opinion. On paper, orchestration looked solved. Yet after using that setup every day on real projects inside penta-agent, I hit a silent wall: having three agents talking does not equal having a system that learns. Every time I opened a fresh session, the trident suffered from partial amnesia, repeated commands that had already failed the previous week, burned the quota of the most expensive provider on routine tasks, or marked tests as "verified" when they had never had a chance to fail. To understand what was missing, it helped to change the question. In a recent systems-theory analysis of artificial intelligence, Benedikt Zönnchen, Mariya Dzhimova, and Gudrun Socher (2025[^zonnchen2025], 2–4) propose setting aside whether a language model "thinks like a human" and asking instead the question posed by Humberto Maturana and Francisco Varela (1987[^maturana1987] [1984]) and extended by Niklas Luhmann (1998[^luhmann1998], 60–69): can the system draw its own boundary with the environment, observe its own failures, and sustain itself through its own operations? In other words, moving from the vague notion of "intelligence" to the concrete mechanism of autopoiesis. As Zönnchen, Dzhimova, and Socher (2025[^zonnchen2025], 8–10) show, an isolated language model in a chat window neither is nor can be an autopoietic, sense-making system: it lacks what George Spencer-Brown (1969[^spencerbrown1969]) called re-entry—the capacity to re-introduce the distinction between system and environment (self-reference vs. other-reference) inside its own operations—because it only computes which token is statistically plausible after another, without internal resistance against error. If I want a system that improves without degrading, I have to build a socio-technical harness around the models that couples the probabilistic flexibility of neural networks with the strict coupling and binary code (works / does not work, work / fail) of deterministic technology described by Luhmann (1998[^luhmann1998], 517–525) and André Reichel (2011[^reichel2011], 105–118). The starting point: what I measured and discarded before making this leap Before diving into the three spoonfuls of this fourth installment, here is the experiment that forced me to adopt that discipline. When I tried to give the system long-term memory, the obvious temptation was to install the most elaborate architecture available: temporal graphs, heavy extractors, or an 8B-parameter neural judge running on CPU. Instead of following intuition, I built a reproducible benchmark over my real work logs—comparing open alternatives such as GraphRAG, Graphiti, Hindsight, Letta, Mem0, and deja-vu—and set a falsification contract upfront: any candidate exceeding 0.10 s in p95 latency or failing to improve recall by at least 10% would be discarded. | What I tested in the laboratory | Measured result | Operational decision | |---|---|---| | Hybrid memory (v3.1) (FTS5 lexical index + semantic neighbors in Qdrant with Qwen3-Embedding-0.6B) | Latency p95 = 0.07 s (< 0.10 s), 96% overall recall, rescuing 1 in 3 zero-lexical-overlap queries | Promoted to production as the engine behind experience-memory and recall-context | | In-memory relational graph (v3.2) for multi-hop entity expansion | Exact tie in accuracy with v3.1, but nearly double the latency (p95 = 0.13 s > 0.10 s) | Frozen in the lab; the extra complexity did not earn its keep | | CPU neural judges (4B and 8B) for live answer auditing | Between 69 s and 197 s per verdict, hitting 180 s timeouts in 2 of 3 runs | Discarded from the critical path; pruned 36.3 GiB from disk | | Deterministic checks + bounded 0.6B judge for local validation | Millisecond latency, 0 remote calls, and 100% reproducibility | Adopted as the standard for control gates and evaluation | Table 1. Summary of the prior local memory and evaluation laboratory in penta-agent: what survived the 0.10 s threshold and why I pruned 36.3 GiB of local models that added no operational value. With that foundation in place, I organized this fourth part into three progressive spoonfuls: in the first, I show how I moved from launching standalone agents by hand to governing them with quota budgets, auditable bridges, and a live board in kitty and tmux; in the second, how the nervous system of hybrid memory, MCP tools, and skills works under the hood; and in the third, how I closed the local autopoiesis loop with Harness2 and where both my metrics and systems theory draw the boundary today. --- Spoonful 1: From invoking agents by hand to governing agents and models In plain terms: when I first wired the three agents together, I acted like a traffic officer waving my arms in the middle of an intersection. If I wanted Codex CLI to review a patch written by Claude Code, I copied file paths, opened another tab, and hoped for the best. That works for a five-minute demo, but it falls apart when a task runs for two hours and touches twenty files. Quota-aware routing and security boundaries My first deductive inference came from a hard constraint: model subscriptions and APIs have usage limits, different context windows, and credential boundaries that must never blur. By definition, if I delegate a heavy task to an agent whose quota is at 98%, the session will die mid-flight and leave the repository in an inconsistent state. So I replaced intuitive provider selection with an explicit policy in routing.yaml and a pre-flight sentinel (quota_status.sh, governed by the quota-guard skill). Before launching any expensive job, the system reads cached pressure across every lane without spending tokens: - 🔍 Claude Code (Opus / Sonnet): handles architectural design, delicate editing, and long-horizon synthesis when its quota is clear (exit 0). - 🛠️ Codex CLI (gpt-5.4): steps in as an implementation peer, deep refactoring engine, session rescuer (codex-rescue), and cross-validator. - 🌐 Gemini CLI and Antigravity (gemini-3-pro / flash): in a direct session (penta-agy) it acts as the primary integrator; when invoked from outside via agy-bridge, it runs inside a strict sandbox over sanitized public context as an explorer, reviewer, or validator, never inheriting private keys or .env files. Instead of calling a raw binary and depending on whatever it prints to stdout, every cross-agent handoff goes through agy-bridge. The bridge requires declaring who is calling (--caller), in what mode (plan, review, patch, test, or explain), and with what time limit (--timeout), leaving an immutable receipt in .agents/runs/<run_id>/ with request.md, result.md, status.json, and diff.patch. The live board (plan-board) and decision gates My second inference was inductive: reviewing dozens of past sessions showed that the biggest waste of time happened at two extremes. Either an agent interrupted me every two minutes to ask permission for trivial, reversible steps, or it silently made a delicate architectural choice and I only discovered at the end that it had gone down the wrong path. To eliminate both extremes without filling this post with abstract flowcharts, here is how my actual kitty terminal—or minimalist Wayland alternatives like foot on Codeberg—looks today when split into two panes with tmux during a live task: ![Demonstration in a Kitty terminal split with tmux where the top pane runs multi-agent delegation, passes through a decision-gate, and validates a falsifiable gate, while the bottom pane updates the plan-board live until closing 4 of 4 steps.](3cucharadas.cl) Watch the full video demo on 3cucharadas.cl. <strong>Figure 1.</strong> Daily workflow in my <a href="kovidgoyal/kitty"><code>kitty</code></a> + <a href="tmux/tmux"><code>tmux</code></a> terminal with the <a href="starship/starship"><code>Starship</code></a> prompt: the top pane runs multi-agent delegation via <code>agy-bridge</code>, the <code>decision-gate</code> brake, and <code>pytest</code>; the bottom pane (<code>watch.mjs</code>) updates each step live (<code>[ ]</code> &rarr; <code>[~]</code> &rarr; <code>[!]</code> &rarr; <code>[x]</code>), along with binding decisions and drift. What appears in the bottom pane of Figure 1 is the contract that changed how I work: 1. Local autonomy with visual traceability (plan-board): every reversible, in-scope step proceeds without asking permission, but must be reflected in real time in the bottom table. And no item can be closed as verified ([x]) unless the agent attaches the concrete test, command, or observation reference that backs it. 2. Decision gate (decision-gate): when an irreversible or architectural fork appears (state [!]), the agent halts only that branch and presents the question with the recommended option first, marked (Recommended) and justified with deductive, inductive, and abductive evidence. 3. A gate that has never been seen red is not a gate (gates-falsables): before accepting any new verifier, I require running it against a synthetic failure (--fixture) and proving that it returns a non-zero exit code (exit 1). If a check passes even when I break its input on purpose, it is not a safety net—it is compliance theater. --- Spoonful 2: The nervous system — hybrid memory, skills, and MCP tools If the first spoonful orders who does what and under which rules, the second solves how the system remembers what it has already learned and how it picks the exact tool without bloating the context window. Here the diagnosis by Zönnchen, Dzhimova, and Socher (2025[^zonnchen2025], 6–7, 9) is decisive again: a neural network maintains a loose coupling with human communication that behaves like a "contingent index-card system (Zettelkasten)" (pp. 7, 9) of semantic associations in vector space, giving rise to what Elena Esposito (2017[^esposito2017], 249–265; 2022[^esposito2022]) calls "virtual double contingency" and "artificial communication." That flexibility lets it connect ideas phrased in very different words, but also makes its outputs inherently probabilistic and devoid of autonomous decision-making. If I want reliable memory and precise execution, I have to couple that vector Zettelkasten with exact indices and deterministic scripts. Experience memory (experience-memory): the hybrid Zettelkasten in 0.07 s When I first started keeping logs, my memory was essentially a folder of Markdown files that I read or searched with ripgrep. The obvious problem is that if a month ago I solved a cold-boot screen freeze under the title "Webview failure on autostart" and today I search for "Panel fails to load at login", a purely lexical search can miss it entirely, whereas a purely vector search can bury the exact name of a script like verify_boot_contract.sh. The solution I validated in Table 1 combines both worlds behind the experience-memory MCP server and the recall-context skill: - Exact lexical lane (SQLite FTS5): instantly catches flag names, error codes, file paths, and invariants (INV-005). - Dense semantic lane (Qdrant + Qwen3-Embedding-0.6B): indexes architectural decisions, handoffs, and operational lessons (penta_context_v2) to retrieve conceptual neighbors even when they share zero keywords. Before designing any non-trivial strategy, the agent queries recall_experience in 70 milliseconds (p95 = 0.07 s). That is how it discovers which command worked previously, which hypothesis was already refuted, and which environment trap to avoid (for instance, knowing that in my shell cp, mv, and rm are aliased to interactive -i, which hangs a headless process unless invoked via command mv -f). Skills as living procedures and proactive MCP selection To avoid saturating the initial prompt with thousands of lines of instructions, I adopted the modular pattern of Anthropic Skills enriched with local contracts. In penta-agent, each skill is a self-contained package with four parts: a concise contract in SKILL.md defining when to activate and when not to use it; on-demand deep documentation in references/ (such as the editorial corpus extracted with Docling or diagramming rules with D2); deterministic executables in scripts/ (such as typed pipelines in Nushell, visual automation with Playwright, or forge integration via glab on GitLab); and a telemetry trail. Similarly, the fleet of MCP servers (plan-board, experience-memory, ideas-rag, paper-search, bibliography-apa, PLAYWRIGHT_LOCAL) is cataloged in specs/mcp-capabilities.json. When a task arrives, triage evaluates which capabilities provide real evidence and records both hits and justified abstentions. And when I found that two older servers (quota status and remote SSH infrastructure) were faster, clearer, and easier to audit as direct scripts (quota_status.sh and remote_exec.sh), I decommissioned them as MCP servers and turned them into lightweight skills. Fewer resident daemons mean a smaller failure surface. --- Spoonful 3: The autopoiesis loop (Harness2) — how the system rehearses its own improvements Here I reach the core of this fourth installment. Having capable agents (Spoonful 1) and fast hybrid memory with skills (Spoonful 2) still leaves a critical question open: what happens when a delegation route ages, a skill starts inducing errors, or a memory tweak degrades accuracy on edge cases? If I rely solely on noticing by eye weeks later, the system degrades through silent drift. Why a standalone LLM lacks re-entry and internal resistance In their study on autopoiesis and artificial intelligence, Zönnchen, Dzhimova, and Socher (2025[^zonnchen2025], 8–9) explain with surgical precision why asking a model to "reflect on its own errors" via chain-of-thought (CoT) is not enough. When a model generates intermediate tokens like "Is this step correct?", it exhibits only rudimentary processual self-referentiality (p. 8)—producing the most statistically plausible continuation inside its training distribution—while lacking reflective self-reference and genuine re-entry (Spencer-Brown 1969[^spencerbrown1969]). If a model takes itself as its sole reference without external contrast, it quickly falls into infinite recursion or collapse; if it depends entirely on a human retraining its weights from outside (RLHF or delayed fine-tuning), it remains an allopoietic artifact determined from the outside (Zönnchen, Dzhimova, and Socher 2025[^zonnchen2025], 4, 8–9). To escape that trap, Zönnchen, Dzhimova, and Socher (2025[^zonnchen2025], 7) recover a decisive formulation from Niklas Luhmann (1995[^luhmann1995]) on how operational constructivism relocates Kant's "resistance of reality" inside a system: > "I think we should not abandon [Kant's] idea of resistance, but we should relocate it into the system. It is the result of resolving an internal conflict—the result of the system's operations resisting the operations of the same system" (Luhmann 1995[^luhmann1995], quoted in Zönnchen, Dzhimova, and Socher 2025[^zonnchen2025], 7). That sentence describes, piece by piece, what I built in penta-agent by adapting and integrating the proactive loop of Harness² proposed by Ruiyao Xu, Yanfei Chen, Zhongying CuiZhu, et al. (2026[^xu2026]): making the system's own deterministic verification operations resist and filter change proposals generated from its own operational friction. <details markdown="1"> <summary><strong>In plain terms (ELI5): what is Google's original Harness² and how did I adapt it to my machine?</strong></summary> Imagine your AI agents are very creative chefs, but the recipe book they follow (their rules, memory, and tools) sometimes has confusing steps that make them burn the rice. The original Harness² from Google Research (Xu et al. 2026) proposes a clever loop called Propose–Probe–Compose: instead of swapping out the chef's brain, it puts several assistants to work rewriting the recipe book, asks them to cook test dishes in the cloud, and keeps the winning recipe. For my daily workflow, the factory setup had two catches: it is designed to burn hundreds of paid cloud model calls (Vertex AI), and when driving CLI agents it unbuckles their seatbelt (--dangerously-bypass-approvals-and-sandbox) with open internet access. To adapt it to penta-agent without spending an extra cent or opening security holes, I took its recursive search engine (commit 1cfe254e) and locked it inside a "test kitchen" completely unplugged from the internet (unshare -Urn), with a disposable home folder and zero access to my API keys or model CLIs (model_calls = 0). Instead of running cloud benchmarks, my wrapper (penta-harness2 and local-cycle) feeds that test kitchen with the real stumbles my agents suffered during the week (CSI), requires any recipe tweak to first fail the test when broken (red) and then pass every historical case without breaking anything else (green), and finally stages the winning recipe across all three agents (Claude, Codex, and Gemini/Antigravity) with a one-step undo button (rollback-local) in case I do not approve it. </details> <figure class="d2-responsive" style="width: 100%;"> <img src="3cucharadas.cl" width="1001" height="954" style="width: 100%; height: auto; display: block; border-radius: 12px;" alt="Diagram of the closed local autopoiesis loop in Penta Agent with Harness2: CSI friction signals feed the case generator and the local cycle across routing, memory, and skills; a deterministic judge evaluates against holdout cases with zero model calls, discarding regressions and keeping only verified improvements for human promotion."> <figcaption><strong>Figure 2.</strong> Governed autopoiesis loop in <code>penta-agent</code> + <code>Harness2</code>: relocating internal resistance (Luhmann 1995; Zönnchen, Dzhimova, and Socher 2025) through <code>holdout</code> evaluation with <code>model_calls = 0</code> prior to any human promotion.</figcaption> </figure> How the closed loop operates across my three domains (routing, memory, skills) As Figure 2 shows (adapting into a three-column horizontal layout on desktop and a vertical flow on mobile), the loop operates in four strict stages: 1. Observing real friction (CSI — Continuous Self-Improvement): while I use the system, a collector logs objective friction signals: a task that had to switch agents after a timeout, an experience-memory query that returned too few useful neighbors, or a skill where the user had to correct a command. 2. Bridging evidence into reproducible cases (--from-csi latest): the local_cycle.py module takes that friction report and automatically translates it into a test specification (CaseSpec) inside an isolated environment, without touching my active configuration. 3. Internal resistance without spending tokens (eval_harness with model_calls = 0): the harness runs the full suite (--profile autopoiesis-all, currently covering 9/9 baseline cases across routing, memory, and skills), enforcing two hard conditions: every control case (holdout) must pass (holdout_passed = true), and external API calls must equal zero (model_calls = 0). 4. Auditable decision (KEEP vs. DISCARD) and human promotion: if a candidate degrades even a single holdout case or fails to beat the baseline, the deterministic judge discards it (DISCARD). Only when it improves the score with zero regressions does it receive a KEEP verdict and leave a signed receipt for me to review before promoting it to the main repository. So this does not remain a theoretical promise, the next mini-video shows penta-harness2-shadow local-cycle --profile autopoiesis-all running in my kitty + tmux terminal, including what happens when I inject a regressive candidate (--fixture) alongside a healthy improvement: ![Demonstration in a Kitty terminal split with tmux running penta-harness2-shadow local-cycle across 9 of 9 cases in routing, memory, and skills with zero model calls, applying internal resistance to discard a regressor and keep the healthy candidate.](3cucharadas.cl) Watch the full video demo on 3cucharadas.cl. <strong>Figure 3.</strong> Execution in my <a href="kovidgoyal/kitty"><code>kitty</code></a> + <a href="tmux/tmux"><code>tmux</code></a> terminal of the local autopoiesis loop (<code>local-cycle --profile autopoiesis-all</code>): it evaluates all <code>9/9</code> cases in <code>routing</code>, <code>memory</code>, and <code>skills</code> with <code>model_calls = 0</code>, applies internal resistance to reject the regressor (<code>DISCARD</code>), and preserves the verified improvement (<code>KEEP +0.250</code>) with all <code>82</code> harness tests green. --- Closing: what my architecture achieves today and where its limits lie Looking back at the path from part I, part II, and part III, the main difference is no longer which model writes the prettiest reply to an isolated prompt, but the structure that holds the whole system together when I am not watching every line. Following the rigorous distinction drawn by Zönnchen, Dzhimova, and Socher (2025[^zonnchen2025], 5, 9–10) and by Elena Esposito (2017[^esposito2017]; 2022[^esposito2022]; 2024[^esposito2024]), it would be an epistemic mistake to claim that a language model or a bundle of scripts has on its own achieved the biological autopoiesis of a living cell (Maturana and Varela 1987[^maturana1987] [1984]) or the reflective sense-making (Sinn) of human consciousness (Luhmann 1998[^luhmann1998], 50–69). As Zönnchen, Dzhimova, and Socher (2025[^zonnchen2025], 5, 10) caution when critiquing merely metaphorical invocations of technological autopoiesis, language models remain statistical engines that compute distributions without mental states of their own. Yet—and this is my engineering synthesis for the socio-technical system as a whole—when I couple their capacity for contingent variation with verified hybrid memory, strict delegation contracts, a binary internal-resistance harness (work / fail; Reichel 2011[^reichel2011]) that filters its own proposals before touching production, and deliberative human oversight, I obtain in practice a loop of governed operational autopoiesis. To close with full transparency, Table 2 summarizes what is running and measured on my machine today, where the next step points, and under what objective condition I would discard each component if it stopped earning its keep: | System pillar | What it achieves today (verified in production) | What it aims to achieve next & falsification condition | |---|---|---| | 1. Agent and model routing (routing.yaml, quota-guard, agy-bridge) | Routes tasks across Claude Code, Codex CLI, and Gemini CLI / Antigravity based on cached quota pressure; isolates handoffs in .agents/runs/ under a strict sandbox and displays live progress in plan-board (Figure 1). | Goal: reweight routing priorities from historical domain success rates.<br>Discard if: the bridge introduces spurious failures or bureaucratic latency exceeding quota savings. | | 2. Hybrid memory (experience-memory, Qdrant + FTS5) | Resolves lexical and semantic queries in p95 = 0.07 s (< 0.10 s), rescues 33% of zero-keyword-overlap pairs, and saves 36.3 GiB after pruning slow CPU judges (Table 1). | Goal: add automatic decay for obsolete lessons when a contract changes.<br>Discard if: p95 latency exceeds 0.10 s or semantic noise degrades top-3 precision. | | 3. Skills and MCP governance (mcp-fleet, gates-falsables) | Maintains declarative parity across agents (24/24 checks green), measures MCP usage and abstention, and requires every new gate to fail first against a red canary (--fixture -> exit 1). | Goal: semi-automatic pruning of skills that accumulate repeated friction in CSI telemetry.<br>Discard if: maintaining a skill's contract takes longer than running the direct command. | | 4. Local autopoiesis (Harness2) (local-cycle, eval_harness) | Converts real CSI friction into reproducible Cases and evaluates candidates across routing, memory, and skills (9/9 cases, 82/82 tests) with model_calls = 0, applying internal resistance (KEEP / DISCARD, Figures 2 and 3). | Goal: expand the bank of real cases extracted from failed sessions without losing millisecond evaluation.<br>Hard boundary (INV-004): blind auto-merge is forbidden; final promotion to production always requires human review. | Table 2. Balance between verified production results in penta-agent today, the design horizon, and the falsification thresholds that keep the system under human control. If building this fourth stage made one thing clear to me, it is that the maturity of a multi-agent system is not measured by how many new pieces I bolt onto it each week, but by how much unnecessary complexity I can prune and how many of its own mistakes the system can catch before asking for my help. --- References [^esposito2017]: Esposito, Elena. 2017. "Artificial Communication? The Production of Contingency by Algorithms." Zeitschrift für Soziologie 46 (4): 249–265. Scholar [^esposito2022]: Esposito, Elena. 2022. Artificial Communication: How Algorithms Produce Social Intelligence. Cambridge, MA: The MIT Press. Scholar [^esposito2024]: Esposito, Elena. 2024. Kommunikation mit unverständlichen Maschinen. Salzburg and Vienna: Residenz Verlag. Review of Kommunikation mit unverständlichen Maschinen by Eric Van der Beek in merz | medien + erziehung: DOI · Scholar [^luhmann1995]: Luhmann, Niklas. 1995. "Systems Theory and Postmodernism." University lecture, London. Quoted in Zönnchen, Dzhimova, and Socher, From Intelligence to Autopoiesis (2025, 7): DOI · Scholar [^luhmann1998]: Luhmann, Niklas. 1998. Die Gesellschaft der Gesellschaft. Frankfurt am Main: Suhrkamp Verlag. <search.worldcat.org>. [^maturana1987]: Maturana, Humberto R., and Francisco J. Varela. 1987 [1984]. El árbol del conocimiento: las bases biológicas del entendimiento humano. Santiago de Chile: Editorial Universitaria. 1st Chilean ed. 1984; 1987 international ed. cited in Zönnchen, Dzhimova, and Socher, From Intelligence to Autopoiesis (2025, 3): DOI · Scholar [^reichel2011]: Reichel, André. 2011. "Technology as System: Towards an Autopoietic Theory of Technology." International Journal of Innovation and Sustainable Development 5 (2–3): 105–118. Scholar [^spencerbrown1969]: Spencer-Brown, George. 1969. Laws of Form. London: Allen & Unwin. <archive.org>. [^xu2026]: Xu, Ruiyao, Yanfei Chen, Zhongying CuiZhu, Bhavana Dalvi Mishra, Yifei Ming, Han Yu, Rujun Han, Chen-Yu Lee, and Tomas Pfister. 2026. "Harness²: Recursive Agent Harnessing for an Open World." arXiv preprint arXiv:2610.14224 (open source at <google-research/harness2>). arXiv · Scholar [^zonnchen2025]: Zönnchen, Benedikt, Mariya Dzhimova, and Gudrun Socher. 2025. "From Intelligence to Autopoiesis: Rethinking Artificial Intelligence through Systems Theory." Frontiers in Communication 10:1585321. DOI · Scholar

  4. エージェントの記憶喪失を治す:OSS「Hindsight」をClaude APIに繋いで長期記憶を持たせる セッションが終わるたびに、エージェントは全部忘れる Claude APIでエージェントを組んでいると、必ずぶつかる壁がある。会話が終わってプロセスが落ちれば、そこまでの文脈は綺麗さっぱり消える。ユーザーの好みも、過去に失敗したアプローチも、次のセッションでは「初対面」からやり直しだ。 RAGでドキュメントを検索させるのとは話が別で、これは「エージェント自身の経験」を覚えさせたいという要求になる。自前でPostgres+pgvectorのテーブルを設計してretain/recallのロジックを書いてもいいが、まず既製品で試して足りない部分だけ自作する方が早い。 今回はOSSのエージェント向け長期記憶システム Hindsight(vectorize-io製、MITライセンス)を、素のClaude APIエージェントに繋ぎ込むところまで手を動かす。 Hindsightとは何か Hindsightは2026年4月にGitHub Star数1万を突破し、直近のリリースは v0.10.1(2026年9月21日、50件超のPRと22人以上のコントリビューターがマージされた)。エージェントメモリのベンチマークであるLongMemEvalでSOTA相当のスコアを主張しており、記憶を「world facts(事実)」「experiences(経験)」「observations(観察)」「mental models(メンタルモデル)」に分けて構造化して持つ点が特徴になっている。 APIはシンプルで3つしかない。 retain — 記憶を書き込む recall — 記憶を検索する reflect — 蓄積した記憶を分析し、上位の理解(メンタルモデル)を形成する 単純なベクトル検索のラッパーではなく、reflect で「経験の積み重ねから学習する」層を持っているのが他のシンプルなメモリストアとの違いだ。 1. サーバーを立てる Docker一発で立ち上がる。ローカル検証ならこれが一番早い。 docker run -it --pull always --name hindsight \ --restart unless-stopped \ -p 8888:8888 -p 9999:9999 \ -e HINDSIGHT_API_LLM_API_KEY=$OPENAI_API_KEY \ -v hindsight-data:/home/hindsight/.pg0 \ ghcr.io/vectorize-io/hindsight:latest HINDSIGHT_API_LLM_API_KEY は記憶の抽出・要約に内部で使うLLM用のキーで、エージェント本体がClaudeでもHindsight側は別プロバイダーで構わない。8888 がREST API、9999 は管理系ポート。起動したら疎通確認する。 curl -s localhost 2. クライアントを入れて最小構成で試す pip install hindsight-client anthropic まず生のretain/recallだけで感覚を掴む。 from hindsight_client import Hindsight client = Hindsight(base_url="localhost") client.retain( bank_id="user-yukito", content="ユーザーはDockerのlatestタグを避ける方針。ピン留めしたバージョンを使う。", ) result = client.recall(bank_id="user-yukito", query="Dockerタグの方針は?") print(result) bank_id が記憶の名前空間になる。マルチユーザー・マルチプロジェクトで運用するなら、ここをユーザーIDやプロジェクトIDで切るのがそのまま権限分離にもなる。 3. Claudeエージェントに組み込む ここからが本題。セッションの開始時に関連する記憶をrecallしてシステムプロンプトに注入し、セッション終了時に得られた新しい事実をretainする、という往復を1つのクラスにまとめる。 import anthropic from hindsight_client import Hindsight class MemoryAgent: def init(self, bank_id: str): self.bank_id = bank_id self.memory = Hindsight(base_url="localhost") self.claude = anthropic.Anthropic() def _recall_context(self, query: str, limit: int = 5) -> str: hits = self.memory.recall(bank_id=self.bank_id, query=query, limit=limit) if not hits: return "" facts = "\n".join(f"- {h['content']}" for h in hits) return f"過去のやり取りから分かっている事実:\n{facts}" def ask(self, user_message: str) -> str: context = self._recall_context(user_message) system = "あなたは開発アシスタントです。" + (f"\n\n{context}" if context else "") response = self.claude.messages.create( model="claude-sonnet-5", max_tokens=1024, system=system, messages=[{"role": "user", "content": user_message}], ) answer = response.content[0].text このやり取り自体を経験として書き戻す self.memory.retain( bank_id=self.bank_id, content=f"Q: {user_message}\nA: {answer}", ) return answer 動作確認は別プロセス(別セッション)で行うのが重要。プロセスを一度落として、記憶がDBに残っていることを確かめる。 セッション1(プロセスA) agent = MemoryAgent(bank_id="user-yukito") agent.ask("このプロジェクトではpnpmを使う。npmは使わない。") ここでプロセス終了 セッション2(別プロセス) agent = MemoryAgent(bank_id="user-yukito") print(agent.ask("パッケージマネージャは何を使えばいい?")) → recallでpnpmの方針を拾ってからClaudeが回答する これでプロセスをまたいだ記憶が機能する。RAGのドキュメント検索と違い、ここに入るのは「このエージェントが実際にやり取りした内容」なので、事実確認ではなく方針・好み・過去の失敗の再現防止に効く。 4. reflectで経験を要約させる retainを積み重ねただけだと、生の会話ログが線形に溜まっていくだけでrecallのノイズが増える。定期的にreflectを呼んで上位の理解を作らせるのが公式の使い方だ。 client.reflect(bank_id="user-yukito") これを1日1回のcronなどで回しておくと、個別のQ&Aペアから「このユーザーはDockerのlatestタグを嫌う」「pnpmを優先する」といったメンタルモデル的な記憶に集約されていく。リリースノート(v0.10.1)でも「コーディングエージェント向けにautomatic reflectの予算制限を修正」という変更が入っており、reflectを回しすぎるとLLM呼び出しコストが積み上がる点は運用上のパラメータとして意識しておく必要がある。 つまずいたところ recallは空配列を返すことがある(まだ何もretainしていない、またはbank_idの綴りミス)。ガードを外して素通しすると、システムプロンプトに空文字列の見出しだけが残ってClaudeが混乱するので、上のコードのように空なら注入自体をスキップする。 bank_idを適当な固定文字列にすると、複数ユーザーの記憶が混ざる。最初から「誰の記憶か」をbank_idの設計に落とし込んでおく。 retainのcontentを生の会話ログそのまま入れ続けるとreflect前は検索ノイズが増える。要約してからretainする運用にした方が精度は安定した。 まとめ HindsightはREST経由のretain/recall/reflectという最小限のAPIで、Claude Agentに「セッションをまたぐ記憶」を持たせられる。自前でpgvectorスキーマを設計する前に、まずこの3操作で要件を満たせるか試す価値はある。今回はローカルDocker+Python SDKでの最小構成だったが、本番運用するならbank_idの権限分離とreflectの実行頻度(コスト)の2点を先に設計しておくと手戻りが少ない。 参考 vectorize-io/hindsight (GitHub) Hindsight Releases — v0.10.1 Hindsight Reaches 10,000 Stars

  5. I built OptMem plugin for Hermes. It's one of the 24 in the official catalog. Zero dependencies. No database, no embeddings, no API key. An append-only log: summaries keep context small, the raw record is never deleted. OptMem from @VictorTaelin rarf/optmem-hermes-plugin

    2 likes · 1 repost · 297 views
  6. Reddit · · r/u_YogurtclosetTop9174 · u/YogurtclosetTop9174 · vectorize-io/hindsight

    Adding Recall to GatherIt Without Blocking Guest Uploads Adding Recall to GatherIt Without Blocking Guest Uploads The problem: an event creates more information than people can keep track of When I started building GatherIt, I wanted to make sharing memories at an event feel effortless. Guests should be able to join without installing an app, upload photos and videos, leave voice notes, and see moments collected in one place. Hosts should be able to manage the experience without constantly asking everyone to send their media through separate messaging apps. The challenge is that an event produces much more than a collection of files. It creates context. A guest might upload a photo from a particular moment, add a voice note explaining what happened, or join an event after several activities have already taken place. Later, the host might want to recall a particular moment or understand what people shared. A conventional gallery can store and display media, but it does not automatically provide a useful way to recall the surrounding context. That led me to explore a question: Could I give GatherIt a memory layer without slowing down the experience that makes it useful in the first place? I explored Hindsight, an open-source memory system designed to help AI applications retain and recall information. Instead of treating every interaction as an isolated request, a memory system can make relevant information available when an application needs it again. For GatherIt, the interesting part was not simply adding another AI feature. It was exploring how event context could be captured in the background and retrieved later when a host wanted to look back. Why memory needs to be separate from the main user experience One of the most important engineering decisions in an application like GatherIt is deciding what must happen immediately and what can happen later. When a guest uploads a photo, the main experience should focus on accepting the upload, handling the media, and giving the guest clear feedback. The guest should not have to wait for an additional memory operation to finish before continuing. If memory processing is placed directly in the critical upload path, it introduces another dependency. A slow memory service or a temporary network problem could affect a feature that should otherwise work independently. I therefore approached memory as a supporting capability rather than the centre of the upload workflow. The basic flow I was working toward was: 1. A guest joins an event or shares media. 2. GatherIt performs the normal application work. 3. Relevant event context is passed to a memory operation separately. 4. The host can request a recall when they need that context. This separation matters because a memory system should improve an application without becoming a single point of failure for its core features. It also encourages a useful engineering principle: optional intelligence should not make essential functionality unnecessarily fragile. Where Hindsight fits Hindsight provides a way to retain information and later retrieve relevant context. Its repository and documentation were useful starting points for understanding how a memory layer could fit into an existing application. References: - Hindsight on GitHub: vectorize-io/hindsight - Hindsight documentation: hindsight.vectorize.io - Background on agent memory: vectorize.io For GatherIt, the conceptual mapping was straightforward. Each event has its own context, and memory operations need to be associated with the correct event. A host asking about one event should not accidentally retrieve information belonging to another. That makes event-level separation important. It also makes authorization important: a recall operation should be available only to an appropriately authenticated host, and the server should determine which event the host is allowed to access. I explored an integration pattern in which the server handles memory operations rather than exposing memory-service credentials to the browser. This keeps credentials on the backend and gives the application a single place to apply authorization, validation, and error handling. The important distinction is that Hindsight does not replace GatherIt’s database or media storage. Those systems have different jobs. The application database manages structured application records, media storage holds files, and a memory layer can help retrieve useful context from retained information. Designing the integration around failure A third-party service can be unavailable, slow, or temporarily unreachable. A resilient integration should anticipate those conditions instead of treating them as exceptional surprises. A simplified example of the pattern looks like this: // Illustrative example — adapt names and types // to the actual GatherIt implementation. async function handleGuestUpload(upload: Upload) {   const savedMedia = await saveMedia(upload);   // Memory processing is separate from the   // essential media-saving operation.   void retainEventContext({ eventId: upload.eventId, mediaId: savedmedia.id,   }).catch((error) => { logger.warn( { error, eventId: upload.eventId }, "Could not retain event context" );   });   return savedMedia; } This snippet illustrates the design principle, not a verified copy of GatherIt’s source code. The actual implementation must use the project’s existing upload types, storage logic, logger, and memory service. There is also an important limitation: a detached promise is not the same as a durable background job. If the server process stops at the wrong time, work that has not completed can be lost. For a production system where every memory operation matters, a persistent queue, retry policy, and idempotent processing may be more appropriate. For an early integration, the first priority is to make sure memory-service failures do not incorrectly turn a successful media save into a failed upload. The next priority is to make background processing observable and recoverable. I also considered how a recall endpoint should be structured. It should validate incoming requests, authenticate the host, check access to the relevant event, and handle failures from the memory service. It should not accept an arbitrary event identifier and assume that the requester is entitled to see the result. These checks are especially important for an application where different groups create private event spaces. Keeping credentials and event boundaries secure An integration can work correctly in a local demo and still be unsafe if its credentials or access boundaries are handled poorly. A memory-service API key belongs on the server, in an environment variable or the hosting platform’s secret configuration. It should not be embedded in frontend code, committed to a public repository, or returned in an API response. Event isolation is equally important. If memory is organized around event identifiers, those identifiers must be consistently associated with authorization checks. Knowing or guessing an identifier should not be enough to retrieve another event’s context. I also need to be careful about what gets retained. An event can contain personal conversations, faces, locations, and other sensitive information. Retaining every available detail by default may create unnecessary privacy risks. A responsible implementation should minimize retained information, explain relevant data practices to users, and provide an appropriate way to manage or delete stored context. It should also avoid sending unnecessary personal information to an external service. These are not secondary details to add after the feature works. They are part of the integration itself. What this changes for the host The goal of a memory layer is not to add AI terminology to an interface. It is to make an existing task easier. In GatherIt, the host already has a reason to revisit event content after guests have shared it. A recall interface could eventually help the host find relevant context without manually searching through every upload or note. For example, a host might want to find information related to a particular activity or understand the context around something that was shared. The quality of the result would depend on what was retained, how the memory system indexed it, and how the request was phrased. That last point matters. A memory system should not be presented as an infallible record of everything that happened. It can return incomplete or irrelevant results, especially when the information was never retained or the available context is ambiguous. The interface should communicate those limits instead of presenting every response as a verified fact. It is also important to distinguish retrieval from authorization. A technically relevant memory is not necessarily a memory that the current user is permitted to see. How I would evaluate the feature I would not evaluate this integration only by asking whether a recall request returns text. I would test the complete experience around it. First, normal guest uploads should continue to work if the memory service is unavailable. Second, a host should only be able to recall information for events they are authorized to access. Third, memory failures should be logged in a way that helps debugging without leaking secrets or unnecessary personal information. I would also test whether retained context can actually be retrieved with realistic questions, whether duplicate events or retries create confusing records, and whether the system handles missing or incomplete information gracefully. Finally, I would measure the user-facing impact. Does the integration make it easier to find context? Does it add noticeable delay? Are the results relevant enough to be useful? Those questions need real tests and observations, not assumptions. I do not want to claim a particular speed improvement or accuracy rate without measurements. A good engineering story should distinguish between a design goal, an implemented feature, and a result demonstrated through testing. What I learned The biggest lesson from exploring this integration is that adding memory is not simply a matter of connecting an API. The harder work is deciding what information should be retained, when it should be processed, who is allowed to retrieve it, and what the application should do when the memory system is unavailable. Separating optional memory work from essential user actions is a useful design pattern beyond AI. It applies to analytics, notifications, search indexing, and other supporting services. A system becomes more resilient when a failure in an optional capability does not automatically break its primary workflow. I also came away with a clearer view of what makes an AI feature useful. The goal is not to insert a model into every interaction. It is to introduce a capability where it solves a real problem, keep the surrounding system understandable, and evaluate the result honestly. GatherIt is an ongoing project, and there is still work to do before any memory feature should be treated as production-ready. Testing failure cases, strengthening background-job reliability, reviewing data retention, and validating recall quality are all part of that work. For me, the most interesting part of Hindsight is the possibility of making event information more useful over time. Photos and videos preserve moments. Context can help people make sense of them later. The engineering challenge is connecting those two things without compromising reliability, privacy, or the simplicity of sharing in the first place. That is the direction I want to keep exploring with GatherIt: not AI for its own sake, but technology that helps people return to the moments they care about. Further reading - Hindsight source code: vectorize-io/hindsight - Hindsight documentation: hindsight.vectorize.io - What is agent memory?: vectorize.io

    1 point
  7. Reddit · · r/sideprojects · u/Even_Phrase_4319 · vectorize-io/hindsight

    Portable Local LLM # I built PortLLM to explore portable local AI with persistent memory ## The problem I’m exploring Running an LLM locally gives you more control over your data, but it doesn’t automatically give the assistant persistent memory across sessions. I wanted to explore how a portable local AI environment could work with a memory layer to make interactions more continuous. That’s the idea behind PortLLM. ## How it works PortLLM is designed as a portable environment for running local AI models, with a shared interface and support for different platforms. The project explores local inference through backends such as Ollama and llama.cpp, depending on the configuration. I’m also exploring Hindsight as a persistent memory layer. Its core operations are: - Retain: Save useful information from interactions. - Recall: Retrieve relevant information when a new question comes in. - Reflect: Reason over stored memories to build a more informed response. The main technical challenge is not simply storing conversation history. It’s deciding what information is worth keeping, when to retrieve it, and how to avoid irrelevant or outdated memories. ## Architecture and limitations The project separates local model inference from the memory layer. This distinction matters because local inference alone doesn’t guarantee that memory storage, retrieval, or synchronization will work offline. Those capabilities depend on how the memory component is configured. I’m interested in making the experience portable while handling cases where network access is unavailable or relevant memories cannot be retrieved. ## What I’ve learned so far Working on this has made me think more carefully about the trade-offs between context windows and persistent memory. A larger context window can hold more information in one session, while a memory layer can potentially carry useful details across sessions. However, poor retrieval can introduce irrelevant information, and stale memories can lead to incorrect responses. Useful next steps include testing memory retrieval across separate sessions, checking how conflicting facts are handled, and measuring whether retrieved memories actually improve answers. ## Resources - Project website: port-llm.vercel.app - Source code: Keshav-pro1/PORT-LLM- - Hindsight: vectorize-io/hindsight I’d appreciate feedback from people working with local LLMs or agent memory: What test cases would you use to evaluate a persistent memory system, especially when memories are missing, outdated, or contradictory? I’m sharing this to get technical feedback and learn how to improve the design.

    2 points
  8. Shared Long-Term Memory for Claude Code and Codex, Fully Local: A Hindsight Daemon Setup Guide This is a start-to-finish guide to giving Claude Code and Codex CLI a shared long-term memory that runs entirely on your Mac. It uses Hindsight, an MIT-licensed agent-memory engine, in local daemon mode. Your ChatGPT plan (model gpt-6-luna) does the memory extraction, the database lives in a folder you choose, and only the repositories you list are ever remembered. I wrote it as the runbook for setting up a second laptop. Follow the steps in order. > Versions used (Oct 2026): @vectorize-io/hindsight-coding-agents 0.8.2, hindsight-api 1.1.0, hindsight CLI 1.1.0, macOS on Apple Silicon, zsh. Newer releases may differ. See the Coding Agents docs. What you will have at the end Claude Code ─┐ hooks: SessionStart · UserPromptSubmit · Stop ├─► Hindsight daemon (hindsight-embed) http://127.0.0.1:9077 Codex CLI ───┘ MCP server: hindsight_* tools │ ├─ embedded PostgreSQL (pg0) │ data in ~/projects/hindsight-data └─ LLM: chatgpt provider, gpt-6-luna hindsight CLI ─────────────────────────────────────────┤ hindsight ui (web control plane, http://localhost:9999)┘ - One plugin for both agents. @vectorize-io/hindsight-coding-agents installs three hooks, an MCP server with the hindsight_* tools, and a companion skill into each agent. - One memory bank per repository, named coding-agent::<repo>. Claude Code and Codex read and write the same bank, so a decision made in one is visible in the other. - Automatic capture and recall. A session's first prompt gets a memory synthesis injected. Each session is written back when it ends. Git history and a short codebase survey seed every new bank, and the survey re-runs as the code moves on. - Five knowledge pages per repo: Component map, Conventions and patterns, Core concepts, Key decisions and rationale, and Initiatives and enhancements. - Opt-in only. Repositories you don't list are never touched. Step 1 — Prerequisites | Requirement | Why | Check / install | |---|---|---| | Claude Code and/or Codex CLI | The agents being wired | claude --version, codex --version | | Node.js (npx) | Runs the plugin installer and the hooks | node --version | | uv | The daemon is launched with uvx | brew install uv | | Rust toolchain, current | Daemon mode on macOS builds a dependency (litellm) that has no macOS wheel | rustup update stable | | ChatGPT plan that allows usage in third-party apps | Pays for memory extraction instead of an API key | Confirmed during sign-in (Step 3) | | hindsight CLI (recommended) | Inspect banks, refresh pages, launch the web UI | curl -fsSL https://hindsight.vectorize.io/get-cli \| bash | Step 2 — Write the config file first Create ~/.hindsight/coding-agent.json before installing, so the first session already follows your rules: { "optInOnly": true, "optInPaths": ["~/projects/my-repo"], "pageTriggerCron": "H * * * *", "surveyRefreshCommits": 20 } chmod 600 ~/.hindsight/coding-agent.json What each key does: - optInOnly: true: memory is off everywhere by default. A repository outside optInPaths is inert: no bank is created, nothing is retained, and nothing is seeded. - optInPaths: path prefixes, with ~ expanded. ~/projects/my-repo approves that repo and its git worktrees. ~/projects would approve every repo under it, each with its own bank. To add a repo later, append its path; there is nothing to reinstall. - pageTriggerCron: "H * * * *": refreshes each knowledge page at most once an hour. This is the default; writing it out makes it easy to change. H is replaced by a value hashed from the bank and page name, so pages refresh at different minutes instead of all at once. A refresh is skipped when nothing new arrived. Each refresh is one LLM synthesis per page. With a local daemon that comes out of your ChatGPT plan, so hourly is affordable. Use "H H * * *" (once a day) if you want to save plan usage. - surveyRefreshCommits: 20: the codebase survey that seeds a new bank's structural knowledge re-runs whenever 20 new commits have landed since the last survey. This is the default. In Claude Code each survey is a headless claude -p --model haiku run capped at $2 (surveyModel, surveyBudgetUsd). In Codex it runs through Codex itself. Set it to 0 to survey each repo only once, when it is first opened. Busy repos will otherwise keep re-surveying. The installer adds "serverMode": "daemon" to this file in Step 5. > On a company laptop: list only repositories you are allowed to process this way. With the daemon, memory stays on disk locally, but the extraction step still sends transcript text to your LLM provider (OpenAI, through your ChatGPT plan). Each laptop also has its own memory. Two daemons don't sync. Opt-in list or every repo? The config file supports two modes. Pick one per machine: | Mode | Config | When to use it | |---|---|---| | Opt-in only (allowlist) | "optInOnly": true + "optInPaths": [...] | A work laptop, or any machine where only some repositories may be processed | | Every repo (denylist) | Remove optInOnly and optInPaths entirely; exclude individual repos with banks.<id>.disabled | A personal machine where you want memory everywhere | Switching from opt-in to every repo means deleting the two keys: { "serverMode": "daemon", "pageTriggerCron": "H * * * *", "surveyRefreshCommits": 20, "banks": { "coding-agent::private-notes": { "disabled": true } } } The change applies at your next prompt, because the hooks re-read the file on every call. MCP tools pick it up in the next session. From then on, the first session in any repo creates its coding-agent::<repo> bank, seeds it from git history (the most recent commits, 300 by default), and runs a codebase survey. The survey runs again every surveyRefreshCommits (20) new commits. In Claude Code each survey is a claude -p --model haiku run with a $2 budget cap. Every repo's transcripts now go to your extraction LLM. With a local daemon the storage stays on your Mac, but the extraction still happens at the provider. Disable the repos where that is not acceptable. Optional per-repo controls live in the same file, keyed by bank id: { "banks": { "coding-agent::some-repo": { "disabled": true }, "coding-agent::big-monorepo": { "gitIngest": "full", "retainSessions": false } } } Step 3 — Sign Hindsight in to your ChatGPT plan Hindsight's chatgpt provider uses OpenAI's official Sign in with ChatGPT flow. Hindsight registers as its own OAuth client and stores its own credentials, separate from the Codex CLI's login. uvx --from hindsight-api-slim hindsight-admin chatgpt login A browser window opens. Sign in and approve plan usage. The command waits for the callback on 127.0.0.1:1455, then saves ~/.hindsight/chatgpt/credentials.json with mode 0600. You may see warnings that sentence-transformers is not installed. They come from running the admin tool out of the slim package and do not affect sign-in. Confirm: uvx --from hindsight-api-slim hindsight-admin chatgpt status # Signed in: yes # Plan usage enabled: yes Tokens refresh automatically. Usage counts against your ChatGPT plan and shows at <chatgpt.com>. Step 4 — Pin the provider and model in your shell Add to ~/.zshrc: # Hindsight daemon: extract memories with the ChatGPT plan, model pinned export HINDSIGHT_API_LLM_PROVIDER=chatgpt export HINDSIGHT_API_LLM_MODEL=gpt-6-luna Open a new terminal and check: echo "$HINDSIGHT_API_LLM_PROVIDER / $HINDSIGHT_API_LLM_MODEL" # chatgpt / gpt-6-luna Why set both explicitly: - Provider. When the daemon starts, the plugin chooses the provider in this order: HINDSIGHT_API_LLM_PROVIDER, then whichever of OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, GROQ_API_KEY is set first, then claude-code if the claude CLI is on PATH. Setting it explicitly guarantees chatgpt, even if an API key happens to be in your environment. - Model. gpt-6-luna is the chatgpt provider's default today. Pinning it keeps it if a future release changes the default. The runtime updates itself daily. - All HINDSIGHT_API_* variables in the environment that starts the daemon are passed on to it. To use a different model only for extraction, use the per-operation variables (for example HINDSIGHT_API_RETAIN_LLM_MODEL). Step 5 — Install the plugin in daemon mode From that new terminal: npx @vectorize-io/hindsight-coding-agents install claude-code codex --server daemon The output should include local extraction will use chatgpt (from HINDSIGHT_API_LLM_PROVIDER). The installer: | Agent | What gets wired | |---|---| | Claude Code | 3 hooks merged into ~/.claude/settings.json; MCP server registered with claude mcp add (user scope); skill at ~/.claude/skills/hindsight-coding-agent | | Codex CLI | 3 hooks merged into ~/.codex/hooks.json; [mcp_servers.hindsight] in ~/.codex/config.toml; skill at ~/.agents/skills/hindsight-coding-agent | | Shared | Runtime copied to ~/.hindsight/coding-agents; "serverMode": "daemon" written to ~/.hindsight/coding-agent.json | Codex also needs its hooks feature flag. If ~/.codex/config.toml has no [features] section, the installer adds one for you. If the section already exists, the installer prints a reminder instead, and you add the line yourself: [features] hooks = true The installer accepts either hooks = true or the older spelling codex_hooks = true, which some docs still use. Notes: - The plugin is installed with npx, not through a Claude Code marketplace, so it is not listed under /plugin. Manage it with npx @vectorize-io/hindsight-coding-agents install | uninstall | update | stats. - If an older per-agent Hindsight plugin (such as hindsight-memory) is installed, uninstall it first so only one set of hooks runs. Step 6 — Start the daemon and verify it The SessionStart and Stop hooks start the daemon by themselves, in the background, whenever port 9077 is free. Start it once by hand so the slow first run (download, Rust build, model load) happens while you watch: node ~/.hindsight/coding-agents/dist/daemon-start.js --harness claude-code Verify: lsof -iTCP:9077 -sTCP:LISTEN # a python process on localhost:9077 PID=$(lsof -tiTCP:9077 -sTCP:LISTEN) ps eww -p $PID | tr ' ' '\n' | grep '^HINDSIGHT_API_LLM_' # HINDSIGHT_API_LLM_PROVIDER=chatgpt # HINDSIGHT_API_LLM_MODEL=gpt-6-luna Under the hood, the plugin asks hindsight-embed to start the server. hindsight-embed runs hindsight-api --idle-timeout 0 --port 9077 together with an embedded PostgreSQL 18 instance managed by pg0. Step 7 — Pin the provider in the daemon profile file The daemon also has a per-profile env file, ~/.hindsight/profiles/coding-agent.env, created on first start. Make it agree with your shell. Then a daemon started from a context that doesn't load ~/.zshrc, such as an agent opened from the Dock, still uses ChatGPT and gpt-6-luna: f=~/.hindsight/profiles/coding-agent.env cp "$f" "$f.bak" grep -n '^HINDSIGHT_API_LLM_' "$f" # inspect what it currently says Edit it so it contains these two lines, and remove any HINDSIGHT_API_LLM_API_KEY= line: HINDSIGHT_API_LLM_PROVIDER=chatgpt HINDSIGHT_API_LLM_MODEL=gpt-6-luna chmod 600 "$f" "$f.bak" Step 8 — Put the memory bank where you want it By default the database lives in ~/.pg0/instances/hindsight-embed-coding-agent/data. Hindsight has no setting for this path, but pg0 follows a symlink. Here is how to move it to ~/projects/hindsight-data. 1. Stop the daemon and its PostgreSQL. Never copy a running database. kill $(lsof -tiTCP:9077 -sTCP:LISTEN) # wait until postgres has exited and postmaster.pid is gone pgrep -f 'postgres -D .*hindsight-embed-coding-agent' || echo "postgres stopped" ls ~/.pg0/instances/hindsight-embed-coding-agent/data/postmaster.pid 2>/dev/null || echo "clean shutdown" 2. Copy, verify, then swap in a symlink: SRC=~/.pg0/instances/hindsight-embed-coding-agent DST=~/projects/hindsight-data mkdir -p "$DST" cp -a "$SRC" "$DST/" # -a keeps the 0700 permissions PostgreSQL requires diff -rq "$SRC" "$DST/hindsight-embed-coding-agent" && echo "identical" mv "$SRC" "$SRC.old" ln -s "$DST/hindsight-embed-coding-agent" "$SRC" 3. Restart and confirm PostgreSQL now runs from the new folder: node ~/.hindsight/coding-agents/dist/daemon-start.js --harness claude-code lsof -p $(pgrep -f 'postgres -D .*hindsight-embed-coding-agent' | head -1) | grep -m1 hindsight-data 4. Once everything works (Step 12), delete $SRC.old. Keep ~/projects/hindsight-data out of git and out of iCloud Drive or Dropbox. Live syncing can corrupt a running database. To back it up, stop the daemon and copy the folder. Step 9 — Seed memory from past conversations From inside each opted-in repository: cd ~/projects/my-repo npx @vectorize-io/hindsight-coding-agents install claude-code --import-conversations # and/or: ... install codex --import-conversations - The import reads the agent's local transcripts and keeps only sessions whose recorded working directory is this repository. - It uses LLM tokens in proportion to the history (your ChatGPT plan here). It is safe to re-run, because documents are de-duplicated by id. - Git commit messages and a codebase survey are ingested automatically at the next session start. New commits are appended as they land, and the survey re-runs every 20 commits (surveyRefreshCommits). - CLAUDE.md and Claude Code's auto-memory notes (~/.claude/projects/*/memory/*.md) are not imported. CLAUDE.md is loaded into every session anyway. To store a memory note in the bank, ask the agent to save it with the hindsight_ingest_document tool. Step 10 — Start fresh agent sessions The hooks read ~/.hindsight/coding-agent.json every time they run. The MCP server behind the hindsight_* tools reads it once, when it starts. After installing, start new Claude Code and Codex sessions. In an already-open Claude Code session, run /mcp → hindsight → Reconnect. In a new session you should see the Hindsight memory banner. The tools the agent can call: | Tool | Use | |---|---| | hindsight_search_knowledge_pages / hindsight_read_knowledge_page / hindsight_list_knowledge_pages | Look up architecture, conventions, decisions | | hindsight_reflect | Deep reasoning over all memory ("why is X like this?") | | hindsight_ingest_document | Save notes or a document into memory | | hindsight_capture_initiative | Track a new feature or plan as its own page | | hindsight_sync_status / hindsight_diagnose | Check ingestion status and configuration | Step 11 — Point the CLI at the daemon Without configuration the hindsight CLI targets http://localhost:8888. Point it at the daemon: hindsight configure --api-url http://localhost:9077 chmod 600 ~/.hindsight/config Useful commands (<bank> is coding-agent::my-repo): hindsight health # Status: healthy · Database: connected hindsight bank list hindsight bank stats <bank> # nodes, links, documents, pending/failed operations hindsight document list <bank> hindsight operation list <bank> # retain / consolidation / refresh jobs and their status hindsight mental-model list <bank> # the knowledge pages hindsight mental-model refresh <bank> <id> # refresh one page now hindsight explore # interactive terminal explorer The plugin also ships a one-shot status report: node ~/.hindsight/coding-agents/dist/status.js --repo ~/projects/my-repo # {"bank":"coding-agent::my-repo","gitlogPresent":true,"chatDocs":…,"pagesCount":5,"surveyDocs":4,"synced":true,…} Querying another repo's memory (cross-bank) The hindsight_* MCP tools are bound to the current repo's bank. None of them takes a bank parameter, so an agent working in repo A can't use them to ask what was decided in repo B. Use the CLI against the other bank instead: hindsight bank list # find the bank id hindsight memory recall 'coding-agent::other-repo' "how do we handle retries on 4xx?" -o json hindsight memory recall 'coding-agent::other-repo' "deployment steps" -t world,experience -o json - Use recall, not reflect, for cross-bank lookups. recall returns the stored memories (facts, experiences, observations) ranked by relevance. reflect synthesizes an answer through the target bank's reflect_mission and disposition. Coding-agent banks get a debugging-assistant mission, so reflect answers in that bank's voice instead of showing you what it holds. - -t/--fact-type narrows the types (world, experience, observation). Separate several with commas (-t world,experience) or repeat the flag. -o json makes the output easy for an agent to parse. - Say where a fact came from. When an agent quotes cross-bank results, it should name the source bank (coding-agent::other-repo) so nobody mistakes it for the current repo's own memory. - To make agents do this automatically, add a line like this to your global ~/.claude/CLAUDE.md (and Codex's AGENTS.md): - Cross-repo memory: `hindsight_*` MCP tools only see the current repo's bank. To read another repo's memory run `hindsight memory recall 'coding-agent::<repo>' "<question>" -o json` (recall, not reflect — reflect applies the target bank's mission) and cite the source bank in the answer. - If some of your repos must never inform each other, write that rule next to it. Separate banks keep the data apart, but the agent can still bridge them with this command. The CLI query is the only path across banks, so the rule only has to govern that one command. Step 12 — Generate the knowledge pages A new bank's pages show "No content yet." until their first hourly slot comes, which can take up to an hour. To build them right away (this only uses your ChatGPT plan): B=coding-agent::my-repo for id in $(hindsight mental-model list $B -o json | python3 -c "import sys,json;[print(m['id']) for m in json.load(sys.stdin)['items']]"); do hindsight mental-model refresh $B $id done hindsight operation list $B # wait for the refresh_mental_model jobs to finish From then on, each page refreshes at most once an hour, and only when there is new material. Step 13 — The web UI The CLI can launch Hindsight's web control plane (@vectorize-io/hindsight-control-plane, a Next.js app) against the API URL in your CLI config, which is the daemon. It needs Node.js. By default it is reachable from your whole network with no login. It binds to 0.0.0.0 and requires no sign-in unless an access key is set. Launch it locked down instead: KEY=$(openssl rand -hex 16); echo "UI access key: $KEY" HOSTNAME=127.0.0.1 HINDSIGHT_CP_ACCESS_KEY="$KEY" hindsight ui - HOSTNAME=127.0.0.1 binds it to localhost only, so other devices on the network can't reach it. The startup log then shows Network: http://localhost:9999 instead of 0.0.0.0. - HINDSIGHT_CP_ACCESS_KEY turns on the login page. Opening / redirects to /login, and the UI's API routes return 401 until you enter the key printed above. - The line No API key configured (public access) in the log is about the key the UI sends to the daemon (HINDSIGHT_CP_DATAPLANE_API_KEY). The local daemon needs none. That line does not mean the UI itself is open. Then: 1. The first run installs the control-plane package through npx, which takes about a minute. When it is ready it prints Local: http://localhost:9999 and Connecting to dataplane at: http://localhost:9077. 2. Open <localhost> and sign in with the key. The dashboard lists your banks. Inside a bank you can browse documents, memories, entities and the memory graph, look at the knowledge pages (mental models), check operations, and try recall and reflect queries. 3. Stop it when you're done: kill $(lsof -tiTCP:9999 -sTCP:LISTEN) For a quick look without a browser, hindsight explore opens a terminal explorer of the same data. How it behaves day to day - Start: the SessionStart and Stop hooks of Claude Code or Codex start the daemon in the background if port 9077 is free. Both agents and all repos share one daemon. - Stop: it does not exit when idle. Closing your agents leaves it running, using roughly 1–1.5 GB of RAM and no LLM usage while idle. It stops on reboot and comes back with the next session. To stop it yourself: kill $(lsof -tiTCP:9077 -sTCP:LISTEN). - Changing provider, model or other daemon settings: a running daemon is reused and never restarted, so stop it after any change. The next session (or daemon-start.js) starts it with the new settings. - Updates: the plugin checks npm once a day and updates its runtime. Re-run install only when a release adds new hooks. - Writes are asynchronous: a saved document appears once its retain job completes (hindsight operation list <bank>). - Logs: ~/.hindsight/coding-agents-logs/plugin.log, diag.jsonl (every reflect/retain/page event), usage.jsonl. Summary: npx @vectorize-io/hindsight-coding-agents stats. Final checklist - [ ] ~/.zshrc: HINDSIGHT_API_LLM_PROVIDER=chatgpt, HINDSIGHT_API_LLM_MODEL=gpt-6-luna, visible in a new terminal - [ ] hindsight-admin chatgpt status: signed in, plan usage enabled - [ ] ~/.hindsight/coding-agent.json: serverMode: "daemon", pageTriggerCron: "H * * * *", surveyRefreshCommits set the way you want (20 by default, 0 = survey once), mode 600. Either optInOnly: true with the right optInPaths, or no opt-in keys plus banks.<id>.disabled for the repos to exclude. - [ ] Cross-bank lookup works: hindsight memory recall 'coding-agent::<repo>' "<question>" -o json returns results - [ ] ~/.hindsight/profiles/coding-agent.env: chatgpt + gpt-6-luna, no API-key line, mode 600 - [ ] ~/.codex/config.toml: hooks = true under [features], [mcp_servers.hindsight] present - [ ] Daemon on 127.0.0.1:9077 with the right HINDSIGHT_API_LLM_* in ps eww; hindsight health healthy - [ ] ~/.pg0/instances/hindsight-embed-coding-agent → symlink to ~/projects/hindsight-data/…; PostgreSQL has files open there - [ ] Per repo: status.js --repo … shows synced: true, pagesCount: 5, surveyDocs: 4; hindsight operation list shows nothing failed - [ ] In a new agent session, hindsight_sync_status returns the same numbers as status.js - [ ] Web UI launched only with HOSTNAME=127.0.0.1 and HINDSIGHT_CP_ACCESS_KEY, and stopped when not in use (nothing listening on :9999) Uninstall npx @vectorize-io/hindsight-coding-agents uninstall all # removes the hooks, MCP entries and skills install added # (Codex's [features] hooks flag stays, since other hooks may use it) kill $(lsof -tiTCP:9077 -sTCP:LISTEN) # stop the daemon # memory data: ~/projects/hindsight-data (and the symlink in ~/.pg0/instances) — delete only if you mean it

  9. toktok is the first library to have a @typesafeai jev tokenizer vectorize-io/toktok t.co

    3 likes · 2 reposts · 162 views
  10. 한 달에 ★45,470 붙은 GitHub 저장소의 정체 (10월 트렌딩 TOP 5) 이번 달 GitHub 트렌딩(월간)에서 스타가 가장 많이 늘어난 저장소 5개를, 뭘 하는 건지·왜 뜨는지까지 설명합니다. 0:00 한 달에 스타 4만 5천 개가 붙은 저장소? 0:10 5위 ai-engineering-from-scratch 0:28 4위 ECC 0:50 3위 paperclip 1:12 2위 hindsight 1:33 1위 VoiceStudio 1:55 한 줄 정리 ■ 이번 영상의 저장소 5위 rohitg00/ai-engineering-from-scratch 4위 affaan-m/ECC 3위 paperclipai/paperclip 2위 vectorize-io/hindsight 1위 debpalash/VoiceStudio ■ 데이터 기준 - 순위·이번 달 증가 스타: GitHub 트렌딩(monthly) 2026-10-21 스냅샷. 증가량은 트렌딩 페이지 값이며 별도로 검증하지 못했습니다. - 총 스타·라이선스·설명: GitHub API 2026-10-21 확인. - "개발사 주장"과 "제 해석"은 영상에서 구분해 표시했습니다. hindsight의 LongMemEval 91.4%는 개발사가 논문에 밝힌 자체 결과입니다. - 스타 수는 품질을 보장하지 않습니다. - VoiceStudio는 AGPL-3.0 라이선스입니다. 상업적으로 쓰기 전에 직접 확인하세요. ■ 음성 내레이션은 AI 음성(Gemini TTS)입니다. #GitHub #깃허브 #GitHub트렌딩 #오픈소스 #AI에이전트 #개발자 #AI개발

    109 likes · 3 comments · 36 views

Achievements

Awards earned by the repositories vectorize-io owns. Select an award to embed its badge.

Gold
11st place finishes
Silver
32nd place finishes
Bronze
33rd place finishes
Awarded repositories
1Owned by vectorize-io now

Repositories

Ordered by gold, then silver, then bronze.

  1. hindsightBest: 1st by stars, 5,280 stars133

Every award

Top-three finishes of these repositories in completed trending days and weeks, newest first.

  1. hindsight
  2. hindsight
  3. hindsight
  4. hindsight
  5. hindsight
  6. hindsight
  7. hindsight

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.