Show HN: OpenSymbolicAI – 开放符号智能:使用类型变量的智能体,而非仅是上下文填充

2作者: rksart大约 8 小时前
Hi HN, 过去一年,我们一直在构建 AI 智能体,但一直遇到同样的瓶颈:提示工程感觉不像软件工程,更像是在瞎猜。 我们构建了 OpenSymbolicAI,旨在将智能体开发转变为真正的编程。它是一个开源框架(MIT 许可证),允许您使用类型化的原语、显式分解和单元测试来构建智能体。 主要问题:上下文窗口滥用 大多数智能体框架(如 ReAct)迫使您将工具输出转储回 LLM 的上下文窗口,以决定下一步。 智能体搜索数据库。 智能体取回 50kb 的 JSON。 您将这 50kb 粘贴回提示中,只是为了问“我下一步该怎么做?” 这很慢,成本高昂,并且会混淆模型。 解决方案:将数据作为变量 在 OpenSymbolicAI 中,LLM 生成一个操作变量的计划(代码)。实际的重型数据(搜索结果、PDF 内容、API 有效载荷)存储在 Python/运行时变量中,并且在特定原语实际需要读取它之前,永远不会通过 LLM 上下文。 可以将其视为智能体的传引用。LLM 操作变量句柄(文档),而 Python 运行时存储实际数据。 示例:RAG 智能体 LLM 不再基于一堆文本幻构一个计划,而是简单地编写操作数据容器的逻辑。 ```python class ResearchAgent(PlanExecute): @primitive def retrieve_documents(self, query: str) -> list[Document]: """从向量数据库中提取大型文档。""" # 返回保留在 Python 内存中的大型对象 return vector_store.search(query) @primitive def synthesize_answer(self, docs: list[Document]) -> str: """使用文档生成答案。""" # 这是唯一实际读取文档文本的步骤 context = "\n".join([d.text for d in docs]) return llm.generate(context) @decomposition(intent="研究量子计算") def _example_flow(self): # LLM 生成此执行计划。 # 关键是:LLM 管理 'docs' 变量符号, # 但在规划期间从未看到其中的大量有效载荷。 docs = self.retrieve_documents("量子计算的现状") return self.synthesize_answer(docs) ``` ```python agent = ResearchAgent() agent.run("研究固态电池的最新进展") ``` 讨论 我们很乐意听取社区的意见: 您在提示工程的脆弱性方面遇到过哪些困难? 什么会说服您尝试将提示视为代码? 这种方法在其他领域是否会大放异彩? 为了让它为您的用例做好生产准备,还缺少什么? 代码是有意使用简单的 Python,没有魔法,没有框架锁定。如果这种方法引起共鸣,很容易适应您的特定需求或与现有代码库集成。 代码库: 核心(Python):[https://github.com/OpenSymbolicAI/core-py](https://github.com/OpenSymbolicAI/core-py) 文档:[https://www.opensymbolic.ai/](https://www.opensymbolic.ai/) 博客(技术深度探讨):[https://www.opensymbolic.ai/blog](https://www.opensymbolic.ai/blog)
查看原文
Hi HN,<p>We&#x27;ve spent the last year building AI agents and kept hitting the same wall: prompt engineering doesn&#x27;t feel like software engineering. It feels like guessing.<p>We built OpenSymbolicAI to turn agent development into actual programming. It is an open-source framework (MIT) that lets you build agents using typed primitives, explicit decompositions, and unit tests.<p>THE MAIN PROBLEM: CONTEXT WINDOW ABUSE<p>Most agent frameworks (like ReAct) force you to dump tool outputs back into the LLM&#x27;s context window to decide the next step.<p>Agent searches DB.<p>Agent gets back 50kb of JSON.<p>You paste that 50kb back into the prompt just to ask &quot;What do I do next?&quot;<p>This is slow, expensive, and confuses the model.<p>THE SOLUTION: DATA AS VARIABLES<p>In OpenSymbolicAI, the LLM generates a plan (code) that manipulates variables. The actual heavy data (search results, PDF contents, API payloads) is stored in the Python&#x2F;runtime variables and is never passed through the LLM context until a specific primitive actually needs to read it.<p>Think of it as pass-by-reference for Agents. The LLM manipulates variable handles (docs), while the Python runtime stores the actual data.<p>EXAMPLE: A RAG AGENT<p>Instead of the LLM hallucinating a plan based on a wall of text, it simply writes the logic to manipulate the data containers.<p>class ResearchAgent(PlanExecute):<p><pre><code> @primitive def retrieve_documents(self, query: str) -&gt; list[Document]: &quot;&quot;&quot;Fetches heavy documents from vector DB.&quot;&quot;&quot; # Returns heavy objects that stay in Python memory return vector_store.search(query) @primitive def synthesize_answer(self, docs: list[Document]) -&gt; str: &quot;&quot;&quot;Consumes documents to generate an answer.&quot;&quot;&quot; # This is the ONLY step that actually reads the document text context = &quot;\n&quot;.join([d.text for d in docs]) return llm.generate(context) @decomposition(intent=&quot;Research quantum computing&quot;) def _example_flow(self): # The LLM generates this execution plan. # Crucially: The LLM manages the &#x27;docs&#x27; variable symbol, # but never sees the massive payload inside it during planning. docs = self.retrieve_documents(&quot;current state of quantum computing&quot;) return self.synthesize_answer(docs) </code></pre> agent = ResearchAgent() agent.run(&quot;Research the latest in solid state batteries&quot;)<p>DISCUSSION<p>We&#x27;d love to hear from the community about:<p>Where have you struggled with prompt engineering brittleness?<p>What would convince you to try treating prompts as code?<p>Are there other domains where this approach would shine?<p>What&#x27;s missing to make this production-ready for your use case?<p>The code is intentionally simple Python, no magic, no framework lock-in. If the approach resonates, it&#x27;s easy to adapt to your specific needs or integrate with existing codebases.<p>Repos:<p>Core (Python): <a href="https:&#x2F;&#x2F;github.com&#x2F;OpenSymbolicAI&#x2F;core-py" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;OpenSymbolicAI&#x2F;core-py</a><p>Docs: <a href="https:&#x2F;&#x2F;www.opensymbolic.ai&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.opensymbolic.ai&#x2F;</a><p>Blog (Technical deep dives): <a href="https:&#x2F;&#x2F;www.opensymbolic.ai&#x2F;blog" rel="nofollow">https:&#x2F;&#x2F;www.opensymbolic.ai&#x2F;blog</a>