DeepAI Paper Hermes Agent 教程,Hermes 上下文、流式与输出,Hermes 模型与 Provider API 对象不是流:Copilot ACP 把 SimpleNamespace 塞进迭代器后的连锁崩溃

对象不是流:Copilot ACP 把 SimpleNamespace 塞进迭代器后的连锁崩溃

有些 Agent 报错看起来像 provider 不稳定:

API call failed
Non-retryable error
trying fallback
Aborting

但真正的问题可能很底层:协议适配器拿到的是一个对象,却把它当成可迭代的 streaming 数据来处理。

NousResearch/hermes-agent issue #16271 记录的就是这种典型适配层错误。用户使用 copilot-acp provider,模型是 claude-opus-4.7,endpoint 是:

acp://copilot

结果请求失败:

TypeError: 'types.SimpleNamespace' object is not iterable

这不是模型不会回答,也不是 API Key 错,更不是简单重试能解决的问题。

这是 ACP Copilot CLI 的 streamable HTTP response 没有被正确解析。


错误日志透露了什么?

issue 里的日志很短,但信息密度很高:

⚠️  API call failed (attempt 1/3): TypeError
   🔌 Provider: copilot-acp  Model: claude-opus-4.7
   🌐 Endpoint: acp://copilot
   📝 Error: 'types.SimpleNamespace' object is not iterable
⚠️ Non-retryable error (HTTP None) — trying fallback...
❌ Non-retryable error (HTTP None): 'types.SimpleNamespace' object is not iterable
❌ Non-retryable client error (HTTP None). Aborting.
   🔌 Provider: copilot-acp  Model: claude-opus-4.7
   🌐 Endpoint: acp://copilot
   💡 This type of error won't be fixed by retrying.

Error: 'types.SimpleNamespace' object is not iterable

几个关键点:

  • provider 是 copilot-acp
  • endpoint 是 acp://copilot
  • HTTP status 是 None
  • 错误类型是 Python TypeError
  • 系统判断为 non-retryable;
  • fallback 也救不了。

这说明请求并不是远端返回了一个标准 4xx / 5xx。

它更像是在本地解析/适配 response 的过程中,代码对返回结构做了错误假设。


为什么 SimpleNamespace 不能被当成 iterable?

types.SimpleNamespace 是 Python 里一种很轻量的对象容器。

它适合这样访问:

obj.foo
obj.bar

但它不是 list,不是 generator,也不是 async iterator。

如果某段代码期待:

for chunk in response:
    ...

但实际拿到的是:

SimpleNamespace(...)

就会出现:

'types.SimpleNamespace' object is not iterable

这类错误的重点不是 SimpleNamespace 本身,而是上游返回结构和下游消费方式不匹配。


ACP 场景为什么更容易出现这种错?

ACP,也就是 Agent Communication Protocol,本质上是在 Agent 与外部工具/模型/CLI 之间建立一层协议适配。

它不是传统的:

HTTP JSON request → HTTP JSON response

很多 ACP provider 会涉及:

  • streamable response;
  • event message;
  • JSON-RPC 风格结构;
  • CLI bridge;
  • stdout/stderr;
  • object wrapper;
  • async stream;
  • partial result;
  • final result。

如果适配层没有清楚区分“事件流”和“最终对象”,就容易把对象当 chunk 流处理。

这正是 #16271 的核心。


评论里的线索:它不是孤立问题

维护者评论指出:

Likely duplicate of #14437 — same copilot-acp SimpleNamespace iteration crash.
Fix PRs: #15365 (api_mode detection), #14442 (NotImplementedError guard), #14438 (full streaming), #12274.

这说明问题不是单次用户环境异常,而是 Copilot ACP streaming 支持链路中的一类已知缺陷。

几个修复方向也很有信息量:

  • api_mode detection:先判断当前 API 返回模式;
  • NotImplementedError guard:未实现路径不要伪装成可运行;
  • full streaming:真正支持 streaming,而不是半截兼容;
  • 其他适配修复:补齐 ACP response 的消费逻辑。

换句话说,这不是给 TypeError 外面包个 try/except 就结束。

真正要修的是协议层对返回模式的识别。


“重试三次”为什么没用?

很多 API 错误可以重试,例如:

  • timeout;
  • 502;
  • rate limit;
  • connection reset;
  • incomplete chunked read。

但这个错误不属于那类。

SimpleNamespace object is not iterable 是本地代码路径错误。

只要输入结构不变,重试 100 次也会得到同样的 TypeError。

所以日志里说:

This type of error won't be fixed by retrying.

这个判断是对的。

问题在于:用户需要知道这不是 provider 临时抽风,而是 Hermes / ACP adapter 的版本或实现能力问题。


正确的修复思路:先识别 response 形态,再决定消费方式

一个健壮的 ACP adapter 至少要区分这些情况。

1. 普通一次性对象

例如:

SimpleNamespace(content="...", status="completed")

这种不能直接 for-loop。

应该读取字段,转换成 Hermes 内部统一 message/result 格式。

2. 同步 iterable stream

例如:

for event in response:
    handle(event)

这种才适合普通迭代。

3. 异步 stream

例如:

async for event in response:
    handle(event)

这种要走 async iterator。

4. 未实现 streaming

如果某个 mode 还没实现,应该明确抛出 NotImplementedError,并给出可读错误,而不是让用户看到 SimpleNamespace TypeError。

5. 混合结构

有些 provider 会先返回 wrapper,再从 wrapper 里取 stream。

这种要明确解包字段,而不是假设顶层 response 就是可迭代对象。


用户怎么快速判断是不是这个问题?

如果你看到下面组合,就基本可以定位到 ACP adapter 层:

Provider: copilot-acp
Endpoint: acp://copilot
Error: 'types.SimpleNamespace' object is not iterable
HTTP None
Non-retryable client error

这时不建议优先折腾:

  • API Key;
  • DeepAI base_url;
  • 模型上下文窗口;
  • 网络代理;
  • provider fallback;
  • 重试次数。

更应该检查:

  • Hermes 版本是否包含 Copilot ACP streaming 修复;
  • 是否命中了 #14437 / #16271 同类问题;
  • copilot-acp 是否支持当前模型和当前 api mode;
  • 是否有 full streaming 相关 PR 已合并;
  • 是否可以临时切到非 ACP Copilot provider 或标准 OpenAI-compatible provider。

为什么这类错误对 Agent 特别致命?

普通脚本遇到 TypeError,最多这次请求失败。

Agent 场景里会更麻烦:

  • fallback 可能切到另一个 provider,导致输出风格/能力变化;
  • session 状态可能记录一次失败工具调用;
  • 用户以为是模型不可用;
  • 长任务可能被迫中断;
  • 如果错误发生在 streaming 中途,可能没有完整 final answer。

协议适配层越靠近底部,错误越容易被上层包装成模糊的 “API call failed”。

所以文章标题里的“对象不是流”,其实是这类问题的核心:数据形态不能靠猜。


和 DeepAI API 中转站的边界

DeepAI API 中转站提供标准 OpenAI-compatible API 入口:

Base URL: https://api.deepai.wang/v1
API Key: 你的 DeepAI Key
Model: 以 DeepAI 控制台为准

copilot-acp 是 GitHub Copilot + ACP adapter 的专用路径,endpoint 是:

acp://copilot

这和标准 OpenAI-compatible HTTP API 不是一回事。

所以如果你遇到 SimpleNamespace object is not iterable,不要把它归因到 DeepAI API 中转站。这类错误发生在 Hermes 的 Copilot ACP 适配层,而不是 DeepAI 的模型转发层。

更实际的建议是:

  • 需要标准模型 API:用 DeepAI / OpenAI-compatible provider;
  • 需要 GitHub Copilot ACP:升级 Hermes,确认 Copilot ACP streaming 修复是否包含在当前版本;
  • 不要把 acp://copilot 当成普通 https://.../v1/chat/completions

FAQ

SimpleNamespace object is not iterable 是模型错误吗?

不是。它是本地 Python 代码把对象当成 iterable 使用时产生的 TypeError。

重试能解决吗?

通常不能。只要 response 结构不变,重试仍会走同一条错误代码路径。

为什么 HTTP status 是 None?

因为错误可能发生在本地适配/解析阶段,而不是远端返回了标准 HTTP 错误码。

该查 API Key 吗?

如果日志已经明确是 SimpleNamespace object is not iterable,优先查 Hermes Copilot ACP adapter 版本和相关修复,而不是 API Key。

DeepAI API 中转站会导致这个错误吗?

不会。这个错误属于 copilot-acp / acp://copilot 路径,和标准 OpenAI-compatible DeepAI API 不是同一层。


总结

#16271 的教训非常工程化:

不要在协议适配层猜 response 是流。

ACP Copilot CLI 返回的 streamable data 可能是对象、wrapper、同步流、异步流或尚未实现的模式。Hermes 只有先识别 response 形态,再选择消费方式,才能避免 SimpleNamespace object is not iterable 这类本地崩溃。

对用户来说,看到这个错误时也别急着怀疑模型或中转 API。真正该查的是 Copilot ACP adapter 的 streaming 支持和版本修复。

Related Post

Gemini 报 Multiple authentication credentials?Hermes Agent 接入 Google OpenAI-compatible 端点的排错指南Gemini 报 Multiple authentication credentials?Hermes Agent 接入 Google OpenAI-compatible 端点的排错指南

Hermes Agent 接入 Gemini provider 报 HTTP 400 Multiple authentication credentials received?这通常不是简单 API Key 粘错,而是 Google OpenAI-compatible endpoint、Bearer、x-goog-api-key、AIza legacy key 与 AQ 新 key 的认证兼容问题。本文总结排查顺序、临时绕法和 native Gemini adapter 的长期方向。

Hermes 输入 @ 就报 NameError: self is not defined?fuzzy file completions 排错指南Hermes 输入 @ 就报 NameError: self is not defined?fuzzy file completions 排错指南

Hermes CLI 输入 @ 触发文件补全时抛出 NameError: self is not defined?本文解释 _context_completions、@staticmethod、fuzzy file completions 的根因、临时绕过和升级修复路径。

Hermes Agent 跨平台排错:Windows 代理 502、Docker 后端残留和飞书表格源码显示Hermes Agent 跨平台排错:Windows 代理 502、Docker 后端残留和飞书表格源码显示

基于 Hermes GitHub Issues,总结 Windows 系统代理导致 auxiliary client 502、terminal.backend=local 仍跑 Docker、飞书 Markdown 表格显示源码等跨平台问题,帮助区分 DeepAI 模型层和 Hermes 运行环境层。