Files
mirosociety/docs/问题记录-2026-09-27-硬编码与搜索替换.md
T
2026-09-27 23:06:24 +08:00

4.8 KiB
Raw Blame History

问题记录:2026-09-27

状态:待处理(明天再动) 记录人:项目相关方 本文件只记问题,不附解决方案。


一、背景

今天在排查项目时发现两个独立但都和"千人模拟"业务相关的问题。先记下来,明天再决定怎么处理。


二、问题一:每轮 active agent 数量硬编码,与"千人模拟"业务叙事冲突

现象

在 backend/app/services/engine.py 的 _select_active_agents 里,每一轮参与决策的市民数量由这两个常量决定:

active_agents_per_round_min: int = 3
active_agents_per_round_max: int = 10

来源:backend/app/models/world.py 的 TimeConfig

我观察到的问题

  1. 抽样率随人口规模塌缩。 100 人社区 → 3%–10% 采样,1000 人 → 0.3%–1%,10000 人 → 0.03%。但产品的对外叙事是"千人社会模拟"。
  2. 业务参数 vs 工程参数混淆。 这两个数字看起来是 TimeConfig(业务/世界设定),但更像是 LLM 成本阀门。混在一起,没办法独立调。
  3. len(agents) * 0.6 这个上限看起来是为更大规模预留的,但在默认 3–10 的基础上永远是死代码。 暗示当初设计是想过随规模调整的。
  4. 3–10 个人的表态,能涌现出什么? 默认权重 w=0.3,平静的人天然偏低,抽样会偏向情绪激动的小群体。
  5. 业务承诺 vs 实际行为错配。 用户为"千人社会模拟"付费,生成阶段认真做了 1000 个 backstory;一轮跑下来认真读 prompt 的只有 6 个。这到底是性能问题还是产品问题?

待澄清的几个点

  • 为什么 min/max 默认是 3–10?
  • 是否有人为"千人"规模做过代表性 / 抽样率的论证?
  • 这个参数应该让用户在产品层感知到(作为旋钮),还是只放在工程内部?

三、问题二:搜索后端从 DuckDuckGo 替换为 SearXNG

现象

现在 backend/app/services/research.py 用的是 duckduckgo_search:

from duckduckgo_search import DDGS
with DDGS() as ddgs:
    return list(ddgs.text(query, max_results=max_results))

我想替换为自托管的 SearXNG,原因(这里只描述动机,不给方案):

  • DDG 经常触发反爬 / CAPTCHA,结果不稳定
  • 模拟场景需要可重复性(同一 query 多次结果尽量一致)
  • 想避免外部限流风险

相关材料(已确认)

项目里已有 SearXNG 的 skill 文档:skills/searxng_skills/

关键信息(待修改时要严格遵守):

  • 域名是 searxng.erhe.top(不是 ehre.top — h/r 反着,#1 常见坑)⚠
  • 必须带 token=fGWEFWGrgasegtjt1jUJG,否则 403
  • 当前服务器 GET 即可(本地 stock docker 默认 POST,不要照搬本地配置)
  • JSON 200 路径:/search?format=json&token=...
  • 返回字段:title / content / url,需要重命名映射到现有 title / body / href

已处理

  • ✅ 域名拼写错误问题,今天已修。

待处理(明天动手)

  • research.py 的 _raw_search 替换为 SearXNG 调用
  • __init__ 加 searxng_base_url / searxng_token / searxng_timeout 参数
  • config.py 加对应 Settings 字段
  • main.py 注入新参数
  • .env 写 SEARXNG_BASE_URL / SEARXNG_TOKEN / SEARXNG_TIMEOUT
  • 是否保留 DDG fallback?待定
  • 是否加 query 短缓存(避免同 query 短时间重复打后端)?待定

还需要决定的

  • searxng_timeout 取多少?skills 里两处不一致(SKILL.md 是 30,searxng_skills.md 是 15)。模拟里 30 太久(卡轮),5 太短。倾向 15。
  • safesearch 取 0 还是 1?模拟里有些社会议题可能需要未过滤内容。

四、相关代码位置

  • 抽样逻辑:backend/app/services/engine.py _select_active_agents(约 765–833 行)
  • 抽样配置:backend/app/models/world.py TimeConfig(约 14–17 行)
  • 搜索实现:backend/app/services/research.py
  • 搜索配置:backend/app/config.py Settings.search_enabled / max_searches_per_round
  • LLM 客户端 / semaphore:backend/app/services/llm.py
  • LLM 并发配置:backend/app/config.py Settings.max_concurrent_llm_calls
  • SearXNG skill 文档:skills/searxng_skills/SKILL.md

五、与上一份记录的关系

这是第二份问题记录(第一份是 问题记录-硬编码与千人模拟.md)。

两者的区别:

  • 第一份 只聚焦硬编码 / 千人模拟的业务问题(问题一),是完整提问人视角的论述。
  • 这份 把搜索替换作为独立问题追加进来,并标注"今天已修 / 明天待办"的拆分。