Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions docs/ai-conversation-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ uv run python scripts/gen_ai_flow_doc.py
|---|---|---|
| 总流程与计时 | `ConversationTurn.run`、`StageTimer`、`run_turn` | [conversation/turn.py](../src/fogmoe_telegram_bot/features/conversation/turn.py)、[conversation/turn_types.py](../src/fogmoe_telegram_bot/features/conversation/turn_types.py) |
| 估价、扣费 | `_plan`、`_charge`、`charge_turn` | [conversation/billing.py](../src/fogmoe_telegram_bot/features/conversation/billing.py) |
| 了解用户 | `_load_context`、`format_user_state_prompt` | [core/prompt_utils.py](../src/fogmoe_telegram_bot/core/prompt_utils.py) |
| 了解用户 | `_load_context`、`user_state_prompt`、`format_user_state_prompt` | [ai/user_state.py](../src/fogmoe_telegram_bot/features/ai/user_state.py)、[core/prompt_utils.py](../src/fogmoe_telegram_bot/core/prompt_utils.py) |
| 看图(历史里只存描述,原图通过 `runtime_replacements` 只给这一次请求) | `_prepare_inputs` | [conversation/turn.py](../src/fogmoe_telegram_bot/features/conversation/turn.py) |
| 记下用户的话 | `_record_input` → `insert_records`、`get_history` | [conversation/turn_services.py](../src/fogmoe_telegram_bot/features/conversation/turn_services.py) |
| 思考与动手 | `_run_model` → `run_model`(`ModelRequest` / `ModelResponse`) | 见第 3 节 |
| 记下做了什么 | `_record_output`、`tool_logs_to_record_entries` | [ai/tool_history.py](../src/fogmoe_telegram_bot/features/ai/tool_history.py) |
| 思考与动手 | `_run_model` → `run_model`(`ModelRequest` / `ModelResponse`);工具上下文 `build_tool_context`,回复整理 `finish_reply` | 见第 3 节;[ai/tools/context.py](../src/fogmoe_telegram_bot/features/ai/tools/context.py)、[ai/outbound.py](../src/fogmoe_telegram_bot/features/ai/outbound.py) |
| 记下做了什么 | `_record_output`、`tool_logs_to_record_entries`、`reply_record_entries` | [ai/tool_history.py](../src/fogmoe_telegram_bot/features/ai/tool_history.py) |
| 发出回复 | `_deliver`、`_deliver_messages` | [conversation/turn.py](../src/fogmoe_telegram_bot/features/conversation/turn.py) |
| 收尾 | `_finalize`、`archive_completed_clear`、`flush_events` | [conversation/turn_services.py](../src/fogmoe_telegram_bot/features/conversation/turn_services.py) |
| 每次写入历史后:打包发送被淘汰的归档、容量提示、溢出时生成摘要 | `_persist_records` | [conversation/turn.py](../src/fogmoe_telegram_bot/features/conversation/turn.py) |
Expand All @@ -57,17 +57,18 @@ uv run python scripts/gen_ai_flow_doc.py

| 步骤 | 代码 | 文件 |
|---|---|---|
| 按顺序选模型服务、熔断、看不了图时换成文字、失败分类 | `get_ai_response`、`_try_ai_services`、`_messages_for_service`、`_provider_circuit_is_open` | [ai/router.py](../src/fogmoe_telegram_bot/features/ai/router.py) |
| 主模型失败后用备用模型、跳过的工具 | `run_chat_provider`、`skip_tools` | [ai/chat_provider.py](../src/fogmoe_telegram_bot/features/ai/chat_provider.py) |
| 每次尝试跑一次工具循环(带上声明里隐藏的工具)、看不了图时换成文字、失败转成提示 | `get_ai_response`、`_try_ai_services`、`_run_chat_candidate`、`_messages_for_service`、`skip_tools` | [ai/router.py](../src/fogmoe_telegram_bot/features/ai/router.py) |
| 按顺序换 provider 与备用模型、安全拦截、熔断(主聊天、摘要、回顾与 `run_ai_task` 共用) | `run_with_fallback`、`ProviderCircuit`、`CHAT_CIRCUIT` | [ai/task_runner.py](../src/fogmoe_telegram_bot/features/ai/task_runner.py) |
| 拼好上下文(人设 + 用户状态) | `compose_system_prompt` | [ai/prompts.py](../src/fogmoe_telegram_bot/features/ai/prompts.py) |
| 工具循环、边做边说、工具执行后的重试 | `run_tool_loop`、`emit_visible_content`、`_create_chat_completion_with_post_tool_retries`、`resolve_assistant_message` | [ai/tool_runner.py](../src/fogmoe_telegram_bot/features/ai/tool_runner.py)、[ai/tool_loop_delivery.py](../src/fogmoe_telegram_bot/features/ai/tool_loop_delivery.py)、[ai/tool_loop_messages.py](../src/fogmoe_telegram_bot/features/ai/tool_loop_messages.py) |
| 一次工具调用:参数校验、执行、媒体立刻发出、只把公开部分交回模型、附带的事件 | `_validate_tool_args`、`_call_tool`、`send_media_result_immediately`、`public_tool_result`、`context_messages_from_tool_result` | [ai/tool_loop_execution.py](../src/fogmoe_telegram_bot/features/ai/tool_loop_execution.py)、[ai/tool_loop_delivery.py](../src/fogmoe_telegram_bot/features/ai/tool_loop_delivery.py) |
| 时间用完时:结果未知、未执行 | `close_interrupted_round`、`TurnDeadlineError` | [ai/tool_loop_deadline.py](../src/fogmoe_telegram_bot/features/ai/tool_loop_deadline.py)、[ai/tool_runner.py](../src/fogmoe_telegram_bot/features/ai/tool_runner.py) |
| 单次请求上限、按服务的协议整理消息 | `create_chat_completion`、`enforce_messages_context_budget`、`sanitize_messages_for_provider` | [ai/litellm_client.py](../src/fogmoe_telegram_bot/features/ai/litellm_client.py)、[ai/context_budget.py](../src/fogmoe_telegram_bot/features/ai/context_budget.py)、[ai/litellm_message_sanitizer.py](../src/fogmoe_telegram_bot/features/ai/litellm_message_sanitizer.py) |
| 发到 Telegram | `TelegramVisibleContentHandler` | [ai/telegram_visible_sender.py](../src/fogmoe_telegram_bot/features/ai/telegram_visible_sender.py) |

出问题时的处理规则见 [ai-provider-architecture.md](ai-provider-architecture.md) 的「主聊天的 fallback」:
上下文超限 `ContextBudgetExceededError`、工具执行后失败 `PartialAIResponseError`、安全拦截 `SafetyBlockError`。
出问题时的处理规则见 [ai-provider-architecture.md](ai-provider-architecture.md) 的「回退规则」与「主聊天的 fallback」:
上下文超限 `ContextBudgetExceededError`、执行过工具或发出过可见内容之后失败 `PartialAIResponseError`(由 `has_side_effects` 判断)、
安全拦截 `SafetyBlockError`。

## 4. 工具箱

Expand Down Expand Up @@ -159,7 +160,7 @@ uv run python scripts/gen_ai_flow_doc.py
| 每次写入:锁住这一行、清理配不上对的 tool 消息、估算 token、插入 `near_limit` / `new_session` 事件 | `insert_chat_records`、`_insert_chat_records_once`、`_sanitize_messages_with_tool_pairs`、`estimate_conversation_tokens` | [core/chat_records.py](../src/fogmoe_telegram_bot/core/chat_records.py)、[core/token_estimator.py](../src/fogmoe_telegram_bot/core/token_estimator.py) |
| 只留最近的一段,保留它们需要的工具调用 | `_trim_messages_with_tool_context` | [core/chat_records.py](../src/fogmoe_telegram_bot/core/chat_records.py) |
| 存进归档,淘汰超出保留数的旧快照并打包发给用户 | `prune_permanent_records`、`send_permanent_records_archive` | [core/archive_utils.py](../src/fogmoe_telegram_bot/core/archive_utils.py) |
| 溢出时先即时生成摘要,来不及就转后台 | `handle_history_overflow`、`handle_snapshot_created` | [conversation/history_hooks.py](../src/fogmoe_telegram_bot/features/conversation/history_hooks.py) |
| 溢出时先即时生成摘要,来不及就转后台 | `handle_history_overflow`、`handle_snapshot_created`、`refresh_summary_after_overflow` | [conversation/history_hooks.py](../src/fogmoe_telegram_bot/features/conversation/history_hooks.py)、[ai/summary.py](../src/fogmoe_telegram_bot/features/ai/summary.py) |
| 摘要助手、把摘要放回开头 | `generate_summary_immediately`、`schedule_summary_generation`、`_run_summary_agent`、`async_update_latest_history_state_summary` | [ai/summary.py](../src/fogmoe_telegram_bot/features/ai/summary.py) |
| 清空对话 | `archive_chat_and_start_new_session` | [conversation/clear.py](../src/fogmoe_telegram_bot/features/conversation/clear.py) |
| 金币用完时暂停记录、恢复时补标记 | `_build_coin_service_state_event`,`_finalize` 里以 `suspend_if_zero` 写入 | [core/chat_records.py](../src/fogmoe_telegram_bot/core/chat_records.py) |
Expand All @@ -172,6 +173,9 @@ uv run python scripts/gen_ai_flow_doc.py
| 空闲回顾:`_run_recap_agent` 写回顾(`idle_recap` 事件),主模型再写跟进消息 | 回顾:`IDLE_RECAP_TOOLS`;跟进:主聊天全套 | [ai/idle_followup.py](../src/fogmoe_telegram_bot/features/ai/idle_followup.py) |
| 摘要助手 `_run_summary_agent` | `search_prior_context` | [ai/summary.py](../src/fogmoe_telegram_bot/features/ai/summary.py) |

定时消息和空闲跟进的主模型与一轮对话共用同样的步骤:用户状态提示词 `build_user_state_prompt`、工具上下文
`build_tool_context`(没有聊天字段,带撤销信号)、回复整理 `finish_reply`;历史经 `write_history` 写入
([ai/history_writer.py](../src/fogmoe_telegram_bot/features/ai/history_writer.py)),回复经 `send_private_reply` 发出。
claim、租约与崩溃恢复见 [job-recovery.md](job-recovery.md)。

## 阈值与上限(自动生成)
Expand All @@ -189,7 +193,7 @@ claim、租约与崩溃恢复见 [job-recovery.md](job-recovery.md)。
| `请求硬上限(推导)` | `150000` | [features/ai/litellm_client.py](../src/fogmoe_telegram_bot/features/ai/litellm_client.py) | CHAT_TOKEN_LIMIT × 倍数;消息 + 工具 schema + 最大输出 + 预留超过它就报错,不删也不截断任何内容 |
| `CHAT_CONTEXT_SAFETY_TOKENS` | `2048` | [core/config.py](../src/fogmoe_telegram_bot/core/config.py) | 估算请求大小时额外预留的 token |
| `run_tool_loop(max_iterations)` | `10` | [features/ai/tool_runner.py](../src/fogmoe_telegram_bot/features/ai/tool_runner.py) | 工具循环最多几轮;用完后不带工具再要一次最终回复 |
| `POST_TOOL_COMPLETION_RETRY_DELAYS_SECONDS` | `(1.0, 3.0)` | [features/ai/tool_runner.py](../src/fogmoe_telegram_bot/features/ai/tool_runner.py) | 工具执行过之后,模型调用遇到临时错误时的重试间隔(同一模型,不换 provider) |
| `POST_TOOL_COMPLETION_RETRY_DELAYS_SECONDS` | `(1.0, 3.0)` | [features/ai/tool_runner.py](../src/fogmoe_telegram_bot/features/ai/tool_runner.py) | 执行过工具或发出过可见内容之后,模型调用遇到临时错误时的重试间隔(同一模型,不换 provider) |
| `_trim_messages_with_tool_context(keep_non_tool)` | `10` | [core/chat_records.py](../src/fogmoe_telegram_bot/core/chat_records.py) | 压缩时保留最近几条非 tool 消息;它们引用的 tool_call 会一并保留,保持配对 |
| `PERMANENT_RECORDS_KEEP` | `100` | [core/chat_records.py](../src/fogmoe_telegram_bot/core/chat_records.py) | 每个用户保留的归档快照数(user.permanent_records_limit 可单独设置),更早的打包发给用户后删除 |
| `SUMMARY_IMMEDIATE_TIMEOUT_SECONDS` | `120.0` | [features/ai/summary.py](../src/fogmoe_telegram_bot/features/ai/summary.py) | 压缩时这一轮最多等多久的即时摘要,超时转后台生成 |
Expand Down
Loading
Loading