Frona - 自托管个人AI助手

Reddit r/AI_Agents 产品

摘要

Frona 是一款全新发布的、基于 Rust 构建的自托管个人 AI 助手,它通过沙盒环境、统一策略引擎以及基于保险箱的凭据管理,着重强调安全性。

嘿,自从大型语言模型(LLM)的工具调用成为常态以来,主流模式一直是:先发布一个能够执行代码、浏览网页和调用 API 的 AI 助手,至于安全问题则留待以后解决。Frona 的诞生正是为了对抗这种模式。 Frona 是一款个人 AI 助手。你可以创建自主代理(autonomous agents),它们在沙箱环境中运行,对你的文件、网络和凭据拥有受控的访问权限。这些代理可以浏览网页、运行代码、构建应用程序、拨打电话、连接消息通道、互相委派任务,并在对话间保持上下文记忆。你只需给出任务,它们就会自行找出完成方法。你可以将其部署在自己的基础设施上。 该平台从底层开始就优先考虑安全性,引擎由 Rust 编写,因此速度快、轻量级,且所有操作均在单进程中运行。现在已正式发布。我认为这个社区会欣赏这种设计理念,因为它是为自建(self-hosting)用户打造的。这是一个成品,而非让你花一个周末去组装的工具包。 每一次工具调用、每条通道消息以及每个沙箱决策都经过同一个策略引擎处理。凭据由保险库支持,沙箱按主体(principal)隔离,内置单点登录(SSO),MCP 服务器作为一等公民存在。你无需编写认证胶水代码、加固容器、手动集成保险库,或在凌晨两点用“胶带”把通道粘到代理上。所有功能在第一天就已就绪。 你可以把它看作是一个更用户友好的 OpenClaw 或 Hermes Agent,但区别在于它从第一天起就内置了安全性,而不是事后修补,更不是把问题推给用户去解决。如果你想知道详细对比,请查看评论区的链接(包含与 OpenClaw 和 Hermes Agent 的全面比较)。以下是简短版的核心差异: **无需为每个代理使用容器的沙箱** OpenClaw 和 Hermes 在沙箱化时都依赖 Docker,这意味着每个新代理(有时是每个新 MCP 服务器)都会成为你需要管理的一段容器基础设施。Frona 运行在单个 Rust 进程中,为每项工作生成沙箱化的子进程:每个 CLI 工具调用一个、每个 MCP 服务器一个、每个部署的应用一个,并针对每个主体应用系统调用级别的过滤。拥有 10 个代理和 5 个 MCP 服务器时,你只需要一个引擎和几个沙箱化子进程,而不是 10 个容器。且沙箱默认开启。如果沙箱无法初始化,引擎将拒绝启动。 **统一的策略引擎** 工具访问权限、文件系统规则、网络目的地、端口绑定、通道授权、信号处理等,全部使用同一种策略语言编写。“此 MCP 服务器只能访问 `api.github.com:443`”、“此通道仅接受来自这些配对号码的入站消息”、“此代理仅在系统代理委派时才能使用 Shell 工具”。这些都是一行规则,无需自定义代码。每个代理的网络访问可以是完全开放/限制特定主机/完全离线,文件路径和资源限制也是如此。 **入站消息的双 LLM 模式** 来自外部发送者的入站通道消息属于不可信输入。这正是提示注入(prompt injection)容易得手的地方。Frona 的分发器实现了 Simon Willison 的双 LLM 模式:一个隔离的、工具注册表被精简的 LLM 处理不可信内容(它只能标记并结束任务,无法回复,也无通用工具),而特权 LLM 仅能看到经策略审核的内容。因此,恶意短信无法欺骗响应代理泄露数据或运行工具。 **凭据由保险库支持,绝不存入聊天** 无需将 API 密钥粘贴到提示词中并希望模型会忘记它们(它们不会)。代理请求凭据时,你会收到通知,显示它们想要什么以及原因,你可以设定时间限制(一次性、几小时、几天或永久)进行批准。本地凭据在静止状态下使用 AES-256-GCM 加密。或者接入你现有的保险库:1Password、Bitwarden(包括自建版)、HashiCorp Vault、KeePass、Keeper。沙箱化进程获得仅针对该进程及其生命周期范围内的临时令牌。即使令牌泄露,影响范围也是有限的。 **MCP 支持,但更高效地使用 Token** MCP 服务器作为一等公民存在,每个服务器在各自的沙箱中运行,拥有各自的策略。默认的*桥接模式*将所有 MCP 服务器暴露给 LLM 作为单个 CLI 工具,而不是单独广告每个 MCP 工具的 Schema。对于一个拥有 5 个 MCP 服务器和 60 多个工具的代理来说,每轮对话可节省数千个 Token。上下文用于你的任务,而不是模型尚未需要的 JSON Schema。 **持久化浏览器会话** 代理获得命名浏览器配置文件,可在对话间保留 Cookie、本地存储和会话。登录一次,保持登录状态。遇到验证码或双重身份验证(2FA)时,它会暂停,提供调试器链接供你处理,完成后自动恢复。 **其他值得提及的功能** * **自带 LLM(BYO LLM):** 支持 Ollama、Anthropic、OpenAI、Groq、DeepSeek、Gemini 以及十多种其他模型 * **简易部署:** 通过 Docker Compose 仅需 3 个容器:Frona、Browserless(浏览器自动化)、SearXNG(私有网页搜索) * **多用户与 SSO:** 支持 Google、Okta、Keycloak、Authentik 及任何 OIDC 提供商 * **应用程序:** 要求代理为你构建工具/仪表板/集成,批准后,Frona 会在相同的沙箱和策略机制保护下立即提供服务 * **记忆与技能:** 跨对话保留的事实,以及可按代理范围分发的可复用指令包 * **信号(Signals):** 代理可以暂停对话,等待匹配的入站消息(验证码、回复、特定类别的消息),并在消息到达时自动恢复 * **通道:** 目前支持 Web UI、Telegram、SMS;更多通道即将推出 * **电话呼叫:** 通过 Twilio 进行出站语音通话 * **API 访问:** 个人访问令牌(Personal Access Tokens)用于你自己的自动化流程 * **Rust 编写:** 占用资源少,流式传输快。 obligatory Rust mention :) 目前仍在打磨细节。下一步计划:提供一个插件框架,让你在不触碰核心代码的情况下扩展平台,以及除了 Telegram 和 SMS 之外的更多通道适配器。 非常希望能听到实际自建工具的用户反馈。你们希望首先连接什么? 如果你无法访问所有的前沿模型,Haiku 4.5 是大多数任务的坚实选择。价格便宜,且在给予适当的工具反馈时,能力令人惊喜。
查看原文

相似文章

Phrony

Product Hunt

Phrony 是一款新产品,旨在帮助开发者在降低运营负担的同时部署 AI 智能体。

OpenAI Frontier 介绍

OpenAI Blog

# OpenAI Frontier 介绍 来源:[https://openai.com/index/introducing-openai-frontier/](https://openai.com/index/introducing-openai-frontier/) AI 让团队能够承担他们过去只谈论但从未执行的事情。事实上,75% 的企业员工表示 AI 帮助他们完成了以前无法完成的任务。我们听到来自各个部门的反馈,而不仅仅是技术团队。工作的方式已经改变,企业开始感受到巨大变化。我们已经看到这在行动中 w

# 我厌倦了"保姆式"管理我的AI。于是我花了6个月时间构建了一个C++20自主软件工厂,让它在我睡觉时也能持续交付 大约一年前,我和大多数开发者一样使用AI辅助编码——在IDE里接受建议,偶尔请它帮我解释某段代码,或者让它生成一些样板代码。这还不错,但我发现自己一直在做的事情本质上是:**充当AI的执行层**。 我来决定做什么。AI来建议怎么做。我来评估建议。我来运行代码。我来解读错误信息。然后我再把结果喂回给AI,整个循环重新开始。 每次会话都让我觉得自己更像一个翻译,而不是一个开发者。 --- ## 打破循环 我开始思考:为什么AI不能自己关闭这个循环? 不是"下一行代码建议"那种意义上的自主——而是真正的**任务级自主**:接收一个高层规格说明,然后自主规划、实现、测试并交付完整的软件组件,无需手把手指导。 挑战在于,这需要的不仅仅是一个更好的提示词。它需要一个具备真实内存、真实工具访问权限和真实决策能力的**架构**。 我花了6个月时间构建它。用C++20编写。这就是我学到的东西。 --- ## 架构概览 我将整个系统称为**自主软件工厂(Autonomous Software House,ASH)**。其核心思想是:你提供一个意图(以自然语言、工单或规格文档的形式),系统负责将其转化为可工作的软件。 系统由五个主要层次组成: ``` ┌─────────────────────────────────────┐ │ 意图接收层 │ │ (自然语言 → 结构化任务) │ ├─────────────────────────────────────┤ │ 规划与分解层 │ │ (任务 → 有序子任务图) │ ├─────────────────────────────────────┤ │ 执行层 │ │ (子任务 → 代码/测试/文档) │ ├─────────────────────────────────────┤ │ 验证层 │ │ (输出 → 通过/失败 + 诊断) │ ├─────────────────────────────────────┤ │ 内存与上下文层 │ │ (跨会话持久状态) │ └─────────────────────────────────────┘ ``` 让我逐层分解。 --- ## 第一层:意图接收 大多数AI工具在这一步就已经失败了。它们要求你用AI能理解的方式来表达你的意图,而不是反过来。 ASH的意图接收器会将模糊的高层描述转化为结构化的**任务规格(TaskSpec)**: ```cpp struct TaskSpec { std::string id; std::string intent; // 原始自然语言描述 std::vector<std::string> acceptance_criteria; std::map<std::string, std::string> constraints; Priority priority; std::optional<std::string> parent_task_id; // 从意图推断出的字段 TaskType inferred_type; // FEATURE / BUGFIX / REFACTOR / TEST std::vector<std::string> inferred_dependencies; ConfidenceScore intent_confidence; }; ``` 关键设计决策:系统存储**原始意图**以及解析后的结构。当后续层次需要消歧时,它们可以回溯到原始表述,而不是在已经经过转化的描述上继续操作。 意图接收器还会检测**欠规格说明**——它不是在遇到歧义时直接执行,而是生成澄清问题,并在继续之前等待答复。这消除了大量由于AI对不明确指令做出假设而导致的"错误方向"执行。 --- ## 第二层:规划与分解 这是最有趣的层,也是最难做好的层。 给定一个`TaskSpec`,规划器需要生成一个可执行的子任务图。挑战在于:子任务必须足够细粒度,以便可以独立执行,同时又必须足够高层,以便有意义地组合。 我使用了一个**递归分解策略**,配合复杂度预算: ```cpp class TaskPlanner { public: SubTaskGraph decompose(const TaskSpec& spec) { auto initial_plan = llm_client_.plan(spec); SubTaskGraph graph; for (auto& subtask : initial_plan.subtasks) { if (estimate_complexity(subtask) > complexity_budget_) { // 递归分解过于复杂的子任务 auto sub_graph = decompose(subtask); graph.merge(sub_graph); } else { graph.add_node(subtask); } } // 推断依赖关系 dependency_analyzer_.annotate(graph); // 检测循环依赖(不能存在) if (graph.has_cycles()) { graph = cycle_resolver_.resolve(graph); } return graph; } private: float estimate_complexity(const SubTask& task); LLMClient llm_client_; DependencyAnalyzer dependency_analyzer_; CycleResolver cycle_resolver_; float complexity_budget_ = 0.7f; // 可调参数 }; ``` `complexity_budget_`参数是系统中最重要的可调旋钮之一。设置过高,你会得到执行失败的庞大单体子任务。设置过低,你会得到过于细碎、难以整合的任务碎片。 我最终针对不同任务类型采用了不同的预算值:功能实现用0.7,bug修复用0.5,重构用0.8。 --- ## 第三层:执行层 这是代码真正生成的地方。执行层为每个子任务维护一个独立的上下文窗口,同时通过共享的内存层(见下文)保持对全局项目状态的感知。 ```cpp class ExecutionAgent { public: ExecutionResult execute(const SubTask& task, const ProjectContext& context) { // 构建执行上下文 auto exec_context = build_context(task, context); // 生成初始实现 auto implementation = llm_client_.implement(task, exec_context); // 自我评审循环 for (int attempt = 0; attempt < max_attempts_; ++attempt) { auto review = self_review(implementation, task); if (review.is_acceptable()) { break; } // 根据评审意见修改实现 implementation = llm_client_.revise( implementation, review.critique, exec_context ); } return ExecutionResult{ .implementation = implementation, .confidence = calculate_confidence(implementation, task), .side_effects = detect_side_effects(implementation, context) }; } private: ExecutionContext build_context(const SubTask& task, const ProjectContext& context); ReviewResult self_review(const Implementation& impl, const SubTask& task); LLMClient llm_client_; int max_attempts_ = 3; }; ``` **自我评审循环**是这里的关键创新。执行智能体不仅生成代码——它还用一个独立的提示词来评审自己的输出,专门检查: - 对任务规格的符合性 - 边界条件处理 - 与已知项目约定的一致性 - 潜在的副作用 这将"第一次尝试"的验证通过率从约40%提升到约75%。 --- ## 第四层:验证层 即使有了自我评审,生成的代码也经常无法通过验证。验证层负责实际运行代码并解读结果。 关键洞察:**错误消息本身就是数据**。大多数AI工具在遇到编译错误或测试失败时会崩溃退出。ASH将这些错误解析为结构化的诊断信息,并将其反馈回执行层: ```cpp struct ValidationResult { bool passed; std::vector<Diagnostic> diagnostics; CoverageReport coverage; PerformanceProfile performance; // 关键:将失败原因分类 FailureCategory failure_category; std::string remediation_hint; }; enum class FailureCategory { COMPILATION_ERROR, RUNTIME_ERROR, TEST_ASSERTION_FAILURE, PERFORMANCE_REGRESSION, COVERAGE_INSUFFICIENT, STYLE_VIOLATION }; ``` 对失败原因进行分类改变了执行层的修复方式。`COMPILATION_ERROR`通常意味着语法问题——执行层会专注于修复语法。`TEST_ASSERTION_FAILURE`通常意味着逻辑问题——执行层会重新检查其对任务规格的理解。 --- ## 第五层:内存与上下文 这是整个架构中最难解释的层,但可以说是最重要的层。 LLM的一个基本限制是上下文窗口。对于需要数百个文件和数千行代码的真实项目,你不可能将整个代码库塞入每一次LLM调用。 ASH使用了一个**分层内存系统**: ```cpp class MemorySystem { public: // 工作内存:当前任务的即时上下文 WorkingMemory working; // 情景记忆:最近操作的历史记录 EpisodicMemory episodic; // 语义记忆:项目知识(架构、约定、模式) SemanticMemory semantic; // 程序记忆:已知有效的操作序列 ProceduralMemory procedural; // 为给定任务检索相关上下文 RelevantContext retrieve_for_task(const SubTask& task) { return retriever_.query( task, working, episodic, semantic, procedural ); } private: ContextRetriever retriever_; }; ``` 语义记忆存储经过编码的项目知识: ```cpp struct ProjectKnowledge { std::string architecture_summary; std::vector<CodingConvention> conventions; std::map<std::string, ModuleInterface> module_interfaces; std::vector<DesignPattern> established_patterns; std::vector<KnownPitfall> known_pitfalls; }; ``` `known_pitfalls`字段特别有价值。每当验证失败并且根本原因被诊断出来时,该失败就会被编码为一个已知陷阱,并存储在语义记忆中。未来的执行不会重蹈覆辙。 --- ## 实际效果如何? 经过6个月的迭代,系统在以下方面表现良好: **✅ 运行良好的场景:** - 具有明确接口的独立模块 - 跟随已建立模式的功能添加 - 有清晰错误信息的Bug修复 - 有明确目标的重构 - 测试编写 **⚠️ 仍需人工参与的场景:** - 涉及多个系统的架构决策 - 具有外部依赖的性能优化 - 安全敏感代码(我会审查每一处) - 业务逻辑需要领域专家知识的场景 **❌ 尚未奏效的场景:** - 跨代码库进行大规模重构 - 调试非确定性问题(竞态条件等) - 需要创意权衡的设计工作 吞吐量方面:在一个良好运作的夜晚,系统能够处理8-12个票据(ticket),从规格说明到通过验证的代码。并非所有这些都能在第一次尝试时合并——我通常会在早上进行一次审查会话——但这比我一个人手动处理要多得多。 --- ## 为什么选择C++20? 这个选择引发了一些问题,所以值得解释一下。 原因主要有以下几点: 1. **协程**:C++20的协程对于管理并发智能体任务的执行流程非常合适。执行智能体可以在等待LLM响应时挂起,而不会阻塞整个系统。 2. **概念(Concepts)**:C++20的概念让我能够表达精确的类型约束,这在处理多种类型的任务、结果和上下文时非常有价值。 3. **Ranges**:对于许多数据转换操作,ranges库使代码更具表达力且不易出错。 4. **性能**:整个系统的大部分时间都在等待LLM API响应,所以性能并不是主要因素——但对于内存操作和上下文检索,低延迟确实很重要。 我不是说C++20是实现此类系统的唯一合理选择。但它对我来说效果很好。 --- ## 我学到的最重要的东西 **1. AI自主性的瓶颈是上下文,而不是能力** 现代LLM足够聪明,可以完成大多数编码任务。让它们失败的是缺乏上下文——不了解项目约定、不了解最近的变更、不了解代码库的整体架构。解决上下文问题比提升模型能力更有影响力。 **2. 失败是数据,而不是异常** 大多数AI编码工具将失败视为需要处理的错误,而不是需要学习的信息。当你开始将失败作为数据捕获和存储时,系统会随着时间推移变得更加可靠。 **3. 欠规格说明比过度规格说明更危险** 我的直觉是要尽可能地欠规格说明任务,让AI去填补细节。这是错误的。欠规格说明的任务会产生技术上可行但业务上错误的实现。现在系统在开始执行之前会主动探测欠规格说明的情况。 **4. 分层内存比更大的上下文窗口更重要** 当更大的上下文窗口开始普及时,我以为这会解决我的上下文问题。在某种程度上确实有帮助,但分层内存系统——它能够精确检索相关上下文,而不是将一切都塞入窗口——的效果要好得多。 **5. 人工监督仍然是必要的,但位置不同了** 我并没有消除人工监督。我改变了它的位置:从实时监督(保姆式)变为异步审查(编辑式)。这在主观体验上是一个巨大的改变。 --- ## 下一步 我目前正在研究的问题: - **多智能体协调**:多个执行智能体并行处理同一代码库上的独立任务,而不会产生冲突 - **更好的副作用检测**:当一个实现对系统其他部分产生意外影响时 - **规格说明生成**:将高层路线图条目自动分解为可操作的任务规格 如果有人正在构建类似的系统,我很乐意交流。这个领域移动得非常快,我在这里分享的很多内容可能在6个月后就会显得过时——但底层原则,关于上下文、失败学习和异步监督的原则,我认为会比较持久。 --- *如果你想深入了解某个特定层次,或者想讨论C++20实现的具体细节,请在评论中告诉我。*

Reddit r/AI_Agents

# Neon Sovereign Neon Sovereign 是一款原生 C++20/Vulkan 自主软件开发工作站,通过多智能体集群端到端执行软件开发任务,使用 Ollama/GGUF 在本地运行 LLM 权重,无需依赖任何云服务。目前该项目正式进入 Active Alpha 阶段,创建者正在寻找系统工程师和早期测试人员。

Nemotron Labs:OpenClaw Agent 对各类组织的意义

NVIDIA Blog

OpenClaw 是一个开源的持久化 AI 助手,已成为 GitHub 上星标最多的项目,引发了关于安全与自主性的讨论。NVIDIA 正与其合作以增强安全性,并发布了 NemoClaw 作为安全的参考实现。