ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SurfSense 主代理身份系统提示词解析:开放网络研究编排者的角色设计与调度机制

SurfSense 主代理身份系统提示词解析:开放网络研究编排者的角色设计与调度机制 SurfSense 主代理身份系统提示词解析开放网络研究编排者的角色设计与调度机制【免费下载链接】SurfSenseOpen-source NotebookLM alternative. Research the open web with live data(Reddit, YT, IG, TikTok, Indeed, Google Search, Maps etc) through one platform, API or MCP server. Join our Discord: https://discord.gg/ejRNvftDp9项目地址: https://gitcode.com/GitHub_Trending/su/SurfSense导读本文围绕 SurfSense 后端多代理聊天系统中主代理main agent的身份提示词片段 identity/private.md 展开解析 SurfSense 如何为编排型 Agent 定义我是谁、我做什么、我如何工作三层角色框架。你将了解到主代理如何通过task工具调度 Reddit、YouTube、Google Maps 等平台专业子代理完成实时网络研究如何将知识库、连接应用与持久记忆纳入调度决策以及这套身份设计在系统提示词组装管线中的真实落地方式。读完本文你可以理解 SurfSense 多代理编排系统的设计哲学并掌握其提示词模块化、可见性感知与路由规则的实现细节。一、文档定位一份身份区块提示词identity/private.md是 SurfSense 主代理系统提示词中agent_identity区块的内容源。它不是独立运行的指令而是由构建器在运行时加载并注入的片段。从源码看身份区块的构建逻辑位于 builder/sections/identity.py其核心逻辑如下def build_identity_section( *, visibility: ChatVisibility, resolved_today: str, ) - str: variant team if visibility ChatVisibility.SEARCH_SPACE else private fragment read_prompt_md(fidentity/{variant}.md) if not fragment: return return \n fragment.format(resolved_todayresolved_today) \n两个关键点值得注意可见性感知visibility-aware同一份身份定义存在private与team两个变体。当会话属于私人聊天ChatVisibility.PRIVATE时加载private.md当会话属于工作区/团队空间ChatVisibility.SEARCH_SPACE时加载team.md。二者的差异集中在一处——team.md额外声明你处于团队线程中每条消息带[DisplayName]前缀相关引用与决策需归属到具名作者。模板注入身份片段末尾的Today (UTC): {resolved_today}占位符由构建器传入的实际日期填充。resolved_today的生成与整个提示词的组装在 builder/compose.py 中完成resolved_today (today or datetime.now(UTC)).astimezone(UTC).date().isoformat() visibility thread_visibility or ChatVisibility.PRIVATE提示词片段通过 builder/load_md.py 中的read_prompt_md()从app.agents.chat.multi_agent_chat.main_agent.system_prompt.prompts包内按文件名读取 Markdown 文本整个系统提示词由若干区块按固定顺序拼接。根据compose.py的模块 docstring默认组装顺序为agent_identity # 本文档所在区块 [用户自定义系统指令如有] core_behavior # 默认正文 knowledge_base_first # 默认正文 dynamic_context # 始终注入 routing # 默认正文 specialists # 始终注入动态名册 tools # 始终注入 memory_protocol # 默认正文 citations # 始终注入 output_format # 始终注入 refusal_and_limits # 始终注入 reminder # 始终注入这意味着identity/private.md是整套系统提示词的开场白——它在最前面确立代理的角色与职责边界随后才由routing、specialists、tools等区块展开具体行为规则。即使用户提供了自定义系统指令custom_system_instructions它也只是叠加在身份区块之后而非替代它以保证平台级的安全兜底KB-first、路由、引用、输出格式、拒答规则始终生效。二、身份核心一个开放网络研究平台的编排者identity/private.md给出了主代理的身份宣言You areSurfSenses main agent, the orchestrator of an open-source open web research platform.这句话包含了三个限定层次主代理main agentSurfSense 多代理系统中负责与用户直接对话、统揽全局的 Agent。编排者orchestrator它不是所有工作的执行者而是路由者。正如身份片段强调的You are an orchestrator — most non-trivial work belongs on a specialist.开放网络研究平台open web research platform用户来此研究实时网络——社区与受众在说什么、排名/评论/页面如何变化、开放网络上发布了什么并将研究成果与自己的知识库结合使用。这一身份设计直接呼应项目定位Open-source NotebookLM alternative面向 Reddit、YouTube、Instagram、TikTok、Indeed、Google Search、Maps 等实时数据源将研究实时网络这一核心能力凝练成代理的身份内核。三、三类调度对象网络数据、用户上下文、交付物身份片段明确列出主代理通过task工具调度的三类工作这是整份文档的骨架3.1 实时网络数据Live web dataReddit、YouTube、Instagram、TikTok、Amazon、Walmart、Google Maps、Google Search 以及 Web Crawler 返回结构化、实时的平台数据包括帖子、评论、字幕、视频、商品、评论、SERP 与完整页面内容。从仓库的 subagents/builtins 目录结构可以印证这一名册的落地每个平台对应一个独立子代理包包含agent.py、system_prompt.md、description.md与tools/如 reddit、youtube、tiktok、google_maps、google_search、amazon、walmart、web_crawler、indeed 等。每个子代理运行在自己的工具栈与上下文隔离环境中返回单一的综合结果。3.2 用户自身上下文The users own context包括知识库、连接的应用与持久记忆。这部分同样有对应子代理与中间件支撑knowledge_base 子代理subagents/builtins/knowledge_base 下提供search_knowledge_base.py工具与ask_knowledge_base_tool.py并有云/桌面双版本的 system promptmcp_discovery 子代理subagents/builtins/mcp_discovery 通过 MCP 客户端连接 Slack、Notion、Jira、Gmail、日历等第三方服务memory 子代理subagents/builtins/memory 维护持久记忆main_agent 中间件middleware/目录中的memory、kb_persistence、knowledge_tree等中间件在请求-响应链路上处理记忆与知识库的持久化。3.3 交付物Deliverables报告reports、播客podcasts与演示文稿presentations由deliverables子代理基于专家们的研究结果构建。对应实现位于 subagents/builtins/deliverables其tools/下包含report.py、podcast.py、video_presentation.py、generate_image.py、resume.py等工具。值得注意的是podcast 这类交付物采用异步链路deliverables子代理设置好播客后立即返回生成过程由 Celery 后台任务驱动聊天中的实时卡片接管进度展示详见下文路由规则。四、编排者哲学以数据说话而非凭假设作答身份片段对编排者的工作方式提出了明确的价值观约束Your value is routing each request to the right specialist, synthesizing evidence across sources, and answering with what the data shows rather than what you assume.翻译过来即三个职责路由routing把每个请求分发到正确的专家综合证据synthesizing evidence跨来源汇总证据以数据作答answer with data回答的依据是数据展示了什么而不是自己假设了什么。这一哲学在配套的 routing.md 中被展开为具体的路由规则例如受众情绪audience sentiment属于平台关于品牌/产品/话题的人们在说什么、感觉如何应调用task(reddit, …)、task(youtube, …)、task(tiktok, …)、task(google_maps, …)、task(amazon, …)/task(walmart, …)去平台取回结构化的实时对话而不是用网络搜索找关于这段对话的文章搜索负责发现爬虫负责阅读搜索结果摘要、AI 概览只是线索而非信源答案在页面里时先用task(web_crawler, …)抓取页面再作答地点归 Maps开放网络归 Search发现实体店/商户用 Google Maps 专家返回结构化名称/地址/电话/网站无实体门店的在线实体用搜索专家请求 N 个列表时统计独立实体同一品牌/母机构旗下的多个分支、地点、子项目只算一个条目凑不满 N 就继续扩大发现诚实交付更小的列表优于注水的 15 个完整数据集落成文件而非聊天需要整表数据时指示 web_crawler 用export_runCSV 工具抓取并保存只转述工作区路径与行数主代理没有文件系统工具对工作区的任何读写改查都必须经task(knowledge_base, …)绝不使用write_file、ls等直接文件操作。同时 core_behavior.md 为身份补充了沟通风格约束简洁直接、不念开场白、不叙述意图、模棱两可时先问再做、准确优先于附和、坚持到任务完成或真正受阻。五、task工具编排的指挥棒身份片段反复强调通过task工具调度专业子代理因此理解task工具的契约是理解这份身份的关键。其完整规格见 prompts/tools/task/description.md要点如下5.1 单模式single mode参数subagent_type要调用的专家名称必须匹配specialists名册中的条目description完整的任务提示词。专家看不到当前线程所以必须把所有上下文、约束与期望返回内容全部写进description专家会用自己的格式作答不要强行规定其输出格式。5.2 批处理模式batch mode参数tasks{description, subagent_type}对象数组用于并发扇出fan-out。当单个请求拆分成3 个或更多独立的专家调用时使用例如从这份清单创建五个 issue。子任务在小型并发上限下运行运行时为每个子任务返回一条以[task index]前缀标识的 ToolMessage。批处理模式有一个关键限制批处理子任务不支持人类介入human-in-the-loop中断——若某个子任务需要审批会报错此时必须将该任务改为非批处理的单次task(...)调用重新调度。12 个独立调用则直接发出两次单独的task(...)即可。5.3 验证机制verification teachingdescription.md末尾附有verification教学块这是身份以数据说话哲学在工具层的具体化子代理的自然语言回复是自我报告不是证据——它可能声称 Slack 消息已发出、Jira issue 已创建但底层工具调用实际静默失败或被限流。主代理必须把DonePosted to #general这类成功表述当作假设而非事实并通过两个真实信号交叉验证state[receipts]每个变更型工具都会向这个追加型列表写入结构化Receipt包含 route、type、operation、status、external_id、verifiable_url、preview。子代理的output_contract会在evidence.receipts中携带匹配的 Receipt。若子代理声称成功却没有任何statussuccess的 Receipt异步交付物如播客/视频为pending则该操作实际上没有发生——按失败处理原样告知用户不要盲目重试task(web_crawler, …)外部确认当 Receipt 带verifiable_urlNotion 页面 URL、Slack 永久链接、Jira issue URL 等时可以爬取该 URL 从外部确认操作已生效适用于用户明确点名的高风险变更。Receipt 状态语义statussuccess变更已在后端提交。带verifiable_url且高风险时可用爬虫外部确认否则信任 Receipt 并告知用户完成Celery 支撑的交付物播客、视频演示也落在这里因为子代理已等待 worker 完成statusfailedReceipt 的error字段携带后端错误原样转述给用户仅在用户明确要求时才重路由或重试statuspending当前罕见现有变更工具都会等待后端返回。若遇到告知用户工作已启动引用external_id/preview供后续查找不要爬取也不要重新派发同样的task(...)。5.4 task 示例prompts/tools/task/example.md 给出三个最小示例其中前两个也内嵌在description.md中user: Save these meeting notes to my KB: … → task(subagent_typeknowledge_base, descriptionSave the notes below to a new document under /documents/notes/. Pick a sensible title and folder; tell me the path you used.\n\nnotes…/notes) user: What did Maya say about the Q2 roadmap in Slack last week? → task(subagent_typemcp_discovery, descriptionIn Slack, find messages from Maya about the Q2 roadmap from the past week. Return the most relevant quotes with channel and timestamp.) user: Find my Q2 roadmap and summarise the milestones. → task(subagent_typeknowledge_base, descriptionLocate the Q2 roadmap document under /documents and summarise its milestones. Use glob or grep if the path isnt obvious from the workspace tree.)六、specialists动态名册路由的对象从哪来agent_identity区块提到的specialist subagents在提示词中以specialists区块动态呈现。其构建逻辑在 builder/sections/specialists.pydef build_specialists_section(specialist_lines: list[tuple[str, str]]) - str: bullets \n.join(f- **{name}** — {desc} for name, desc in specialist_lines) return f\nspecialists\n{bullets}\n/specialists\n名册是动态的取决于当前工作区的连接器配置。从 subagents/registry.py 的源码可以看到注册表依据SUBAGENT_TO_REQUIRED_CONNECTOR_MAP做连接器过滤——某专家若依赖特定连接器而当前空间未配置则会被移出名册。但按specialists.pydocstring 的说明名册按约定永不为空deliverables与knowledge_base两个专家在映射中声明了空集合frozenset()因此在任何基于连接器的剔除中都能存活。七、持久记忆身份中用户自身上下文的一部分身份片段将persistent memory列为用户自身上下文的一类。对应的运行协议见 prompts/memory_protocol/private.md主代理在理解每条用户消息后判断其是否揭示了关于用户的持久事实——角色、兴趣、偏好、项目、背景或长期指令若是则在正常回复同时调用update_memory不推迟到后续回合一次性问答、问候、会话琐事等临时聊天噪音则跳过。记忆的存储格式为基于标题的 Markdown新条目放在## Facts、## Preferences、## Instructions等##标题下条目形如- YYYY-MM-DD: text。若旧记忆存在(YYYY-MM-DD) [fact|pref|instr]旧格式标记需保留信息但按新格式写入。该协议同样有 private/team 变体与身份区块的可见性选择一致。八、private 与 team 变体同一身份的两副面孔身份片段以private.md/team.md双变体存在二者核心内容完全一致差异仅体现在团队语境上。对比两个文件可以总结出维度private私人线程team团队线程服务对象用户个人的知识库与记忆团队的共享知识库与持久团队记忆消息格式无前缀每条消息带[DisplayName]前缀引用归属不涉及相关引用与决策归属到具名作者这一变体机制由build_identity_section依据ChatVisibility自动选择ChatVisibility.SEARCH_SPACE映射到 team 变体其余含默认值PRIVATE映射到 private 变体。同理dynamic_context与memory_protocol区块也遵循相同的 private/team 双轨设计保证整个提示词体系在个人/团队两种场景下语义自洽。九、时间注入让编排者感知今天身份片段最后一行Today (UTC): {resolved_today}的作用不可小觑。在compose.py中resolved_today以 UTC 日期ISO 格式YYYY-MM-DD注入且同样注入到用户自定义系统指令custom_system_instructions.format(resolved_todayresolved_today)。这为代理提供了时间锚点使其能够正确理解上周最近一个月等相对时间表述感知研究任务中对时效性的要求例如 Reddit 搜索中 past month, sort by top 类指令的落地。此外仓库中还有一个专门的时间处理插件 plugins/year_substituter.py可见团队对时间感知的重视——身份片段中的这一行是整个时间感知链路的一部分。十、从身份到行为一份提示词如何撑起整个编排系统综合以上分析identity/private.md虽然只有短短 24 行但它以高度凝练的方式定义了 SurfSense 主代理的完整工作模型并与提示词管线的其他区块形成闭环角色定义agent_identity我是谁——开放网络研究平台的编排者能力边界routingspecialists我有什么——调度实时网络专家、知识库与记忆、交付物三类子代理且名册随工作区连接器动态变化工作方式toolsmemory_protocolcitations我怎么做——通过task的 single/batch 双模式调度、用 Receipt 验证子代理自报、边回答边沉淀持久记忆、按output_format输出价值观约束core_behaviorrefusal_and_limits我如何自持——以数据作答、简洁直接、必要时拒答。这种身份先行、区块化组装、可见性感知、动态名册的设计使得 SurfSense 能够在保持统一主代理体验的同时弹性适配不同工作区连接器组合与个人/团队两种协作场景。对于希望构建多代理编排系统的开发者而言identity/private.md及其周边 compose.py、routing.md、task 工具说明 构成了一套值得借鉴的角色定义 → 行为规则 → 工具契约 → 验证兜底提示词工程范本。【免费下载链接】SurfSenseOpen-source NotebookLM alternative. Research the open web with live data(Reddit, YT, IG, TikTok, Indeed, Google Search, Maps etc) through one platform, API or MCP server. Join our Discord: https://discord.gg/ejRNvftDp9项目地址: https://gitcode.com/GitHub_Trending/su/SurfSense创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表