20: 对于 AI 代理
Phlo 的构建旨在由 AI 代理驱动,而不仅仅是被它们读取。每个应用程序都暴露出三个 CLI 层,让代理在没有先前代码库知识的情况下工作:reflect:: 用于理解代码,phlo_eval 用于执行代码,build:: 用于转译和验证。这三者都需要 build: true,并且绝不能在生产环境中运行。
如果你是一个正在接手 Phlo 应用的代理,从这里开始。
20.1: 三位一体:理解、执行、构建
三个层次,三个平面。按此顺序访问它们。
| 层 | 平面 | 用于 |
|---|---|---|
reflect:: |
静态 | 在不运行任何内容的情况下理解结构:routes、views、解析的 AST、搜索、依赖图。安全、只读,即使在运行时损坏时也能工作。 |
phlo_eval |
运行时 | 在实时应用中执行一串 Phlo:读取记录、调用方法、渲染视图、重现错误。强大且有副作用。 |
build:: |
转换 | 将 .phlo 源代码构建为 PHP,并在编辑前后对结果进行 lint。 |
reflect:: 和 build:: 在应用 外部 运行(仅源代码,无需启动),这就是它们快速且无副作用的原因。phlo_eval 在启动的应用 内部 运行,这就是它可以接触实时数据的原因,以及它带来真实风险的原因。
20.2: 推荐的工作流程
- 定位。
reflect::context用于一次性快照:身份、路由/视图计数、加载的包、最近的错误。然后reflect::compactRoutes。 - 探索。
reflect::find <type>、reflect::search <query>、reflect::nodeBody <name>、reflect::fileContent <relPath>。 - 执行。 使用
phlo_eval '<phlo>'检查实时数据和行为:计数、记录、方法的实际输出、渲染的视图。 - 阅读。 在编辑之前阅读实际的
.phlo源代码。 - 编辑。 仅限
.phlo、data/app.json和入口点。绝不要编辑生成的 PHP。 - 构建和检查。
build::run,然后build::lint(空数组 = 干净;如果不是,请修复源代码并重复)。 - 记录。 更新
data/app.md,包括结构更改、新路由、已解决的 TODO 和剩余工作。
20.3: 反射:: 在实践中
php www/app.php reflect::context # orient
php www/app.php reflect::compactRoutes # route map
php www/app.php reflect::search "createRecord" all # find usage
php www/app.php reflect::nodeBody home # one method's body
php www/app.php reflect::objectIndex # resources, methods, props
输出为 JSON。 reflect::context 读取 data/app.md,这是一个由人类和代理编写的草稿,帮助您了解意图和状态。有关完整命令参考,请参见 Tooling 章节。
20.4: phlo_eval 在实践中
phlo_eval '<phlo source>' 将一串 Phlo 语句转译并在实时应用中运行。它是反射的运行时补充:reflect:: 读取静态源,而 phlo_eval 则针对真实数据、资源和视图执行。
php www/app.php phlo_eval "user::recordCount()" # 38, no return keyword
php www/app.php phlo_eval "%app->title" # "App"
php www/app.php phlo_eval "echo %app->error('boom')" # <div class="app-error">boom</div>
单个表达式不需要 return:它会像 => 箭头体一样自动返回。只有在多行块中需要时,才使用 return:
php www/app.php phlo_eval '$pro = array_filter(user::records(), fn($u) => $u->tier === "pro")
return array_values(array_column($pro, "email"))'
规则:
- 自动返回。 单行自动返回,正如
=>箭头体,除非它以return/apply/echo/unset/yield开头。多行块需要自己的return。 - 输出。
return <expr>以 JSON 格式打印值:类型安全、不可标量,并且错误以{"error": ...}的形式返回。echo <expr>原样打印到 stdout,以查看渲染的 HTML/标记。 - 作用域。
%resource引用正常解析。应用程序被构建,但其应用控制器(路由器/初始化)被跳过,就像任何 CLI 回调;资源控制器会运行,因此数据库和资源是实时的。 - 错误可读。 失败的调用返回结构化的
{"error": ...},包含类型、消息和源,因此你可以迭代:一次运行教会你user::records()返回对象,下一次使用->tier而不是["tier"]。
20.5: 权力与危险
phlo_eval 以完整的应用权限在实时应用中运行任意代码。在一次调用中,它可以读取密码哈希、API 密钥和个人数据,而在另一次调用中,它可以变更或删除数据(%db->exec(...))。没有沙箱。
这正是它受到限制的原因:
- 仅限 CLI。 即使连接到路由,它也拒绝在 HTTP 请求期间运行。它永远不能成为一个可通过网络访问的 eval 端点。
- 仅限构建。 只有在
build: true时它才存在。它从未被构建到发布或生产应用中;在那里调用它只是一个未定义的函数。 - 仅限开发者编写。 将其输入视为
eval()本身:自己编写,绝不要传递不受信任或用户提供的输入。
在这些限制内,它是一个精确、诚实的工具:它向你展示应用实际执行的内容,而不是源代码所暗示的内容。
20.6: build:: 在实践中
php www/app.php build::run # transpile changed .phlo to PHP
php www/app.php build::lint # [] means clean; otherwise fix the .phlo source
php www/app.php build::release # build the release when stage/prod output changes
Lint 报告在 transpiled PHP 中存在解析错误。始终修复 .phlo 源文件并重新构建;绝不要修补生成的 PHP。有关完整命令参考,请参见工具章节。