出于无聊,在等待后续面试时,我构建了一个由 genruler 提供支持的状态机库。准确地说,是我毕业后第一份工作期间建造的。这个实现大致是基于我的主管当时起草的设计。该项目还旨在展示如何利用规则 dsl。
根据谷歌搜索有限状态机返回的有用摘要(强调我的)
“有限状态机”是指一种计算模型,其中系统在任何给定时间只能处于有限数量的不同状态,并且这些状态之间的转换由特定输入触发,本质上允许它根据一组定义的条件处理信息,不可能有无限数量的状态; “有限”这里指的是系统可以存在的有限的一组可能状态。
该库接收一个表示有限状态机模式的字典。比如我们要建立一个订单追踪系统
graphviz 生成的有限状态机图
架构看起来像这样(为了清晰起见,采用截断的 yaml 形式)
machine: initial_state: pending_payment states: pending_payment: name: pending payment transitions: order_authorization: name: order is authorized destination: authorized rule: (condition.equal (basic.field "is_authorized") (boolean.tautology)) authorized: name: authorized action: authorize_order transitions: order_partially_paid: name: order is partially paid destination: partially_paid rule: (boolean.tautology) order_fully_paid: name: order is fully paid destination: paid rule: (boolean.tautology) ...
登录后复制
因此,为了设置一切,我们调用
import genstates import yaml import order_processor with open("states.yaml") as schema: machine = genstates.machine(yaml.safe_load(schema), order_processor)
登录后复制
因此,在这个虚构的示例中,每当订单发生变化时,我们都会收到一些有效负载。例如,当卖家确认订单时,我们得到
{ "is_authorized": true, ... }
登录后复制
然后我们就可以通过图书馆查
state = machine.initial # assume the order is created transition = machine.get_transition(state, "order_authorization") assert transition.check_condition(payload)
登录后复制
如果在架构中定义,该检查还会运行额外的验证检查。如果您打算向调用者返回错误消息,这会很有帮助。
try: assert transition.check_condition(payload) except validationfailederror as e: logger.exception(e)
登录后复制
有时,我们知道每次有效负载到达时,它都应该触发一次转换,但我们并不总是知道是哪一个。因此,我们只需将其传递给 machine.progress
try: state = machine.progress(state, payload) except validationfailederror as e: logger.exception(e)
登录后复制
一旦知道订单应该进展到什么状态,我们就可以开始编写代码来处理逻辑
# fetch the order from database order = order.get(id=payload["order_id"]) current_state = machine.states[order.state] # fetch next state try: new_state = machine.progress(current_state, payload) except validationfailederror as e: # validation failed, do something logger.exception(e) return except missingtransitionerror as e: # can't find a valid transition from given payload logger.exception(e) return except duplicatetransitionerror as e: # found more than one transition from given payload logger.exception(e) return # do processing (example) log = log.create(order=order, **payload) log.save() order.state = new_state.key order.save()
登录后复制
理想情况下,我还可以提取处理逻辑,这就是我一开始导入 order_processor 的原因。在授权状态定义中,我们还定义了一个action
authorized: name: authorized action: authorize_order ...
登录后复制
因此在 order_processor 模块中,我们定义了一个新函数,名为authorized_order
def authorize_order(payload): # do the processing here instead pass
登录后复制
这样,以下情况是可能的,其中状态管理代码与其余处理逻辑分离
# fetch the order from database order = Order.get(id=payload["order_id"]) current_state = machine.states[order.state] # fetch next state new_state = machine.progress(current_state, payload) # do processing (example) new_state.do_action(payload)
登录后复制
不过,我现在仍在努力,应该会在下一个版本中实现。同时,如果每个状态都定义了操作,它还能够执行类似于map和reduce的操作。请随时检查项目的开发进度。 genruler 和 genstates 现在都在 pypi 上,耶!
现在,人工智能怎么样?
在库有点用后我下载了 codeium windsurf。我最终使用它从 genruler 中去除了 hy 依赖,并向项目添加了文档和自述文件。对于发电机状态,我使用级联来生成文档、自述文件以及测试。总的来说,感觉就像我身边有一个中高级程序员来帮助我完成分配给实习生甚至初级员工的任务。
大部分核心逻辑仍然来自我这边,尽管目前的语言模型已经很智能了,但他们仍然会犯一些错误,因此需要监督。我还尝试了 qwen2.5-coder:7b 模型,它运行得相当好,尽管由于我的工作站蹩脚,速度相当慢。我发现如果我要构建自己的产品并设法从中赚钱,codeium 要求的价格是公平的。
虽然生成部分工作正常,但编写实际代码并不那么好。我不确定 pylance 是否在那里正常工作,认为它是专有的,或者是否是由于完成魔法 windsurf 所做的,我的编辑器在我编写代码时不再能够自动导入库。例如,当我在代码中自动完成 reduce() 函数时,在 vscode 中,它会自动将 from functools import reduce 插入到我的代码中。然而,风帆冲浪却并非如此,这使得它有点令人恼火。然而,考虑到这是新的,编码体验应该随着时间的推移而修复。
另一方面,我仍在寻找一个更轻的编辑器,zed 确实引起了我的注意。然而,由于我的 surface book 2 最近坏了,当我离开家庭办公室时,我只剩下三星 galaxy tab s7fe。因此,连接到我的工作站的具有 web 前端(而且非常有用)的 vscode 仍然是我的主要编辑器(它甚至可以与 neovim 扩展一起使用)。
由 llm 提供支持的生成式人工智能正在迅速改变我们的生活,没有理由抗拒它。然而,恕我直言,我们也应该有一些自我克制,不要把它用于所有事情。它确实应该用作创新或创造性工作的补充,而不是创新和创造力的替代品。
我们也应该知道它在输出什么,而不是盲目接受它做了什么。例如,在 genruler 中,我用更广泛的示例改进了我原来的自述文件。我没有按原样接受它,而是让它为自述文件中生成的所有示例生成测试,因此示例代码通过并按我的预期工作。
总的来说,是的,我确实认为这些生成式人工智能增强编辑器确实物有所值。归根结底,这些都是工具,它们的目的是为工作提供帮助,而不是取代敲键盘的人。
以上就是在人工智能工具的帮助下构建状态机库的详细内容,更多请关注其它相关文章!