直接调用
from openprogram import agent
answer = agent("Analyze this paper",
model="configured-model")使用当前执行的会话;没有外层执行时创建独立的一次执行。
维护者设计 · 装饰器移除实施中
Agent 定义可复用模型配置。Context 定义父继承、命名内容、动态求值和历史可见性。
框架自动管理执行上下文。应用调用 agent() 或普通 Agent 方法,不需要手动构造 Context。
所有入口复用 Runtime、AgentSpec、工具策略、执行控制和 Session DAG。Agent 配置不默认拥有会话。
from openprogram import agent
answer = agent("Analyze this paper",
model="configured-model")使用当前执行的会话;没有外层执行时创建独立的一次执行。
from openprogram import Agent
bot = Agent(model="configured-model")
first = bot("Investigate this topic")
second = bot(first)无需继承类。实例复用配置;历史是否连续由执行作用域决定。同一实例的独立顶层调用默认互不共享历史。
class Researcher(Agent):
model = "configured-model"
def research(self, question):
text = self.prepare(question)
return self(text)
def prepare(self, text):
return text.strip()
result = Researcher().research("A topic")方法正常编写,无逐方法装饰器;research 和 prepare 均可记录。self(...) 使用相同的 Agent 执行内核。
小写 agent() 提供便捷调用入口,大写 Agent 是可配置、可调用的类。二者进入同一内部执行函数;不创建进程级共享历史的默认 Bot。构造实例只解析配置,不发模型请求、不分配持久会话。首次执行时才解析会话和创建调用。
同步入口用于普通同步代码;异步代码使用 await bot.arun(...) 或 await agent_async(...)。已有事件循环内使用异步入口。
| 触发条件 | 规则 |
|---|---|
| 进入程序或顶层调用 | 框架建立执行作用域并绑定当前 Context;存在外层会话时沿用其明确分支。 |
| 进入函数或方法 | 派生当前作用域,保留父子关系与可见性规则;不复制完整历史。 |
| 每次模型请求之前 | 解析 Context 的 DAG 来源、实例内容、动态内容和调用覆盖;筛选、去重、预算处理后生成模型输入。 |
| 模型返回 | 将模型交互更新到当前执行状态;下一次构建可按规则使用。 |
| 函数返回、异常或取消 | 恢复父作用域;已产生的模型交互按 expose / render_range 可见,不把全部子上下文无条件合并。 |
| 离开顶层执行 | 解除任务局部绑定并关闭本次拥有的资源。复用 Agent 本身不延续历史;会话续接由宿主或显式会话选择决定。 |
调用关系决定上下文的继承与可见性;predecessor 决定会话顺序。Context 是运行时的构建对象,不要求复制或持久化每个时刻的完整内容。会话持久化与 Trace 导出沿用现有机制,不能决定 Agent 的上下文所有权。
每个 Agent 执行分别管理自己的 DAG。聊天只记录用户消息、模型请求和直接工具调用;普通辅助函数不产生持久化节点。调用另一个 Agent 时创建独立 DAG,父图只保存调用结果和 child_session_id 引用。权限、取消与文件修改备份仍由原执行负责,不依赖图所有权。
行为测试的宿主在应用 OS 沙箱前初始化标准 SessionStore。测试进程通过 Context 绑定已有 SessionNodeWriter,Agent 调用复用它。候选测试不能创建子进程、修改源码快照、访问宿主秘密或使用网络。取消结束规范执行;结果未知的外部操作记录仍可检查。确切的 assistant 投影在节点或存储暂不可用时通过持久 DAG outbox 重试。显示投影失败不能使已执行的取消变为拒绝。取消带恢复错误的暂停执行时,显示状态改为 cancelled,清除错误元数据,并保留已有内容。资源释放 observer 失败仍向控制调用方报告。普通 Job 完成由持有结果的执行方完成投影。取消通知不能在该执行方提供结果与错误详情前写入其他 Job 终态。
def research(question):
data = prepare(question)
return analyze(data)
def prepare(question):
return question.strip()
def analyze(data):
return agent(data)受管 Program 加载器保留必要的 Runtime 注入与入口适配,内部辅助函数使用轻量作用域,不逐次持久化。函数签名、返回值、异常与 import 保持正常 Python 语义。
Agent 子类的实例、静态和类方法遵循 Agent 所有权边界。普通内部方法不写入 DAG,也不自动注册为工具。
方法配置函数与受管 Agent 方法使用同一作用域处理,不重复采集。入口登记与工具暴露保持显式。
任意宿主文件、依赖包、lambda、动态生成代码与不可用源码不自动采集。其 agent() 调用仍可执行,普通 Python 调用关系不逐次持久化。
Context 具有父作用域、命名内容、动态提供函数和历史可见性规则。每次模型请求都使用同一模型。
| 组成 | 行为 |
|---|---|
| 父作用域 | 子上下文继承当前执行上下文。作用域退出时恢复父绑定。 |
| 内容 | 命名值提供指令和业务数据。子上下文可覆盖名称,不修改父上下文。 |
| 求值 | Python 提供函数收到当前 Context,在框架构建模型请求时运行。 |
| 可见性 | 现有 Session DAG 按分支、调用作用域、expose 和 render_range 选择允许读取的交互。 |
实例绑定是命名内容的特例。调用派生 Context 时加入 Agent 配置中的内容。Agent 实例不默认拥有执行会话。
父 Context + Agent 配置 + 调用内容
→ 派生当前 Context
→ 求值命名内容并选择可见 DAG 交互
→ 应用现有预算与压缩
→ Runtime.exec 模型请求历史选择与内容替换分别处理。文本相同不表示交互相同。框架在实际请求中记录选中的 DAG 身份。
Context 不增加第二个历史数据库或 provider 运行时。工具授权与历史可见性分别处理。
Context(store=writer, head_id=None) 为重复调用绑定现有 SessionNodeWriter。Context 会话通过已有 Session DAG 续接模型交互。
head_id 选择已有分支末端。未指定末端时续接当前会话末端。调用者拥有显式提供的 store。
NOOA 式实例事件生命周期属于显式 Context 绑定。Agent 配置仍不默认拥有历史。
| 配置 | 归属与优先级 |
|---|---|
| model / effort / instructions / tools | 显式调用覆盖 → 实例配置 → 类默认 → 当前会话默认 → 产品默认。缺省与空列表等显式清空须区分。 |
| expose / render_range | 默认沿用现有行为;method_options 或显式函数元数据提供可见性设置。 |
| tool visibility / approval | 独立于 DAG 可见性;必须经过现有工具注册、权限检查和审批。更内层的配置不能扩大外层权限。 |
| AgentSpec / session | 持久 Bot 配置复用 AgentSpec;执行作用域引用 Session DAG;实例可配置 Context 内容与来源。仅创建 Python 对象不自动创建侧栏 Bot 或调度任务。 |
构建上下文默认只需要模型交互与必要调用关系;普通函数的完整参数、返回值和局部变量不属于默认采集要求。显式传入的模型内容仍需有界序列化;self 使用身份或类型引用,不序列化整个对象或客户端。方法名必须包含模块及类限定名,避免两个类的同名方法冲突。普通 Python 副作用仍遵循宿主执行和沙箱规则;记录调用不等于对任意 Python 操作逐一审批。
当前 Context、调用身份和有效配置使用任务局部绑定,进入时保存、退出时恢复。继承时不复制完整历史,也不共享可被原地修改的分支配置。嵌套调用可重入;共享 Agent 配置不意味着共享执行上下文。若显式使用可变实例内容或共享会话,需要明确的同步与快照规则。
异常、超时、取消均恢复父作用域,保留已完成模型交互的状态。独立调用复用现有权限请求上下文;缺少审批时沿用非交互规则。恢复仍通过现有安全点和显式步骤完成,不恢复任意 Python 栈。
Context 位于 openprogram/context/model.py,Agent 位于 agentic_programming/agent_class.py,共用调用作用域位于 agentic_programming/call_scope.py。
Runtime 历史选择保留在 agentic_programming/runtime/history.py。受管源码加载保留在 programs/_source_loader.py 和 _registry.py。
实现状态以代码审查与受影响检查为依据,在文末集中说明。
| 方面 | 取舍 |
|---|---|
| 类与方法 | 采用类声明、普通调用以及框架内部方法处理;实例绑定本身已存在。 |
| Context 建模 | 采用类与实例式内容管理、动态求值和作用域覆盖;增加已有 DAG 来源与组合能力。默认有效上下文属于执行作用域。 |
| 历史筛选 | NOOA 按 call_id 筛选当前调用事件,并支持嵌套配置继承。我们保留 DAG 分支和范围规则;不能声称对方完全不按调用调整上下文。 |
| Trace 与模型上下文 | NOOA 区分 events 与 traces。我们保留单一 DAG,生成不同展示和模型输入视图。 |
| 生成策略 | Predict、CodeAct、typed return 和持久 cell 作为后续独立方案,复用现有 llm/agent 执行内核。 |
| 不采用 | 逐函数手写上下文、进程全局共享历史、全解释器追踪、第二套 provider/事件数据库。 |
公开文档和示例注明受 NVIDIA-labs OO Agents 启发,并引用其仓库与论文。独立实现不声称上游 API 兼容或复现其基准结果;若复用源码,保留对应许可和署名。
Context 是具有父作用域、命名内容、动态提供函数和历史可见性规则的类。所有请求使用相同的构建过程。DAG 只提供可见交互及调用关系,不作为另一个策略。实例绑定是该模型的特例:将命名内容绑定到实例,再在调用时加入当前作用域。
公共入口为 Agent、Context、agent 和 agent_async。Agent.__call__ 提供同步调用,Agent.arun 提供异步调用。Agent 子类普通方法,包括单下划线帮助方法,自动建立作用域。已登记 Program 的普通函数由限定源码加载器处理。业务代码不需要逐方法配置,也不需要手动启动 Trace。
Context.current() 返回当前绑定。Context.derive() 派生子上下文。Context 支持命名内容、动态提供函数以及可选历史过滤。bind() 发布当前任务上下文及显式 writer,拒绝与已有 writer 冲突,退出时恢复绑定。动态提供函数收到当前 Context,构建请求时求值。使用 Python callable,不执行字符串表达式。显式修改实例内容保留在实例上,框架生成的模型交互属于执行会话。
CallScope 区分正式操作记录与轻量函数执行。另一个 Agent 使用独立会话写入器;同一 Agent 的内部方法不新增结构节点。
模型请求继续经过 Runtime.exec、现有 provider、工具权限、预算及压缩路径。无外层执行时创建本次拥有的执行环境,结束时释放。模型配置相同或 Agent 对象相同不意味着会话相同。异步分支各自派生上下文,并保留明确调用身份。
实现包含统一 Context、Runtime 构建、共享调用作用域、Agent 类与便捷入口、已登记源码采集、产品文档和已交付程序迁移。NOOA 的 Predict、CodeAct 与完整 API 兼容不属于上下文建模等价的要求。
按用户要求优先编码。只运行覆盖公共入口、分支隔离、迁移后的原有行为及权限的必要验证。验证在后台进行,独立编码继续。完成前检查结果,不用未结束的测试证明完成。英文接口说明与错误信息采用 ASD-STE100 的简短句和一致术语。
实现复用 Session DAG、Runtime、AgentSpec、权限检查、预算和压缩。方法配置与新自动作用域使用共用的调用作用域。
自动源码采集仅作用于受管 Program 加载器选择的源码。普通宿主文件和依赖包不自动采集函数调用。
入口登记和工具暴露保持显式。记录私有帮助函数不会将其注册为模型工具。生成器创建不产生已完成函数记录。
公共 API 与实际迁移必须符合已实现的加载器和执行范围。独立代码审查和受影响检查决定下方实现状态。
| 场景 | 可观察结果 |
|---|---|
| 无模型父函数 | research → prepare / analyze → agent 的所有范围正确;模型输入输出和失败归属可核对;无需完整保留普通函数数据。 |
| Context 继承与求值 | 父继承、实例内容、动态求值与可见性均通过公共入口验证;动态内容每次请求刷新,同名覆盖顺序固定,来源去重不丢失重复发生的交互。 |
| 上下文等价 | 相同 DAG、分支和规则下,新旧入口得到相同历史;只在真实请求产生时记录读取来源。 |
| 会话生命周期 | 构造无副作用;同实例跨任务不混入历史,不同 Agent 在同任务按规则共享;独立调用隔离,已有会话显式续接。 |
| 自动预算与压缩 | 长历史触发已有压缩且引用可追踪;摘要费用计入预算;失败不静默遗失历史。 |
| 并发与资源 | 兄弟任务分支隔离、共享可变实例状态的并发策略、内部重入、取消/异常后父范围恢复、资源仅由所有者关闭。 |
| 加载与身份 | 只采集授权源码;递归/导入别名保持记录;跨类同名方法不冲突;方法配置无重复节点。 |
| 权限及展示 | 方法被记录不自动成为工具;拒绝先于副作用;独立入口同样执行策略;默认 App 展示函数、模型、工具和最终状态。 |
验证只执行公共入口、分支隔离、原有行为与权限所需的最少受影响检查,以已完成结果作为证据。默认安装 App 使用 default profile、18100、~/.openprogram 和 /Applications/OpenProgram.app。
可恢复函数执行在初次调用与继续执行时使用同一个持久函数节点 ID。模型 tool-call 身份保存在节点元数据中。继续执行复用该节点,并保留原始模型调用身份。
Agent 与 Context 承担完整函数执行约定。删除的公共装饰器没有兼容适配器。Agent method_options 保留输入元数据、Runtime 注入、登记与 schema、可用性、权限、可见性、重试、执行控制及显式步骤恢复。
受管源码声明 PROGRAM_ENTRIES 与 __agent_options__。内部模块引用 call_state.py,方法使用 _is_agent_method 标记。已有执行节点数据格式与会话历史保留。
第一方 workflow、生成程序、扫描器、分发器和文档使用普通 Agent 类,不引入替代装饰器。
GUI、research 与 wiki harness 的源码迁移保留 agentics 包路径。构建阶段使用 scripts/release/program-patches 内的源码补丁产生待安装包,stage-program-source.py 应用源码变更,product-runtime.json 校验 checksum。这属于源码构建步骤,不是运行时兼容适配器。
六个本机已发布 workflow 同样在隔离源码中迁移并本地集成。本机与打包变更不证明上游远端已经发布。
装饰器移除和源码迁移已实现,独立规格审查与质量审查均通过。针对性检查覆盖源码加载、schema、Runtime 注入、权限、取消、恢复及不同方法的身份。实际本地源码和已安装 App 的部署另行验收。
图所有权代码已通过独立规格和质量审查,安装版本行为单独验收。
Agent 与 Context 公共入口及源码迁移已经存在,针对核心迁移的规格与质量审查已有结果。原框架全部行为的保留需要独立规格审查、质量审查及完整验证。任务证据分别记录这些结果与核心迁移检查。验收覆盖自动调用作用域、会话展示、Goal 生命周期、取消、恢复与随产品发布的 Programs。调用记录必须保留 DAG 关系,并保持会话内容、Session 所有权与执行权限。
| 项目 | 状态 |
|---|---|
| Session DAG、Runtime、AgentSpec、权限与压缩 | 本设计复用现有实现。 |
| 公共 Agent 与 Context 入口、共用作用域及受管源码 | 已实现。受影响公共入口检查与两项独立审查均通过。 |
| 默认安装 App 验收 | 提交源码后单独核验安装状态。使用 scripts/refresh-local-app.sh 与默认安装 App;源码检查不能单独证明安装后的行为。 |
| NOOA Predict、持久 cell 与 CodeAct 兼容 | 不在本次实现范围内。不声称上游 API 兼容或基准等价。 |