synalinks

SynaLinksApache-2.0活跃维护

基于 Keras 的神经符号语言模型框架,把 LM 与符号推理、强化学习结合,支持上下文学习和测试时自适应。

Keras based framework for neuro-symbolic LM systems

暂无版本465star +1 / 7 天48fork同步于 2026-11-10 17:59 UTC

怎么上手

由 README 提炼,执行前请确认
uvx synalinks init
uv add synalinks
硬件要求按 README 说明

README 未说明显存或 GPU 要求;模型通过 LiteLLM 调用远程 API 或本地 Ollama/vLLM/SGLang 等服务,硬件取决于所选后端。

支持 Apple Silicon
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

基于 Keras 的神经符号 LM 框架,用声明式 API 快速搭建 RAG、Agent 与推理系统

基于 Keras 的神经符号语言模型框架,把 LM 与符号推理、强化学习结合,支持上下文学习和测试时自适应。

核心能力

  • 像搭 Keras Layer 一样组合 Module 构建 LM 程序
  • 用 .compile()/.fit() 做上下文强化学习优化提示词
  • 内置嵌入式图数据库支持知识图谱 RAG 与语义去重
  • 通过 LiteLLM 一行切换 Ollama、OpenAI、Anthropic 等后端
  • 内置无 Docker 的纯 Python 沙箱运行不可信代码与工具

容易踩的坑

需自行配置并运行所选的模型后端(如 Ollama、vLLM 或云 API key),框架本身不含模型;示例中的 DeepAgent 依赖额外用 npx skills add 安装的 skills 目录;项目处于 Beta 阶段,API 可能变动。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

0 个版本

暂无 release 数据(可能没有发版,或尚未同步)。

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    From idea to production in just few lines

    The first neuro-symbolic Language Model (LM) framework leveraging the simplicity of Keras and the rigor of Deep Learning best practices.

    Build RAGs, tool-using agents, multi-agents systems, recursive agents and more in just few lines

    Deutsch | English | Español | Français | Italiano | 日本語 | 한국어 | Português | Русский | 中文

    If you find Synalinks useful, please star the repo! Help us reach more AI/ML engineers and grow the community.

    Beta Code style: black Coverage Badge Downloads Discord Python package License: Apache-2.0

    Want to use Synalinks with your own coding agent (Claude Code, Cursor, Copilot, etc.)? Add the Synalinks-specific skills from synalinks-skills on GitHub to your agent; they teach it the framework conventions and give it the context it needs to build Synalinks programs right away.

    What Is Synalinks?

    Synalinks is an open-source neuro-symbolic framework that makes it simple to create, train, evaluate, and deploy advanced LM-based applications, including RAGs, autonomous agents, and self-evolving reasoning systems.

    Think Keras for Language Models applications, a clean, declarative API where:

    Key Principles

    Who Is It For?

    RoleWhy Synalinks Helps
    AI DevelopersBuild complex production grade LM apps without boilerplate.
    AI ResearchersPrototype neuro-symbolic and RL-in-context systems fast.
    Data ScientistsIntegrate LM workflows with APIs & databases.
    Students/HobbyistsLearn AI composition in a clean, intuitive framework.

    Why Synalinks?

    Many frameworks exist today; here is what Synalinks does differently:

    • Embedded, container-free sandbox : agents run untrusted code and tools in a safe, isolated runtime that needs no Docker or external sandbox service. The whole stack is pure-Python and embeddable, so it is great for scripting, research, serverless/cloud deployment (S3, Lambda, notebooks, etc.) or even for creating CLI harnesses!
    • Embedded database support : build graph-based RAG and agentic memories with constrained Knowledge Graph extraction and automatic semantic deduplication, on top of an embedded graph database, with no separate graph server to run. Additionally, a fast embedded SQL knowledge base is available to store relational data and build vector/SQL RAGs.
    • In-Context RL to optimize your prompts (and anything else) : train and optimize prompts, few-shot examples, and any trainable variable per module without touching model weights, using the familiar .compile() / .fit() / .evaluate() / .predict() API.
    • Effortless model switching : set a default once with synalinks.set_default_language_model(...) or pass a string identifier, and swap between Ollama, vLLM, SGLang, OpenAI, Azure, Anthropic, Mistral, Groq, Gemini, xAI, Cohere, DeepSeek, Together AI, OpenRouter, AWS Bedrock, Doubleword and Mirai via LiteLLM, including multi-objective model selection to pick the best model for cost/quality.
    • Scaffold in one command, bring your own coding agent : bootstrap a production-ready project with synalinks init (batteries-included templates for scripts, agents, and training), then drop in the official Synalinks skills so Claude Code, Cursor, Copilot and friends write idiomatic Synalinks code from the start.

    Plus everything you'd expect from a production-grade framework:

    Requirements

    Python 3.12 or newer, plus the code sandbox's system dependency for your OS.

    Linux: install fuse3, which brings the libfuse of your distribution:

    sudo apt install fuse3      # Debian / Ubuntu
    sudo dnf install fuse3      # Fedora / RHEL
    sudo pacman -S fuse3        # Arch
    sudo zypper install fuse3   # openSUSE
    # Ubuntu 23.10+ only: allow the unprivileged user namespaces the sandbox needs
    sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
    

    macOS (Apple silicon):

    xcode-select --install
    brew tap slp/krun
    brew trust --formula slp/krun/libkrun slp/krun/libkrunfw slp/krun/virglrenderer-krun  # recent Homebrew only
    brew install slp/krun/libkrun
    

    Windows: install WSL2 (wsl --install), then run the Linux commands inside it.

    The sandbox always uses the strongest isolation your machine supports and refuses to run code it cannot confine (on Macs without libkrun, such as Intel Macs, it falls back to a weaker macOS sandbox).

    Quickstart in 3s with uv (recommended)

    If you don't know uv, install it here.

    Follow the instructions to start a new synalinks project in 3s:

    uvx synalinks init
    

    You can also install the library in a new project with:

    uv add synalinks
    

    To transform your coding agent into an AI engineer, do this at the root of your project:

    npx skills add SynaLinks/synalinks-skills --skill synalinks
    

    Example

    Synalinks agents can now read your project's AGENTS.md conventions and use Agent Skills. The example below wires the official Synalinks skills into a DeepAgent, a sandboxed coding agent, and asks it to design the input/output data models for a task, writing them into a workspace/ folder.

    First set up the workspace. Install the official Synalinks skill with the skills CLI and add an AGENTS.md. The skill lands under the workdir, so the sandboxed agent can read its body on demand:

    mkdir -p workspace && cd workspace
    # Installs the `synalinks` skill into ./.agents/skills/ and writes skills-lock.json.
    npx skills add SynaLinks/synalinks-skills --skill synalinks
    

    This gives the layout below: .agents/skills is the skills root (one sub-folder per skill, each holding a SKILL.md):

    workspace/
    ├── AGENTS.md                     # injected as the agent's conventions
    ├── skills-lock.json              # pins the skill to a source repo + content hash
    └── .agents/
        └── skills/                   # the skills root
            └── synalinks/
                └── SKILL.md          # name + description surfaced; body read on demand
    

    main.py:

    import synalinks
    import asyncio
    
    # Set the default once; modules pick it up automatically.
    synalinks.set_default_language_model("gemini/gemini-3.1-flash-lite-preview")
    
    
    # The agent's structured final answer.
    class Deliverable(synalinks.DataModel):
        summary: str = synalinks.Field(
            description="What was created and where",
        )
        files: list[str] = synalinks.Field(
            description="Paths of the files written into the workspace",
        )
    
    
    async def main():
        # A DeepAgent converses in ChatMessages (it is a coding agent).
        inputs = synalinks.Input(data_model=synalinks.ChatMessages)
    
        agent = synalinks.DeepAgent(
            data_model=Deliverable,
            # The sandbox is seeded from this directory (host-safe: the agent's
            # writes land in the sandbox copy, never on your disk). Its `AGENTS.md` is
            # injected so the agent follows your conventions.
            workdir="workspace",
            # The skills root (installed by `skills add`). Listed to the agent as
            # `<available_skills>`; it reads each `SKILL.md` on demand from the
            # sandbox, which is why the skills live under `workdir`.
            skills=["workspace/.agents/skills"],
        )
        outputs = await agent(inputs)
    
        program = synalinks.Program(
            inputs=inputs,
            outputs=outputs,
            name="datamodel_designer",
            description="Designs Synalinks data models for a given task",
        )
    
        task = (
            "Define the input and output Synalinks DataModels for a support-ticket "
            "triage task: the input is a raw customer message; the output is the "
            "predicted category, a priority, and a short suggested reply. Write them "
            "to `models.py` using idiomatic Synalinks; consult the skills first."
        )
        result = await program(
            synalinks.ChatMessages(
                messages=[synalinks.ChatMessage(role="user", content=task)],
            )
        )
        print(result.prettify_json())
    
    
    if __name__ == "__main__":
        asyncio.run(main())
    

    Data Model Operators

    Synalinks provides Python operators for combining and manipulating data models, enabling sophisticated control flow. See the Control Flow guide for the routing, fan-out, and merge patterns these operators enable:

    OperatorNameDescriptionUse Case
    +ConcatenationCombines fields from both data models. Raises exception if either is None.Merging outputs from parallel branches
    &Logical AndSafe concatenation that returns None if either input is None.Combining with potentially null branch outputs
    |Logical OrReturns the non-None data model. If both are non-None, merges them.Gathering outputs from conditional branches
    ^Logical XorReturns data if exactly one input is non-None, otherwise None.Exclusive branch selection
    ~Logical NotReturns None if input is non-None, or a empty data model if None.Inverting branch conditions
    inContainsChecks if a string key exists in the schema properties, or if another data model's schema is contained. Returns True or False.Conditional field checking, schema validation
    # Parallel branches with concatenation
    x1 = await generator1(inputs)
    x2 = await generator2(inputs)
    # combined = x1 *and* x2
    combined = x1 & x2  # Merge both outputs (add _{i} suffix if key collision)
    # [...]
    # Conditional branches with logical or
    (easy, hard) = await synalinks.Branch(
        question="Is this query complex?",
        labels=["easy", "hard"],
        branches=[simple_generator, complex_generator],
    )(inputs)
    # result = easy *or* hard
    result = easy | hard  # Get whichever branch was selected
    

    Getting a summary of your program

    To print a tabular summary of your program:

    program.summary()
    

    Or a plot (Useful to document your system):

    synalinks.utils.plot_program(
        program,
        show_module_names=True,
        show_trainable=True,
        show_schemas=True,
    )
    

    The data model designer program visualized with plot_program: Input → DeepAgent. Trainable modules are marked in green.

    Running your program

    To run your program use the following:

    result = await program(
        Query(
            query=(
                "A bookstore receives a shipment of 135 new books."
                "They place the books evenly onto 9 shelves."
                "Later, they decide to move 3 books from each shelf to a display table"
                " at the front of the store. "
                "How many books are left on the shelves after the books are moved?"
            )
        ),
    )
    

    Training your program/agent

    # Setting the default language/embedding models allows you
    # to use the string identifier (Keras-like) to configure your pipeline/training.
    # You can still instantiate the classes if you want fine-grained control.
    synalinks.set_default_language_model("gemini/gemini-3.1-flash-lite-preview")
    synalinks.set_default_embedding_model("gemini/text-embedding-004")
    
    
    async def main():
    
        # ... your program definition
    
        (x_train, y_train), (x_test, y_test) = synalinks.datasets.gsm8k.load_data()
    
        program.compile(
            reward=synalinks.rewards.ExactMatch(in_mask=["answer"]),
            optimizer="omega",
        )
    
        batch_size = 1
        epochs = 10
    
        history = await program.fit(
            x_train,
            y_train,
            validation_split=0.2,
            batch_size=batch_size,
            epochs=epochs,
        )
    
    
    if __name__ == "__main__":
        asyncio.run(main())
    

    Saving & Loading

    To save the entire architecture and variables (the program's state) into a JSON file, do:

    program.save("my_program.json")
    

    In order to load it, do:

    loaded_program = synalinks.Program.load("my_program.json")
    

    To save only the state your program (the variables) into JSON:

    program.save_variables("my_program.variables.json")
    

    To load its variables (needs a program with the same architecture), do:

    program.load_variables("my_program.variables.json")
    

    Logging

    To enable logging, use the following at the beginning of your script:

    synalinks.enable_logging()
    

    Observability

    Synalinks provides built-in observability through MLflow for tracing and monitoring your programs.

    Important: Call enable_observability() before creating any modules.

    import synalinks
    
    # Enable observability first
    synalinks.enable_observability(
        tracking_uri="http://localhost:5000",  # Optional: MLflow server URI
        experiment_name="my_experiment",  # Optional: defaults to "synalinks_traces"
    )
    
    # Then create your modules - they will be automatically traced
    inputs = synalinks.Input(data_model=Query)
    outputs = await synalinks.Generator(...)(inputs)
    

    For training metrics and artifacts, use the Monitor callback:

    monitor = synalinks.callbacks.Monitor(
        tracking_uri="http://localhost:5000",
        experiment_name="training_runs",
    )
    
    await program.fit(x=train_x, y=train_y, callbacks=[monitor])
    

    See the Observability guide for advanced configuration.

    Learn more

    You can learn more by reading our documentation. If you have questions, the FAQ might help you.

    Contributions

    Contributions are welcome, either for the implementation of additional modules, metrics, or optimizers. For more information, or help for implementing your ideas (or ones from a paper), please join our discord.

    Beware that every additional metric/module/optimizer should be approved by the core team, we want to keep the library minimal and clean as possible to avoid an uncontrolled growth leading to bad software practices like in most current leading LM frameworks.

    If you have specific feedbacks or features request we invite you to open an issue.

    Contributors

    Your contributions, feedback, and support are what make this project thrive.

    From small bug fixes to major features, thank you for believing in open collaboration and the future of neuro-symbolic AI.

    Community

    Join our community to learn more about neuro-symbolic systems and the future of AI. We welcome the participation of people from very different backgrounds or education levels.

    Citing our work

    This work have been done under the supervision of François Chollet, the author of Keras. If this work is useful for your research please use the following bibtex entry:

    @misc{sallami2025synalinks,
      title={Synalinks},
      author={Sallami, Yoan and Chollet, Fran\c{c}ois},
      year={2025},
      howpublished={\url{https://github.com/SynaLinks/Synalinks}},
    }
    

    Credit

    Synalinks would not be possible without the great work of the following open-source projects:

    • Keras for the graph-based computation backbone, API and overall code, design and philosophy.
    • DSPy for the modules/optimizers inspiration.
    • Pydantic for the backend data layer.
    • LiteLLM for the LMs integrations.
    • DuckDB, Ladybug, LanceDB for their amazing embedded databases.
    • MirageAI for their amazing sandbox!