docs: publish architecture and experiment portal

This commit is contained in:
wuyang
2026-07-26 21:03:23 +08:00
parent 4eb915283d
commit 688ddec1fe
17 changed files with 3582 additions and 56 deletions
+570
View File
@@ -0,0 +1,570 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#f2f0e9" />
<title>K1412 Agent · 架构、实现与实验</title>
<meta
name="description"
content="K1412 多用户 Web Agent 的架构设计、Agent Loop 实现、隔离模型和实验记录。"
/>
<meta property="og:type" content="website" />
<meta property="og:site_name" content="K1412 Agent" />
<meta property="og:title" content="K1412 Agent · Architecture & Experiments" />
<meta
property="og:description"
content="A multi-user Web Agent built as an evolvable system for context, tools, parallelism, memory and delegation."
/>
<meta property="og:url" content="https://agent.k1412.top/doc/" />
<meta property="og:image" content="https://agent.k1412.top/doc/og.png" />
<link rel="icon" href="../static/favicon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="./styles.css" />
<script>
document.documentElement.classList.add('js');
</script>
<script src="./app.js" defer></script>
</head>
<body>
<a class="skip-link" href="#main-content">跳到正文</a>
<header class="topbar">
<a class="brand" href="#overview" aria-label="K1412 Agent 文档首页">
<span class="brand-mark" aria-hidden="true">K</span>
<span>
<strong>K1412 Agent</strong>
<small>Architecture / Lab Notes</small>
</span>
</a>
<div class="topbar-actions">
<span class="system-status"><i></i> 当前架构 · 2026.07</span>
<a class="button button-quiet hide-mobile" href="https://git.k1412.top/wuyang/zk-data-agent">
查看源码
</a>
<a class="button button-primary" href="/">进入 Agent <span aria-hidden="true"></span></a>
<button
class="nav-toggle"
type="button"
aria-label="打开文档目录"
aria-expanded="false"
aria-controls="side-navigation"
>
<span></span><span></span>
</button>
</div>
</header>
<div class="page-shell">
<aside class="sidebar" id="side-navigation">
<nav aria-label="文档目录">
<p class="nav-label">系统</p>
<a class="nav-link is-active" href="#overview"><span>01</span>概览</a>
<a class="nav-link" href="#architecture"><span>02</span>架构边界</a>
<a class="nav-link" href="#agent-loop"><span>03</span>Agent Loop</a>
<a class="nav-link" href="#workspace"><span>04</span>执行空间</a>
<a class="nav-link" href="#models"><span>05</span>模型与强度</a>
<p class="nav-label">演进</p>
<a class="nav-link" href="#experiments"><span>06</span>实验记录</a>
<a class="nav-link" href="#operations"><span>07</span>部署与观测</a>
<a class="nav-link" href="#timeline"><span>08</span>项目历程</a>
<a class="nav-link" href="#repository"><span>09</span>仓库文档</a>
</nav>
<div class="sidebar-note">
<span>核心原则</span>
<p>稳定的平台外壳,快速演进的 Agent 核心。</p>
</div>
</aside>
<main id="main-content">
<section class="hero section" id="overview">
<div class="eyebrow"><span>ONE AGENT PATH</span> / MULTI-USER / SELF-HOSTED</div>
<h1>一套可以被持续<br />实验的 Web Agent</h1>
<p class="hero-copy">
K1412 Agent 把账户、界面和执行隔离做成稳定平台,把上下文、工具调度、并行、多 Agent、
记忆和完成判定留在我们自己的 Agent Loop 中。这里既是系统说明,也是后续实验的公开台账。
</p>
<div class="hero-actions">
<a class="button button-dark" href="#architecture">理解架构 <span aria-hidden="true"></span></a>
<a class="text-link" href="#experiments">查看实验记录 <span aria-hidden="true"></span></a>
</div>
<div class="metric-strip" aria-label="当前系统摘要">
<div>
<strong>01</strong>
<span>统一 Agent 路径</span>
<small>没有 Chat / Work 分叉</small>
</div>
<div>
<strong>04</strong>
<span>可选模型</span>
<small>模型与推理强度分离</small>
</div>
<div>
<strong>1 : 1</strong>
<span>用户执行空间</span>
<small>容器、网络与持久卷</small>
</div>
<div>
<strong>SSE</strong>
<span>运行事件流</span>
<small>模型、工具与完成证据</small>
</div>
</div>
</section>
<section class="section architecture-section" id="architecture">
<div class="section-heading">
<div>
<span class="section-index">02 / ARCHITECTURE</span>
<h2>稳定外壳与<br />实验核心解耦</h2>
</div>
<p>
点击一条链路,观察一次请求如何穿过系统。公开入口只有 Web;模型密钥、Docker
权限和用户执行环境始终留在服务端。
</p>
</div>
<div class="architecture-lab">
<div class="flow-tabs" role="tablist" aria-label="架构链路">
<button class="flow-tab is-active" type="button" role="tab" data-flow="agent">
Agent 请求
</button>
<button class="flow-tab" type="button" role="tab" data-flow="identity">身份链路</button>
<button class="flow-tab" type="button" role="tab" data-flow="tool">工具执行</button>
<button class="flow-tab" type="button" role="tab" data-flow="file">文件交付</button>
</div>
<div class="system-map" aria-label="K1412 Agent 系统架构图">
<div class="map-lane map-public">
<span class="lane-label">PUBLIC EDGE</span>
<article class="system-node" data-node="browser">
<small>01 / CLIENT</small>
<strong>Browser</strong>
<span>登录、会话、文件下载</span>
</article>
<span class="map-arrow" aria-hidden="true"></span>
<article class="system-node node-web" data-node="web">
<small>02 / STABLE SHELL</small>
<strong>Open WebUI</strong>
<span>Auth · RBAC · History · UI</span>
</article>
</div>
<div class="map-lane map-core">
<span class="lane-label">PRIVATE APPLICATION NETWORK</span>
<article class="system-node node-runtime" data-node="runtime">
<small>03 / EXPERIMENT CORE</small>
<strong>Agent Runtime</strong>
<span>Context · Loop · Tools · Memory</span>
</article>
<span class="map-arrow" aria-hidden="true"></span>
<article class="system-node" data-node="provider">
<small>04 / INFERENCE</small>
<strong>Model Provider</strong>
<span>K1412 API · DeepSeek</span>
</article>
<article class="system-node" data-node="gateway">
<small>05 / POLICY GATE</small>
<strong>Workspace Gateway</strong>
<span>Identity · Path · Docker lifecycle</span>
</article>
<article class="system-node node-store" data-node="store">
<small>STATE</small>
<strong>PostgreSQL + Redis</strong>
<span>Chats · Events · Plans · Memory</span>
</article>
</div>
<div class="map-lane map-execution">
<span class="lane-label">TAILSCALE / PHYSICAL WORKER</span>
<article class="system-node node-workspace" data-node="workspace">
<small>06 / USER BOUNDARY</small>
<strong>Per-user Workspace</strong>
<span>Container · Network · Persistent volume</span>
</article>
</div>
</div>
<div class="flow-explainer" aria-live="polite">
<span id="flow-kicker">AGENT REQUEST / 7 HOPS</span>
<p id="flow-description">
浏览器的已登录请求由 Web 转换成兼容 OpenAI 的流式调用;Runtime
独立完成上下文构建、模型调用、工具循环和证据校验。
</p>
</div>
</div>
<div class="boundary-grid">
<article>
<span class="boundary-number">A</span>
<h3>Open WebUI</h3>
<p>负责用户系统、会话、历史和呈现。它是产品外壳,不决定 Agent 如何思考与执行。</p>
<small>STABLE / UPSTREAM-BASED</small>
</article>
<article>
<span class="boundary-number">B</span>
<h3>Agent Runtime</h3>
<p>负责模型、上下文、工具、并行、委派、记忆和完成判定,是我们主要的实验面。</p>
<small>FAST-MOVING / OWNED</small>
</article>
<article>
<span class="boundary-number">C</span>
<h3>Gateway + Workspace</h3>
<p>把已验证用户绑定到唯一执行空间,控制路径、资源和 Docker 生命周期。</p>
<small>SECURITY BOUNDARY</small>
</article>
</div>
</section>
<section class="section loop-section" id="agent-loop">
<div class="section-heading inverse-heading">
<div>
<span class="section-index">03 / AGENT LOOP</span>
<h2>模型不是 Agent<br />循环才是。</h2>
</div>
<p>
当前基线为 <code>agent-loop-v3</code>。模型每轮可以回答或提出工具调用;Runtime
负责校验、调度、恢复,并拒绝没有证据的“已完成”。
</p>
</div>
<div class="loop-console">
<div class="loop-stages" role="tablist" aria-label="Agent Loop 阶段">
<button class="loop-stage is-active" type="button" data-stage="context">
<span>01</span><strong>Context</strong><small>裁剪与记忆</small>
</button>
<button class="loop-stage" type="button" data-stage="model">
<span>02</span><strong>Model</strong><small>生成意图</small>
</button>
<button class="loop-stage" type="button" data-stage="validate">
<span>03</span><strong>Validate</strong><small>规范与限制</small>
</button>
<button class="loop-stage" type="button" data-stage="schedule">
<span>04</span><strong>Schedule</strong><small>并行与串行</small>
</button>
<button class="loop-stage" type="button" data-stage="execute">
<span>05</span><strong>Execute</strong><small>工具与委派</small>
</button>
<button class="loop-stage" type="button" data-stage="evidence">
<span>06</span><strong>Evidence</strong><small>验证与完成</small>
</button>
</div>
<div class="loop-detail">
<div>
<span class="detail-label" id="stage-kicker">CONTEXT / recent-visible-v1</span>
<h3 id="stage-title">把有限上下文留给真正影响下一步的内容</h3>
</div>
<p id="stage-description">
移除旧的工具详情渲染,按模型预算保留最新可见消息,再注入最多 8
条持久记忆。上下文策略和 Agent Loop 分别版本化。
</p>
<ul id="stage-points">
<li>去掉历史消息中的工具 UI 标记</li>
<li>最近消息优先,按字符预算截断</li>
<li>记忆只作为补充上下文,不直接取得执行权限</li>
</ul>
</div>
</div>
<div class="loop-principles">
<article>
<span>PARALLELISM</span>
<h3>只并行已知安全的读取</h3>
<p>
连续的只读、<code>parallel_safe</code> 工具可以并发;写入和状态变更保持顺序,
避免输出更快但结果不可复现。
</p>
</article>
<article>
<span>RECOVERY</span>
<h3>失败不是上下文噪声</h3>
<p>命令失败必须被修复并重新运行,重复无进展调用会被守卫阻止,模型不能用文字绕过失败。</p>
</article>
<article>
<span>DELEGATION</span>
<h3>委派是受限的工具</h3>
<p>只读子任务可并行,子 Agent 不能继续委派。父循环仍然负责整合证据和最终完成判定。</p>
</article>
</div>
<div class="evidence-table" aria-label="完成证据规则">
<div class="table-row table-head">
<span>声称完成的类型</span><span>最低证据</span><span>阻止条件</span>
</div>
<div class="table-row">
<strong>生成文件</strong><span>成功写入 + 随后读取或列出</span><span>只有模型文字</span>
</div>
<div class="table-row">
<strong>修改代码</strong><span>变更操作 + 相关验证</span><span>未解决的失败命令</span>
</div>
<div class="table-row">
<strong>生成报告</strong><span>来源或执行结果 + 报告文件验证</span><span>报告早于实验</span>
</div>
<div class="table-row">
<strong>性能比较</strong><span>可解析的精确数值</span><span>只有定性结论</span>
</div>
</div>
</section>
<section class="section workspace-section" id="workspace">
<div class="section-heading">
<div>
<span class="section-index">04 / EXECUTION SPACE</span>
<h2>每个用户,一套<br />长期存在的工具台</h2>
</div>
<p>
生产执行发生在物理机 <code>home-node-itx</code>。Gateway 通过 Tailscale + SSH
管理 Docker;用户得到独立容器、网络和持久卷,而不是宿主机账号。
</p>
</div>
<div class="isolation-visual">
<div class="identity-card">
<small>IMMUTABLE INPUT</small>
<strong>Open WebUI user_id</strong>
<code>sha256(user_id) → workspace_id</code>
</div>
<div class="identity-arrow" aria-hidden="true"></div>
<div class="workspace-stack">
<div><span>CONTAINER</span><code>k1412-ws-&lt;id&gt;</code></div>
<div><span>NETWORK</span><code>k1412-ws-net-&lt;id&gt;</code></div>
<div><span>VOLUME</span><code>k1412-ws-data-&lt;id&gt;</code></div>
</div>
</div>
<div class="security-grid">
<article>
<span class="security-icon">01</span>
<h3>身份不下放给浏览器</h3>
<p>Web 验证登录,Runtime 每次调用 Gateway 前重新签发短期身份。内部服务密钥从不进入前端。</p>
</article>
<article>
<span class="security-icon">02</span>
<h3>容器不是主机边界的替代品</h3>
<p>只读根目录、丢弃 capabilities、no-new-privileges、资源限制、无宿主端口和 Docker socket。</p>
</article>
<article>
<span class="security-icon">03</span>
<h3>依赖和文件都会留下</h3>
<p><code>/workspace</code> 由命名卷持久化;Python 位于 <code>.venv</code>,镜像升级不会删除用户数据。</p>
</article>
<article>
<span class="security-icon">04</span>
<h3>输出可以直接取回</h3>
<p>工作区抽屉支持浏览、下载文件和流式归档。用户无需接触 Gateway、SSH 或容器名称。</p>
</article>
</div>
</section>
<section class="section models-section" id="models">
<div class="section-heading">
<div>
<span class="section-index">05 / MODEL POLICY</span>
<h2>先标清模型,<br />再标真实思考能力</h2>
</div>
<p>
Luna、Terra、Sol 是三个独立模型,不是同一模型的轻、中、高强度。前端只显示后端确认支持的
思考语义;provider、循环和上下文预算仍由服务端模型目录固定。
</p>
</div>
<div class="model-grid">
<article class="model-card">
<div><span class="model-dot luna"></span><small>LOCAL MODEL</small></div>
<h3>Luna</h3>
<p>思考:开启(不分档)</p>
<dl><div><dt>循环上限</dt><dd>8</dd></div><div><dt>上下文预算</dt><dd>120k chars</dd></div></dl>
</article>
<article class="model-card is-default">
<div><span class="model-dot terra"></span><small>LOCAL / DEFAULT</small></div>
<h3>Terra</h3>
<p>思考:开启(不分档)</p>
<dl><div><dt>循环上限</dt><dd>16</dd></div><div><dt>上下文预算</dt><dd>240k chars</dd></div></dl>
</article>
<article class="model-card">
<div><span class="model-dot sol"></span><small>LOCAL MODEL</small></div>
<h3>Sol</h3>
<p>思考:开启(不分档)</p>
<dl><div><dt>循环上限</dt><dd>24</dd></div><div><dt>上下文预算</dt><dd>400k chars</dd></div></dl>
</article>
<article class="model-card model-deepseek">
<div><span class="model-dot deepseek"></span><small>CLOUD / MAX EFFORT</small></div>
<h3>DeepSeek V4 Pro</h3>
<p>思考强度:极高(max</p>
<dl><div><dt>循环上限</dt><dd>32</dd></div><div><dt>上下文预算</dt><dd>800k chars</dd></div></dl>
</article>
</div>
<div class="policy-note">
<span>命名规则</span>
<p>
<strong>Luna / Terra / Sol / DeepSeek V4 Pro</strong> 是四个独立模型。前三者目前只暴露
“思考开启”的布尔能力,不能严谨地标成轻、中、高;DeepSeek 才明确使用
<strong>reasoning_effort=max</strong>,界面标注为“极高”。
</p>
</div>
</section>
<section class="section experiments-section" id="experiments">
<div class="section-heading">
<div>
<span class="section-index">06 / EXPERIMENT LOG</span>
<h2>每次改进都应该<br />留下可比较的记录</h2>
</div>
<p>
实验以问题、基线、变量、数据集、指标和结论为最小单元。页面读取仓库里的
<code>experiments.json</code>,与实现一起版本化。
</p>
</div>
<div class="experiment-toolbar">
<div class="filter-group" role="group" aria-label="实验状态筛选">
<button class="filter-button is-active" type="button" data-filter="all">全部</button>
<button class="filter-button" type="button" data-filter="baseline">基线</button>
<button class="filter-button" type="button" data-filter="validated">已验证</button>
<button class="filter-button" type="button" data-filter="backlog">待实验</button>
</div>
<label class="experiment-search">
<span class="sr-only">搜索实验</span>
<input id="experiment-search" type="search" placeholder="搜索上下文、并行、记忆…" />
<span aria-hidden="true"></span>
</label>
</div>
<div class="experiment-grid" id="experiment-grid" aria-live="polite">
<article class="experiment-loading">正在读取实验台账…</article>
</div>
<p class="experiment-count" id="experiment-count"></p>
</section>
<section class="section operations-section" id="operations">
<div class="section-heading inverse-heading">
<div>
<span class="section-index">07 / OPERATIONS</span>
<h2>一条公开入口,<br />多层私有服务</h2>
</div>
<p>
生产栈运行于 Unraid NAS,公开流量经 VPS 上的 Nginx Proxy Manager 和 Tailscale
进入 NAS。文档和聊天由同一个 Web 镜像提供。
</p>
</div>
<div class="deployment-path" aria-label="部署链路">
<div><small>GIT</small><strong>git.k1412.top</strong></div>
<span></span>
<div><small>OCI</small><strong>docker.k1412.top</strong></div>
<span></span>
<div><small>COMPOSE</small><strong>Unraid NAS :12004</strong></div>
<span></span>
<div><small>PUBLIC</small><strong>agent.k1412.top</strong></div>
</div>
<div class="ops-grid">
<article>
<span>01 / BUILD</span>
<h3>不可变镜像</h3>
<p>镜像按 UTC 时间与 Git commit 标记;发布只替换发生变化的服务。</p>
</article>
<article>
<span>02 / VERIFY</span>
<h3>分层验证</h3>
<p>静态检查、单元测试、真实 Docker、完整 E2E、镜像审计与公开路径冒烟。</p>
</article>
<article>
<span>03 / OBSERVE</span>
<h3>事件优先</h3>
<p>每轮上下文、模型、工具和完成状态进入运行事件,便于重放与实验比较。</p>
</article>
<article>
<span>04 / ROLLBACK</span>
<h3>保留上个版本</h3>
<p>配置先备份,旧镜像不覆盖;验证失败时恢复镜像引用即可回退。</p>
</article>
</div>
</section>
<section class="section timeline-section" id="timeline">
<div class="section-heading">
<div>
<span class="section-index">08 / PROJECT HISTORY</span>
<h2>从业务 Agent 到<br />通用实验平台</h2>
</div>
<p>
项目按“干净重建”推进,不保留旧业务 Skill 和旧 API 兼容层。下面记录已经改变系统性质的关键决策。
</p>
</div>
<ol class="timeline">
<li>
<span>01</span>
<div><small>FOUNDATION</small><h3>重建为多人 Web Agent</h3><p>Open WebUI 承担账户和聊天外壳,自研 Runtime 承担 Agent 能力。</p></div>
</li>
<li>
<span>02</span>
<div><small>PRODUCT</small><h3>收敛为单一 Agent 路径</h3><p>删除 Chat / Work 双模式,降低交互和后端维护成本。</p></div>
</li>
<li>
<span>03</span>
<div><small>EXECUTION</small><h3>迁移到远端持久工作区</h3><p>接入 home-node-itx,打通每用户容器、持久卷与文件交付。</p></div>
</li>
<li>
<span>04</span>
<div><small>RELIABILITY</small><h3>建立证据驱动的完成策略</h3><p>加入恢复、重试守卫、精确报告证据和结构化事件。</p></div>
</li>
<li>
<span>05</span>
<div><small>PLATFORM</small><h3>补齐 Python 环境与长期身份</h3><p>持久化虚拟环境、pipefail、900 秒工具超时和每次调用的新鲜身份令牌。</p></div>
</li>
<li class="is-current">
<span>06</span>
<div><small>NOW</small><h3>文档与实验成为产品界面</h3><p>架构、实现、运维和实验台账随代码发布到同域门户。</p></div>
</li>
</ol>
</section>
<section class="section repository-section" id="repository">
<div class="repository-panel">
<div>
<span class="section-index">09 / REPOSITORY</span>
<h2>网页负责建立心智模型,<br />仓库文档负责成为事实来源。</h2>
<p>
所有设计说明、限制、运维步骤和实验规范都与代码一同提交。门户是摘要,
Markdown 文档是评审与变更时的正式依据。
</p>
<a class="button button-light" href="https://git.k1412.top/wuyang/zk-data-agent">
打开 Git 仓库 <span aria-hidden="true"></span>
</a>
</div>
<div class="doc-list">
<a href="https://git.k1412.top/wuyang/zk-data-agent">
<span>README.md</span><small>产品入口与快速开始</small>
</a>
<a href="https://git.k1412.top/wuyang/zk-data-agent">
<span>docs/architecture.md</span><small>系统边界与请求生命周期</small>
</a>
<a href="https://git.k1412.top/wuyang/zk-data-agent">
<span>docs/agent-loop.md</span><small>Loop、调度、证据与委派</small>
</a>
<a href="https://git.k1412.top/wuyang/zk-data-agent">
<span>docs/experiments.md</span><small>实验方法与路线图</small>
</a>
<a href="https://git.k1412.top/wuyang/zk-data-agent">
<span>docs/operations.md</span><small>发布、恢复与故障处理</small>
</a>
<a href="https://git.k1412.top/wuyang/zk-data-agent">
<span>docs/security.md</span><small>威胁边界与安全控制</small>
</a>
</div>
</div>
</section>
</main>
</div>
<footer>
<span>K1412 AGENT / SYSTEM NOTES</span>
<p>代码、文档与实验共同演进。</p>
<a href="#overview">回到顶部 ↑</a>
</footer>
</body>
</html>