Python 版¶
Python 版位于 python/from_scratch_agent/,不依赖任何第三方运行时库。它保持同步 API,
但现在与 TypeScript 版共享 Tools、Memory、Skills 和可靠性策略的设计语义。
阅读顺序¶
types.py:Tool、ModelProvider 和 Context;agent.py:完整循环;tools.py:计算器和时间工具;minimax.py:国内 MiniMax 协议适配;registry.py:按名称加载工具;memory.py:内存、JSON 与 SQLite ConversationStore;skills.py:读取、选择和注入 SKILL.md;reliability.py:timeout、retry 和指数退避;budget.py:单次任务的 token / 成本软预算;rate_limit.py:跨任务共享的模型请求限流;tracing.py:零依赖父子 span 与 JSONL exporter;runtime.py:统一读取环境变量;subagents.py:handoff、预算、event bus 与 scheduler;graph.py:独立状态图运行时;evolution.py:版本化候选、eval gate、审批、发布与回滚;evals.py:JSONL dataset、trace replay 和 report store;workspace.py:限定目录的文件工具与 artifact;mcp.py:stdio MCP、白名单、超时与脱敏;structured_output.py/routing.py:结构化结果与模型路由;durable.py:SQLite checkpoint、task queue 与 event store;cli.py:终端交互外壳。
Stage 2/3 对照组件位于 context_builder.py、memory_index.py 和 skills.py:Python Agent
现在也会在每次模型请求前调用 ContextBuilder,并支持 tokenizer、摘要、三类长期记忆、
BM25-like Skill 发现、版本和依赖解析。
subagents.py 与 graph.py 对齐 Stage 4/5。Python 同步线程不能安全强杀阻塞函数,因此
timeout 返回 cancelled 并停止等待;生产版应使用支持协作取消的 asyncio provider。
evolution.py 对齐 Stage 6,并继续只使用 Python 标准库。Evaluator 是普通函数,因此可以
接假模型、MiniMax、人工 rubric 或经过人工标注验证的 LLM judge。
Stage 10–12 同样只依赖标准库:MCP 通过 subprocess stdio,结构化输出通过 json 和递归
校验,durable store 使用 sqlite3。这些模块与 TypeScript 版保持相同的权限和恢复语义。
运行¶
测试不访问网络:
核心组件配置¶
Python CLI 与 TypeScript CLI 使用相同环境变量:
AGENT_TOOLS=calculator,current_time
AGENT_TOOL_EXECUTION=sequential
AGENT_MEMORY_DATABASE=.agent-data/conversations.sqlite3
AGENT_MEMORY_INDEX_DATABASE=.agent-data/memory-index.sqlite3
AGENT_MEMORY_RECALL_LIMIT=5
AGENT_SESSION_ID=python-cli
AGENT_SKILLS_DIR=skills
AGENT_SKILLS=tool-first
AGENT_MODEL_TIMEOUT_MS=120000
AGENT_MODEL_MAX_RETRIES=1
AGENT_RETRY_DELAY_MS=500
AGENT_MAX_RETRY_DELAY_MS=8000
AGENT_RATE_LIMIT_MAX_REQUESTS=60
AGENT_RATE_LIMIT_WINDOW_MS=60000
AGENT_MAX_TOTAL_TOKENS=120000
AGENT_TRACE_FILE=.agent-data/traces.jsonl
需要可直接阅读的文件时,可改用 AGENT_MEMORY_FILE=.agent-data/conversations.json;
JSON 与 SQLite 只能选择一个,都不设置时仍是纯内存对话。Python SQLite 版只使用标准库
sqlite3,表结构与 TypeScript 版一致。不设置 AGENT_SKILLS 时不会加载任何 skill。
工具参数会在执行前通过与 TypeScript 版相同的 JSON Schema 子集校验。
Python 无法安全地强制终止任意同步函数,因此教学版 timeout 使用 daemon worker 停止 外层等待,同时 MiniMax provider 自身也设置 socket timeout。生产级异步服务建议改用 asyncio/httpx,而不是无限增加后台线程。
预算语义也与 TypeScript 版一致:每次 run() 重新累计,MiniMax 返回一条完整响应后产生
usage 事件,达到上限时不再开始下一次模型调用。需要成本预算时,再按 .env.example
填写 AGENT_MAX_COST、币种和当前套餐的真实 token 单价。
Python 的 ModelRateLimiter 同样跨多次 run() 共享,并在等待前产生
rate_limit_wait。同步教学版使用 time.sleep();迁移到 asyncio 时可直接替换为
await asyncio.sleep(),限流算法不需要改变。
设置 AGENT_TOOL_EXECUTION=parallel 后,Python 版使用标准库 ThreadPoolExecutor
并发执行同一轮的独立工具;future 虽然并行完成,结果仍按模型原始顺序读取和写回。
tracing.py 只使用标准库,并与 TypeScript 输出相同的 JSON 字段。一次 run、每次模型调用
和工具执行形成父子 span;不设置 AGENT_TRACE_FILE 时不会创建文件,也没有额外运行开销。
memory_consolidation.py 是 Stage 16 的同构实现,同样包含不可变 episode、反例、replay
gate、人工激活和 rollback。它没有依赖向量库或 LLM,方便在单元测试和 Notebook 中逐步
替换 evaluator;apply_governed_memories_to_prompt() 只接受 active(tags) 返回的记忆。
Stage 15 的 security.py 同样只用标准库,提供 hashed API Key、RBAC、tenant session key、
*_FILE secret 和 JSONL audit。把 Principal 传给 create_agent_from_env() 后,runtime 会
在 tool、skill、workspace 装配前授权,并自动把外部 session id 映射到租户命名空间。
为什么用 yield¶
如果 run() 只返回最终字符串,外部就不知道模型何时请求工具。生成器允许每走一步就
发出一个事件:
Notebook、CLI 和未来的日志系统都能消费相同事件。
MiniMax 国内版¶
MiniMaxProvider 默认请求:
它只用标准库 urllib,方便读者直接看见 headers、messages 和 tools 如何成为 HTTP
请求。真实项目可以换成支持连接池、重试和异步流式响应的客户端。