Ruby 独立消费者¶
在自己的应用中使用已发布的 praxo-core==0.9.0,要求 Ruby 3.1 或更新版本。
无需检出 PRAXO-CORE 源码、API Key、模型服务或 AxisVela 产品。安装需要 RubyGems
访问或已有 gem 缓存。
这是扩展语言 starter,只演示 allow/deny 路径,不在四个具备治理负向矩阵的试点语言范围内。
选择边界¶
适用于需要显式工具范围和 Policy 的嵌入式模型/工具循环。应用仍负责模型访问、真实身份、 持久审批、外部效果和隔离。它不是托管 Agent 平台、持久图引擎或沙箱服务。 选型前阅读何时不应选择 Core。
创建应用¶
在 Gemfile 中声明精确依赖:
source 'https://rubygems.org'
gem 'praxo-core', '0.8.0'
然后运行 bundle install。不要使用 path:、git:、vendored 检出或 $LOAD_PATH
替代已发布 gem。
应用源码¶
以下为 starter.rb,来自受测源码。
require 'praxo'
module Starter
M = Praxo::Models
class FixtureModel
def initialize(target)
@target = target
end
def generate(request)
last = request.messages.last
if last.role == M::TOOL
M.response(message: M.message_assistant('recorded'))
else
M.response(message: M.message_assistant('', [
M.tool_call(id: 'record-1', name: 'record', arguments: { 'target' => @target })
]))
end
end
end
class RecordTool
attr_reader :calls
def initialize
@calls = 0
end
def call(_arguments)
@calls += 1
'recorded'
end
end
def self.run_scenario(target)
tool = RecordTool.new
registry = Praxo::Agent::ToolRegistry.new
registry.register(Praxo::Agent::FuncTool.new(
'record', 'Record a target in an in-memory counter.',
->(arguments) { tool.call(arguments) }
))
options = Praxo::Agent::AgentOptions.new(FixtureModel.new(target))
options.tools = registry
options.allowed_tools = ['record']
options.policy = lambda do |action|
case action.kind
when 'model.generate'
M.decision(allowed: true)
when 'tool.invoke'
M.decision(
allowed: action.tool_name == 'record' && action.arguments['target'] == 'public',
reason: 'only the public target is permitted'
)
else
M.decision(allowed: false, reason: 'unsupported action')
end
end
result = Praxo::Agent.run_agent(
options, M.session(id: "consumer-#{target}"), 'Record the requested target.'
)
[result.output, tool.calls, nil]
rescue StandardError => error
['', tool.calls, error]
end
def self.run(out = $stdout)
output, calls, error = run_scenario('public')
unless error.nil? && output == 'recorded' && calls == 1
raise "allow verification failed: output=#{output.inspect} effects=#{calls} error=#{error}"
end
out.puts 'allow: recorded; effects=1'
_, calls, error = run_scenario('private')
unless error && error.message.include?('policy denied') && calls.zero?
raise "deny verification failed: effects=#{calls} error=#{error}"
end
out.puts 'deny: policy rejected; effects=0'
end
end
Starter.run if $PROGRAM_NAME == __FILE__
验收测试¶
以下为 test_starter.rb,来自受测源码。
require_relative 'starter'
output, calls, error = Starter.run_scenario('public')
raise "allow: output=#{output.inspect} effects=#{calls} error=#{error}" unless error.nil? && output == 'recorded' && calls == 1
_, calls, error = Starter.run_scenario('private')
raise "deny: effects=#{calls} error=#{error}" unless error && error.message.include?('policy denied') && calls.zero?
puts 'ruby consumer tests passed'
验证¶
bundle install
bundle exec ruby test_starter.rb
程序预期输出:
allow: recorded; effects=1
deny: policy rejected; effects=0
模型是确定性 fixture,不是真实 LLM。allowed_tools 限制工具名,Policy 额外检查目标
参数。被拒绝的 private 目标不得到达内存效果计数器。替换为真实适配器后仍需保留这些测试。
若使用无 Bundler 的源码检出,可运行 ruby -I language/ruby/lib test_starter.rb;
该路径不算独立消费者证据。
范围¶
本 starter 仅证明指定 gem 与 fixture 行为,不包含治理负向矩阵,也不证明真实身份、 持久审批、效果对账或隔离。后续参考 Ruby 实现指南及 安全模型。