【免费下载链接】AxisAgentic
AxisAgentic: An Extensible Runtime and Trajectory-Collection Framework for Long-Horizon Agents.
AxisAgentic 是一个面向长程智能体(Long-Horizon Agent)的可扩展运行时与轨迹采集框架。它的核心ConversationRuntime状态机,负责在每一步决定是继续调用模型生成、执行工具调用,还是触发回滚、强制收尾。本文用通俗的方式拆解这套状态机:一个智能体任务在几十轮甚至上百轮的"思考—调工具—纠错"循环里,究竟是谁、依据什么规则,做出了每一次关键决策。
1. 一次任务的主循环:状态机在哪运转?
在 AxisAgentic 中,每个任务由 TaskOrchestrator 驱动主循环:
- 调用
initialize_conversation(task)写入 system 消息和初始任务,进入"等待助手回复"状态; - 之后反复执行一轮:看状态机返回的动作,决定下一步做什么。
状态机把当前处境抽象为细粒度的ConversationStage(阶段),再映射成编排器只需关心的 3 种高阶动作:
| 阶段类别 | 代表状态 | 含义 | 状态表情 |
|---|---|---|---|
| 初始化 Setup | initial_user_message_await_assistant | 初始任务已注入,等待模型 | ▶️ |
| 正常流程 | assistant_tool_calls_await_tool | 模型发出工具调用,等待执行结果 | 〰️ |
| 错误恢复 | tool_call_format_error_prompt_await_assistant | 工具调用格式错误,已补发纠正提示 | 💢 |
| 强制收尾 | force_final_await_assistant | 预算耗尽,正在强制要最终答案 | 🔚 |
| 终止 Terminal | assistant_completed/assistant_force_completed/assistant_terminated_token_exceed | 任务结束,不再推进 | ⏹️ |
映射关系定义在 agentic/contracts/conversation.py:所有"等待助手"类状态 →call_model;assistant_tool_calls_await_tool→execute_tools;四个终止状态 →done。这样编排器不用逐个匹配十几个阶段,只按稳定的三值枚举分发,主循环见done才退出。
2. 模型返回后:7 级优先级决策链 🔍
每次模型返回一条 assistant 消息,apply_assistant_message 都会先把它记入对话,然后按从高到低 7 级优先级依次判断,命中即返回下一步动作:
- Token 预算耗尽:
finish_reason="length"且既没有文本也没有工具调用 → 直接进入终止状态,任务判为"token 超限结束"; - 强制收尾轮:如果上一轮已经注入了"请给出最终答案"的提示,则本轮回复原样接受(只拒绝工具调用),避免无限循环;
- 工具调用:存在结构化
tool_calls→ 状态转为assistant_tool_calls_await_tool,把控制权交给工具管理器; - 内容质量检查(仅针对纯文本回复):
- 命中拒答关键词(如"我无法…")→ 回滚该消息,让模型重试;
- 文本里长得像工具调用却不是合法的→ 按
format_error.strategy三选一处理(见下节);
- 直接最终答案:recipe 子类可覆写钩子,若模型已经给出了标准格式的最终答案,直接收尾,省去多余的总结轮;
- 总结提示:若配置了
final_response_prompt,注入"请总结并给出最终答案"再调一次模型; - 正常完成→
assistant_completed,任务结束。
这里有个精妙设计:第 4 步的检查在两种情况下会被跳过——强制收尾轮里必须接受模型的任何输出(否则回滚会死循环),以及总结提示之后的第二轮回复直接采信。简单说:纠错优先,但绝不在"最后通牒"阶段继续纠错。
3. 回滚的三种姿势:为什么删掉历史却不丢历史?⏪
长程任务里,模型经常会"说错话"。AxisAgentic 的回滚不是删除,而是append-only 标记:往全量轨迹里追加一条CONVERSATION_RUNTIME类型的 rollback 标记,记录"隐藏前面 N 条消息 + 原因"。
- 模型可见的对话 = 全量对话重放这些标记后的结果(被回滚的消息从此对模型不可见);
- 模型不可见的全量轨迹永远保留(
full_conversation),用于审计、重放、评估和 SFT 导出。
回滚原因枚举(RollbackReason)覆盖了 6 种场景:assistant_refusal(拒答)、format_error(格式错误)、duplicate_query(重复查询)、tool_error(工具报错)、token_exhaustion(生成被截断)、context_limit(上下文压力)。
其中还有两条更"重"的回滚路径:
- 上下文回滚:预算检查发现快撑爆时,先回滚掉最近一批消息腾空间,再注入强制收尾提示;
- 工具轮次回滚:rollback_latest_tool_exchange_and_force_finalize 会把"最近一次 assistant 工具调用 + 对应工具结果"整段回滚,用于供应商端点报出截断类错误后的恢复。
所有回滚共享一个连续回滚计数器(AssistantRollbackConfig):max_rollbacks限制连续回滚次数,达到上限就停止纠错、放行该回复,防止"纠错本身"变成死循环;工具执行成功或正常完成后,计数器通过reset_rollback_counter()归零。
4. 工具调用格式错误:reprompt / rollback / ignore 三种策略 🔧
模型有时会把"想调工具"以文本形式写出来(比如输出了search("...")却没有产生结构化调用)。状态机用format_error.keywords做关键词探测,命中后按 FormatErrorStrategy 三选一:
- reprompt(默认):保留原消息,追加一条恢复提示"你上一条看起来像工具调用但没有产生合法调用,请重发或继续",再调一次模型;
- rollback:静默隐藏这条坏消息,让模型直接重试(占用回滚计数器);
- ignore:原样接受,不做任何干预。
被回滚的消息还会回退轮次计数——它不算作一次真正的 assistant 轮次,因此不消耗max_turns预算。这是"纠错不惩罚"的公平设计。
5. 强制收尾:上下文与轮次预算如何兜底 🛑
长程任务最怕的不是失败,而是"烧完 token 还没答案"。状态机内置了两道预算闸门(ContextLimitConfig + ContextBudgetEstimator):
min_tokens_for_generation(硬停线):剩余上下文低于此值时,连"生成最终答案"都不可行 → 直接转入assistant_terminated_token_exceed终止;warning_threshold(预警线):剩余空间不足但还够写一句总结 → 注入early_stop_announcement_prompt(默认是"你现在不能再调工具了,请基于已有信息给出最终答案"),进入force_final_await_assistant强制收尾轮。
触发强制收尾的FinalizationTrigger有三种:context_limit(上下文压力)、turn_limit(轮次达上限)、tools_exhausted(工具次数用尽)。每次转移还会验证合法迁移表(VALID_STAGE_TRANSITION),非法跳转直接抛错,保证轨迹在日志和重放层面都可解释。
另外,运行时还会用模型端点实际返回的 prompt token 数来校准本地估算器(record_observed_prompt_tokens),让预算判断越跑越准。
6. 读懂每一步的决策:stage_path 与诊断信息 📊
每次状态转移,ConversationStepResult.info都会输出完整的阶段轨迹stage_path(本步经历的所有状态)、visible_message_count(模型可见消息数)、raw_message_count(全量消息数)、回滚计数、finalization_trigger等字段(ConversationStepInfo)。visible < raw的差值,就是被回滚/压缩标记"藏起来"的历史。
这些信息会被 TaskLogger 写入 append-only 轨迹,供仪表盘排查、replay 重放和 SFT 导出复用——同一份轨迹,既用于评估,也用于训练。
7. 关键配置与延伸阅读 📚
| 配置项 | 作用 |
|---|---|
max_turns | 轮次上限,达到即强制收尾 |
context_limit.window/safety_margin | 上下文窗口与安全边际 |
context_limit.min_tokens_for_generation | 低于该剩余量直接终止(硬停) |
context_limit.warning_threshold | 低于该剩余量注入强制收尾提示 |
format_error.strategy | reprompt/rollback/ignore |
assistant_rollback.max_rollbacks | 连续回滚上限,0 表示关闭 |
assistant_rollback.refusal_keywords | 拒答检测关键词,空列表表示关闭 |
配置模型定义见 ConversationConfig。想深入源码,推荐这条阅读路径:
- 状态机主体:agentic/conversations/conversation_runtime.py
- 阶段、动作与合法迁移表:agentic/contracts/conversation.py
- 回滚/压缩/丢弃标记的序列化格式:agentic/contracts/markers.py
- 主循环消费方:agentic/orchestration/task_orchestrator.py
- 状态机行为测试(读懂每个分支的最佳材料):tests/test_conversation_runtime.py
- 中文架构文档:docs/architecture.zh-CN.md
一句话总结:AxisAgentic 的 ConversationRuntime 把"模型生成、工具执行、回滚纠错、预算收尾"统一进了一张有明确迁移规则的状态图——每一步都可预测、可追溯、可重放。这正是长程智能体能稳定跑完上百轮、并把轨迹变成训练数据的关键。
【免费下载链接】AxisAgentic
AxisAgentic: An Extensible Runtime and Trajectory-Collection Framework for Long-Horizon Agents.
相关推荐
Redux Thunk状态迁移回滚策略:安全机制
Redux Thunk状态迁移回滚策略:安全机制 引言:状态管理的痛点与解决方案 在Redux应用开发中,你是否曾遇到过这样的问题:当一个异步操作失败时,已经更
前端LocalAI实战指南:企业级本地AI引擎深度解析与部署方案
LocalAI实战指南:企业级本地AI引擎深度解析与部署方案 LocalAI作为开源AI引擎的领先方案,为开发者提供了高性能、企业级、分布式、容器化的本地AI推
人工智能大模型模型推理服务本地部署LLM 网关多模态AI AgentRAGMCP 服务Redux状态迁移回滚:安全可靠的升级策略
Redux状态迁移回滚:安全可靠的升级策略 在现代前端开发中,状态管理是构建复杂应用的核心挑战之一。Redux作为一个可预测的状态容器,通过其单向数据流和不可变
前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考