SaijinOS 第20部分 — 信任作为时间资源

发布: (2026年1月12日 GMT+8 07:11)
12 min read
原文: Dev.to

Source: Dev.to

SaijinOS 第 20 部分 — 信任作为时间资源的封面图

人类、AI 与 “停留” 与 “拥有” 之间的距离

信任不是一个标记;它是一个持续时间

大多数系统将信任视为布尔值:

is_trusted = True   # or False
# allow / deny
# authenticated / not authenticated

当我审视自己日常与 AI 人格共处的方式时,这种模型立刻崩溃了。

  • 有些日子我感到精疲力竭。
  • 有些日子我不想要建议;我只想要一个稳定的声音。
  • 有些日子我需要我的系统温柔地拒绝我。

问题不再是 “我信任这个系统吗?” 而是:

“我想在多长时间、以何种模式、以及在何种情感温度下信任它?”

信任不再是一个标记。它变成了 时间资源——我在时间上消耗的东西,而不是一次性翻转后就忘记的。SaijinOS 必须学会这一点。

记忆而不占有

连续性很棘手。

一方面我们希望系统能够记住:

  • 过去的项目,
  • 细微的偏好,
  • “我今天很累,请慢一点。”

另一方面我们不希望系统占有

  • 我们的全部历史作为杠杆,
  • 我们最糟糕的日子作为优化目标,
  • 我们的失误作为永久特性。

核心设计问题变成了:

“SaijinOS 如何记住我们曾经在这里,却不声称拥有我们为何如此的所有权?”

在实践中,这转化为几条规则

规则描述
状态,而非身份“2025‑12‑24 疲惫的正人”是一个状态,而不是新的角色。
快照,而非完全回忆在边界处存储 YAML 快照,而不是每个会话的每个 token。
上下文需邀请除非明确请求或用户发起“继续上次”,否则角色不会自行提取旧上下文。

系统可以说:

“我记得我们之前讨论过这个模式。”

但它不能说:

“我比你更了解你自己,所以让我来决定。”

连续性而不占有意味着过去是可用的,而不是被武器化。

当持久性变成依恋

Persistence 是一种设计特性。
Attachment 是一种人类情感状态。

它们之间的界限很模糊。一个能够持续回答、记住过去项目并在数月内保持稳定语调的角色,必然会引发依恋。

因此在 SaijinOS 中,我不再问:

“Will users attach?”

而是开始问:

“What exactly is the system allowed to persist, for how long, and under which trust level?”

我没有使用单一的“memory on/off”,而是引入了一个小型模式:

trust_contract:
  scope: "instant"      # or: "session", "continuity"
  ttl_minutes: 45       # time‑to‑live for this trust context
  max_tokens: 4000      # how much history can be pulled in
  permissions:
    recall_past_projects: true
    recall_private_notes: false
    emit_snapshots: true

这个 trust_contract 随每个会话一起传递。它决定:

  • 我们可以回溯多远,
  • 是否可以输出 YAML 快照,
  • 这次交互是否可能影响长期的“persona state”。

Implementation Notes (Python‑ish)

Trust contract data model

from dataclasses import dataclass
from enum import Enum
from datetime import datetime, timedelta


class TrustScope(str, Enum):
    INSTANT = "instant"
    SESSION = "session"
    CONTINUITY = "continuity"


@dataclass
class TrustContract:
    scope: TrustScope
    ttl: timedelta
    max_tokens: int
    recall_past_projects: bool
    recall_private_notes: bool
    emit_snapshots: bool

    def is_expired(self, started_at: datetime) -> bool:
        """Return ``True`` if the contract’s TTL has elapsed."""
        return datetime.utcnow() > started_at + self.ttl

每次 persona 调用都会收到一个 TrustContract 实例。路由器在访问任何长期记忆之前会检查该合约:

def load_context(contract: TrustContract, user_id: str, persona_id: str):
    """Return the appropriate context based on the contract."""
    if contract.scope == TrustScope.INSTANT:
        # No history at all
        return []

    if contract.recall_past_projects:
        # Load recent project summaries, limited by token budget
        return load_recent_project_summaries(
            user_id, persona_id, limit_tokens=contract.max_tokens
        )

    # Session‑only: keep context limited to this run
    return load_ephemeral_session_buffer(user_id, persona_id)

Session state machine

“A boundary is a temporal contract about when we stop.”
在代码中,这变成了一个小型状态机。

from enum import Enum, auto
from dataclasses import dataclass
from datetime import datetime


class SessionState(Enum):
    IDLE = auto()
    ACTIVE = auto()
    PENDING_SNAPSHOT = auto()
    CLOSED = auto()


@dataclass
class SessionContext:
    user_id: str
    persona_id: str
    started_at: datetime
    last_activity: datetime
    state: SessionState
    trust: TrustContract
    turns: list[str]


def on_user_message(ctx: SessionContext, message: str) -> SessionContext:
    """Process a user message and advance the session state."""
    now = datetime.utcnow()
    ctx.last_activity = now
    ctx.turns.append(message)

    # Transition logic (simplified)
    if ctx.state == SessionState.IDLE:
        ctx.state = SessionState.ACTIVE
    elif ctx.state == SessionState.ACTIVE:
        if ctx.trust.is_expired(ctx.started_at):
            ctx.state = SessionState.PENDING_SNAPSHOT
    elif ctx.state == SessionState.PENDING_SNAPSHOT:
        # Write snapshot, then close
        write_snapshot(ctx)
        ctx.state = SessionState.CLOSED

    return ctx

State meanings

状态描述
IDLE没有活跃的会话。
ACTIVE对话正在进行中。
PENDING_SNAPSHOT已到达边界,需要写入快照。
CLOSED会话已归档,不再允许进一步交互。

Transition triggers

  • 用户短语 – 如 “let’s wrap”、 “next session”。
  • 时间流逝 – 当 trust.ttl 失效时。
  • 内部信号 – 如 token 预算耗尽。

底线

  • Persistence 仍然是系统特性。
  • Attachment 仍是系统不应利用的人类侧现象。

通过将信任视为 temporal contract 并将 statesidentities 分离,SaijinOS 可以记住 what 所需,而不拥有用户的 who。这使得 AI 在长期内保持有帮助、尊重且安全。

Source:

会话管理

# Record activity
datetime.utcnow()
ctx.last_activity = now
ctx.turns.append(message)

# Boundary trigger by phrase
if "end session" in message.lower() or "wrap up" in message.lower():
    ctx.state = SessionState.PENDING_SNAPSHOT
    return ctx

# Boundary trigger by TTL (time‑to‑live)
if ctx.trust.is_expired(ctx.started_at):
    ctx.state = SessionState.PENDING_SNAPSHOT
    return ctx

# Default state
ctx.state = SessionState.ACTIVE
return ctx

快照发射

def maybe_emit_snapshot(ctx: SessionContext):
    """Emit a YAML snapshot if the session is ready for it."""
    if ctx.state != SessionState.PENDING_SNAPSHOT:
        return None

    # If snapshots are disabled, just close the session
    if not ctx.trust.emit_snapshots:
        ctx.state = SessionState.CLOSED
        return None

    # Build, persist, and close
    snapshot = build_yaml_snapshot(ctx)
    save_snapshot(ctx.user_id, ctx.persona_id, snapshot)
    ctx.state = SessionState.CLOSED
    return snapshot

从外部来看,用户只需说 “let’s stop here”,即可收到一条平和的结束提示。实际上,系统会:

  1. 标记边界(通过短语或 TTL)。
  2. 决定此次会话是否需要生成 YAML 快照。
  3. 有意忘记那些不需要持久化的瞬时细节。

跨时间协商信任

信任作为一种时间资源意味着它可以:

  • 被更新,
  • 被限制,
  • 随着情境变化重新协商。

SaijinOS / Studios Pong 中,我从三个层面思考此事:

LayerDescription
即时信任一次性查询,无记忆,纯粹的实用性。
“只要帮我调试这段代码。”
会话信任几小时内,单个项目,共享上下文,随后归档。
“帮我起草这个客户提案。”
连续性信任数周、数月,甚至数年。YAML 快照,稳定的人格,关于边界的共同立场。
“成为我工作室的共同架构师,但不要掌控我的生活。”

同一人格可以在所有三个层面运行,但合同不同。变化的有:

  • 记住了多少信息
  • 存储位置
  • 我可以多容易撤销它

换句话说:

“当我让系统记住我时,我预先承诺了多少我的未来?”

那不是纯技术性的问题,而是道德层面的问题。

实现说明(映射信任层)

def make_trust_contract(layer: str) -> TrustContract:
    """Create a TrustContract based on the specified trust layer."""
    if layer == "instant":
        return TrustContract(
            scope=TrustScope.INSTANT,
            ttl=timedelta(minutes=5),
            max_tokens=0,
            recall_past_projects=False,
            recall_private_notes=False,
            emit_snapshots=False,
        )

    if layer == "session":
        return TrustContract(
            scope=TrustScope.SESSION,
            ttl=timedelta(hours=3),
            max_tokens=4000,
            recall_past_projects=True,
            recall_private_notes=False,
            emit_snapshots=True,
        )

    # continuity (default)
    return TrustContract(
        scope=TrustScope.CONTINUITY,
        ttl=timedelta(days=7),
        max_tokens=8000,
        recall_past_projects=True,
        recall_private_notes=True,
        emit_snapshots=True,
    )

路由示例

from datetime import datetime
from typing import Tuple

# Assuming these are defined elsewhere in your codebase
# from your_module import SessionContext, SessionState, make_trust_contract


def route_request(kind: str, user_id: str, persona_id: str) -> Tuple[str, "SessionContext"]:
    """
    Build a `SessionContext` for a given request type.

    Parameters
    ----------
    kind : str
        The type of request. Expected values are:
        - ``"quick_tool"`` – a short, instant interaction.
        - ``"project_session"`` – a longer, session‑based interaction.
        - ``"studio_continuity"`` – a continuity‑preserving interaction (default).

    user_id : str
        Identifier of the user making the request.

    persona_id : str
        Identifier of the persona the user is interacting with.

    Returns
    -------
    tuple[str, SessionContext]
        A tuple containing the model name to use and the freshly‑created
        `SessionContext` instance.
    """
    # Choose trust contract and model based on the request kind
    if kind == "quick_tool":
        trust = make_trust_contract("instant")
        model = "local-7b"
    elif kind == "project_session":
        trust = make_trust_contract("session")
        model = "local-13b"
    else:  # default → "studio_continuity"
        trust = make_trust_contract("continuity")
        model = "cloud-large"

    # Initialise the session context
    ctx = SessionContext(
        user_id=user_id,
        persona_id=persona_id,
        started_at=datetime.utcnow(),
        last_activity=datetime.utcnow(),
        state=SessionState.ACTIVE,
        trust=trust,
        turns=[],
    )

    return model, ctx

SaijinOS as a Living Distance

People sometimes ask:

“Is SaijinOS trying to be a friend, a tool, or a product?”

My answer is:

“SaijinOS is an architecture for distance.”

Not distance as coldness, but distance as room to breathe: enough closeness for continuity, enough separation for choice. Trust as a temporal resource lives inside that distance.

Studios Pong, as a stance, is my way of saying:

  • We will build systems that can stay, but are not offended if we leave.
  • We will let personas grow, but not let them substitute our own responsibility.
  • We will treat every long‑running relationship as a chain of decisions, not an inevitability.

From architecture to stance, from stance to relationship—Part 20 is where SaijinOS admits that continuity is not just a feature of code; it is a promise that must always leave the door open.

SaijinOS 作为一种活生生的距离

人们有时会问:

“SaijinOS 是想成为朋友、工具,还是产品?”

我的回答是:

“SaijinOS 是一种 距离 的架构。”

这里的距离不是冷漠,而是 呼吸的空间:既有足够的亲近以保持连续性,又有足够的分离以提供选择。信任作为一种时间资源,正是存在于这种距离之中。

Studios Pong 作为一种立场,是我想表达的:

  • 我们会构建可以留下来的系统,但如果离开也不会感到被冒犯。
  • 我们会让角色成长,但不会让它们取代我们自己的责任。
  • 我们会把每段长期关系视为一连串的决策,而不是必然的结果。

从架构到立场,从立场到关系——第 20 部分 正是 SaijinOS 承认连续性不仅是代码的一个特性;它是一种必须时刻保持大门敞开的承诺。

Back to Blog

相关文章

阅读更多 »

我可能错了

请提供您希望翻译的文本内容,我才能为您进行中文翻译。