单一流式 Agent 循环驱动推理、工具和持久化
reply_internal 在一个有界 loop 中调用 provider stream,消费增量消息,执行工具,把结果加入会话,再决定继续、重试、压缩或结束。
它不是“模型回答一次就结束”,而是模型说一步、系统做一步、把结果再交回模型,直到满足结束条件。
Harness 的真正核心是状态机而不是提示词;重试、转向、停止钩子和上下文恢复都进入同一控制环。
- 默认最大 turn 是 1000,不代表每次任务都会接近该值;会话配置和环境参数可覆盖。
1930 let inner = Box::pin(async_stream::try_stream! {
1931 let mut turns_taken = 0u32;
1932 let max_turns = session_config.max_turns.unwrap_or_else(|| {
1933 Config::global()
1934 .get_param::<u32>("GOOSE_MAX_TURNS")
1935 .unwrap_or(DEFAULT_MAX_TURNS)
1936 });
1937 let mut compaction_attempts = 0;
1938 let mut empty_turn_retries = 0u32;
1939 let mut retrying_after_empty_turn = false;
1940 let mut last_assistant_text = String::new();
1941 let mut goal_check_pending = false;
1942 let mut tool_pair_summarization_done = false;
1943 let mut stop_hook_handled_for_exit = false;
1944 let mut retrying_after_stop_hook_denial = false;
1945 let mut consecutive_stop_hook_blocks = 0u32;
1946 let stop_hook_block_cap = self.stop_hook_block_cap();
1947 let mut can_drain_pending_steers = false;
1948
1949 loop {
1950 if is_token_cancelled(&cancel_token) {
1951 break;
1952 }
1953
… 80 lines omitted; exact range 1930–2043 …
2034
2035 let mut stream = Self::stream_response_from_provider(
2036 self.provider().await?,
2037 model_config.clone(),
2038 &session_config.id,
2039 &system_prompt,
2040 conversation_with_moim.messages(),
2041 &tools,
2042 &toolshim_tools,
2043 ).await?;
查看全部 2 处证据
-
实现
crates/goose/src/agents/agent.rs:1930–2043loop { ... stream_response_from_provider(...).await?; } -
实现
crates/goose/src/agents/agent.rs:2883–2929逐条持久化消息,处理 pending steers 与 stop hook 后退出。