v1.2 真实模型接入 + Thinking 死循环修复

- 新增 OpenAIProvider / ClaudeProvider,接入 Deepseek 真实 API
- 修复 Deepseek thinking 模式 reasoning_content 回传问题
- 修复 Thinking 阶段过渡指令每轮重复插入导致的死循环
- 新增 maxTurns 保护、dumpMessages/dumpTools 调试输出
This commit is contained in:
zhuyongxin
2026-05-14 20:35:44 +08:00
parent f75d0c49ae
commit daa89531f5
9 changed files with 491 additions and 47 deletions
+38 -3
View File
@@ -29,6 +29,28 @@ func NewAgentEngine(p provider.LLMProvider, r tools.Registry, workDir string, en
}
}
// dumpMessages 打印当前上下文中的所有消息 (调试用)
func dumpMessages(msgs []schema.Message) {
for i, msg := range msgs {
content := msg.Content
if len(content) > 80 {
content = content[:80] + "..."
}
log.Printf(" [%02d] %-10s | %s", i, msg.Role, content)
}
}
// dumpTools 打印当前可用的工具列表
func dumpTools(tools []schema.ToolDefinition) {
if len(tools) == 0 {
log.Printf(" [Tools] (无可用工具)\n")
return
}
for i, t := range tools {
log.Printf(" [Tool %d] %s — %s", i, t.Name, t.Description)
}
}
// internal/engine/loop.go (续)
func (e *AgentEngine) Run(ctx context.Context, userPrompt string) error {
log.Printf("[Engine] 引擎启动,锁定工作区: %s\n", e.WorkDir)
@@ -46,18 +68,25 @@ func (e *AgentEngine) Run(ctx context.Context, userPrompt string) error {
}
turnCount := 0
const maxTurns = 10
for {
turnCount++
if turnCount > maxTurns {
log.Printf("[Engine] 已达最大轮数 (%d),强制终止。\n", maxTurns)
break
}
log.Printf("\n========== [Turn %d] 开始 ==========\n", turnCount)
dumpMessages(contextHistory)
// 获取当前挂载的所有工具定义
availableTools := e.registry.GetAvailableTools()
dumpTools(availableTools)
// ====================================================================
// Phase 1: 慢思考阶段 (Thinking) - 剥夺工具,强制规划
// Phase 1: 慢思考阶段 (Thinking) - 仅第一轮执行初始规划
// ====================================================================
if e.EnableThinking {
if e.EnableThinking && turnCount == 1 {
log.Println("[Engine][Phase 1] 剥夺工具访问权,强制进入慢思考与规划阶段...")
// 核心机制:传入的 availableTools 为 nil!
@@ -72,6 +101,12 @@ func (e *AgentEngine) Run(ctx context.Context, userPrompt string) error {
fmt.Printf("🧠 [内部思考 Trace]: %s\n", thinkResp.Content)
contextHistory = append(contextHistory, *thinkResp)
}
// 插入过渡指令:让模型知道现在可以调用工具了
contextHistory = append(contextHistory, schema.Message{
Role: schema.RoleUser,
Content: "根据你的推理,现在请使用可用的工具来完成任务。执行具体行动。",
})
}
// ====================================================================
@@ -79,7 +114,7 @@ func (e *AgentEngine) Run(ctx context.Context, userPrompt string) error {
// ====================================================================
log.Println("[Engine][Phase 2] 恢复工具挂载,等待模型采取行动...")
// 此时的 contextHistory 中已经包含了上一阶段模型自己的 Thinking Trace。
// 此时的 contextHistory 中已经包含了上一阶段模型自己的 Thinking Trace + 过渡指令。
// 模型会顺着自己的逻辑,结合恢复的 availableTools 发起精准的工具调用。
actionResp, err := e.provider.Generate(ctx, contextHistory, availableTools)
if err != nil {