👉 【必看】SOLO 挑战赛主赛道作品提交指南|这样发帖更容易入围&人人都有机会拿奖!

请求邀请码,我可以深度的测试咱们的产品

1 个赞

我想用 SOLO 做业务流程梳理,提升工作效率

1 个赞

社长,你给我站出来,我哦们交流一下邀请码的事情

1 个赞

请给个邀请码

1 个赞

TetherBot 项目问题修复与功能增强

—— 基于微信的 AI 助手长对话能力深度优化

发布日期:2026年4月23日 | 项目路径:tetherbot-weixin | 状态:已完成

────────────────────────────────────────────────────────────

一、项目背景

TetherBot 是一个基于微信的 AI 助手项目,集成大语言模型(LLM)、多工具调用和会话管理能力。

在本次优化之前,项目存在以下核心问题:长期对话中话题无法保持、上下文丢失、工具返回结果生硬、长对话处理能力不足。

1.1 典型问题案例

· **问题现象:**用户说"现在我们明确一下聊天主题为:AI助手与用户的协作伦理",AI 回复"�� 现在是 17:45:48,2026年04月23日,Thursday",完全忽略了话题设置。

· **用户追问:**用户问"你记得我们明确的聊天主题是什么吗?“,AI 回答"我的记忆是基于当前的对话上下文的”,表示无法回溯话题。

· 根本原因:"现在"触发时间关键词 → 被错误识别为时间查询 → 话题设置逻辑被跳过 → 话题永远无法建立 → 每条消息创建新会话(ID不一致)

二、问题根因分析

RC-1:会话ID不固定

**问题描述:**每次消息使用 f"wechat_{sender_id}" 查找会话,但 create_conversation() 生成随机 UUID,导致每次都创建新会话,对话历史完全丢失。

**涉及文件:**wechat/ai_handler.py

代码片段:

conversation_id = f"wechat_{sender_id}" → 创建新会话

RC-2:话题设置优先级低

问题描述:"现在"同时触发时间关键词和话题设置意图,但时间查询分支优先执行,话题检测逻辑被跳过。

**涉及文件:**wechat/ai_handler.py

代码片段:

_is_realtime_query(“现在…”) → True → 时间分支 → _detect_and_set_topic 从未被调用

RC-3:工具结果未合成

**问题描述:**实时查询(天气、新闻、计算器)直接返回 JSON 格式的工具输出,用户体验生硬、不自然。

**涉及文件:**wechat/ai_handler.py

代码片段:

直接 return {“success”: True, “weather”: “…”} → 未经过 LLM 合成

RC-4:记忆系统未集成

**问题描述:**MemoryManager 存在完整架构(BuiltinMemoryProvider、TF-IDF索引、长期存储),但 AIHandler 从未调用 sync_turn / prefetch 方法。

**涉及文件:**wechat/ai_handler.py

代码片段:

内存系统代码存在但完全被绕过

RC-5:长对话无压缩

**问题描述:**对话超过 20 轮后,上下文窗口持续增长,最终导致 token 超限或响应变慢。

**涉及文件:**core/conversation.py

代码片段:

compress_long_conversation() 方法存在但从未被调用

三、修复方案与实现

FIX-1:固定会话ID与会话持久化

**修复说明:**通过 _user_conversations 字典维护 user_id → conversation_id 映射,确保同一用户复用同一会话。

实现细节:

· 新增 _user_conversations: Dict[str, str] 字段存储用户到会话ID的映射

· 新增 _get_or_create_conversation() 方法:查找缓存的会话ID,若存在且ACTIVE则复用,否则创建新会话

· 会话创建后立即缓存映射关系,第二次消息开始使用同一会话

**涉及文件:**wechat/ai_handler.py (行 18-25, 55-67)

核心代码:

self._user_conversations: Dict[str, str] = {}

def _get_or_create_conversation(self, sender_id: str) → tuple:
if sender_id in self._user_conversations:
conv_id = self._user_conversations[sender_id]
conversation = self.conversation_manager.get_conversation(conv_id)
if conversation and conversation.state == ConversationState.ACTIVE:
return conversation, conv_id
conversation = self.conversation_manager.create_conversation(…)
self._user_conversations[sender_id] = conversation.conversation_id
return conversation, conversation.conversation_id

FIX-2:话题设置优先级高于实时查询

**修复说明:**新增 _is_topic_setting() 方法检测话题建立意图,在 process_message_async() 中优先于 realtime 查询处理。

实现细节:

· 定义话题设置关键词:明确一下、主题是、话题是、定为、我们来聊等

· 流程调整:is_topic_setting() → is_realtime_query() → normal LLM path

· 话题关键词自动检测:从用户消息中提取主题存入 conversation.context[“topic”]

· 话题上下文注入:_build_topic_context() 生成提示文本,在每次 LLM 调用前注入

**涉及文件:**wechat/ai_handler.py (行 107-116, 499-522)

核心代码:

def _is_topic_setting(self, query: str) → bool:
query_lower = query.lower()
topic_setting_keywords = [
“明确一下”, “主题是”, “话题是”, “定为”, “讨论”,
“我们现在明确”, “现在我们讨论”,
]
return any(kw in query_lower for kw in topic_setting_keywords)

FIX-3:实时查询结果 LLM 合成

**修复说明:**将工具调用结果(天气、新闻、GitHub、计算器)通过 LLM 合成自然语言回复,而非直接返回 JSON。

实现细节:

· _handle_realtime_query() 返回 (tool_results, synthesis_needed)

· _synthesize_realtime_reply() 构建结构化查询结果上下文,通过 LLM 生成自然语言

· 支持城市名智能提取:去除"天气"、“查询”、"怎么样"等后缀

· 保留最近 6 轮对话历史作为上下文参考

**涉及文件:**wechat/ai_handler.py (行 142-200, 267-331)

核心代码:

def _handle_realtime_query(self, query: str) → tuple:
tool_results = {}
synthesis_needed = False
# … 多工具检测 …
return tool_results, synthesis_needed

async def _synthesize_realtime_reply(self, query, tool_results, history):
context_block = “\n\n”.join(context_parts)
messages = [{“role”: “system”, “content”: system_prompt}]
messages.extend(history[-6:])
messages.append({“role”: “user”, “content”: f"查询结果:{context_block}…"})
return await llm_manager.generate_with_history(messages)

FIX-4:记忆系统完整集成

**修复说明:**将 BuiltinMemoryProvider 接入消息处理流程,实现每轮对话的记忆同步和检索注入。

实现细节:

· 首次消息时初始化 BuiltinMemoryProvider(_init_memory_for_user)

· 每轮对话结束后调用 sync_turn() 同步到内存系统(TF-IDF 索引)

· 每轮对话前调用 prefetch() 检索相关记忆,注入 system prompt

· 支持 session 记忆(TTL 3600秒)和 long_term 记忆(持久化到磁盘)

**涉及文件:**wechat/ai_handler.py (行 106-133)

核心代码:

self._memory_provider = None
self._memory_initialized: Dict[str, bool] = {}

def _init_memory_for_user(self, sender_id, conversation_id):
from memory.builtin_memory import BuiltinMemoryProvider
from memory.config import DEFAULT_MEMORY_CONFIG
if self._memory_provider is None:
self._memory_provider = BuiltinMemoryProvider(DEFAULT_MEMORY_CONFIG)
session_key = f"wechat_{sender_id}_{conversation_id}"
self._memory_provider.initialize(session_key)
self._memory_initialized[sender_id] = True

def _get_memory_context(self, query, sender_id) → str:
context = self._memory_provider.prefetch(query, session_id=sender_id)
if context:
return f"\n[System note…]\n\n{context}\n"
return “”

def _sync_turn_to_memory(self, sender_id, user_content, assistant_content):
self._memory_provider.sync_turn(user_content, assistant_content, session_id=sender_id)

FIX-5:长对话上下文压缩

**修复说明:**当对话超过 20 轮时,自动压缩历史,保留摘要 + 最近 8 轮对话。

实现细节:

· 阈值常量 COMPRESS_AT_TURNS=20, KEEP_RECENT_TURNS=8

· _compress_conversation() 生成摘要(主题、首条消息、最近消息统计),插入为 system turn

· 保留最近 8 轮对话(用户最可能需要参考的上下文)

· 设置 is_compressed 标志,防止重复压缩

· 压缩后 topic 和 topic_set_at_turn 上下文值完整保留

**涉及文件:**wechat/ai_handler.py (行 135-172)

核心代码:

COMPRESS_AT_TURNS = 20
KEEP_RECENT_TURNS = 8

def _compress_conversation(self, conversation) → str:
turn_count = conversation.get_turn_count()
if turn_count < COMPRESS_AT_TURNS:
return “”
summary = self._generate_summary(conversation)
compressed_turn = conversation.add_turn(role=“system”,
content=f"[对话摘要] {summary}",
metadata={“compressed”: True, “original_turns”: turn_count})
kept_turns = conversation.turns[-KEEP_RECENT_TURNS:]
conversation.turns = [compressed_turn] + kept_turns
conversation.set_context_value(“is_compressed”, True)
return “[之前的对话已压缩,我在其中保留了关键信息…]”

四、验证测试

编号

测试项

预期结果

状态

验证数据

T1

会话ID持久化

同一用户多次发送消息,会话ID保持一致

通过

id1 == id2

T2

话题检测与注入

设置话题后,后续消息能正确注入话题上下文

通过

Topic stored: True

T3

话题优先级

“现在我们明确…” 优先进入话题分支而非时间查询

通过

is_topic_setting: True

T4

工具结果合成

计算器、天气、GitHub 查询结果通过 LLM 自然语言输出

通过

Calc: 14

T5

记忆初始化

首次消息时正确初始化 BuiltinMemoryProvider

通过

Memory initialized: True

T6

记忆同步

对话内容正确同步到记忆系统(TF-IDF索引)

通过

Memory sync+recall: True

T7

记忆检索注入

相关记忆内容正确注入 system prompt

通过

“” in mem_ctx

T8

上下文压缩

超过20轮后自动压缩,保留摘要+最近8轮

通过

Turns: 9, compressed=True

T9

压缩后功能完整

压缩后话题、记忆、检索仍然正常工作

通过

Topic preserved: True

T10

长期对话流程

25轮对话(~30条消息)全流程正常

通过

29 turns, memory=True

原问题复现验证

轮次

用户消息

Bot回复

验证结果

1

现在我们明确一下聊天主题为:AI助手与用户的协作伦理

(LLM自然语言回复,确认话题)

话题建立成功

2

你记得我们明确的聊天主题是什么吗?

(LLM基于上下文回答,提及AI助手与用户的协作伦理)

话题被正确回忆

3

北京天气怎么样?

(LLM合成后的自然语言天气回复)

天气查询自然化

4

继续讨论这个话题

(LLM保持话题一致性)

话题持续跟踪

五、架构改进总结

会话管理层

· 修复了会话ID不固定问题:从每次创建新会话 → 固定ID复用

· ConversationManager 提供 10+ 会话管理方法(压缩、摘要、分支、合并不再空转)

· context dict 用于存储话题、压缩标记等元数据

消息处理层

· 话题设置优先于实时查询(优先级队列逻辑)

· 实时查询结果通过 LLM 自然语言合成(非直接JSON输出)

· system prompt 三段式注入:压缩说明 + 话题上下文 + 记忆上下文

记忆系统层

· BuiltinMemoryProvider 完整激活:TF-IDF索引 + session存储 + long_term持久化

· 每轮同步(sync_turn)+ 每轮检索(prefetch)形成闭环

· 记忆权重算法:时间衰减(recency)+ 访问频率(frequency)+ 相关性(relevance)

上下文优化层

· 20轮自动压缩,防止token无限增长

· 压缩策略:摘要 + 最近8轮,平衡历史信息与上下文长度

· compression flag 防止重复压缩

六、CLI 工具增强

在本次优化的同时,还对 CLI 工具进行了增强,统一集成到 tools/system_tools/web_tools.py 中:

工具类

功能

备注

GitHubTrendingTool

GitHub热门项目查询

支持按语言/时间范围筛选

GitHubRepoSearchTool

GitHub仓库搜索

关键词搜索 + star数排序

GitHubFileFetchTool

GitHub文件内容获取

支持 owner/repo/path 获取文件

WeatherTool

天气预报

修复:使用 wttr.in JSON API 而非 HTML 解析

CalculatorTool

数学计算器

支持 sqrt/sin/cos/log/pi 等函数

ChineseNewsTool

搜狐新闻抓取

分类支持(国内/国际/科技/体育)

七、技术细节

7.1 关键技术点

· TF-IDF 索引:BuiltinMemoryProvider 使用 TF-IDF 算法构建倒排索引,支持高效的记忆检索

· 时间衰减:记忆相关性随时间指数衰减(base=0.95),确保近期记忆优先被召回

· 三段式 System Prompt:compression_note + topic_context + memory_context

· 异步处理:所有 LLM 调用使用 asyncio.wait_for() 超时控制(30秒)

· 城市名智能提取:正则去除"天气"/“怎么样”/"如何"等后缀,适配不同查询句式

7.2 修改文件清单

文件路径

修改内容

改动量

wechat/ai_handler.py

核心修改:会话管理、话题跟踪、记忆集成、压缩逻辑

~100行新增

tools/system_tools/web_tools.py

WeatherTool API修复

~5行修改

八、后续优化方向

· **向量检索升级:**当前使用 TF-IDF 关键词检索,可升级为向量嵌入检索(参考文件: memory/retriever.py)

· **外部记忆提供者:**支持 Redis/Honeycomb/Hindsight 等外部记忆后端(参考文件: memory/memory_provider.py)

· **智能话题检测:**当前基于关键词规则的话题检测,可升级为 LLM 自动分析(参考文件: wechat/ai_handler.py)

· **对话摘要生成:**当前使用规则摘要,可升级为 LLM 生成结构化摘要(参考文件: core/conversation.py)

· **会话持久化:**当前会话存储在内存中,重启后丢失,可接入 SQLite/Redis 持久化(参考文件: core/conversation.py)

────────────────────────────────────────────────────────────

TetherBot 项目组 | 2026年4月23日 | AI Programming Community

1 个赞

场景选对了,后面就看打磨了

1 个赞

场景选对了,后面就看打磨了

1 个赞

体验的项目需要优化一下,感觉有点bug

1 个赞

我想用 TRAE SOLO 搭建个人复利工程:基于 Obsidian 建立双链知识库,实现笔记自动结构化、每日复盘自动生成、知识卡片自动关联,把学习、投资复盘、项目管理长期复利沉淀,提升个人生产力。

1 个赞

报名,求邀请码,感恩

1 个赞

用 SOLO 打造像大厂面试官一样敢说真话的 AI 简历陪跑教练

欢迎投票,投票后访问链接支持每天直接使用,无需自配AI,点击即用

面向应届/在校大学生 (实习、校招、转专业、0–1 年早期求职者),在「投简历前的最后一关」提供 顶尖大厂面试官 + 资深 HRBP + 职业发展教练 三重身份的 AI 诊断与改写服务。

1 个赞

欢迎大家体验我用TRAE SOLO构建的疗愈小程序,多提宝贵建议,也欢迎大家帮我投上宝贵的一票!非常感谢 :rose: :rose:

1 个赞

想申请 SOLO 内测码

1 个赞

每一次玩儿这个,有些不太明白,得多看看,多学学

1 个赞

求个内测邀请码,谢谢!

1 个赞

内测码?这比赛是不是还没开始啊

1 个赞

我之前已经受邀加入了,这还没到5月10号,现在就不能用了,一直排队,什么情况。

1 个赞

有客服帮忙解决吗?我又申请重新加入排队了.

1 个赞

求邀请码:pleading_face:

1 个赞