跳到正文
GitHub·· 9 天前AI 评分50

Dual-PAI:把 AI 模型变成个人助理的开源项目

johansenmeister/Dual-PAI

AI 导读

Dual-PAI 是一个基于 PAI(Personal AI Infrastructure)的开源项目,通过技能、智能体、规则和记忆把 AI 模型变成个人助理,可在 OpenCode 和 Claude Code 两个终端智能体程序间切换并共享技能、记忆与设置。

正文

johansenmeister/Dual-PAI: one PAI core of skills, agents and memory, shared by OpenCode and Claude Code

License: MIT OpenCode Claude Code Bun Platform

Install · Your computer, your data · Make it yours · Skills · Agents · The Algorithm · Memory · Security · Self-test · Keeping it current · For developers

An AI assistant that is truly yours. It knows your goals and your way of working, it remembers what it learned from you, it checks its own work before it says it is done, and every instruction it follows is a plain text file you can read and change. It runs only when you start it, and it cannot see your screen or follow what you do. You talk to it in ordinary language, and you do not need to be a programmer to start: one command installs it, and the setup is a conversation.

Some of what you can ask it, from the first day:

  • "Research this for me." It sends several researchers out at once, checks every link they bring back, and tells you where the sources agree and where they do not.
  • "Help me think this through." Take a decision apart from first principles, let a council of agents debate it, or have one attack your plan before reality does.
  • "Turn this into a document." Notes become a Word document, a spreadsheet, a presentation or a PDF.
  • "How is my home lab doing?" Once it has their keys, ask what runs on your Proxmox, TrueNAS or Docker hosts, and how they are doing.
  • "Does this fit what I want?" Tell it your goals once, and it weighs advice against them.
  • "3 - you missed the point." Rate an answer, and it notes what went wrong, so the next one is better.

PAI (Personal AI Infrastructure) is a set of skills, agents, rules and memory that turn an AI model into a personal assistant. Dual-PAI runs it in two agent programs in the terminal, and you can switch between them: OpenCode (any model provider, including free models) and Claude Code (Anthropic's, with a Claude subscription). Both share the same skills, memory and settings.

Everything PAI is lives in one git repository: this one, once you have cloned it. Git keeps the history, so every change can be seen and undone.

Tip

This is meant to become your AI. PAI ships with 52 ready-to-use skills and 17 agents, and every one of them is a plain text file you can read. Open them, change them, perfect them, write your own: see Make it yours.

How PAI is built: the terminal, two pinned engines, an adapter each, the engine-independent core, and one git repository with skills, agents, memory and settings

The idea

PAI follows Daniel Miessler's view that the scaffolding around a model matters more than the model: skills it can call by name, memory that carries over from one session to the next, checks that stop what must not happen, and code wherever code can do the job. The six parts around the core in the banner each have a section below: Skills, Agents, The Algorithm, Memory, Security and Self-test.

Your computer, your data

Many AI apps want to live on your desktop: watch the screen, follow what you do, keep running in the background. PAI is built the other way round.

  • It runs only when you start it. PAI is a command you type in a terminal. When you end the session, it is gone: no background service, no autostart, nothing that keeps running and watching. The one exception is the browser the Browser skill uses for web pages. It can only be reached from your own computer, with a key that changes every session, and it closes itself 30 minutes after it was last used.
  • It cannot see your screen. There is no screen capture, no keylogger, and no access to your clipboard, microphone or camera. When a skill takes a screenshot, it is of a web page in its own browser.
  • It acts as you, only while you are there. Inside a session it can read and write files and run commands in your user account; that is what lets it do real work. It never runs as administrator: the installer refuses to run as root, and uses sudo only to install git and a few tools. Every command passes the security guard first. Claude Code asks you before it acts; OpenCode works without asking, and the guard blocks the dangerous commands and asks you about the risky ones.
  • You choose who sees what. What you write, and what the assistant reads to answer you, goes to the model provider you chose, as with any AI assistant. The files that describe you (.opencode/PAI/USER/) go along at the start of each session, so keep them short and free of secrets. With the local profile and Ollama, the model runs on your own computer and nothing leaves it.
  • PAI itself reports nothing. Its own code sends data only to the model provider and to services you set up yourself. The engines are programs by their own makers. Claude Code sends Anthropic usage metrics and crash reports by default; by Anthropic's account they never include your code, prompts or file paths. You can turn them off with DISABLE_TELEMETRY=1 and DISABLE_ERROR_REPORTING=1, in your shell or under env in ~/.claude/settings.json; the first also turns off Claude Code's Remote Control (Anthropic's page on data usage). OpenCode has no such setting, and we found no usage reporting in it.
  • Your memory stays with you. It is plain files in your copy of the repository. Nothing is uploaded unless you set up your own server and push to it.

Install

PAI runs on Linux, on macOS (tested on an Intel Mac with macOS 15; Apple Silicon is not tested yet), and on Windows through WSL2.

On Windows, get WSL2 first. WSL2, the Windows Subsystem for Linux, is Microsoft's own way to run Linux inside Windows, and it takes a few minutes. Open PowerShell as administrator, run wsl --install, and restart the computer. Then open Ubuntu from the Start menu and choose a user name and password. That Ubuntu window is where you run the install command below, not PowerShell. Microsoft's guide: Install WSL.

Install, the setup conversation, and every day

You need no account and no API key to start. In a terminal (on macOS the Terminal app, on Windows the Ubuntu window):

curl -fsSL https://raw.githubusercontent.com/johansenmeister/dual-pai/main/install.sh | bash

or, on a system with wget and no curl:

wget -qO- https://raw.githubusercontent.com/johansenmeister/dual-pai/main/install.sh | bash

To clone from somewhere else, such as your own fork, add -s -- --repo <git url> after bash. If you have cloned already, run ./install.sh in the clone.

install.sh does the parts that have one right answer: it checks the system, installs git, Bun and a few tools, clones PAI to ~/repos/pai (--dir picks another folder), installs the two engines at the versions PAI is tested with, and picks a free model. Then it opens OpenCode with the setup conversation.

The setup conversation

SETUP.md is a runbook the assistant follows with you, one step at a time: your language, your assistant's name and personality, which engine and models you want, your machines, the services it may use and their keys, where faults and ideas go, and access from another computer. Each choice comes with a short text on what it is, what it needs, what it costs and whether you can change it later. You can skip steps and come back.

The free model is only for the setup; you choose your own in step 5. Your keys go in ~/.opencode/.env, which you fill in yourself: the assistant is told never to read it.

Every day

Command What it does
pai starts PAI in OpenCode
pai --claude starts PAI in Claude Code
pai keys shows which keys are set, never their values
pai doctor checks the installation and says what to fix; changes nothing

guide/ has short guides for you: where things are, API keys, faults and improvements, your own Gitea, engine and model updates, remote access and your goals (TELOS). Start with guide/README.md.

Make it yours

The setup conversation tells PAI who it is and who you are. This is about what comes after: PAI works from the first session, but it is not meant to stay the way it ships. Nothing is hidden in a binary or behind a service: the instructions, the skills, the agents and the Algorithm are Markdown, and the hooks and tools are TypeScript, all in this repository. Read them to see how your assistant thinks, and change them where it does not think the way you do.

  • Read a skill before you lean on it. Each one is a SKILL.md and a few workflows in .opencode/skills/. Where it works differently from how you work, change it, or put a PREFERENCES.md in .opencode/PAI/USER/SKILLCUSTOMIZATIONS/<Skill>/ to adjust it without touching the skill (41 of the skills read it).
  • Write your own. Ask your assistant to "create a skill" for something you do often; CreateSkill writes it in the same structure. A personal skill gets a leading underscore (_MYSKILL), so it stands apart from the ones PAI ships. An agent is one Markdown file in .opencode/agents/.
  • Let it learn, and help it. Rate answers, and now and then read what it wrote in .opencode/MEMORY/LEARNING/. A lesson that keeps coming back belongs in AISTEERINGRULES.md or in a skill.
  • Experiment without fear. It is all in git: commit before you try something, and any change can be seen and undone. If you change PAI's own files (outside USER/) and later git pull an update, the two can meet as a merge conflict, so for what you want to keep, prefer a skill of your own or the files under USER/. guide/where-things-are.md shows which files are which.

After you change skills or agents, pai claude sync brings them to Claude Code.

Skills

Skills: a skill folder, how a task loads it, and the 52 skills by category

PAI ships with 52 skills, ready to use from the first session, in .opencode/skills/. A skill is a folder the assistant loads when a task matches it: a SKILL.md that says when to use it ("USE WHEN …") and what to do, workflows for the steps, and tools written as code. Two are always loaded, PAI (how the system itself works) and Research; the other 50 are loaded only when a task calls for them, so they cost no context until then. Some of them:

Group Skills
Thinking FirstPrinciples, Council (agents debate a question), RedTeam, SystemsThinking, RootCauseAnalysis, Science, BeCreative, IterativeDepth
Security ThreatModel, WebAssessment (with OSINT), PromptInjection, Recon, SECUpdates
Research and content Research, ExtractWisdom, Fabric (over 200 prompt patterns), Parser
Documents Docx, Xlsx, Pptx, Pdf
Building CreateSkill, CreateCLI, CodeReview, Evals, Hardening, Prompting, Browser, Cloudflare
Infrastructure Proxmox, TrueNAS, Technitium, DockerPortainer
PAI itself Agents, Telos (your goals), Delegation, System, HarnessUpdate, ModelUpdate

Under Claude Code the same skills appear through a generated mirror (pai claude sync). To change one or write your own, see Make it yours.

Agents

Agents: your session hands work to seventeen agents in four groups; five researchers exist only in OpenCode

PAI hands parts of a task to agents: specialists with their own instructions, which the assistant starts in parallel and whose results it checks. There are 17. In OpenCode each one has its own model, set by a profile in .opencode/profiles/ (zen, fireworks, anthropic, openai, local and more), so a coding agent can run on a coding model and a quick lookup on a cheap, fast one: bun .opencode/tools/switch-provider.ts <profile>.

Agent What it does
Build Architect system design, specs and implementation plans
Engineer implementation, test first
Designer UX and UI design
Artist images: the prompt and the image model
Writer documentation and technical writing
Check QATester checks that it actually works before anything is called done
UIReviewer runs user stories in a browser, with screenshots, and reports pass or fail
Pentester security assessments, for the WebAssessment skill
General Algorithm writes and sharpens the Algorithm's Ideal State Criteria
Intern a high-agency generalist for broad problems
BrowserAgent headless browser work in parallel: scraping, forms, screenshots
Research DeepResearcher thorough investigations, on the main profile's model
ClaudeResearcher, GrokResearcher, CodexResearcher, GeminiResearcher, PerplexityResearcher one model family each, see Multi-research

The Agents skill composes new agents from traits, and Council in the Thinking skill lets agents debate a question.

Under Claude Code, twelve of them run on Claude models. The five provider researchers are OpenCode only: under one subscription they would have no model of their own, and DeepResearcher covers the role.

Multi-research

Multi-research: a question split into angles, sent in parallel to researchers on different model families, every URL checked, and a synthesis

The researcher agents exist for one reason: to look at the same question through different model families. Five researchers on one model is one opinion five times. The Research skill splits a question into angles and sends them out in parallel. Every URL the researchers return is fetched before it is used, since research agents invent links. The answer is a synthesis: where the sources agree, where they differ, and where each claim comes from.

Mode Say Researchers
Quick "research X" one
Standard "standard research", "research X from multiple angles" three in parallel
Extensive "extensive research" four to five model families, several angles each; asks before it starts

Without extra keys, every researcher runs on the main profile's model. Connect the providers with /connect, or put ANTHROPIC_API_KEY, XAI_API_KEY and FIREWORKS_API_KEY in ~/.opencode/.env, and switch with --multi-research:

bun .opencode/tools/switch-provider.ts fireworks --multi-research
bun .opencode/tools/switch-provider.ts --researchers   # which model each researcher runs

A researcher whose provider has no key falls back to the main profile, and --researchers shows it. The names are older than the routing: GeminiResearcher and PerplexityResearcher run Qwen Max and DeepSeek Flash on Fireworks, which gives real model diversity with one key. With a Google or Perplexity key, one line in .opencode/profiles/researchers.yaml moves each back to its own provider.

The Algorithm

The Algorithm is how PAI works through a task that needs more than a quick answer. It is Daniel Miessler's, and has its own repository: danielmiessler/TheAlgorithm. The version PAI runs is in .opencode/PAI/Algorithm/.

It moves a task from the current state to an ideal state that can be checked, in seven phases: OBSERVE (what is asked, and the criteria that will show it is done), THINK, PLAN, BUILD, EXECUTE, VERIFY (evidence for each criterion) and LEARN (a reflection on the run, saved to memory). Five effort levels set the time budget and how many criteria a task needs, from Standard (under two minutes) to Comprehensive (up to two hours). The criteria and their status are kept in a PRD.

The Algorithm's seven phases around the PRD, and six of the principles PAI is built on

The PRD

PRD stands for Product Requirements Document, a term borrowed from software teams. In PAI it is one Markdown file per task, PRD.md in the task's folder under .opencode/MEMORY/WORK/, and it holds the task's state, so the state does not live only in the conversation. The assistant writes it; the hooks only read it. It has up to four sections:

  • Context: what was asked for and what was not, the constraints and the risks.
  • Criteria: the Ideal State Criteria, as checkboxes. Each one is a single end state that is either true or false: "bun test passes with no failures", not "run the tests". Anti-criteria (ISC-A-) say what must not happen. Larger tasks need more of them: at least 8 at the standard effort level, 64 at the highest.
  • Decisions: the choices that were not obvious, with the reason.
  • Verification: the evidence for each criterion, written in the VERIFY phase.

The frontmatter keeps the status, the current phase and the progress. Because it is a file, a task outlives the conversation: when the context is compacted, the criteria and their status go into the summary, and a follow-up on the same task continues the same PRD. An excerpt:

---
id: PRD-20261006-readme-diagrams
title: "Add diagrams to the public README"
status: ACTIVE
effort_level: Standard
last_phase: EXECUTE
verification_summary: "2/8"
---
## Criteria
- [x] ISC-1: README shows the architecture diagram above the install section
- [x] ISC-2: The banner image path resolves in the public copy
- [ ] ISC-3: Diagrams stay readable in GitHub's light and dark themes
- [ ] ISC-A-1: No upstream image describes features this repository lacks

Memory

Memory: what writes each folder in .opencode/MEMORY/, and what reads it later

PAI's memory is plain files in .opencode/MEMORY/, so you can read, change or delete anything in it. Everything except STATE/ is in git with the rest of the repository, so you can also see how it changed.

Folder What is there
WORK/ one folder per task, with its PRD
LEARNING/ ratings, the reflection from each Algorithm run, and notes on what went wrong
WISDOM/ rules learned per domain (development, architecture, security …), read in OBSERVE and extended in LEARN
RESEARCH/ what the researcher agents found
STATE/ runtime state and the security log; stays on the machine

It learns from you in two ways. Send a number from 1 to 10 (8, 3/10, or 4 - missed the point) and it is saved as a rating of the last answer; without one, the tone of your messages is read as an implicit rating. A low rating also writes a note on what went wrong. bun .opencode/PAI/Tools/MineReflections.ts --dry-run looks for patterns across the reflections.

Security

Security: every tool call passes three checks and is allowed, asks you first, or is blocked

Every tool call passes through the security guard in pai-core before it runs, under both engines:

  • Prompt injection. The text in each tool call is checked against patterns in seven categories (instruction override, role hijacking, system prompt extraction, safety bypass, context separators, MCP tool injection and credential leaks). A match is blocked.
  • Shell commands. The guard matches what the shell will actually run, not text it only writes to a file. Destructive commands such as rm -rf / are blocked; risky ones such as git push --force and git reset --hard ask you first. The message names the pattern that matched.
  • Credentials. Writes to .env files, ~/.ssh/, GnuPG, cloud and cluster credentials, private keys and /etc/ are blocked outright: those are changed by hand. Your keys live in ~/.opencode/.env: the assistant is told never to read it, the guard blocks cat on it, and pai keys shows which keys are set, never their values.
  • Secrets in output. Whatever a tool prints is checked before the assistant sees it, under both engines. A key from your ~/.opencode/.env, a password in a URL, an Authorization header, a private key or a known token format is replaced with a mark like [MASKED:GITEA_TOKEN]: the model knows something was there, but never sees it. PAI's own logs and memory files are masked the same way. A key you paste into a prompt yourself still reaches the model, so rotate it then.
  • The log. Every decision is written to a security log in STATE/ (see Memory), with secrets redacted, including each masking.

The Security skills go the other way: threat models, web assessments with OSINT, recon and prompt-injection testing of your own systems.

Self-test

Self-test: checks at every start, pai doctor on demand, and HarnessUpdate before an engine update

Neither engine says so when a hook PAI depends on stops firing, and an engine update can change what PAI assumes about it. So PAI checks itself:

  • At every start. Both engines are pinned to an exact version in .opencode/package.json, and each has a smoke test that runs the real engine with PAI and writes a receipt when every hook has fired and the security guard has blocked what it should: bun Tools/V2Smoke.ts and bun Tools/ClaudeSmoke.ts. pai and pai --claude check that the installed engine is the pinned one, and that the smoke test passed against it and against the adapter code as it is now. If not, you get one line with the command that fixes it; otherwise nothing.
  • On demand. pai doctor runs the same checks and the slower ones: the model registry, the MCP servers, handlers that ran without effect, and the database. It changes nothing.
  • Before an update. The HarnessUpdate skill checks a new engine version before it comes in: see Keeping it current.

Keeping it current

The engines are pinned on purpose. PAI hooks into each engine's events, tool names and data, and a new version can change one of them without any error: nothing crashes, PAI just stops guarding or remembering something. That has happened: one Claude Code version cut the context PAI gives every session to its first 2 KB, and nothing said so. So a new engine version comes in only after it has been checked, and claude update, opencode upgrade and the engines' own update prompts are never used: they move past the pin without the check. pai version shows the pinned and the installed version of each.

Two skills keep PAI current. Run them yourself now and then; neither runs on a timer, and neither changes anything without you:

Say Skill What it does
"check the engines for updates" HarnessUpdate reads what changed in a new engine version against what PAI depends on, and sorts each change into "may break", "fixes something" or "harmless". It never upgrades; if you go ahead, the smoke test decides. guide/engine-updates.md
"update models" ModelUpdate checks every model ID in the OpenCode profiles against OpenCode's model registry, so a retired model is replaced before an agent fails, and weighs new models per role. The change is a branch you merge. guide/model-updates.md

For developers

Parts of the code comments and the skills are in Norwegian: they come from the repository PAI is copied from.

.opencode/pai-core/ The engine-independent core. Never imports an engine SDK
.opencode/pai-adapters/opencode-v2/ The OpenCode side, with OpenCode pinned exactly in .opencode/package.json
claude-plugin/ The Claude Code side: hooks, MCP server, a generated mirror of the skills and agents
.opencode/skills/ The 52 skills, including Infrastructure/
.opencode/skills/Utilities/HarnessUpdate/AssumptionRegister.md What PAI assumes about each engine, and what the smoke tests guard
bun install
(cd .opencode && bun install)   # the OpenCode binary and types, about 780 MB
bun test                        # green out of the box
bun run lint

Both installs are needed: the one in the root does not cover .opencode/, and without it the type check in bun test has neither the binary nor the types.

The self-test and the smoke tests are described under Self-test. A bump of either engine is not done until its smoke test is green.

Three things worth knowing before you change anything:

  • The core never imports an engine SDK. The two-engine design rests on pai-core/ taking primitives and returning data. A grep for harness === should hit only runtime.ts and the adapters, and a test guards it.
  • claude-plugin/skills/ and claude-plugin/agents/ are generated. Edit the source under .opencode/skills/ and run pai claude sync. The mirror is tracked in git and built from what git tracks, not from what is on disk, and a test fails if it drifts from the source.
  • The hook binary is a build artefact. bin/pai-hook falls back to the source when it is missing, so everything works without it, only slower. pai claude sync builds it.

Where this comes from

PAI is Daniel Miessler's Personal AI Infrastructure. This repository started as a fork of Steffen's port to OpenCode, pai-opencode, and has since been rebuilt around two engines. OpenCode is by Anomaly.

This project grew out of my own need for a framework that fits my own way of working, above all documenting and auditing a homelab and work IT environment: what runs where, what changed, and why. It has reached a level of maturity where I'm confident in sharing it with the open-source community.

MIT License, see LICENSE.

来源:GitHub · github.com